.
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 class SvgFontFormatWriter : Object {
18
19 DataOutputStream os;
20
21 public SvgFontFormatWriter () {
22 }
23
24 public void open (File file) throws Error {
25 if (file.query_exists ()) {
26 throw new FileError.EXIST ("SvgFontFormatWriter: file exists.");
27 }
28
29 os = new DataOutputStream (file.create(FileCreateFlags.REPLACE_DESTINATION));
30 }
31
32 public void close () throws Error {
33 os.close ();
34 }
35
36 public void write_font_file (Font font) throws Error {
37 string font_name = font.get_full_name ();
38
39 int units_per_em = 100;
40
41 int ascent = 80;
42 int descent = -20;
43
44 StringBuilder b;
45
46 Glyph? g;
47 Glyph glyph;
48 unichar index = 0;
49
50 string uni;
51
52 KerningClasses classes;
53
54 put ("""<?xml version="1.0" standalone="no"?>""");
55 put ("""<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >""");
56 put ("""<svg>""");
57
58 // (metadata goes here)
59
60 string font_id = font_name.replace (" ", "-");
61 font_id = BirdFontFile.encode (font_id);
62
63 Glyph space = font.get_space ().get_current ();
64 double space_width = space.get_width ();
65
66 put (@"<font id=\"$font_id\" horiz-adv-x=\"$(to_float (space_width))\" >");
67 put (@"<font-face units-per-em=\"$(to_float (units_per_em))\" ascent=\"$(to_float (ascent))\" descent=\"$(to_float (descent))\" />");
68
69 // (missing-glyph goes here)
70
71 // regular glyphs
72 while (true) {
73 g = font.get_glyph_index (index++);
74
75 if (g == null) {
76 break;
77 }
78
79 glyph = (!) g;
80
81 b = new StringBuilder ();
82 b.append_unichar (glyph.get_unichar ());
83
84 if (glyph.get_unichar () >= ' ' && b.str.validate ()) {
85 if (b.str == "\"" || b.str == "&" || b.str == "<" || b.str == ">") {
86 uni = Font.to_hex_code (glyph.get_unichar ());
87 put (@"<glyph unicode=\"&#x$(uni);\" horiz-adv-x=\"$(to_float (glyph.get_width ()))\" d=\"$(glyph.get_svg_data ())\" />");
88 } else {
89 put (@"<glyph unicode=\"$(b.str)\" horiz-adv-x=\"$(to_float (glyph.get_width ()))\" d=\"$(glyph.get_svg_data ())\" />");
90 }
91 }
92 }
93
94 // FIXME: ligatures
95 classes = BirdFont.get_current_font ().get_kerning_classes ();
96 classes.all_pairs ((kerning) => {
97 string l, r;
98
99 foreach (Kerning k in kerning.kerning) {
100 try {
101 if (k.glyph != null) {
102 l = Font.to_hex_code (kerning.character.unichar_code);
103 r = Font.to_hex_code (((!)k.glyph).unichar_code);
104 os.put_string (@"<hkern u1=\"&#x$l;\" u2=\"&#x$r;\" k=\"$(to_float (-k.val))\"/>\n");
105 } else {
106 warning ("No glyph.");
107 }
108 } catch (GLib.Error e) {
109 warning (e.message);
110 }
111 }
112 });
113
114 put ("</font>");
115 put ("</svg>");
116 }
117
118 string to_float (double d) {
119 string s = @"$d";
120 if (s.index_of ("e") != -1) {
121 return "0".dup ();
122 }
123 return s.replace (",", ".");
124 }
125
126 /** Write a new line */
127 private void put (string line) throws Error {
128 os.put_string (line);
129 os.put_string ("\n");
130 }
131
132 }
133
134
135 }
136