1 // -*- related-file-name: "../include/efont/cff.hh" -*-
2
3 /* cff.{cc,hh} -- Compact Font Format fonts
4 *
5 * Copyright (c) 1998-2019 Eddie Kohler
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version. This program is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 * Public License for more details.
14 */
15
16 #ifdef HAVE_CONFIG_H
17 # include <config.h>
18 #endif
19 #include <efont/cff.hh>
20 #include <lcdf/error.hh>
21 #include <efont/t1item.hh>
22 #include <lcdf/straccum.hh>
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <math.h>
27 #include <ctype.h>
28 #include <efont/t1unparser.hh>
29
30 #undef static_assert
31 #ifndef static_assert
32 #define static_assert(c, msg) switch ((int) (c)) case 0: case (c):
33 #endif
34
35 namespace Efont {
36
37 const char * const Cff::operator_names[] = {
38 "version", "Notice", "FullName", "FamilyName",
39 "Weight", "FontBBox", "BlueValues", "OtherBlues",
40 "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW",
41 "UNKNOWN_12", "UniqueID", "XUID", "charset",
42 "Encoding", "CharStrings", "Private", "Subrs",
43 "defaultWidthX", "nominalWidthX", "UNKNOWN_22", "UNKNOWN_23",
44 "UNKNOWN_24", "UNKNOWN_25", "UNKNOWN_26", "UNKNOWN_27",
45 "UNKNOWN_28", "UNKNOWN_29", "UNKNOWN_30", "UNKNOWN_31",
46 "Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition",
47 "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix",
48 "StrokeWidth", "BlueScale", "BlueShift", "BlueFuzz",
49 "StemSnapH", "StemSnapV", "ForceBold", "UNKNOWN_12_15",
50 "UNKNOWN_12_16", "LanguageGroup", "ExpansionFactor", "initialRandomSeed",
51 "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend",
52 "UNKNOWN_12_24", "UNKNOWN_12_25", "UNKNOWN_12_26", "UNKNOWN_12_27",
53 "UNKNOWN_12_28", "UNKNOWN_12_29", "ROS", "CIDFontVersion",
54 "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase",
55 "FDArray", "FDSelect", "FontName"
56 };
57
58 const int Cff::operator_types[] = {
59 tSID, tSID, tSID, tSID, // version, Notice, FullName, FamilyName
60 tSID, tArray4, tP+tArray, tP+tArray, // Weight, FontBBox, BlueValues, OtherBlues
61 tP+tArray, tP+tArray, tP+tNumber, tP+tNumber, // FamBlues, FamOthBlues, StdHW, StdVW
62 tNone, tNumber, tArray, tOffset, // escape, UniqueID, XUID, charset
63 tOffset, tOffset, tPrivateType, tP+tLocalOffset, // Encoding, CharStrings, Private, Subrs
64 tP+tNumber, tP+tNumber, tNone, tNone, // defaultWX, nominalWX, 22, 23
65 tNone, tNone, tNone, tNone, // 24, 25, 26, 27
66 tNone, tNone, tNone, tNone, // 28, 29, 30, 31
67 tSID, tBoolean, tNumber, tNumber, // Copyright, isFixedPitch, ItalicAngle, UnderlinePosition
68 tNumber, tNumber, tNumber, tArray6, // UnderlineThickness, PaintType, CharstringType, FontMatrix
69 tNumber, tP+tNumber, tP+tNumber, tP+tNumber, // StrokeWidth, BlueScale, BlueShift, BlueFuzz
70 tP+tArray, tP+tArray, tP+tBoolean, tNone, // StemSnapH, StemSnapV, ForceBold, 12 15
71 tNone, tP+tNumber, tP+tNumber, tP+tNumber, // 12 16, LanguageGroup, ExpansionFactor, initialRandomSeed
72 tNumber, tSID, tSID, tArray, // SyntheticBase, PostScript, BaseFontName, BaseFontBlend
73 tNone, tNone, tNone, tNone, // 12 24, 12 25, 12 26, 12 27
74 tNone, tNone, tArray, tNumber, // 12 28, 12 29, ROS, CIDFontVersion
75 tNumber, tNumber, tNumber, tNumber, // CIDFontRevision, CIDFontType, CIDCount, UIDBase
76 tOffset, tOffset, tSID // FDArray, FDSelect, FontName
77 };
78
79 static PermString::Initializer initializer;
80 static const char * const standard_strings[] = {
81 // Automatically generated from Appendix A of the CFF specification; do
82 // not edit. Size should be 391.
83 ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar",
84 "percent", "ampersand", "quoteright", "parenleft", "parenright",
85 "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one",
86 "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon",
87 "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C",
88 "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
89 "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash",
90 "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c",
91 "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
92 "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright",
93 "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen",
94 "florin", "section", "currency", "quotesingle", "quotedblleft",
95 "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash",
96 "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet",
97 "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
98 "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex",
99 "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla",
100 "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash",
101 "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe",
102 "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth",
103 "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar",
104 "degree", "thorn", "threequarters", "twosuperior", "registered", "minus",
105 "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex",
106 "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute",
107 "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
108 "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve",
109 "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave",
110 "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis",
111 "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex",
112 "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave",
113 "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde",
114 "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute",
115 "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall",
116 "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall",
117 "parenleftsuperior", "parenrightsuperior", "twodotenleader",
118 "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle",
119 "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle",
120 "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior",
121 "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
122 "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior",
123 "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior",
124 "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
125 "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
126 "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall",
127 "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall",
128 "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
129 "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary",
130 "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle",
131 "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall",
132 "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
133 "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
134 "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths",
135 "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior",
136 "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior",
137 "ninesuperior", "zeroinferior", "oneinferior", "twoinferior",
138 "threeinferior", "fourinferior", "fiveinferior", "sixinferior",
139 "seveninferior", "eightinferior", "nineinferior", "centinferior",
140 "dollarinferior", "periodinferior", "commainferior", "Agravesmall",
141 "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall",
142 "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall",
143 "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall",
144 "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall",
145 "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
146 "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall",
147 "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall",
148 "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black",
149 "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold"
150 };
151 static PermString standard_permstrings[Cff::NSTANDARD_STRINGS];
152 static HashMap<PermString, int> standard_permstrings_map(-1);
153
154 static const int standard_encoding[] = {
155 // Automatically generated from Appendix B of the CFF specification; do
156 // not edit. Size should be 256.
157 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
158 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
159 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
160 0, 0, 1, 2, 3, 4, 5, 6, 7, 8,
161 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
162 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
163 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
164 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
165 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
166 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
167 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
168 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
169 89, 90, 91, 92, 93, 94, 95, 0, 0, 0,
170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
173 0, 96, 97, 98, 99, 100, 101, 102, 103, 104,
174 105, 106, 107, 108, 109, 110, 0, 111, 112, 113,
175 114, 0, 115, 116, 117, 118, 119, 120, 121, 122,
176 0, 123, 0, 124, 125, 126, 127, 128, 129, 130,
177 131, 0, 132, 133, 0, 134, 135, 136, 137, 0,
178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
179 0, 0, 0, 0, 0, 138, 0, 139, 0, 0,
180 0, 0, 140, 141, 142, 143, 0, 0, 0, 0,
181 0, 144, 0, 0, 0, 145, 0, 0, 146, 147,
182 148, 149, 0, 0, 0, 0
183 };
184
185 static const int expert_encoding[] = {
186 // Automatically generated from Appendix B of the CFF specification; do
187 // not edit. Size should be 256.
188 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
191 0, 0, 1, 229, 230, 0, 231, 232, 233, 234,
192 235, 236, 237, 238, 13, 14, 15, 99, 239, 240,
193 241, 242, 243, 244, 245, 246, 247, 248, 27, 28,
194 249, 250, 251, 252, 0, 253, 254, 255, 256, 257,
195 0, 0, 0, 258, 0, 0, 259, 260, 261, 262,
196 0, 0, 263, 264, 265, 0, 266, 109, 110, 267,
197 268, 269, 0, 270, 271, 272, 273, 274, 275, 276,
198 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
199 287, 288, 289, 290, 291, 292, 293, 294, 295, 296,
200 297, 298, 299, 300, 301, 302, 303, 0, 0, 0,
201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
204 0, 304, 305, 306, 0, 0, 307, 308, 309, 310,
205 311, 0, 312, 0, 0, 313, 0, 0, 314, 315,
206 0, 0, 316, 317, 318, 0, 0, 0, 158, 155,
207 163, 319, 320, 321, 322, 323, 324, 325, 0, 0,
208 326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
209 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
210 343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
211 353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
212 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
213 373, 374, 375, 376, 377, 378
214 };
215
216 static const int iso_adobe_charset[] = {
217 // Automatically generated from Appendix C of the CFF specification; do
218 // not edit.
219 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
220 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
221 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
222 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
223 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
224 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
225 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
226 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
227 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
228 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
229 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
230 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
231 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
232 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
233 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
234 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
235 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
236 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
237 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
238 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
239 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
240 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
241 220, 221, 222, 223, 224, 225, 226, 227, 228
242 };
243
244 static const int expert_charset[] = {
245 // Automatically generated from Appendix C of the CFF specification; do
246 // not edit.
247 0, 1, 229, 230, 231, 232, 233, 234, 235, 236,
248 237, 238, 13, 14, 15, 99, 239, 240, 241, 242,
249 243, 244, 245, 246, 247, 248, 27, 28, 249, 250,
250 251, 252, 253, 254, 255, 256, 257, 258, 259, 260,
251 261, 262, 263, 264, 265, 266, 109, 110, 267, 268,
252 269, 270, 271, 272, 273, 274, 275, 276, 277, 278,
253 279, 280, 281, 282, 283, 284, 285, 286, 287, 288,
254 289, 290, 291, 292, 293, 294, 295, 296, 297, 298,
255 299, 300, 301, 302, 303, 304, 305, 306, 307, 308,
256 309, 310, 311, 312, 313, 314, 315, 316, 317, 318,
257 158, 155, 163, 319, 320, 321, 322, 323, 324, 325,
258 326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
259 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
260 343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
261 353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
262 363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
263 373, 374, 375, 376, 377, 378
264 };
265
266 static const int expert_subset_charset[] = {
267 // Automatically generated from Appendix C of the CFF specification; do
268 // not edit.
269 0, 1, 231, 232, 235, 236, 237, 238, 13, 14,
270 15, 99, 239, 240, 241, 242, 243, 244, 245, 246,
271 247, 248, 27, 28, 249, 250, 251, 253, 254, 255,
272 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
273 266, 109, 110, 267, 268, 269, 270, 272, 300, 301,
274 302, 305, 314, 315, 158, 155, 163, 320, 321, 322,
275 323, 324, 325, 326, 150, 164, 169, 327, 328, 329,
276 330, 331, 332, 333, 334, 335, 336, 337, 338, 339,
277 340, 341, 342, 343, 344, 345, 346
278 };
279
280 static const uint8_t default_dict_cff_data[] = {
281 // CFF header
282 1, 0, // format major and minor version
283 4, // header size
284 4, // absolute offset size
285
286 // Name INDEX
287 0, 1, // one element in index
288 1, // offset size
289 1, 14, // offset array
290 '%', 'D', 'E', 'F', 'A', 'U', 'L', 'T', 'D', 'I', 'C', 'T', '%',
291
292 // Top DICT INDEX
293 0, 1, // one element in index
294 1, // offset size
295 1, 92, // offset array
296 // and the DICT
297 139, 12, 1, // isFixedPitch false
298 139, 12, 2, // ItalicAngle 0
299 39, 12, 3, // UnderlinePosition -100
300 189, 12, 4, // UnderlineThickness 50
301 139, 12, 5, // PaintType 0
302 141, 12, 6, // CharstringType 2
303 30, 0x0A, 0x00, 0x1F, 139, 139, 30, 0x0A, 0x00, 0x1F, 139, 139, 12, 7,
304 // FontMatrix 0.001 0 0 0.001 0 0
305 139, 139, 139, 139, 5, // FontBBox 0 0 0 0
306 139, 12, 8, // StrokeWidth 0
307 139, 15, // charset 0
308 139, 16, // Encoding 0
309 139, 12, 31, // CIDFontVersion 0
310 139, 12, 32, // CIDFontRevision 0
311 139, 12, 33, // CIDFontType 0
312 28, 34, 16, 12, 34, // CIDCount 8720
313 30, 0x0A, 0x03, 0x96, 0x25, 0xFF, 12, 9, // BlueScale 0.039625
314 146, 12, 10, // BlueShift 7
315 140, 12, 11, // BlueFuzz 1
316 139, 12, 14, // ForceBold false
317 139, 12, 17, // LanguageGroup 0
318 30, 0x0A, 0x06, 0xFF, 12, 18, // ExpansionFactor 0.06
319 139, 12, 19, // initialRandomSeed 0
320 139, 20, // defaultWidthX 0
321 139, 21, // nominalWidthX 0
322
323 // String INDEX
324 0, 0,
325
326 // Gsubr INDEX
327 0, 0
328 };
329
330 static const Cff::Dict&
default_dict()331 default_dict()
332 {
333 static Cff cff(String::make_stable((const char*) default_dict_cff_data, sizeof(default_dict_cff_data)), 0, ErrorHandler::default_handler());
334 return static_cast<Cff::Font*>(cff.font())->top_dict();
335 }
336
337
338 #define POS_GT(pos1, pos2) ((unsigned)(pos1) > (unsigned)(pos2))
339
340
Cff(const String & s,unsigned units_per_em,ErrorHandler * errh)341 Cff::Cff(const String& s, unsigned units_per_em, ErrorHandler* errh)
342 : _data_string(s), _data(reinterpret_cast<const uint8_t *>(_data_string.data())), _len(_data_string.length()),
343 _strings_map(-2), _units_per_em(units_per_em)
344 {
345 static_assert((sizeof(standard_strings) / sizeof(standard_strings[0])) == NSTANDARD_STRINGS,
346 "NSTANDARD_STRINGS defined incorrectly");
347 static_assert((sizeof(standard_encoding) / sizeof(standard_encoding[0])) == 256,
348 "standard_encoding has wrong size");
349 static_assert((sizeof(expert_encoding) / sizeof(expert_encoding[0])) == 256,
350 "expert_encoding has wrong size");
351 _error = parse_header(errh ? errh : ErrorHandler::silent_handler());
352 }
353
~Cff()354 Cff::~Cff()
355 {
356 for (int i = 0; i < _gsubrs_cs.size(); i++)
357 delete _gsubrs_cs[i];
358 for (int i = 0; i < _fonts.size(); ++i)
359 delete _fonts[i];
360 }
361
362 /*
363 * Parsing the file header
364 */
365
366 int
parse_header(ErrorHandler * errh)367 Cff::parse_header(ErrorHandler *errh)
368 {
369 if (_gsubrs_index.error() >= 0) // already done
370 return 0;
371
372 // parse header
373 if (_len == 0)
374 return errh->error("not a PostScript-flavored OpenType font"), -EFAULT;
375 if (_len < HEADER_SIZE)
376 return errh->error("CFF file corrupted (too small)"), -EFAULT;
377 if (_data[0] != 1) // major version number
378 return errh->error("bad major version number %d", _data[0]), -ERANGE;
379 int hdrSize = _data[2], offSize = _data[3];
380 if (hdrSize < 4 || hdrSize > _len || offSize < 1 || offSize > 4)
381 return errh->error("corrupted file header"), -EINVAL;
382 int name_index_pos = hdrSize;
383
384 // parse name INDEX
385 IndexIterator niter(_data, name_index_pos, _len, errh, "Name INDEX");
386 if (niter.error() < 0)
387 return niter.error();
388 _name_index.clear();
389 for (; niter; niter++) {
390 const uint8_t *d0 = niter[0];
391 const uint8_t *d1 = niter[1];
392 if (d0 == d1 || d0[0] == 0)
393 _name_index.push_back(PermString());
394 else
395 _name_index.push_back(PermString(reinterpret_cast<const char *>(d0), d1 - d0));
396 }
397 int top_dict_index_pos = niter.index_end() - _data;
398
399 // check top DICT INDEX
400 _top_dict_index = IndexIterator(_data, top_dict_index_pos, _len, errh, "Top DICT INDEX");
401 if (_top_dict_index.error() < 0)
402 return _top_dict_index.error();
403 else if (_top_dict_index.nitems() != nfonts())
404 return errh->error("invalid font: Top DICT INDEX has %d elements, but there are %d fonts", _top_dict_index.nitems(), nfonts()), -EINVAL;
405 int string_index_pos = _top_dict_index.index_end() - _data;
406
407 // check strings INDEX
408 _strings_index = IndexIterator(_data, string_index_pos, _len, errh, "Strings INDEX");
409 if (_strings_index.error() < 0)
410 return _strings_index.error();
411 else if (NSTANDARD_STRINGS + _strings_index.nitems() - 1 > MAX_SID)
412 return errh->error("too many strings defined in font"), -EINVAL;
413 _strings.assign(_strings_index.nitems(), PermString());
414 int global_subr_index_pos = _strings_index.index_end() - _data;
415
416 // check gsubr INDEX
417 _gsubrs_index = IndexIterator(_data, global_subr_index_pos, _len, errh, "Gsubrs INDEX");
418 if (_gsubrs_index.error() < 0)
419 return _gsubrs_index.error();
420 _gsubrs_cs.assign(ngsubrs(), 0);
421
422 return 0;
423 }
424
425 int
sid(PermString s)426 Cff::sid(PermString s)
427 {
428 if (!s) // XXX?
429 return -1;
430
431 // check standard strings
432 if (standard_permstrings_map["a"] < 0)
433 for (int i = 0; i < NSTANDARD_STRINGS; i++) {
434 if (!standard_permstrings[i])
435 standard_permstrings[i] = PermString(standard_strings[i]);
436 standard_permstrings_map.insert(standard_permstrings[i], i);
437 }
438 int sid = standard_permstrings_map[s];
439 if (sid >= 0)
440 return sid;
441
442 // check user strings
443 sid = _strings_map[s];
444 if (sid >= -1)
445 return sid;
446
447 for (int i = 0; i < _strings.size(); i++)
448 if (!_strings[i] && s.length() == _strings_index[i+1] - _strings_index[i] && memcmp(s.c_str(), _strings_index[i], s.length()) == 0) {
449 _strings[i] = s;
450 _strings_map.insert(s, i + NSTANDARD_STRINGS);
451 return i + NSTANDARD_STRINGS;
452 }
453
454 _strings_map.insert(s, -1);
455 return -1;
456 }
457
458 String
sid_string(int sid) const459 Cff::sid_string(int sid) const
460 {
461 if (sid < 0)
462 return String();
463 else if (sid < NSTANDARD_STRINGS)
464 return String(sid_permstring(sid));
465 else {
466 sid -= NSTANDARD_STRINGS;
467 if (sid >= _strings.size())
468 return String();
469 else if (_strings[sid])
470 return String(_strings[sid]);
471 else
472 return String(reinterpret_cast<const char *>(_strings_index[sid]), _strings_index[sid + 1] - _strings_index[sid]);
473 }
474 }
475
476 PermString
sid_permstring(int sid) const477 Cff::sid_permstring(int sid) const
478 {
479 if (sid < 0)
480 return PermString();
481 else if (sid < NSTANDARD_STRINGS) {
482 if (!standard_permstrings[sid])
483 standard_permstrings[sid] = PermString(standard_strings[sid]);
484 return standard_permstrings[sid];
485 } else {
486 sid -= NSTANDARD_STRINGS;
487 if (sid >= _strings.size())
488 return PermString();
489 else if (_strings[sid])
490 return _strings[sid];
491 else {
492 PermString s = PermString(reinterpret_cast<const char *>(_strings_index[sid]), _strings_index[sid + 1] - _strings_index[sid]);
493 _strings[sid] = s;
494 _strings_map.insert(s, sid + NSTANDARD_STRINGS);
495 return s;
496 }
497 }
498 }
499
500 Cff::FontParent *
font(PermString font_name,ErrorHandler * errh)501 Cff::font(PermString font_name, ErrorHandler *errh)
502 {
503 if (!errh)
504 errh = ErrorHandler::silent_handler();
505
506 if (!ok())
507 return errh->error("invalid CFF"), (FontParent *) 0;
508
509 // search for a font named 'font_name'
510 int findex;
511 for (findex = 0; findex < _name_index.size(); ++findex) {
512 if (_name_index[findex]
513 && (!font_name || font_name == _name_index[findex]))
514 break;
515 }
516 if (findex >= _name_index.size()) {
517 if (!font_name)
518 errh->error("no fonts in CFF");
519 else
520 errh->error("font %<%s%> not found", font_name.c_str());
521 return 0;
522 }
523
524 // return font
525 for (int i = 0; i < _fonts.size(); ++i)
526 if (_fonts[i]->_font_index == findex)
527 return _fonts[i];
528
529 int td_offset = _top_dict_index[findex] - _data;
530 int td_length = _top_dict_index[findex + 1] - _top_dict_index[findex];
531 Dict top_dict(this, td_offset, td_length, errh, "Top DICT");
532 if (!top_dict.ok())
533 return 0;
534
535 Cff::FontParent* fp;
536 if (top_dict.has_first(oROS))
537 fp = new Cff::CIDFont(this, _name_index[findex], top_dict, errh);
538 else
539 fp = new Cff::Font(this, _name_index[findex], top_dict, errh);
540 fp->_font_index = findex;
541 _fonts.push_back(fp);
542 return fp;
543 }
544
545 static inline int
subr_bias(int charstring_type,int nsubrs)546 subr_bias(int charstring_type, int nsubrs)
547 {
548 if (charstring_type == 1)
549 return 0;
550 else if (nsubrs < 1240)
551 return 107;
552 else if (nsubrs < 33900)
553 return 1131;
554 else
555 return 32768;
556 }
557
558 Charstring *
gsubr(int i)559 Cff::gsubr(int i)
560 {
561 i += subr_bias(2, ngsubrs());
562 if (i < 0 || i >= ngsubrs())
563 return 0;
564 if (!_gsubrs_cs[i]) {
565 const uint8_t *s1 = _gsubrs_index[i];
566 int slen = _gsubrs_index[i + 1] - s1;
567 String cs = data_string().substring(s1 - data(), slen);
568 if (slen == 0)
569 return 0;
570 else
571 _gsubrs_cs[i] = new Type2Charstring(cs);
572 }
573 return _gsubrs_cs[i];
574 }
575
576
577 /*****
578 * Cff::Charset
579 **/
580
Charset(const Cff * cff,int pos,int nglyphs,int max_sid,ErrorHandler * errh)581 Cff::Charset::Charset(const Cff *cff, int pos, int nglyphs, int max_sid, ErrorHandler *errh)
582 {
583 assign(cff, pos, nglyphs, max_sid, errh);
584 }
585
586 void
assign(const Cff * cff,int pos,int nglyphs,int max_sid,ErrorHandler * errh)587 Cff::Charset::assign(const Cff *cff, int pos, int nglyphs, int max_sid, ErrorHandler *errh)
588 {
589 if (!errh)
590 errh = ErrorHandler::silent_handler();
591
592 _sids.reserve(nglyphs);
593
594 if (pos == 0)
595 assign(iso_adobe_charset, sizeof(iso_adobe_charset) / sizeof(int), nglyphs);
596 else if (pos == 1)
597 assign(expert_charset, sizeof(expert_charset) / sizeof(int), nglyphs);
598 else if (pos == 2)
599 assign(expert_subset_charset, sizeof(expert_subset_charset) / sizeof(int), nglyphs);
600 else
601 _error = parse(cff, pos, nglyphs, max_sid, errh);
602
603 if (_error >= 0)
604 for (int g = 0; g < _sids.size(); g++) {
605 if (_gids[_sids[g]] >= 0) {
606 errh->error("glyph %<%s%> in charset twice", cff->sid_permstring(_sids[g]).c_str());
607 _error = -EEXIST;
608 }
609 _gids[_sids[g]] = g;
610 }
611 }
612
613 void
assign(const int * data,int size,int nglyphs)614 Cff::Charset::assign(const int *data, int size, int nglyphs)
615 {
616 if (size < nglyphs)
617 size = nglyphs;
618 _sids.resize(size);
619 memcpy(&_sids[0], data, sizeof(const int) * size);
620 _gids.resize(data[size-1] + 1, -1);
621 _error = 0;
622 }
623
624 int
parse(const Cff * cff,int pos,int nglyphs,int max_sid,ErrorHandler * errh)625 Cff::Charset::parse(const Cff *cff, int pos, int nglyphs, int max_sid, ErrorHandler *errh)
626 {
627 const uint8_t *data = cff->data();
628 int len = cff->length();
629
630 if (pos + 1 > len)
631 return errh->error("charset position out of range"), -EFAULT;
632
633 _sids.push_back(0);
634 int actual_max_sid = 0;
635
636 int format = data[pos];
637 if (format == 0) {
638 if (pos + 1 + (nglyphs - 1) * 2 > len)
639 return errh->error("charset [format 0] out of range"), -EFAULT;
640 const uint8_t *p = data + pos + 1;
641 for (; _sids.size() < nglyphs; p += 2) {
642 int sid = (p[0] << 8) | p[1];
643 if (sid > actual_max_sid)
644 actual_max_sid = sid;
645 _sids.push_back(sid);
646 }
647
648 } else if (format == 1) {
649 const uint8_t *p = data + pos + 1;
650 for (; _sids.size() < nglyphs; p += 3) {
651 if (p + 3 > data + len)
652 return errh->error("charset [format 1] out of range"), -EFAULT;
653 int sid = (p[0] << 8) | p[1];
654 int n = p[2];
655 if (sid + n > actual_max_sid)
656 actual_max_sid = sid + n;
657 for (int i = 0; i <= n; i++)
658 _sids.push_back(sid + i);
659 }
660
661 } else if (format == 2) {
662 const uint8_t *p = data + pos + 1;
663 for (; _sids.size() < nglyphs; p += 4) {
664 if (p + 4 > data + len)
665 return errh->error("charset [format 2] out of range"), -EFAULT;
666 int sid = (p[0] << 8) | p[1];
667 int n = (p[2] << 8) | p[3];
668 if (sid + n > actual_max_sid)
669 actual_max_sid = sid + n;
670 for (int i = 0; i <= n; i++)
671 _sids.push_back(sid + i);
672 }
673
674 } else
675 return errh->error("unknown charset format %d", format), -EINVAL;
676
677 if (max_sid >= 0 && actual_max_sid > max_sid)
678 return errh->error("charset [format %d] uses bad SID %d", format, actual_max_sid), -EINVAL;
679 _sids.resize(nglyphs);
680 _gids.resize(actual_max_sid + 1, -1);
681 return 0;
682 }
683
684
685 /*****
686 * Cff::FDSelect
687 **/
688
689 void
assign(const Cff * cff,int pos,int nglyphs,ErrorHandler * errh)690 Cff::FDSelect::assign(const Cff *cff, int pos, int nglyphs, ErrorHandler *errh)
691 {
692 if (!errh)
693 errh = ErrorHandler::silent_handler();
694 if (_my_fds)
695 delete[] _fds;
696 _fds = 0;
697 _my_fds = false;
698 _nglyphs = nglyphs;
699 _error = parse(cff, pos, nglyphs, errh);
700 }
701
~FDSelect()702 Cff::FDSelect::~FDSelect()
703 {
704 if (_my_fds)
705 delete[] _fds;
706 }
707
708 int
parse(const Cff * cff,int pos,int nglyphs,ErrorHandler * errh)709 Cff::FDSelect::parse(const Cff *cff, int pos, int nglyphs, ErrorHandler *errh)
710 {
711 const uint8_t *data = cff->data();
712 int len = cff->length();
713
714 if (pos + 1 > len)
715 return errh->error("FDSelect position out of range"), -EFAULT;
716
717 int format = data[pos];
718 if (format == 0) {
719 if (pos + 1 + nglyphs > len)
720 return errh->error("FDSelect [format 0] out of range"), -EFAULT;
721 _fds = data + pos + 1;
722 _my_fds = false;
723 return 0;
724
725 } else if (format == 3) {
726 int nranges = (data[pos+1] << 8) | data[pos+2];
727 if (pos + 3 + 3*nranges + 2 > len)
728 return errh->error("FDSelect [format 3] out of range"), -EFAULT;
729
730 const uint8_t *p = data + pos + 3;
731 int last_glyph = (p[3*nranges] << 8) | p[3*nranges + 1];
732 if (p[0] || p[1] || last_glyph != nglyphs)
733 return errh->error("FDSelect [format 3] bad values"), -EINVAL;
734
735 _fds = new uint8_t[nglyphs];
736 _my_fds = true;
737 int curglyph = 0;
738 for (; curglyph < nglyphs; p += 3) {
739 int nextglyph = (p[3] << 8) | p[4];
740 if (nextglyph > nglyphs || nextglyph < curglyph)
741 return errh->error("FDSelect [format 3] sorting error"), -EINVAL;
742 memset(const_cast<uint8_t *>(_fds + curglyph), p[2], nextglyph - curglyph);
743 curglyph = nextglyph;
744 }
745 return 0;
746
747 } else
748 return errh->error("unknown charset format %d", format), -EINVAL;
749 }
750
751
752 /*****
753 * Cff::IndexIterator
754 **/
755
IndexIterator(const uint8_t * data,int pos,int len,ErrorHandler * errh,const char * index_name)756 Cff::IndexIterator::IndexIterator(const uint8_t *data, int pos, int len, ErrorHandler *errh, const char *index_name)
757 : _contents(0), _offset(0), _last_offset(0)
758 {
759 if (!errh)
760 errh = ErrorHandler::silent_handler();
761
762 // check header
763 int nitems = 0;
764 if (POS_GT(pos + 2, len)) {
765 errh->error("%s: position out of range", index_name);
766 _offsize = -EFAULT;
767 } else if (data[pos] == 0 && data[pos + 1] == 0) {
768 _contents = data + pos + 2;
769 _offsize = 0;
770 } else if (POS_GT(pos + 3, len)) {
771 errh->error("%s: position out of range", index_name);
772 _offsize = -EFAULT;
773 } else if ((_offsize = data[pos + 2]), (_offsize < 1 || _offsize > 4)) {
774 errh->error("%s: offset size %d out of range", index_name, _offsize);
775 _offsize = -EINVAL;
776 } else {
777 nitems = (data[pos] << 8) | data[pos + 1];
778 if (POS_GT(pos + 3 + (nitems + 1) * _offsize, len)) {
779 errh->error("%s: data out of range", index_name);
780 _offsize = -EFAULT;
781 } else {
782 _offset = data + pos + 3;
783 _last_offset = _offset + nitems * _offsize;
784 _contents = _last_offset + _offsize - 1;
785 }
786 }
787
788 // check items in offset array
789 uint32_t max_doff_allowed = len - (pos + 2 + (nitems + 1) * _offsize);
790 uint32_t last_doff = 1;
791 for (const uint8_t *o = _offset; o <= _last_offset && _offsize > 0; o += _offsize) {
792 uint32_t doff = offset_at(o);
793 if (doff > max_doff_allowed) {
794 errh->error("%s: element out of range", index_name);
795 _offsize = -EFAULT;
796 } else if (doff < last_doff) {
797 errh->error("%s: garbled elements", index_name);
798 break;
799 }
800 last_doff = doff;
801 }
802 }
803
804 const uint8_t *
index_end() const805 Cff::IndexIterator::index_end() const
806 {
807 if (_offsize <= 0)
808 return _contents;
809 else
810 return _contents + offset_at(_last_offset);
811 }
812
813 int
nitems() const814 Cff::IndexIterator::nitems() const
815 {
816 if (_offsize <= 0)
817 return 0;
818 else
819 return (_last_offset - _offset) / _offsize;
820 }
821
822
823
824 /*****
825 * Cff::Dict
826 **/
827
Dict()828 Cff::Dict::Dict()
829 : _cff(0), _pos(0), _error(-ENOENT)
830 {
831 }
832
Dict(Cff * cff,int pos,int dict_len,ErrorHandler * errh,const char * dict_name)833 Cff::Dict::Dict(Cff *cff, int pos, int dict_len, ErrorHandler *errh, const char *dict_name)
834 {
835 assign(cff, pos, dict_len, errh, dict_name);
836 }
837
838 int
assign(Cff * cff,int pos,int dict_len,ErrorHandler * errh,const char * dict_name)839 Cff::Dict::assign(Cff *cff, int pos, int dict_len, ErrorHandler *errh, const char *dict_name)
840 {
841 _cff = cff;
842 _pos = pos;
843 _operators.clear();
844 _pointers.clear();
845 _operands.clear();
846
847 if (!errh)
848 errh = ErrorHandler::silent_handler();
849
850 const uint8_t *data = cff->data() + pos;
851 const uint8_t *end_data = data + dict_len;
852
853 _pointers.push_back(0);
854 while (data < end_data)
855 switch (data[0]) {
856
857 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
858 case 8: case 9: case 10: case 11: case 13: case 14: case 15:
859 case 16: case 17: case 18: case 19: case 20: case 21:
860 _operators.push_back(data[0]);
861 _pointers.push_back(_operands.size());
862 data++;
863 break;
864
865 case 22: case 23: case 24: case 25: case 26: case 27: case 31:
866 case 255: // reserved
867 errh->error("%s: reserved operator %d", dict_name, data[0]);
868 return (_error = -ERANGE);
869
870 case 12:
871 if (data + 1 >= end_data)
872 goto runoff;
873 _operators.push_back(32 + data[1]);
874 _pointers.push_back(_operands.size());
875 data += 2;
876 break;
877
878 case 28: {
879 if (data + 2 >= end_data)
880 goto runoff;
881 int16_t val = (data[1] << 8) | data[2];
882 _operands.push_back(val);
883 data += 3;
884 break;
885 }
886
887 case 29: {
888 if (data + 4 >= end_data)
889 goto runoff;
890 int32_t val = (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4];
891 _operands.push_back(val);
892 data += 5;
893 break;
894 }
895
896 case 30: {
897 char buf[1024];
898 int pos = 0;
899 if (data + 1 >= end_data)
900 goto runoff;
901 for (data++; data < end_data && pos < 1020; data++) {
902 int d = *data;
903 for (int i = 0; i < 2; i++, d <<= 4) {
904 int digit = (d >> 4) & 0xF;
905 switch (digit) {
906 case 10:
907 buf[pos++] = '.';
908 break;
909 case 11:
910 buf[pos++] = 'E';
911 break;
912 case 12:
913 buf[pos++] = 'E';
914 buf[pos++] = '-';
915 break;
916 case 13:
917 errh->error("%s: bad digit in real number", dict_name);
918 goto invalid;
919 case 14:
920 buf[pos++] = '-';
921 break;
922 case 15:
923 goto found;
924 default:
925 buf[pos++] = digit + '0';
926 break;
927 }
928 }
929 }
930 // number not found
931 goto runoff;
932 found:
933 char *endptr;
934 buf[pos] = '\0';
935 _operands.push_back(strtod(buf, &endptr));
936 if (*endptr) {
937 errh->error("%s: real number syntax error", dict_name);
938 goto invalid;
939 }
940 data++;
941 break;
942 }
943
944 case 247: case 248: case 249: case 250: {
945 if (data + 1 >= end_data)
946 goto runoff;
947 int val = ((data[0] - 247) << 8) + data[1] + 108;
948 _operands.push_back(val);
949 data += 2;
950 break;
951 }
952
953 case 251: case 252: case 253: case 254: {
954 if (data + 1 >= end_data)
955 goto runoff;
956 int val = -((data[0] - 251) << 8) - data[1] - 108;
957 _operands.push_back(val);
958 data += 2;
959 break;
960 }
961
962 default:
963 _operands.push_back(data[0] - 139);
964 data++;
965 break;
966
967 }
968
969 // not closed by an operator?
970 if (_pointers.back() != _operands.size()) {
971 errh->error("%s: not closed by an operator", dict_name);
972 goto invalid;
973 }
974
975 return (_error = 0);
976
977 runoff:
978 errh->error("%s: runoff end of DICT", dict_name);
979 return (_error = -EFAULT);
980
981 invalid:
982 return (_error = -EINVAL);
983 }
984
985 int
check(bool is_private,ErrorHandler * errh,const char * dict_name) const986 Cff::Dict::check(bool is_private, ErrorHandler *errh, const char *dict_name) const
987 {
988 if (!errh)
989 errh = ErrorHandler::silent_handler();
990 int before_nerrors = errh->nerrors();
991
992 // keep track of operator reuse
993 Vector<int> operators_used;
994
995 for (int i = 0; i < _operators.size(); i++) {
996 int arity = _pointers[i+1] - _pointers[i];
997 double num = (arity == 0 ? 0 : _operands[_pointers[i]]);
998 double truncnum = floor(num);
999 int op = _operators[i];
1000 int type = (op > oLastOperator ? tNone : operator_types[op]);
1001
1002 // check reuse
1003 if (op >= operators_used.size())
1004 operators_used.resize(op + 1, 0);
1005 if (operators_used[op] && (type & tTypeMask) != tNone)
1006 errh->error("%s: operator %<%s%> specified twice", dict_name, operator_names[op]);
1007 operators_used[op]++;
1008
1009 // check data
1010 switch (type & tTypeMask) {
1011
1012 case tNone:
1013 if (op >= 32)
1014 errh->warning("%s: unknown operator %<12 %d%>", dict_name, op - 32);
1015 else
1016 errh->warning("%s: unknown operator %<%d%>", dict_name, op);
1017 continue;
1018
1019 case tSID:
1020 if (arity != 1 || num != truncnum || num < 0 || num > _cff->max_sid())
1021 goto bad_data;
1022 break;
1023
1024 case tFontNumber:
1025 if (arity != 1 || num != truncnum || num < 0 || num >= _cff->nfonts())
1026 goto bad_data;
1027 break;
1028
1029 case tBoolean:
1030 if (arity != 1)
1031 goto bad_data;
1032 else if (num != 0 && num != 1)
1033 errh->warning("%s: data for Boolean operator %<%s%> not 0 or 1", dict_name, operator_names[op]);
1034 break;
1035
1036 case tNumber:
1037 if (arity != 1)
1038 goto bad_data;
1039 break;
1040
1041 case tOffset:
1042 if (arity != 1 || num != truncnum || num < 0 || num >= _cff->length())
1043 goto bad_data;
1044 break;
1045
1046 case tLocalOffset:
1047 if (arity != 1 || num != truncnum || _pos + num < 0 || _pos + num >= _cff->length())
1048 goto bad_data;
1049 break;
1050
1051 case tPrivateType: {
1052 if (arity != 2 || num != truncnum || num < 0)
1053 goto bad_data;
1054 double off = _operands[_pointers[i] + 1];
1055 if (off < 0 || off + num > _cff->length())
1056 goto bad_data;
1057 break;
1058 }
1059
1060 case tArray2: case tArray3: case tArray4:
1061 case tArray5: case tArray6:
1062 if (arity != (type & tTypeMask) - tArray2 + 2)
1063 goto bad_data;
1064 break;
1065
1066 case tArray:
1067 break;
1068
1069 }
1070
1071 // check dict location
1072 if (((type & tPrivate) != 0) != is_private)
1073 errh->warning("%s: operator %<%s%> in wrong DICT", dict_name, operator_names[op]);
1074
1075 continue;
1076
1077 bad_data:
1078 errh->error("%s: bad data for operator %<%s%>", dict_name, operator_names[op]);
1079 }
1080
1081 return (errh->nerrors() != before_nerrors ? -1 : 0);
1082 }
1083
1084 bool
has(DictOperator op) const1085 Cff::Dict::has(DictOperator op) const
1086 {
1087 for (int i = 0; i < _operators.size(); i++)
1088 if (_operators[i] == op)
1089 return true;
1090 return false;
1091 }
1092
1093 bool
xvalue(DictOperator op,Vector<double> & out) const1094 Cff::Dict::xvalue(DictOperator op, Vector<double> &out) const
1095 {
1096 out.clear();
1097 for (int i = 0; i < _operators.size(); i++)
1098 if (_operators[i] == op) {
1099 for (int j = _pointers[i]; j < _pointers[i+1]; j++)
1100 out.push_back(_operands[j]);
1101 return true;
1102 }
1103 return false;
1104 }
1105
1106 bool
xvalue(DictOperator op,int * val) const1107 Cff::Dict::xvalue(DictOperator op, int *val) const
1108 {
1109 for (int i = 0; i < _operators.size(); i++)
1110 if (_operators[i] == op && _pointers[i] + 1 == _pointers[i+1]) {
1111 *val = (int) _operands[_pointers[i]];
1112 return true;
1113 }
1114 return false;
1115 }
1116
1117 bool
xvalue(DictOperator op,double * val) const1118 Cff::Dict::xvalue(DictOperator op, double *val) const
1119 {
1120 for (int i = 0; i < _operators.size(); i++)
1121 if (_operators[i] == op && _pointers[i] + 1 == _pointers[i+1]) {
1122 *val = _operands[_pointers[i]];
1123 return true;
1124 }
1125 return false;
1126 }
1127
1128 bool
value(DictOperator op,Vector<double> & out) const1129 Cff::Dict::value(DictOperator op, Vector<double> &out) const
1130 {
1131 return xvalue(op, out) || default_dict().xvalue(op, out);
1132 }
1133
1134 bool
value(DictOperator op,int * val) const1135 Cff::Dict::value(DictOperator op, int *val) const
1136 {
1137 return xvalue(op, val) || default_dict().xvalue(op, val);
1138 }
1139
1140 bool
value(DictOperator op,double * val) const1141 Cff::Dict::value(DictOperator op, double *val) const
1142 {
1143 return xvalue(op, val) || default_dict().xvalue(op, val);
1144 }
1145
1146 void
unparse(ErrorHandler * errh,const char * dict_name) const1147 Cff::Dict::unparse(ErrorHandler *errh, const char *dict_name) const
1148 {
1149 StringAccum sa;
1150 for (int i = 0; i < _operators.size(); i++) {
1151 sa.clear();
1152 if (_pointers[i] + 1 == _pointers[i+1])
1153 sa << _operands[_pointers[i]];
1154 else {
1155 sa << "[";
1156 for (int j = _pointers[i]; j < _pointers[i+1]; j++)
1157 sa << _operands[j] << ' ';
1158 sa.pop_back();
1159 sa << "]";
1160 }
1161 errh->message("%s: %s %s", dict_name, operator_names[_operators[i]], sa.c_str());
1162 }
1163 }
1164
1165
1166 /*****
1167 * CffFontParent
1168 **/
1169
1170 static int
handle_private(Cff * cff,const Cff::Dict & top_dict,Cff::Dict & private_dict,double & default_width_x,double & nominal_width_x,Cff::IndexIterator & subrs_index,Vector<Charstring * > & subrs_cs,ErrorHandler * errh)1171 handle_private(Cff *cff, const Cff::Dict &top_dict, Cff::Dict &private_dict,
1172 double &default_width_x, double &nominal_width_x,
1173 Cff::IndexIterator &subrs_index, Vector<Charstring *> &subrs_cs,
1174 ErrorHandler *errh)
1175 {
1176 Vector<double> private_info;
1177 top_dict.value(Cff::oPrivate, private_info);
1178 int private_offset = (int) private_info[1];
1179 private_dict.assign(cff, private_offset, (int) private_info[0], errh, "Private DICT");
1180 if (private_dict.error() < 0)
1181 return private_dict.error();
1182 else if (private_dict.check(true, errh, "Private DICT") < 0)
1183 return -EINVAL;
1184 //private_dict.unparse(errh, "Private DICT");
1185
1186 private_dict.value(Cff::oDefaultWidthX, &default_width_x);
1187 private_dict.value(Cff::oNominalWidthX, &nominal_width_x);
1188 if (private_dict.has(Cff::oSubrs)) {
1189 int subrs_offset = 0;
1190 private_dict.value(Cff::oSubrs, &subrs_offset);
1191 subrs_index = Cff::IndexIterator(cff->data(), private_offset + subrs_offset, cff->length(), errh, "Subrs INDEX");
1192 if (subrs_index.error() < 0)
1193 return subrs_index.error();
1194 }
1195 subrs_cs.assign(subrs_index.nitems(), 0);
1196 return 0;
1197 }
1198
1199
FontParent(Cff * cff)1200 Cff::FontParent::FontParent(Cff* cff)
1201 : CharstringProgram(cff->units_per_em()), _cff(cff), _error(-1)
1202 {
1203 }
1204
1205 Charstring *
charstring(const IndexIterator & iiter,int which) const1206 Cff::FontParent::charstring(const IndexIterator &iiter, int which) const
1207 {
1208 const uint8_t *s1 = iiter[which];
1209 int slen = iiter[which + 1] - s1;
1210 String cs = _cff->data_string().substring(s1 - _cff->data(), slen);
1211 if (slen == 0)
1212 return 0;
1213 else if (_charstring_type == 1)
1214 return new Type1Charstring(cs);
1215 else
1216 return new Type2Charstring(cs);
1217 }
1218
1219 Charstring *
gsubr(int i) const1220 Cff::FontParent::gsubr(int i) const
1221 {
1222 return _cff->gsubr(i);
1223 }
1224
1225 int
gsubr_bias() const1226 Cff::FontParent::gsubr_bias() const
1227 {
1228 return Efont::subr_bias(2, ngsubrs_x());
1229 }
1230
1231
1232 /*****
1233 * CffFont
1234 **/
1235
Font(Cff * cff,PermString font_name,const Dict & top_dict,ErrorHandler * errh)1236 Cff::Font::Font(Cff *cff, PermString font_name, const Dict &top_dict, ErrorHandler *errh)
1237 : ChildFont(cff, 0, 2, top_dict, errh), _font_name(font_name),
1238 _t1encoding(0)
1239 {
1240 assert(!_top_dict.has_first(oROS));
1241 if (_error < 0)
1242 return;
1243
1244 // extract CharStrings
1245 // must use xvalue because we could be creating the default dict!
1246 int charstrings_offset = 0;
1247 _top_dict.xvalue(oCharStrings, &charstrings_offset);
1248 _charstrings_index = Cff::IndexIterator(cff->data(), charstrings_offset, cff->length(), errh, "CharStrings INDEX");
1249 if (_charstrings_index.error() < 0) {
1250 _error = _charstrings_index.error();
1251 return;
1252 }
1253 _charstrings_cs.assign(_charstrings_index.nitems(), 0);
1254
1255 int charset = 0;
1256 _top_dict.xvalue(oCharset, &charset);
1257 _charset.assign(cff, charset, _charstrings_index.nitems(), cff->max_sid(), errh);
1258 if (_charset.error() < 0) {
1259 _error = _charset.error();
1260 return;
1261 }
1262
1263 int Encoding = 0;
1264 _top_dict.xvalue(oEncoding, &Encoding);
1265 if (parse_encoding(Encoding, errh) < 0)
1266 return;
1267
1268 // success!
1269 _error = 0;
1270 }
1271
~Font()1272 Cff::Font::~Font()
1273 {
1274 for (int i = 0; i < _charstrings_cs.size(); i++)
1275 delete _charstrings_cs[i];
1276 delete _t1encoding;
1277 }
1278
1279 int
parse_encoding(int pos,ErrorHandler * errh)1280 Cff::Font::parse_encoding(int pos, ErrorHandler *errh)
1281 {
1282 _encoding_pos = pos;
1283 for (int i = 0; i < 256; i++)
1284 _encoding[i] = 0;
1285
1286 // check for standard encodings
1287 if (pos == 0)
1288 return assign_standard_encoding(standard_encoding);
1289 else if (pos == 1)
1290 return assign_standard_encoding(expert_encoding);
1291
1292 // otherwise, a custom encoding
1293 const uint8_t *data = _cff->data();
1294 int len = _cff->length();
1295 if (pos + 1 > len)
1296 return errh->error("Encoding position out of range"), -EFAULT;
1297 bool supplemented = (data[pos] & 0x80) != 0;
1298 int format = (data[pos] & 0x7F);
1299
1300 int retval = 0;
1301 int endpos, g = 1;
1302 if (format == 0) {
1303 endpos = pos + 2 + data[pos + 1];
1304 if (endpos > len)
1305 return errh->error("Encoding[0] out of range"), -EFAULT;
1306 const uint8_t *p = data + pos + 2;
1307 int n = data[pos + 1];
1308 for (; g <= n; g++, p++) {
1309 int e = p[0];
1310 if (_encoding[e])
1311 retval = 1;
1312 _encoding[e] = g;
1313 }
1314
1315 } else if (format == 1) {
1316 endpos = pos + 2 + data[pos + 1] * 2;
1317 if (endpos > len)
1318 return errh->error("Encoding[1] out of range"), -EFAULT;
1319 const uint8_t *p = data + pos + 2;
1320 int n = data[pos + 1];
1321 for (int i = 0; i < n; i++, p += 2) {
1322 int first = p[0];
1323 int nLeft = p[1];
1324 for (int e = first; e <= first + nLeft; e++) {
1325 if (_encoding[e])
1326 retval = 1;
1327 _encoding[e] = g++;
1328 }
1329 }
1330
1331 } else
1332 return errh->error("unknown Encoding format %d", format), -EINVAL;
1333
1334 if (g > _charset.nglyphs())
1335 return errh->error("Encoding glyph %d out of range", g), -EINVAL;
1336
1337 // check supplements
1338 if (supplemented) {
1339 if (endpos + data[endpos] * 3 > len)
1340 return -EINVAL;
1341 const uint8_t *p = data + endpos + 1;
1342 int n = data[endpos];
1343 for (int i = 0; i < n; i++, p += 3) {
1344 int e = p[0];
1345 int s = (p[1] << 8) | p[2];
1346 int g = _charset.sid_to_gid(s);
1347 if (_encoding[e])
1348 retval = 1;
1349 if (g < 0 || g >= _charset.nglyphs())
1350 return errh->error("Encoding glyph %d out of range", g), -EINVAL;
1351 _encoding[e] = g;
1352 }
1353 }
1354
1355 // successfully done
1356 return retval;
1357 }
1358
1359 int
assign_standard_encoding(const int * standard_encoding)1360 Cff::Font::assign_standard_encoding(const int *standard_encoding)
1361 {
1362 for (int i = 0; i < 256; i++)
1363 _encoding[i] = _charset.sid_to_gid(standard_encoding[i]);
1364 return 0;
1365 }
1366
1367 void
font_matrix(double matrix[6]) const1368 Cff::Font::font_matrix(double matrix[6]) const
1369 {
1370 Vector<double> t1d_matrix;
1371 if (dict_value(oFontMatrix, t1d_matrix) && t1d_matrix.size() == 6)
1372 memcpy(&matrix[0], &t1d_matrix[0], sizeof(double) * 6);
1373 else {
1374 matrix[0] = matrix[3] = 0.001;
1375 matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0;
1376 }
1377 }
1378
1379 PermString
glyph_name(int gid) const1380 Cff::Font::glyph_name(int gid) const
1381 {
1382 if (gid >= 0 && gid < nglyphs())
1383 return _cff->sid_permstring(_charset.gid_to_sid(gid));
1384 else
1385 return PermString();
1386 }
1387
1388 void
glyph_names(Vector<PermString> & gnames) const1389 Cff::Font::glyph_names(Vector<PermString> &gnames) const
1390 {
1391 gnames.resize(nglyphs());
1392 for (int i = 0; i < nglyphs(); i++)
1393 gnames[i] = _cff->sid_permstring(_charset.gid_to_sid(i));
1394 }
1395
1396 Charstring *
glyph(int gid) const1397 Cff::Font::glyph(int gid) const
1398 {
1399 if (gid < 0 || gid >= nglyphs())
1400 return 0;
1401 if (!_charstrings_cs[gid])
1402 _charstrings_cs[gid] = charstring(_charstrings_index, gid);
1403 return _charstrings_cs[gid];
1404 }
1405
1406 Charstring *
glyph(PermString name) const1407 Cff::Font::glyph(PermString name) const
1408 {
1409 int gid = _charset.sid_to_gid(_cff->sid(name));
1410 if (gid < 0)
1411 return 0;
1412 if (!_charstrings_cs[gid])
1413 _charstrings_cs[gid] = charstring(_charstrings_index, gid);
1414 return _charstrings_cs[gid];
1415 }
1416
1417 int
glyphid(PermString name) const1418 Cff::Font::glyphid(PermString name) const
1419 {
1420 return _charset.sid_to_gid(_cff->sid(name));
1421 }
1422
1423 Type1Encoding *
type1_encoding() const1424 Cff::Font::type1_encoding() const
1425 {
1426 if (_encoding_pos == 0)
1427 return Type1Encoding::standard_encoding();
1428 if (!_t1encoding)
1429 _t1encoding = type1_encoding_copy();
1430 return _t1encoding;
1431 }
1432
1433 Type1Encoding *
type1_encoding_copy() const1434 Cff::Font::type1_encoding_copy() const
1435 {
1436 if (_encoding_pos == 0)
1437 return Type1Encoding::standard_encoding();
1438 Type1Encoding *e = new Type1Encoding;
1439 for (int i = 0; i < 256; i++)
1440 if (_encoding[i])
1441 e->put(i, _cff->sid_permstring(_charset.gid_to_sid(_encoding[i])));
1442 return e;
1443 }
1444
1445 bool
dict_has(DictOperator op) const1446 Cff::Font::dict_has(DictOperator op) const
1447 {
1448 return dict_of(op).has(op);
1449 }
1450
1451 String
dict_string(DictOperator op) const1452 Cff::Font::dict_string(DictOperator op) const
1453 {
1454 Vector<double> vec;
1455 dict_of(op).value(op, vec);
1456 if (vec.size() == 1 && vec[0] >= 0 && vec[0] <= _cff->max_sid())
1457 return _cff->sid_string((int) vec[0]);
1458 else
1459 return String();
1460 }
1461
1462
1463 /*****
1464 * Cff::CIDFont
1465 **/
1466
CIDFont(Cff * cff,PermString font_name,const Dict & top_dict,ErrorHandler * errh)1467 Cff::CIDFont::CIDFont(Cff *cff, PermString font_name, const Dict &top_dict, ErrorHandler *errh)
1468 : FontParent(cff), _font_name(font_name), _top_dict(top_dict)
1469 {
1470 assert(_top_dict.has_first(oROS));
1471
1472 // parse top DICT
1473 _error = -EINVAL;
1474 if (_top_dict.check(false, errh, "Top DICT") < 0)
1475 return;
1476 else if (!_top_dict.has(oCharStrings)) {
1477 errh->error("font has no CharStrings dictionary");
1478 return;
1479 }
1480 //_top_dict.unparse(errh, "Top DICT");
1481
1482 // extract offsets and information from TOP DICT
1483 _top_dict.value(oCharstringType, &_charstring_type);
1484 if (_charstring_type != 1 && _charstring_type != 2) {
1485 errh->error("unknown CharString type %d", _charstring_type);
1486 return;
1487 }
1488
1489 int charstrings_offset = 0;
1490 _top_dict.value(oCharStrings, &charstrings_offset);
1491 _charstrings_index = Cff::IndexIterator(cff->data(), charstrings_offset, cff->length(), errh, "CharStrings INDEX");
1492 if (_charstrings_index.error() < 0) {
1493 _error = _charstrings_index.error();
1494 return;
1495 }
1496 _charstrings_cs.assign(_charstrings_index.nitems(), 0);
1497
1498 int charset = 0;
1499 _top_dict.value(oCharset, &charset);
1500 _charset.assign(cff, charset, _charstrings_index.nitems(), -1, errh);
1501 if (_charset.error() < 0) {
1502 _error = _charset.error();
1503 return;
1504 }
1505
1506 // extract information about child fonts
1507 int fdarray_offset = 0;
1508 if (!_top_dict.value(oFDArray, &fdarray_offset)) {
1509 errh->error("CID-keyed font missing FDArray");
1510 return;
1511 }
1512 IndexIterator fdarray_index(cff->data(), fdarray_offset, cff->length(), errh, "FDArray INDEX");
1513 for (; fdarray_index; fdarray_index++) {
1514 Dict d(cff, fdarray_index[0] - cff->data(), fdarray_index[1] - fdarray_index[0], errh, "Top DICT");
1515 if (!d.ok() || d.check(false, errh, "Top DICT") < 0) {
1516 _error = d.error();
1517 return;
1518 }
1519 _child_fonts.push_back(new ChildFont(cff, this, _charstring_type, d, errh));
1520 if (!_child_fonts.back()->ok())
1521 return;
1522 }
1523
1524 int fdselect_offset = 0;
1525 if (!_top_dict.value(oFDSelect, &fdselect_offset)) {
1526 errh->error("CID-keyed font missing FDSelect");
1527 return;
1528 }
1529 _fdselect.assign(cff, fdselect_offset, _charstrings_cs.size(), errh);
1530 if (_fdselect.error() < 0)
1531 return;
1532
1533 // success!
1534 _error = 0;
1535 set_parent_program(true);
1536 }
1537
~CIDFont()1538 Cff::CIDFont::~CIDFont()
1539 {
1540 for (int i = 0; i < _charstrings_cs.size(); i++)
1541 delete _charstrings_cs[i];
1542 for (int i = 0; i < _child_fonts.size(); i++)
1543 delete _child_fonts[i];
1544 }
1545
1546 void
font_matrix(double matrix[6]) const1547 Cff::CIDFont::font_matrix(double matrix[6]) const
1548 {
1549 // XXX
1550 matrix[0] = matrix[3] = 0.001;
1551 matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0;
1552 }
1553
1554 const CharstringProgram *
child_program(int gid) const1555 Cff::CIDFont::child_program(int gid) const
1556 {
1557 int fd = _fdselect.gid_to_fd(gid);
1558 if (fd >= 0 && fd < _child_fonts.size())
1559 return _child_fonts.at_u(fd);
1560 else
1561 return 0;
1562 }
1563
1564 PermString
glyph_name(int gid) const1565 Cff::CIDFont::glyph_name(int gid) const
1566 {
1567 if (gid >= 0 && gid < nglyphs())
1568 return permprintf("#%d", _charset.gid_to_sid(gid));
1569 else
1570 return PermString();
1571 }
1572
1573 void
glyph_names(Vector<PermString> & gnames) const1574 Cff::CIDFont::glyph_names(Vector<PermString> &gnames) const
1575 {
1576 gnames.resize(nglyphs());
1577 for (int i = 0; i < nglyphs(); i++)
1578 gnames[i] = permprintf("#%d", _charset.gid_to_sid(i));
1579 }
1580
1581 Charstring *
glyph(int gid) const1582 Cff::CIDFont::glyph(int gid) const
1583 {
1584 if (gid < 0 || gid >= nglyphs())
1585 return 0;
1586 if (!_charstrings_cs[gid])
1587 _charstrings_cs[gid] = charstring(_charstrings_index, gid);
1588 return _charstrings_cs[gid];
1589 }
1590
1591 int
glyphid(PermString name) const1592 Cff::CIDFont::glyphid(PermString name) const
1593 {
1594 if (name.length() <= 1 || name[0] != '#' || !isdigit((unsigned char) name[1]))
1595 return -1;
1596 char *endptr;
1597 long cid = strtol(name.c_str() + 1, &endptr, 10);
1598 if (*endptr != 0)
1599 return -1;
1600 return _charset.sid_to_gid(cid);
1601 }
1602
1603 Charstring *
glyph(PermString name) const1604 Cff::CIDFont::glyph(PermString name) const
1605 {
1606 return CIDFont::glyph(CIDFont::glyphid(name));
1607 }
1608
1609
1610 /*****
1611 * ChildFont
1612 **/
1613
ChildFont(Cff * cff,Cff::CIDFont * parent,int charstring_type,const Dict & top_dict,ErrorHandler * errh)1614 Cff::ChildFont::ChildFont(Cff *cff, Cff::CIDFont *parent, int charstring_type, const Dict &top_dict, ErrorHandler *errh)
1615 : FontParent(cff), _parent(parent), _top_dict(top_dict)
1616 {
1617 if (!errh)
1618 errh = ErrorHandler::silent_handler();
1619
1620 if (!cff->ok() || !_top_dict.ok()) {
1621 errh->error("invalid CFF");
1622 _error = -EINVAL;
1623 return;
1624 }
1625
1626 // extract offsets and information from TOP DICT
1627 _charstring_type = charstring_type;
1628 _top_dict.value(oCharstringType, &_charstring_type);
1629 if (_charstring_type != 1 && _charstring_type != 2) {
1630 errh->error("unknown CharString type %d", _charstring_type);
1631 return;
1632 }
1633
1634 // extract information from Private DICT
1635 if (_top_dict.has(oPrivate)
1636 && (_error = handle_private(cff, _top_dict, _private_dict, _default_width_x, _nominal_width_x, _subrs_index, _subrs_cs, errh)) < 0)
1637 return;
1638
1639 // success!
1640 _error = 0;
1641 }
1642
~ChildFont()1643 Cff::ChildFont::~ChildFont()
1644 {
1645 for (int i = 0; i < _subrs_cs.size(); i++)
1646 delete _subrs_cs[i];
1647 }
1648
1649 Charstring *
charstring(const IndexIterator & iiter,int which) const1650 Cff::ChildFont::charstring(const IndexIterator &iiter, int which) const
1651 {
1652 const uint8_t *s1 = iiter[which];
1653 int slen = iiter[which + 1] - s1;
1654 String cs = _cff->data_string().substring(s1 - _cff->data(), slen);
1655 if (slen == 0)
1656 return 0;
1657 else if (_charstring_type == 1)
1658 return new Type1Charstring(cs);
1659 else
1660 return new Type2Charstring(cs);
1661 }
1662
1663 Charstring *
subr(int i) const1664 Cff::ChildFont::subr(int i) const
1665 {
1666 i += Efont::subr_bias(_charstring_type, nsubrs_x());
1667 if (i < 0 || i >= nsubrs_x())
1668 return 0;
1669 if (!_subrs_cs[i])
1670 _subrs_cs[i] = charstring(_subrs_index, i);
1671 return _subrs_cs[i];
1672 }
1673
1674 int
subr_bias() const1675 Cff::ChildFont::subr_bias() const
1676 {
1677 return Efont::subr_bias(_charstring_type, nsubrs_x());
1678 }
1679
1680 double
global_width_x(bool is_nominal) const1681 Cff::ChildFont::global_width_x(bool is_nominal) const
1682 {
1683 return (is_nominal ? _nominal_width_x : _default_width_x);
1684 }
1685
1686 }
1687