The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

ClipTool.vala in libbirdfont

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libbirdfont/ClipTool.vala.
Copy and paste strokes
1 /* 2 Copyright (C) 2012 2014 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 namespace BirdFont { 16 17 public class ClipTool : Tool { 18 19 public static void copy_text (TextArea t) { 20 MainWindow.native_window.set_clipboard_text (t.get_selected_text ()); 21 } 22 23 public static void paste_text (TextArea t) { 24 if (t.carret_is_visible) { 25 t.insert_text (MainWindow.native_window.get_clipboard_text ()); 26 } 27 } 28 29 public static void copy () { 30 FontDisplay fd = MainWindow.get_current_display (); 31 string svg_data; 32 string bf_data; 33 string data; 34 35 if (fd is Glyph) { 36 svg_data = ExportTool.export_selected_paths_to_svg (); 37 bf_data = export_selected_paths_to_birdfont_clipboard (); 38 data = svg_data + bf_data; 39 MainWindow.native_window.set_clipboard (data); 40 MainWindow.native_window.set_inkscape_clipboard (data); 41 } else if (fd is OverView) { 42 copy_overview_glyphs (); 43 } 44 } 45 46 /** Copy entire glyph. */ 47 public static void copy_glyph (Glyph glyph) { 48 string svg_data; 49 string bf_data; 50 string data; 51 52 svg_data = ExportTool.export_to_inkscape_clipboard (glyph, false); 53 bf_data = export_paths_to_birdfont_clipboard (false, false); 54 55 data = svg_data + bf_data; 56 MainWindow.native_window.set_clipboard (data); 57 MainWindow.native_window.set_inkscape_clipboard (data); 58 } 59 60 public static void copy_overview_glyphs () { 61 string svg_data = ""; 62 string bf_data = ""; 63 string data; 64 OverView o = MainWindow.get_overview (); 65 66 if (o.selected_items.size > 0) { 67 svg_data = ExportTool.export_to_inkscape_clipboard ( 68 o.selected_items.get (0).get_current (), false); 69 70 bf_data = export_paths_to_birdfont_clipboard (true, false); 71 72 data = svg_data + bf_data; 73 MainWindow.native_window.set_clipboard (data); 74 MainWindow.native_window.set_inkscape_clipboard (data); 75 } 76 } 77 78 public static void paste_in_place () { 79 paste_paths (true); 80 } 81 82 /** Paste at cursor. */ 83 public static void paste () { 84 FontDisplay fd = MainWindow.get_current_display (); 85 Glyph g = MainWindow.get_current_glyph (); 86 double x, y, w, h; 87 double dx, dy; 88 89 if (fd is Glyph) { 90 paste_paths (false); 91 92 g.selection_boundaries (out x, out y, out w, out h); 93 94 dx = g.motion_x - x - w / 2.0; 95 dy = g.motion_y - y + h / 2.0; 96 97 foreach (Path path in g.active_paths) { 98 path.move (dx, dy); 99 } 100 } else if (fd is KerningDisplay) { 101 paste_letters_to_kerning_tab (); 102 } else if (fd is OverView) { 103 paste_to_overview (); 104 } 105 } 106 107 static void paste_paths (bool paste_guide_lines) { 108 bool is_bf_clipboard; 109 FontDisplay fd; 110 string clipboard_data = MainWindow.native_window.get_clipboard_data (); 111 112 fd = MainWindow.get_current_display (); 113 114 // Determine if clipboard contains data in birdfont format. 115 is_bf_clipboard = clipboard_data.index_of ("BirdFontClipboard") > -1; 116 117 if (fd is Glyph) { 118 paste_to_glyph (is_bf_clipboard, paste_guide_lines); 119 } 120 121 BirdFont.get_current_font ().touch (); 122 } 123 124 static void paste_to_overview () { 125 string data = MainWindow.native_window.get_clipboard_data (); 126 import_birdfont_clipboard (data, true, true); 127 GlyphCanvas.redraw (); 128 } 129 130 static void paste_to_glyph (bool bf_clipboard_data, bool paste_guide_lines) { 131 FontDisplay fd = MainWindow.get_current_display (); 132 Glyph? destination = null; 133 string data; 134 return_if_fail (fd is Glyph); 135 136 destination = (Glyph) fd; 137 ((!)destination).store_undo_state (); 138 ((!)destination).clear_active_paths (); 139 140 data = MainWindow.native_window.get_clipboard_data (); 141 142 if (bf_clipboard_data) { 143 import_birdfont_clipboard (data, paste_guide_lines, false); 144 } else if (data != "") { 145 SvgParser.import_svg_data (data, SvgFormat.INKSCAPE); 146 } 147 148 ((!)destination).update_view (); 149 } 150 151 static string export_selected_paths_to_birdfont_clipboard () { 152 return export_paths_to_birdfont_clipboard (false, true); 153 } 154 155 static string export_paths_to_birdfont_clipboard (bool overview, bool selected = false) { 156 StringBuilder s = new StringBuilder (); 157 Gee.ArrayList<Path> paths = new Gee.ArrayList<Path> (); 158 Path new_path; 159 Glyph glyph; 160 GlyphCollection glyph_collection; 161 OverView o; 162 163 if (overview) { 164 o = MainWindow.get_overview (); 165 unichar last_assigned = '\0'; 166 foreach (GlyphCollection gc in o.selected_items) { 167 s.append ("\n"); 168 s.append ("<!-- BirdFontClipboard\n"); 169 170 if (!gc.is_unassigned ()) { 171 last_assigned = gc.get_unicode_character (); 172 173 s.append ("BF glyph: "); 174 s.append (@"$(Font.to_hex (gc.get_unicode_character ()))"); 175 s.append ("\n"); 176 } else { 177 last_assigned++; 178 179 s.append ("BF glyph: "); 180 s.append (@"$(Font.to_hex (last_assigned))"); 181 s.append ("\n"); 182 } 183 184 s.append ("BF name: "); 185 s.append (@"$(gc.get_name ())"); 186 s.append ("\n"); 187 188 s.append ("BF unassigned: "); 189 s.append (@"$(gc.is_unassigned ())"); 190 s.append ("\n"); 191 192 s.append ("BF left: "); 193 s.append (@"$(gc.get_current ().left_limit)"); 194 s.append ("\n"); 195 196 s.append ("BF right: "); 197 s.append (@"$(gc.get_current ().right_limit)"); 198 s.append ("\n"); 199 200 foreach (Path path in gc.get_current ().path_list) { 201 s.append ("BF path: "); 202 s.append (BirdFontFile.get_point_data (path)); 203 s.append ("\n"); 204 } 205 206 s.append ("BF end -->"); 207 } 208 } else { 209 glyph = MainWindow.get_current_glyph (); 210 glyph_collection = MainWindow.get_current_glyph_collection (); 211 212 s.append ("\n"); 213 s.append ("<!-- BirdFontClipboard\n"); 214 215 s.append ("BF glyph: "); 216 s.append (@"$(Font.to_hex (glyph.unichar_code))"); 217 s.append ("\n"); 218 219 s.append ("BF name: "); 220 s.append (@"$(glyph_collection.get_name ())"); 221 s.append ("\n"); 222 223 s.append ("BF unassigned: "); 224 s.append (@"$(glyph_collection.is_unassigned ())"); 225 s.append ("\n"); 226 227 s.append ("BF left: "); 228 s.append (@"$(glyph.left_limit)"); 229 s.append ("\n"); 230 231 s.append ("BF right: "); 232 s.append (@"$(glyph.right_limit)"); 233 s.append ("\n"); 234 235 if (!selected) { 236 foreach (Path path in glyph.path_list) { 237 s.append ("BF path: "); 238 s.append (BirdFontFile.get_point_data (path)); 239 s.append ("\n"); 240 } 241 } else if (glyph.path_list.size > 0) { 242 foreach (Path path in glyph.active_paths) { 243 s.append ("BF path: "); 244 s.append (BirdFontFile.get_point_data (path)); 245 s.append ("\n"); 246 } 247 } else { 248 new_path = new Path (); 249 foreach (Path path in glyph.path_list) { 250 if (path.points.size > 0 251 && path.points.get (0).is_selected () 252 && path.points.get (path.points.size - 1).is_selected ()) { 253 254 foreach (EditPoint ep in path.points) { 255 if (!ep.is_selected ()) { 256 path.set_new_start (ep); 257 break; 258 } 259 } 260 } 261 262 foreach (EditPoint ep in path.points) { 263 if (!ep.is_selected ()) { 264 if (path.points.size > 0) { 265 paths.add (new_path); 266 new_path = new Path (); 267 } 268 } else { 269 new_path.add_point (ep); 270 } 271 } 272 273 if (all_points_selected (path)) { 274 new_path.close (); 275 } 276 } 277 278 paths.add (new_path); 279 280 foreach (Path path in paths) { 281 if (path.points.size > 0) { 282 s.append ("BF path: "); 283 s.append (BirdFontFile.get_point_data (path)); 284 s.append ("\n"); 285 } 286 } 287 } 288 289 s.append ("BF end -->"); 290 } 291 292 return s.str; 293 } 294 295 static bool all_points_selected (Path p) { 296 foreach (EditPoint ep in p.points) { 297 if (!ep.is_selected ()) { 298 return false; 299 } 300 } 301 return true; 302 } 303 304 static void import_birdfont_clipboard (string data, bool paste_guide_lines, bool overview) { 305 Gee.ArrayList<GlyphCollection> glyphs = new Gee.ArrayList<GlyphCollection> (); 306 Glyph glyph = new Glyph ("null", '\0'); 307 string[] items = data.split ("\nBF "); 308 unichar c; 309 Glyph destination; 310 GlyphCollection glyph_collection = new GlyphCollection ('\0', ""); 311 OverView o; 312 313 foreach (string p in items) { 314 if (p.has_prefix ("glyph:")) { 315 p = p.replace ("glyph: ", ""); 316 p = p.replace ("\n", ""); 317 c = Font.to_unichar (p); 318 glyph_collection = new GlyphCollection (c, (!) c.to_string ()); 319 glyphs.add (glyph_collection); 320 321 glyph = new Glyph ((!) c.to_string (), c); 322 glyph_collection.add_glyph (glyph); 323 } 324 325 if (p.has_prefix ("unassigned:")) { 326 p = p.replace ("unassigned: ", ""); 327 p = p.replace ("\n", ""); 328 glyph_collection.set_unassigned (bool.parse (p)); 329 } 330 331 if (p.has_prefix ("name:")) { 332 p = p.replace ("name: ", ""); 333 p = p.replace ("\n", ""); 334 glyph_collection.set_name (p); 335 glyph.name = p; 336 } 337 338 if (p.has_prefix ("path:")) { 339 p = p.replace ("path: ", ""); 340 p = p.replace ("\n", ""); 341 import_birdfont_path (glyph, p); 342 } 343 344 if (p.has_prefix ("left:")) { 345 glyph.left_limit = double.parse (p.replace ("left: ", "")); 346 glyph.remove_lines (); 347 glyph.add_help_lines (); 348 } 349 350 if (p.has_prefix ("right:")) { 351 glyph.right_limit = double.parse (p.replace ("right: ", "")); 352 glyph.remove_lines (); 353 glyph.add_help_lines (); 354 } 355 } 356 357 if (!overview) { 358 return_if_fail (glyphs.size > 0); 359 destination = MainWindow.get_current_glyph (); 360 glyph = glyphs.get (0).get_current (); 361 362 foreach (Path p in glyph.path_list) { 363 destination.add_path (p); 364 destination.add_active_path (p); 365 } 366 367 if (paste_guide_lines) { 368 destination.left_limit = glyph.left_limit; 369 destination.right_limit = glyph.right_limit; 370 destination.add_help_lines (); 371 destination.update_other_spacing_classes (); 372 } 373 } else { 374 o = MainWindow.get_overview (); 375 o.copied_glyphs.clear (); 376 foreach (GlyphCollection gc in glyphs) { 377 o.copied_glyphs.add (gc); 378 } 379 o.paste (); 380 } 381 } 382 383 static void import_birdfont_path (Glyph glyph, string data) { 384 Path path = new Path (); 385 386 BirdFontFile.parse_path_data (data, path); 387 388 if (path.points.size > 0) { 389 glyph.add_path (path); 390 glyph.active_paths.add (path); 391 path.update_region_boundaries (); 392 } 393 394 PenTool.remove_all_selected_points (); 395 396 foreach (Path p in glyph.active_paths) { 397 if (p.is_open ()) { 398 foreach (EditPoint e in p.points) { 399 e.set_selected (true); 400 } 401 } 402 } 403 404 PenTool.update_selection (); 405 } 406 407 static void paste_letters_to_kerning_tab () { 408 string clipboard_data = MainWindow.native_window.get_clipboard_data (); 409 KerningDisplay kerning_display = MainWindow.get_kerning_display (); 410 411 if (!clipboard_data.has_prefix ("<?xml")) { 412 kerning_display.add_text (clipboard_data); 413 } 414 } 415 } 416 417 } 418