.
1 /*
2 Copyright (C) 2012 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 Math;
16
17 namespace BirdFont {
18
19 class EotWriter : GLib.Object {
20
21 string ttf_file_name;
22 string eot_file_name;
23
24 public EotWriter (string ttf_file, string eot_file) {
25 ttf_file_name = ttf_file;
26 eot_file_name = eot_file;
27 }
28
29 public void write () throws Error {
30 FontData fd = new FontData ();
31 FontData ttf_data = new FontData ();
32 OpenFontFormatReader input;
33 uint32 ttf_length;
34 File ttf_file;
35 File eot_file;
36 FileInfo file_info;
37 OtfInputStream dis;
38 DataOutputStream os;
39 uint8* data;
40 uint32 l;
41 NameTable names;
42 string tn;
43
44 ttf_file = File.new_for_path (ttf_file_name);
45
46 if (!ttf_file.query_exists ()) {
47 warning (@"EotWriter: file does not exist. $((!) ttf_file.get_path ())");
48 return;
49 }
50
51 eot_file = File.new_for_path (eot_file_name);
52
53 if (eot_file.query_exists ()) {
54 warning ("EOT file exists in eot export.");
55 eot_file.delete ();
56 }
57
58 os = new DataOutputStream(eot_file.create (FileCreateFlags.REPLACE_DESTINATION));
59
60 file_info = ttf_file.query_info ("*", FileQueryInfoFlags.NONE);
61 ttf_length = (uint32) file_info.get_size ();
62
63 if (ttf_length == 0) {
64 warning ("TTF file is of zero length.");
65 return;
66 }
67
68 dis = new OtfInputStream (ttf_file.read ());
69 ttf_data.write_table (dis, 0, ttf_length);
70
71 // parse file to find head checksum
72 input = new OpenFontFormatReader ();
73 input.parse_index (ttf_file_name);
74
75 names = input.directory_table.name_table;
76
77 fd.add_littleendian_u32 (0); // table length
78 fd.add_littleendian_u32 (ttf_length);
79
80 fd.add_littleendian_u32 (0x00020001); // table format version
81 fd.add_littleendian_u32 (0); // flags
82
83 // panose
84 for (int i = 0; i < 10; i++) {
85 fd.add (0);
86 }
87
88 // according to specification should charset and italic be added the
89 // other way around, but it does not work
90
91 fd.add (1); // default charset
92 fd.add (0); // italic set to regular
93
94 fd.add_littleendian_u32 (400); // weight
95 fd.add_littleendian_u16 (0); // 0 drm, designer must be notified
96 fd.add_littleendian_u16 (0x504C); // magic number
97
98 // FIXME:
99 // unicode ranges
100 fd.add_littleendian_u32 (0);
101 fd.add_littleendian_u32 (0);
102 fd.add_littleendian_u32 (0);
103 fd.add_littleendian_u32 (0);
104
105 // FIXME:
106 // code page range
107 fd.add_littleendian_u32 (0);
108 fd.add_littleendian_u32 (0);
109
110 fd.add_littleendian_u32 (input.get_head_checksum ()); // head checksum adjustment
111
112 // reserved
113 fd.add_littleendian_u32 (0);
114 fd.add_littleendian_u32 (0);
115 fd.add_littleendian_u32 (0);
116 fd.add_littleendian_u32 (0);
117
118 fd.add_littleendian_u16 (0); // padding
119
120 tn = names.get_name (NameTable.FONT_NAME);
121 fd.add_littleendian_u16 ((uint16) (2 * tn.char_count ())); // strlen of family name
122 fd.add_str_littleendian_utf16 (tn);
123
124 fd.add_littleendian_u16 (0); // padding
125
126 tn = names.get_name (NameTable.SUBFAMILY_NAME);
127 fd.add_littleendian_u16 ((uint16) (2 * tn.char_count ())); // strlen of family name
128 fd.add_str_littleendian_utf16 (tn);
129
130 fd.add_littleendian_u16 (0); // padding
131
132 // FIXA version or name + version
133 tn = names.get_name (NameTable.VERSION);
134 fd.add_littleendian_u16 ((uint16) (2 * tn.char_count ())); // strlen of family name
135 fd.add_str_littleendian_utf16 (tn);
136
137 fd.add_littleendian_u16 (0); // padding
138
139 tn = names.get_name (NameTable.FULL_FONT_NAME);
140 fd.add_littleendian_u16 ((uint16) (2 * tn.char_count ())); // strlen of family name
141 fd.add_str_littleendian_utf16 (tn);
142
143 fd.add_littleendian_u16 (0); // padding
144
145 fd.add_littleendian_u16 (0); // length of root string
146 // the root string goes here.
147
148 // update length of this table
149 fd.seek (0);
150 fd.add_littleendian_u32 (fd.length () + ttf_length);
151
152 l = fd.length_with_padding ();
153 data = fd.table_data;
154 for (int i = 0; i < l; i++) {
155 os.put_byte (data[i]);
156 }
157
158 l = ttf_data.length_with_padding ();
159 data = ttf_data.table_data;
160 for (int i = 0; i < l; i++) {
161 os.put_byte (data[i]);
162 }
163
164 dis.close ();
165 os.close ();
166 input.close ();
167 }
168
169 }
170
171 }
172