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.
Generate mac specific truetype fonts
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 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 MainWindow.file_chooser (t_("Save"), fc, FileChooser.SAVE); 194 } 195 196 public static void generate_html_document (string html_file, Font font) { 197 File file = File.new_for_path (html_file); 198 DataOutputStream os; 199 string name = ExportSettings.get_file_name (font); 200 201 try { 202 os = new DataOutputStream (file.create(FileCreateFlags.REPLACE_DESTINATION)); 203 204 os.put_string ( 205 """<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 206 <html> 207 <head> 208 209 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 210 <title>Lorem ipsum</title> 211 212 <style type="text/css"> 213 214 body { 215 text-rendering: optimizeLegibility; 216 font-feature-settings: "kern"; 217 -moz-font-feature-settings: "kern=1"; 218 -ms-font-feature-settings: "kern"; 219 -webkit-font-feature-settings: "kern"; 220 -o-font-feature-settings: "kern"; 221 } 222 223 @font-face { 224 font-family: '"""); os.put_string (@"$(name)"); os.put_string ("""SVG'; 225 src: url('"""); os.put_string (@"$(name).svg#$(name)"); os.put_string ("""') format('svg'); 226 } 227 """); 228 229 os.put_string (""" 230 @font-face { 231 font-family: '"""); os.put_string (@"$(name)"); os.put_string ("""TTF'; 232 src: url('"""); os.put_string (@"$(name).ttf"); os.put_string ("""') format('truetype'); 233 } 234 """); 235 236 os.put_string (""" 237 @font-face { 238 font-family: '"""); os.put_string (@"$(name)"); os.put_string ("""EOT'; 239 src: url('"""); os.put_string (@"$(name).eot"); os.put_string ("""'); 240 } 241 242 """); 243 244 os.put_string (""" 245 h1 { 246 font-weight:normal; 247 margin: 0 0 5px 0; 248 color: #afafaf; 249 } 250 251 h2 { 252 font-weight:normal; 253 margin: 0 0 5px 0; 254 color: #afafaf; 255 } 256 257 h3 { 258 font-weight:normal; 259 margin: 0 0 5px 0; 260 color: #afafaf; 261 } 262 263 h4 { 264 font-weight:normal; 265 margin: 0 0 5px 0; 266 color: #afafaf; 267 } 268 269 p { 270 margin: 0 0 5px 0; 271 color: #000000; 272 } 273 274 body { 275 margin: 30px 0 0 30px; 276 } 277 278 div { 279 font-family: """); 280 281 os.put_string ("'"); 282 os.put_string (@"$(name)"); 283 os.put_string ("EOT'"); 284 285 os.put_string (", '"); 286 os.put_string (@"$(name)"); 287 os.put_string ("TTF'"); 288 289 os.put_string (", '"); 290 os.put_string (@"$(name)"); 291 os.put_string ("SVG'"); 292 293 os.put_string (";"); 294 os.put_string (""" 295 margin: 0 0 30px 0; 296 } 297 298 h1.bigger { 299 font-size: 58pt; 300 } 301 302 h2.big { 303 font-size: 40pt; 304 } 305 306 h3.small { 307 font-size: 32pt; 308 } 309 310 h4.smaller { 311 font-size: 18pt; 312 } 313 314 h1.percent { 315 font-size: 100%; 316 } 317 318 p.bigger { 319 font-size: 32pt; 320 } 321 322 p.big { 323 font-size: 24pt; 324 } 325 326 p.small { 327 font-size: 18pt; 328 } 329 330 p.smaller { 331 font-size: 12pt; 332 } 333 334 </style> 335 """); 336 337 os.put_string ( 338 """ 339 </head> 340 <body> 341 342 <div> 343 <h1 class="bigger">Lorem ipsum</h1> 344 <p class="bigger">Dolor sit amet!</p> 345 </div> 346 347 <div> 348 <h2 class="big">Hamburgerfonstiv</h2> 349 <p class="big">""" + name + """</p> 350 </div> 351 352 <div> 353 <h3 class="big">Handgloves & Mittoms</h3> 354 <p class="big">Bibliography</p> 355 </p> 356 </div> 357 358 <div> 359 <h4 class="smaller">Headline 16pt</h4> 360 <p class="smaller">Ett litet stycke svalhjärta.</p> 361 </div> 362 363 <div> 364 <h4 class="smaller">""" + t_("Alphabet") + """</h4> 365 <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> 366 <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> 367 <p class="smaller">0 1 2 3 4 5 6 7 8 9</p> 368 </div> 369 370 </body> 371 </html> 372 """); 373 374 } catch (GLib.Error e) { 375 warning (e.message); 376 } 377 } 378 379 public static bool export_ttf_font () { 380 Font font = BirdFont.get_current_font (); 381 File f = font.get_folder (); 382 383 printd (@"export_ttf_font:\n"); 384 printd (@"font.get_path (): $(font.get_path ())\n"); 385 printd (@"font.get_folder_path (): $(font.get_folder_path ())\n"); 386 printd (@"font.get_folder (): $((!) f.get_path ())\n"); 387 388 return export_ttf_font_path (f); 389 } 390 391 public static bool export_ttf_font_path (File folder, bool use_export_settings = true) { 392 Font current_font = BirdFont.get_current_font (); 393 File ttf_file; 394 File eot_file; 395 bool done = true; 396 397 try { 398 ttf_file = get_child (folder, ExportSettings.get_file_name (current_font) + ".ttf"); 399 eot_file = get_child (folder, ExportSettings.get_file_name (current_font) + ".eot"); 400 401 printd (@"Writing TTF fonts to $((!) ttf_file.get_path ())\n"); 402 403 if (ttf_file.query_exists ()) { 404 ttf_file.delete (); 405 } 406 407 if (eot_file.query_exists ()) { 408 eot_file.delete (); 409 } 410 411 write_ttf ((!) ttf_file.get_path ()); 412 413 if (!use_export_settings || ExportSettings.export_eot_setting (current_font)) { 414 write_eot ((!) ttf_file.get_path (), (!) eot_file.get_path ()); 415 } 416 417 if (use_export_settings && !ExportSettings.export_ttf_setting (current_font)) { 418 if (ttf_file.query_exists ()) { 419 ttf_file.delete (); 420 } 421 } 422 } catch (Error e) { 423 critical (@"$(e.message)"); 424 done = false; 425 } 426 427 return done; 428 } 429 430 public static bool export_svg_font () { 431 Font font = BirdFont.get_current_font (); 432 return export_svg_font_path (font.get_folder ()); 433 } 434 435 public static bool export_svg_font_path (File folder) { 436 Font font = BirdFont.get_current_font (); 437 string file_name = @"$(ExportSettings.get_file_name (font)).svg"; 438 File file; 439 SvgFontFormatWriter fo; 440 441 try { 442 file = get_child (folder, file_name); 443 444 if (file.query_exists ()) { 445 file.delete (); 446 } 447 448 fo = new SvgFontFormatWriter (); 449 fo.open (file); 450 fo.write_font_file (font); 451 fo.close (); 452 } catch (Error e) { 453 critical (@"$(e.message)"); 454 return false; 455 } 456 457 return true; 458 } 459 460 static void write_ttf (string ttf) { 461 OpenFontFormatWriter fo = new OpenFontFormatWriter (); 462 Font f = BirdFont.get_current_font (); 463 File file = (!) File.new_for_path (ttf); 464 465 try { 466 fo.open (file); 467 fo.write_ttf_font (f); 468 fo.close (); 469 } catch (Error e) { 470 warning (@"Can't write TTF font to $ttf"); 471 critical (@"$(e.message)"); 472 } 473 } 474 475 static void write_eot (string ttf, string eot) { 476 EotWriter fo = new EotWriter (ttf, eot); 477 478 try { 479 fo.write (); 480 } catch (Error e) { 481 warning (@"EOF conversion falied, $ttf -> $eot"); 482 critical (@"$(e.message)"); 483 } 484 } 485 } 486 487 } 488