The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

ExportTool.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/ExportTool.vala.
Merge branch '2.14' of github.com:johanmattssonm/birdfont into 2.14
1 /* 2 Copyright (C) 2012 2014 2015 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 using B; 16 17 namespace BirdFont { 18 19 public class ExportTool : GLib.Object { 20 21 public ExportTool (string n) { 22 } 23 24 public static string export_selected_paths_to_svg () { 25 return export_current_glyph_to_string (true); 26 } 27 28 public static string export_selected_paths_to_inkscape_clipboard () { 29 return export_current_glyph_to_inkscape_clipboard (true); 30 } 31 32 public static string export_current_glyph_to_string (bool only_selected_paths = false) { 33 return export_to_string (MainWindow.get_current_glyph (), only_selected_paths); 34 } 35 36 public static string export_to_string (Glyph glyph, bool only_selected_paths) { 37 string name; 38 StringBuilder s; 39 40 name = XmlParser.encode (glyph.get_name ()); 41 s = new StringBuilder (); 42 43 s.append ("""<?xml version="1.0" encoding="utf-8"?> 44 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> 45 <svg version="1.0" 46 id="glyph_""" + name + """" 47 mlns="http://www.w3.org/2000/svg" 48 xmlns:xlink="http://www.w3.org/1999/xlink" 49 x="0px" 50 y="0px" 51 width=""" + "\"" + @"$(glyph.get_width ())" + """px" 52 height=""" + "\"" + @"$(glyph.get_height ())" + """px"> 53 """); 54 55 s.append (@"<g id=\"$(name)\">\n"); 56 57 s.append (get_svg_path_elements (glyph, only_selected_paths)); 58 59 s.append ("</g>\n"); 60 s.append ("</svg>"); 61 62 return s.str; 63 } 64 65 public static string export_current_glyph_to_inkscape_clipboard (bool only_selected_paths = false) { 66 return export_to_inkscape_clipboard (MainWindow.get_current_glyph (), only_selected_paths); 67 } 68 69 public static string export_to_inkscape_clipboard (Glyph glyph, bool only_selected_paths = false) { 70 StringBuilder s; 71 72 s = new StringBuilder (); 73 s.append ("""<?xml version="1.0" encoding="UTF-8" standalone="no"?>"""); 74 s.append ("\n"); 75 s.append ("<svg>\n"); 76 77 s.append ("""<inkscape:clipboard 78 id="clipboard3009" 79 style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" 80 min="0,0" 81 max="0,0" /> 82 """); 83 84 s.append (get_svg_path_elements (glyph, only_selected_paths)); 85 s.append ("</svg>"); 86 87 return s.str; 88 } 89 90 private static string get_svg_path_elements (Glyph glyph, bool only_selected_paths) { 91 string glyph_svg; 92 StringBuilder s; 93 string name; 94 int id = 0; 95 96 name = glyph.get_name (); 97 98 Gee.ArrayList<Path> pl; 99 100 s = new StringBuilder (); 101 glyph_svg = ""; 102 103 pl = only_selected_paths ? glyph.active_paths : glyph.get_visible_paths (); 104 foreach (Path p in pl) { 105 if (p.stroke > 0) { 106 s.append (@"<path "); 107 s.append (@"style=\""); 108 s.append (@"fill:none;"); 109 s.append (@"stroke:#000000;"); 110 s.append (@"stroke-width:$(p.stroke)px;"); 111 112 if (p.line_cap == LineCap.ROUND) { 113 s.append (@"stroke-linecap:round;"); 114 } else if (p.line_cap == LineCap.SQUARE) { 115 s.append (@"stroke-linecap:square;"); 116 } 117 118 s.append (@"\" "); 119 120 s.append (@"d=\"$(Svg.to_svg_path (p, glyph))\" id=\"path_$(name)_$(id)\" />\n"); 121 id++; 122 } 123 } 124 125 if (only_selected_paths) { 126 foreach (Path p in glyph.active_paths) { 127 if (p.stroke == 0) { 128 glyph_svg += Svg.to_svg_path (p, glyph); 129 } 130 } 131 } else { 132 foreach (Path p in glyph.get_visible_paths ()) { 133 if (p.stroke == 0) { 134 glyph_svg += Svg.to_svg_path (p, glyph); 135 } 136 } 137 } 138 139 if (glyph_svg != "") { 140 s.append (@"<path "); 141 s.append (@"style=\"fill:#000000;stroke-width:0px\" "); 142 s.append (@"d=\"$(glyph_svg)\" id=\"path_$(name)_$(id)\" />\n"); 143 id++; 144 } 145 146 return s.str; 147 } 148 149 public static void export_current_glyph () { 150 FileChooser fc = new FileChooser (); 151 fc.file_selected.connect ((f) => { 152 Glyph glyph = MainWindow.get_current_glyph (); 153 FontDisplay fd = MainWindow.get_current_display (); 154 string glyph_svg; 155 string svg_file; 156 File file; 157 DataOutputStream os; 158 string name; 159 string fn; 160 int i; 161 162 name = glyph.get_name (); 163 164 if (f == null) { 165 return; 166 } 167 168 svg_file = (!) f; 169 170 if (!(fd is Glyph)) { 171 return; 172 } 173 174 try { 175 i = 1; 176 fn = svg_file.replace (".svg", ""); 177 file = File.new_for_path (fn + ".svg"); 178 while (file.query_exists ()) { 179 file = File.new_for_path (fn + @"$i.svg"); 180 i++; 181 } 182 183 glyph_svg = export_current_glyph_to_string (); 184 os = new DataOutputStream (file.create(FileCreateFlags.REPLACE_DESTINATION)); 185 os.put_string (glyph_svg); 186 187 } catch (Error e) { 188 stderr.printf (@"Export \"$svg_file\" \n"); 189 critical (@"$(e.message)"); 190 } 191 }); 192 193 fc.add_extension ("svg"); 194 MainWindow.file_chooser (t_("Save"), fc, FileChooser.SAVE); 195 } 196 197 public static void generate_html_document (string html_file, Font font) { 198 File file = File.new_for_path (html_file); 199 DataOutputStream os; 200 string name; 201 202 #if MAC 203 name = ExportSettings.get_file_name_mac (font); 204 #else 205 name = ExportSettings.get_file_name (font); 206 #endif 207 try { 208 os = new DataOutputStream (file.create(FileCreateFlags.REPLACE_DESTINATION)); 209 210 os.put_string ( 211 """<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 212 <html> 213 <head> 214 215 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 216 <title>Lorem ipsum</title> 217 218 <style type="text/css"> 219 220 body { 221 text-rendering: optimizeLegibility; 222 font-feature-settings: "kern"; 223 -moz-font-feature-settings: "kern=1"; 224 -ms-font-feature-settings: "kern"; 225 -webkit-font-feature-settings: "kern"; 226 -o-font-feature-settings: "kern"; 227 } 228 229 @font-face { 230 font-family: '"""); os.put_string (@"$(name)"); os.put_string ("""SVG'; 231 src: url('"""); os.put_string (@"$(name).svg#$(name)"); os.put_string ("""') format('svg'); 232 } 233 """); 234 235 os.put_string (""" 236 @font-face { 237 font-family: '"""); os.put_string (@"$(name)"); os.put_string ("""TTF'; 238 src: url('"""); os.put_string (@"$(name).ttf"); os.put_string ("""') format('truetype'); 239 } 240 """); 241 242 os.put_string (""" 243 @font-face { 244 font-family: '"""); os.put_string (@"$(name)"); os.put_string ("""EOT'; 245 src: url('"""); os.put_string (@"$(name).eot"); os.put_string ("""'); 246 } 247 248 """); 249 250 os.put_string (""" 251 h1 { 252 font-weight:normal; 253 margin: 0 0 5px 0; 254 color: #afafaf; 255 } 256 257 h2 { 258 font-weight:normal; 259 margin: 0 0 5px 0; 260 color: #afafaf; 261 } 262 263 h3 { 264 font-weight:normal; 265 margin: 0 0 5px 0; 266 color: #afafaf; 267 } 268 269 h4 { 270 font-weight:normal; 271 margin: 0 0 5px 0; 272 color: #afafaf; 273 } 274 275 p { 276 margin: 0 0 5px 0; 277 color: #000000; 278 } 279 280 body { 281 margin: 30px 0 0 30px; 282 } 283 284 div { 285 font-family: """); 286 287 os.put_string ("'"); 288 os.put_string (@"$(name)"); 289 os.put_string ("EOT'"); 290 291 os.put_string (", '"); 292 os.put_string (@"$(name)"); 293 os.put_string ("TTF'"); 294 295 os.put_string (", '"); 296 os.put_string (@"$(name)"); 297 os.put_string ("SVG'"); 298 299 os.put_string (";"); 300 os.put_string (""" 301 margin: 0 0 30px 0; 302 } 303 304 h1.bigger { 305 font-size: 58pt; 306 } 307 308 h2.big { 309 font-size: 40pt; 310 } 311 312 h3.small { 313 font-size: 32pt; 314 } 315 316 h4.smaller { 317 font-size: 18pt; 318 } 319 320 h1.percent { 321 font-size: 100%; 322 } 323 324 p.bigger { 325 font-size: 32pt; 326 } 327 328 p.big { 329 font-size: 24pt; 330 } 331 332 p.small { 333 font-size: 18pt; 334 } 335 336 p.smaller { 337 font-size: 12pt; 338 } 339 340 span.swashes { 341 -moz-font-feature-settings: "swsh"; 342 -ms-font-feature-settings: "swsh"; 343 -webkit-font-feature-settings: "swsh"; 344 font-feature-settings: "swsh"; 345 } 346 347 span.alternates { 348 -moz-font-feature-settings: "salt" 1; 349 -ms-font-feature-settings: "salt" 1; 350 -webkit-font-feature-settings: "salt" 1; 351 font-feature-settings: "salt" 1; 352 } 353 354 span.smallcaps { 355 font-variant-caps: small-caps; 356 -moz-font-feature-settings: "smcp"; 357 -ms-font-feature-settings: "smcp"; 358 -webkit-font-feature-settings: "smcp"; 359 font-feature-settings: "smcp"; 360 } 361 362 span.capstosmallcaps { 363 font-variant-caps: all-small-caps; 364 -moz-font-feature-settings: "c2sc", "smcp"; 365 -ms-font-feature-settings: "c2sc", "smcp"; 366 -webkit-font-feature-settings: "c2sc", "smcp"; 367 font-feature-settings: "c2sc", "smcp"; 368 } 369 </style> 370 """); 371 372 os.put_string ( 373 """ 374 </head> 375 <body> 376 377 <div> 378 <h1 class="bigger">Lorem ipsum</h1> 379 <p class="bigger">Dolor sit amet!</p> 380 </div> 381 382 <div> 383 <h2 class="big">Hamburgerfonstiv</h2> 384 <p class="big">""" + name + """</p> 385 </div> 386 387 <div> 388 <h3 class="big"></h3> 389 <p class="big"> 390 <span class="capstosmallcaps">OTF</span> features, 391 <span class="swashes">like swashes </span> 392 <span class="alternates">alternates &amp; </span> 393 <span class="smallcaps">small caps</span>, can be added 394 to the font.</span> 395 </p> 396 </div> 397 398 <div> 399 <h4 class="smaller">Headline 16pt</h4> 400 <p class="smaller">Ett litet stycke svalhjärta.</p> 401 </div> 402 403 <div> 404 <h4 class="smaller">""" + t_("Alphabet") + """</h4> 405 <p class="smaller">""" + t_("a b c d e f g h i j k l m n o p q r s t u v w x y z") + """</p> 406 <p class="smaller">""" + t_("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z") + """</p> 407 <p class="smaller">0 1 2 3 4 5 6 7 8 9</p> 408 </div> 409 410 </body> 411 </html> 412 """); 413 414 } catch (GLib.Error e) { 415 warning (e.message); 416 } 417 } 418 419 public static string get_export_folder () { 420 Font font = BirdFont.get_current_font (); 421 string? sandbox = BirdFont.get_sandbox_directory (); 422 423 if (sandbox != null) { 424 File s = File.new_for_path ((!) sandbox); 425 File f = get_child (s, "Fonts"); 426 try { 427 if (!f.query_exists ()) { 428 f.make_directory (); 429 } 430 } catch (GLib.Error e) { 431 warning(e.message); 432 } 433 return (!) get_child (f, font.full_name).get_path (); 434 } else { 435 return (!) font.get_folder ().get_path (); 436 } 437 } 438 439 public static File get_export_dir () { 440 return File.new_for_path (get_export_folder ()); 441 } 442 443 public static bool export_ttf_font () { 444 File f = get_export_dir (); 445 Font font = BirdFont.get_current_font (); 446 447 try { 448 if (!f.query_exists ()) { 449 f.make_directory (); 450 } 451 } catch (GLib.Error e) { 452 warning(e.message); 453 } 454 455 printd (@"export_ttf_font:\n"); 456 printd (@"get_export_folder (): $(get_export_folder ())\n"); 457 printd (@"font.get_path (): $(font.get_path ())\n"); 458 printd (@"font.get_folder_path (): $(font.get_folder_path ())\n"); 459 printd (@"font.get_folder (): $((!) f.get_path ())\n"); 460 461 return export_ttf_font_path (f); 462 } 463 464 public static bool export_ttf_font_path (File folder, bool use_export_settings = true) { 465 Font current_font = BirdFont.get_current_font (); 466 File ttf_file; 467 File ttf_file_mac; 468 File eot_file; 469 bool done = true; 470 string ttf_name; 471 string ttf_name_mac; 472 473 try { 474 ttf_name = ExportSettings.get_file_name (current_font) + ".ttf"; 475 ttf_name_mac = ExportSettings.get_file_name_mac (current_font) + ".ttf"; 476 477 if (ttf_name == ttf_name_mac) { 478 warning ("Same file name for the two ttf files."); 479 ttf_name_mac = ExportSettings.get_file_name_mac (current_font) + " Mac.ttf"; 480 } 481 482 ttf_file = get_child (folder, ttf_name); 483 ttf_file_mac = get_child (folder, ttf_name_mac); 484 eot_file = get_child (folder, ExportSettings.get_file_name (current_font) + ".eot"); 485 486 printd (@"Writing TTF fonts to $((!) ttf_file.get_path ())\n"); 487 488 if (ttf_file.query_exists ()) { 489 ttf_file.delete (); 490 } 491 492 if (ttf_file_mac.query_exists ()) { 493 ttf_file_mac.delete (); 494 } 495 496 if (eot_file.query_exists ()) { 497 eot_file.delete (); 498 } 499 500 write_ttf ((!) ttf_file.get_path (), (!) ttf_file_mac.get_path ()); 501 502 if (!use_export_settings || ExportSettings.export_eot_setting (current_font)) { 503 write_eot ((!) ttf_file.get_path (), (!) eot_file.get_path ()); 504 } 505 506 if (use_export_settings && !ExportSettings.export_ttf_setting (current_font)) { 507 if (ttf_file.query_exists ()) { 508 ttf_file.delete (); 509 } 510 } 511 } catch (Error e) { 512 critical (@"$(e.message)"); 513 done = false; 514 } 515 516 return done; 517 } 518 519 public static bool export_svg_font () { 520 return export_svg_font_path (get_export_dir ()); 521 } 522 523 public static bool export_svg_font_path (File folder) { 524 Font font = BirdFont.get_current_font (); 525 string file_name = @"$(ExportSettings.get_file_name (font)).svg"; 526 File file; 527 SvgFontFormatWriter fo; 528 529 try { 530 file = get_child (folder, file_name); 531 532 if (file.query_exists ()) { 533 file.delete (); 534 } 535 536 fo = new SvgFontFormatWriter (); 537 fo.open (file); 538 fo.write_font_file (font); 539 fo.close (); 540 } catch (Error e) { 541 critical (@"$(e.message)"); 542 return false; 543 } 544 545 return true; 546 } 547 548 static void write_ttf (string ttf, string ttf_mac) { 549 Font f = BirdFont.get_current_font (); 550 OpenFontFormatWriter fo = new OpenFontFormatWriter (f.units_per_em); 551 552 File file = (!) File.new_for_path (ttf); 553 File file_mac = (!) File.new_for_path (ttf_mac); 554 555 try { 556 fo.open (file, file_mac); 557 fo.write_ttf_font (f); 558 fo.close (); 559 } catch (Error e) { 560 warning (@"Can't write TTF font to $ttf"); 561 critical (@"$(e.message)"); 562 } 563 } 564 565 static void write_eot (string ttf, string eot) { 566 EotWriter fo = new EotWriter (ttf, eot); 567 568 try { 569 fo.write (); 570 } catch (Error e) { 571 warning (@"EOF conversion falied, $ttf -> $eot"); 572 critical (@"$(e.message)"); 573 } 574 } 575 } 576 577 } 578