1 // -*- related-file-name: "../include/efont/cff.hh" -*-
2
3 /* cff.{cc,hh} -- Compact Font Format fonts
4 *
5 * Copyright (c) 1998-2014 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;
334 static Cff::Font *cfffont;
335 if (!cfffont) {
336 cff = new Cff(String::make_stable((const char *) default_dict_cff_data, sizeof(default_dict_cff_data)),
337 0, ErrorHandler::default_handler());
338 cfffont = (Cff::Font *) cff->font();
339 }
340 return cfffont->top_dict();
341 }
342
343
344 #define POS_GT(pos1, pos2) ((unsigned)(pos1) > (unsigned)(pos2))
345
346
Cff(const String & s,unsigned units_per_em,ErrorHandler * errh)347 Cff::Cff(const String& s, unsigned units_per_em, ErrorHandler* errh)
348 : _data_string(s), _data(reinterpret_cast<const uint8_t *>(_data_string.data())), _len(_data_string.length()),
349 _strings_map(-2), _units_per_em(units_per_em)
350 {
351 static_assert((sizeof(standard_strings) / sizeof(standard_strings[0])) == NSTANDARD_STRINGS,
352 "NSTANDARD_STRINGS defined incorrectly");
353 static_assert((sizeof(standard_encoding) / sizeof(standard_encoding[0])) == 256,
354 "standard_encoding has wrong size");
355 static_assert((sizeof(expert_encoding) / sizeof(expert_encoding[0])) == 256,
356 "expert_encoding has wrong size");
357 _error = parse_header(errh ? errh : ErrorHandler::silent_handler());
358 }
359
~Cff()360 Cff::~Cff()
361 {
362 for (int i = 0; i < _gsubrs_cs.size(); i++)
363 delete _gsubrs_cs[i];
364 }
365
366 /*
367 * Parsing the file header
368 */
369
370 int
parse_header(ErrorHandler * errh)371 Cff::parse_header(ErrorHandler *errh)
372 {
373 if (_gsubrs_index.error() >= 0) // already done
374 return 0;
375
376 // parse header
377 if (_len == 0)
378 return errh->error("not a PostScript-flavored OpenType font"), -EFAULT;
379 if (_len < HEADER_SIZE)
380 return errh->error("CFF file corrupted (too small)"), -EFAULT;
381 if (_data[0] != 1) // major version number
382 return errh->error("bad major version number %d", _data[0]), -ERANGE;
383 int hdrSize = _data[2], offSize = _data[3];
384 if (hdrSize < 4 || hdrSize > _len || offSize < 1 || offSize > 4)
385 return errh->error("corrupted file header"), -EINVAL;
386 int name_index_pos = hdrSize;
387
388 // parse name INDEX
389 IndexIterator niter(_data, name_index_pos, _len, errh, "Name INDEX");
390 if (niter.error() < 0)
391 return niter.error();
392 _name_index.clear();
393 for (; niter; niter++) {
394 const uint8_t *d0 = niter[0];
395 const uint8_t *d1 = niter[1];
396 if (d0 == d1 || d0[0] == 0)
397 _name_index.push_back(PermString());
398 else
399 _name_index.push_back(PermString(reinterpret_cast<const char *>(d0), d1 - d0));
400 }
401 int top_dict_index_pos = niter.index_end() - _data;
402
403 // check top DICT INDEX
404 _top_dict_index = IndexIterator(_data, top_dict_index_pos, _len, errh, "Top DICT INDEX");
405 if (_top_dict_index.error() < 0)
406 return _top_dict_index.error();
407 else if (_top_dict_index.nitems() != nfonts())
408 return errh->error("invalid font: Top DICT INDEX has %d elements, but there are %d fonts", _top_dict_index.nitems(), nfonts()), -EINVAL;
409 int string_index_pos = _top_dict_index.index_end() - _data;
410
411 // check strings INDEX
412 _strings_index = IndexIterator(_data, string_index_pos, _len, errh, "Strings INDEX");
413 if (_strings_index.error() < 0)
414 return _strings_index.error();
415 else if (NSTANDARD_STRINGS + _strings_index.nitems() - 1 > MAX_SID)
416 return errh->error("too many strings defined in font"), -EINVAL;
417 _strings.assign(_strings_index.nitems(), PermString());
418 int global_subr_index_pos = _strings_index.index_end() - _data;
419
420 // check gsubr INDEX
421 _gsubrs_index = IndexIterator(_data, global_subr_index_pos, _len, errh, "Gsubrs INDEX");
422 if (_gsubrs_index.error() < 0)
423 return _gsubrs_index.error();
424 _gsubrs_cs.assign(ngsubrs(), 0);
425
426 return 0;
427 }
428
429 int
sid(PermString s)430 Cff::sid(PermString s)
431 {
432 if (!s) // XXX?
433 return -1;
434
435 // check standard strings
436 if (standard_permstrings_map["a"] < 0)
437 for (int i = 0; i < NSTANDARD_STRINGS; i++) {
438 if (!standard_permstrings[i])
439 standard_permstrings[i] = PermString(standard_strings[i]);
440 standard_permstrings_map.insert(standard_permstrings[i], i);
441 }
442 int sid = standard_permstrings_map[s];
443 if (sid >= 0)
444 return sid;
445
446 // check user strings
447 sid = _strings_map[s];
448 if (sid >= -1)
449 return sid;
450
451 for (int i = 0; i < _strings.size(); i++)
452 if (!_strings[i] && s.length() == _strings_index[i+1] - _strings_index[i] && memcmp(s.c_str(), _strings_index[i], s.length()) == 0) {
453 _strings[i] = s;
454 _strings_map.insert(s, i + NSTANDARD_STRINGS);
455 return i + NSTANDARD_STRINGS;
456 }
457
458 _strings_map.insert(s, -1);
459 return -1;
460 }
461
462 String
sid_string(int sid) const463 Cff::sid_string(int sid) const
464 {
465 if (sid < 0)
466 return String();
467 else if (sid < NSTANDARD_STRINGS)
468 return String(sid_permstring(sid));
469 else {
470 sid -= NSTANDARD_STRINGS;
471 if (sid >= _strings.size())
472 return String();
473 else if (_strings[sid])
474 return String(_strings[sid]);
475 else
476 return String(reinterpret_cast<const char *>(_strings_index[sid]), _strings_index[sid + 1] - _strings_index[sid]);
477 }
478 }
479
480 PermString
sid_permstring(int sid) const481 Cff::sid_permstring(int sid) const
482 {
483 if (sid < 0)
484 return PermString();
485 else if (sid < NSTANDARD_STRINGS) {
486 if (!standard_permstrings[sid])
487 standard_permstrings[sid] = PermString(standard_strings[sid]);
488 return standard_permstrings[sid];
489 } else {
490 sid -= NSTANDARD_STRINGS;
491 if (sid >= _strings.size())
492 return PermString();
493 else if (_strings[sid])
494 return _strings[sid];
495 else {
496 PermString s = PermString(reinterpret_cast<const char *>(_strings_index[sid]), _strings_index[sid + 1] - _strings_index[sid]);
497 _strings[sid] = s;
498 _strings_map.insert(s, sid + NSTANDARD_STRINGS);
499 return s;
500 }
501 }
502 }
503
504 int
font_offset(int findex,int & offset,int & length) const505 Cff::font_offset(int findex, int &offset, int &length) const
506 {
507 if (findex < 0 || findex >= nfonts())
508 return -ENOENT;
509 offset = _top_dict_index[findex] - _data;
510 length = _top_dict_index[findex + 1] - _top_dict_index[findex];
511 return 0;
512 }
513
514 int
font_offset(PermString name,int & offset,int & length) const515 Cff::font_offset(PermString name, int &offset, int &length) const
516 {
517 for (int i = 0; i < _name_index.size(); i++)
518 if (_name_index[i] == name && name)
519 return font_offset(i, offset, length);
520 return -ENOENT;
521 }
522
523 Cff::FontParent *
font(PermString font_name,ErrorHandler * errh)524 Cff::font(PermString font_name, ErrorHandler *errh)
525 {
526 if (!errh)
527 errh = ErrorHandler::silent_handler();
528
529 if (!ok())
530 return errh->error("invalid CFF"), (FontParent *) 0;
531
532 // search for a font named 'font_name'
533 for (int i = 0; i < _name_index.size(); i++)
534 if (_name_index[i] && (!font_name || font_name == _name_index[i])) {
535 int td_offset = _top_dict_index[i] - _data;
536 int td_length = _top_dict_index[i + 1] - _top_dict_index[i];
537 Dict top_dict(this, td_offset, td_length, errh, "Top DICT");
538 if (!top_dict.ok())
539 return 0;
540 else if (top_dict.has_first(oROS))
541 return new Cff::CIDFont(this, _name_index[i], top_dict, errh);
542 else
543 return new Cff::Font(this, _name_index[i], top_dict, errh);
544 }
545
546 if (!font_name)
547 errh->error("no fonts in CFF");
548 else
549 errh->error("font %<%s%> not found", font_name.c_str());
550 return 0;
551 }
552
553 static inline int
subr_bias(int charstring_type,int nsubrs)554 subr_bias(int charstring_type, int nsubrs)
555 {
556 if (charstring_type == 1)
557 return 0;
558 else if (nsubrs < 1240)
559 return 107;
560 else if (nsubrs < 33900)
561 return 1131;
562 else
563 return 32768;
564 }
565
566 Charstring *
gsubr(int i)567 Cff::gsubr(int i)
568 {
569 i += subr_bias(2, ngsubrs());
570 if (i < 0 || i >= ngsubrs())
571 return 0;
572 if (!_gsubrs_cs[i]) {
573 const uint8_t *s1 = _gsubrs_index[i];
574 int slen = _gsubrs_index[i + 1] - s1;
575 String cs = data_string().substring(s1 - data(), slen);
576 if (slen == 0)
577 return 0;
578 else
579 _gsubrs_cs[i] = new Type2Charstring(cs);
580 }
581 return _gsubrs_cs[i];
582 }
583
584
585 /*****
586 * Cff::Charset
587 **/
588
Charset(const Cff * cff,int pos,int nglyphs,int max_sid,ErrorHandler * errh)589 Cff::Charset::Charset(const Cff *cff, int pos, int nglyphs, int max_sid, ErrorHandler *errh)
590 {
591 assign(cff, pos, nglyphs, max_sid, errh);
592 }
593
594 void
assign(const Cff * cff,int pos,int nglyphs,int max_sid,ErrorHandler * errh)595 Cff::Charset::assign(const Cff *cff, int pos, int nglyphs, int max_sid, ErrorHandler *errh)
596 {
597 if (!errh)
598 errh = ErrorHandler::silent_handler();
599
600 _sids.reserve(nglyphs);
601
602 if (pos == 0)
603 assign(iso_adobe_charset, sizeof(iso_adobe_charset) / sizeof(int), nglyphs);
604 else if (pos == 1)
605 assign(expert_charset, sizeof(expert_charset) / sizeof(int), nglyphs);
606 else if (pos == 2)
607 assign(expert_subset_charset, sizeof(expert_subset_charset) / sizeof(int), nglyphs);
608 else
609 _error = parse(cff, pos, nglyphs, max_sid, errh);
610
611 if (_error >= 0)
612 for (int g = 0; g < _sids.size(); g++) {
613 if (_gids[_sids[g]] >= 0) {
614 errh->error("glyph %<%s%> in charset twice", cff->sid_permstring(_sids[g]).c_str());
615 _error = -EEXIST;
616 }
617 _gids[_sids[g]] = g;
618 }
619 }
620
621 void
assign(const int * data,int size,int nglyphs)622 Cff::Charset::assign(const int *data, int size, int nglyphs)
623 {
624 if (size < nglyphs)
625 size = nglyphs;
626 _sids.resize(size);
627 memcpy(&_sids[0], data, sizeof(const int) * size);
628 _gids.resize(data[size-1] + 1, -1);
629 _error = 0;
630 }
631
632 int
parse(const Cff * cff,int pos,int nglyphs,int max_sid,ErrorHandler * errh)633 Cff::Charset::parse(const Cff *cff, int pos, int nglyphs, int max_sid, ErrorHandler *errh)
634 {
635 const uint8_t *data = cff->data();
636 int len = cff->length();
637
638 if (pos + 1 > len)
639 return errh->error("charset position out of range"), -EFAULT;
640
641 _sids.push_back(0);
642 int actual_max_sid = 0;
643
644 int format = data[pos];
645 if (format == 0) {
646 if (pos + 1 + (nglyphs - 1) * 2 > len)
647 return errh->error("charset [format 0] out of range"), -EFAULT;
648 const uint8_t *p = data + pos + 1;
649 for (; _sids.size() < nglyphs; p += 2) {
650 int sid = (p[0] << 8) | p[1];
651 if (sid > actual_max_sid)
652 actual_max_sid = sid;
653 _sids.push_back(sid);
654 }
655
656 } else if (format == 1) {
657 const uint8_t *p = data + pos + 1;
658 for (; _sids.size() < nglyphs; p += 3) {
659 if (p + 3 > data + len)
660 return errh->error("charset [format 1] out of range"), -EFAULT;
661 int sid = (p[0] << 8) | p[1];
662 int n = p[2];
663 if (sid + n > actual_max_sid)
664 actual_max_sid = sid + n;
665 for (int i = 0; i <= n; i++)
666 _sids.push_back(sid + i);
667 }
668
669 } else if (format == 2) {
670 const uint8_t *p = data + pos + 1;
671 for (; _sids.size() < nglyphs; p += 4) {
672 if (p + 4 > data + len)
673 return errh->error("charset [format 2] out of range"), -EFAULT;
674 int sid = (p[0] << 8) | p[1];
675 int n = (p[2] << 8) | p[3];
676 if (sid + n > actual_max_sid)
677 actual_max_sid = sid + n;
678 for (int i = 0; i <= n; i++)
679 _sids.push_back(sid + i);
680 }
681
682 } else
683 return errh->error("unknown charset format %d", format), -EINVAL;
684
685 if (max_sid >= 0 && actual_max_sid > max_sid)
686 return errh->error("charset [format %d] uses bad SID %d", format, actual_max_sid), -EINVAL;
687 _sids.resize(nglyphs);
688 _gids.resize(actual_max_sid + 1, -1);
689 return 0;
690 }
691
692
693 /*****
694 * Cff::FDSelect
695 **/
696
697 void
assign(const Cff * cff,int pos,int nglyphs,ErrorHandler * errh)698 Cff::FDSelect::assign(const Cff *cff, int pos, int nglyphs, ErrorHandler *errh)
699 {
700 if (!errh)
701 errh = ErrorHandler::silent_handler();
702 if (_my_fds)
703 delete[] _fds;
704 _fds = 0;
705 _my_fds = false;
706 _nglyphs = nglyphs;
707 _error = parse(cff, pos, nglyphs, errh);
708 }
709
~FDSelect()710 Cff::FDSelect::~FDSelect()
711 {
712 if (_my_fds)
713 delete[] _fds;
714 }
715
716 int
parse(const Cff * cff,int pos,int nglyphs,ErrorHandler * errh)717 Cff::FDSelect::parse(const Cff *cff, int pos, int nglyphs, ErrorHandler *errh)
718 {
719 const uint8_t *data = cff->data();
720 int len = cff->length();
721
722 if (pos + 1 > len)
723 return errh->error("FDSelect position out of range"), -EFAULT;
724
725 int format = data[pos];
726 if (format == 0) {
727 if (pos + 1 + nglyphs > len)
728 return errh->error("FDSelect [format 0] out of range"), -EFAULT;
729 _fds = data + pos + 1;
730 _my_fds = false;
731 return 0;
732
733 } else if (format == 3) {
734 int nranges = (data[pos+1] << 8) | data[pos+2];
735 if (pos + 3 + 3*nranges + 2 > len)
736 return errh->error("FDSelect [format 3] out of range"), -EFAULT;
737
738 const uint8_t *p = data + pos + 3;
739 int last_glyph = (p[3*nranges] << 8) | p[3*nranges + 1];
740 if (p[0] || p[1] || last_glyph != nglyphs)
741 return errh->error("FDSelect [format 3] bad values"), -EINVAL;
742
743 _fds = new uint8_t[nglyphs];
744 _my_fds = true;
745 int curglyph = 0;
746 for (; curglyph < nglyphs; p += 3) {
747 int nextglyph = (p[3] << 8) | p[4];
748 if (nextglyph > nglyphs || nextglyph < curglyph)
749 return errh->error("FDSelect [format 3] sorting error"), -EINVAL;
750 memset(const_cast<uint8_t *>(_fds + curglyph), p[2], nextglyph - curglyph);
751 curglyph = nextglyph;
752 }
753 return 0;
754
755 } else
756 return errh->error("unknown charset format %d", format), -EINVAL;
757 }
758
759
760 /*****
761 * Cff::IndexIterator
762 **/
763
IndexIterator(const uint8_t * data,int pos,int len,ErrorHandler * errh,const char * index_name)764 Cff::IndexIterator::IndexIterator(const uint8_t *data, int pos, int len, ErrorHandler *errh, const char *index_name)
765 : _contents(0), _offset(0), _last_offset(0)
766 {
767 if (!errh)
768 errh = ErrorHandler::silent_handler();
769
770 // check header
771 int nitems = 0;
772 if (POS_GT(pos + 2, len)) {
773 errh->error("%s: position out of range", index_name);
774 _offsize = -EFAULT;
775 } else if (data[pos] == 0 && data[pos + 1] == 0) {
776 _contents = data + pos + 2;
777 _offsize = 0;
778 } else if (POS_GT(pos + 3, len)) {
779 errh->error("%s: position out of range", index_name);
780 _offsize = -EFAULT;
781 } else if ((_offsize = data[pos + 2]), (_offsize < 1 || _offsize > 4)) {
782 errh->error("%s: offset size %d out of range", index_name, _offsize);
783 _offsize = -EINVAL;
784 } else {
785 nitems = (data[pos] << 8) | data[pos + 1];
786 if (POS_GT(pos + 3 + (nitems + 1) * _offsize, len)) {
787 errh->error("%s: data out of range", index_name);
788 _offsize = -EFAULT;
789 } else {
790 _offset = data + pos + 3;
791 _last_offset = _offset + nitems * _offsize;
792 _contents = _last_offset + _offsize - 1;
793 }
794 }
795
796 // check items in offset array
797 uint32_t max_doff_allowed = len - (pos + 2 + (nitems + 1) * _offsize);
798 uint32_t last_doff = 1;
799 for (const uint8_t *o = _offset; o <= _last_offset && _offsize > 0; o += _offsize) {
800 uint32_t doff = offset_at(o);
801 if (doff > max_doff_allowed) {
802 errh->error("%s: element out of range", index_name);
803 _offsize = -EFAULT;
804 } else if (doff < last_doff) {
805 errh->error("%s: garbled elements", index_name);
806 break;
807 }
808 last_doff = doff;
809 }
810 }
811
812 const uint8_t *
index_end() const813 Cff::IndexIterator::index_end() const
814 {
815 if (_offsize <= 0)
816 return _contents;
817 else
818 return _contents + offset_at(_last_offset);
819 }
820
821 int
nitems() const822 Cff::IndexIterator::nitems() const
823 {
824 if (_offsize <= 0)
825 return 0;
826 else
827 return (_last_offset - _offset) / _offsize;
828 }
829
830
831
832 /*****
833 * Cff::Dict
834 **/
835
Dict()836 Cff::Dict::Dict()
837 : _cff(0), _pos(0), _error(-ENOENT)
838 {
839 }
840
Dict(Cff * cff,int pos,int dict_len,ErrorHandler * errh,const char * dict_name)841 Cff::Dict::Dict(Cff *cff, int pos, int dict_len, ErrorHandler *errh, const char *dict_name)
842 {
843 assign(cff, pos, dict_len, errh, dict_name);
844 }
845
846 int
assign(Cff * cff,int pos,int dict_len,ErrorHandler * errh,const char * dict_name)847 Cff::Dict::assign(Cff *cff, int pos, int dict_len, ErrorHandler *errh, const char *dict_name)
848 {
849 _cff = cff;
850 _pos = pos;
851 _operators.clear();
852 _pointers.clear();
853 _operands.clear();
854
855 if (!errh)
856 errh = ErrorHandler::silent_handler();
857
858 const uint8_t *data = cff->data() + pos;
859 const uint8_t *end_data = data + dict_len;
860
861 _pointers.push_back(0);
862 while (data < end_data)
863 switch (data[0]) {
864
865 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
866 case 8: case 9: case 10: case 11: case 13: case 14: case 15:
867 case 16: case 17: case 18: case 19: case 20: case 21:
868 _operators.push_back(data[0]);
869 _pointers.push_back(_operands.size());
870 data++;
871 break;
872
873 case 22: case 23: case 24: case 25: case 26: case 27: case 31:
874 case 255: // reserved
875 errh->error("%s: reserved operator %d", dict_name, data[0]);
876 return (_error = -ERANGE);
877
878 case 12:
879 if (data + 1 >= end_data)
880 goto runoff;
881 _operators.push_back(32 + data[1]);
882 _pointers.push_back(_operands.size());
883 data += 2;
884 break;
885
886 case 28: {
887 if (data + 2 >= end_data)
888 goto runoff;
889 int16_t val = (data[1] << 8) | data[2];
890 _operands.push_back(val);
891 data += 3;
892 break;
893 }
894
895 case 29: {
896 if (data + 4 >= end_data)
897 goto runoff;
898 int32_t val = (data[1] << 24) | (data[2] << 16) | (data[3] << 8) | data[4];
899 _operands.push_back(val);
900 data += 5;
901 break;
902 }
903
904 case 30: {
905 char buf[1024];
906 int pos = 0;
907 if (data + 1 >= end_data)
908 goto runoff;
909 for (data++; data < end_data && pos < 1020; data++) {
910 int d = *data;
911 for (int i = 0; i < 2; i++, d <<= 4) {
912 int digit = (d >> 4) & 0xF;
913 switch (digit) {
914 case 10:
915 buf[pos++] = '.';
916 break;
917 case 11:
918 buf[pos++] = 'E';
919 break;
920 case 12:
921 buf[pos++] = 'E';
922 buf[pos++] = '-';
923 break;
924 case 13:
925 errh->error("%s: bad digit in real number", dict_name);
926 goto invalid;
927 case 14:
928 buf[pos++] = '-';
929 break;
930 case 15:
931 goto found;
932 default:
933 buf[pos++] = digit + '0';
934 break;
935 }
936 }
937 }
938 // number not found
939 goto runoff;
940 found:
941 char *endptr;
942 buf[pos] = '\0';
943 _operands.push_back(strtod(buf, &endptr));
944 if (*endptr) {
945 errh->error("%s: real number syntax error", dict_name);
946 goto invalid;
947 }
948 data++;
949 break;
950 }
951
952 case 247: case 248: case 249: case 250: {
953 if (data + 1 >= end_data)
954 goto runoff;
955 int val = ((data[0] - 247) << 8) + data[1] + 108;
956 _operands.push_back(val);
957 data += 2;
958 break;
959 }
960
961 case 251: case 252: case 253: case 254: {
962 if (data + 1 >= end_data)
963 goto runoff;
964 int val = -((data[0] - 251) << 8) - data[1] - 108;
965 _operands.push_back(val);
966 data += 2;
967 break;
968 }
969
970 default:
971 _operands.push_back(data[0] - 139);
972 data++;
973 break;
974
975 }
976
977 // not closed by an operator?
978 if (_pointers.back() != _operands.size()) {
979 errh->error("%s: not closed by an operator", dict_name);
980 goto invalid;
981 }
982
983 return (_error = 0);
984
985 runoff:
986 errh->error("%s: runoff end of DICT", dict_name);
987 return (_error = -EFAULT);
988
989 invalid:
990 return (_error = -EINVAL);
991 }
992
993 int
check(bool is_private,ErrorHandler * errh,const char * dict_name) const994 Cff::Dict::check(bool is_private, ErrorHandler *errh, const char *dict_name) const
995 {
996 if (!errh)
997 errh = ErrorHandler::silent_handler();
998 int before_nerrors = errh->nerrors();
999
1000 // keep track of operator reuse
1001 Vector<int> operators_used;
1002
1003 for (int i = 0; i < _operators.size(); i++) {
1004 int arity = _pointers[i+1] - _pointers[i];
1005 double num = (arity == 0 ? 0 : _operands[_pointers[i]]);
1006 double truncnum = floor(num);
1007 int op = _operators[i];
1008 int type = (op > oLastOperator ? tNone : operator_types[op]);
1009
1010 // check reuse
1011 if (op >= operators_used.size())
1012 operators_used.resize(op + 1, 0);
1013 if (operators_used[op] && (type & tTypeMask) != tNone)
1014 errh->error("%s: operator %<%s%> specified twice", dict_name, operator_names[op]);
1015 operators_used[op]++;
1016
1017 // check data
1018 switch (type & tTypeMask) {
1019
1020 case tNone:
1021 if (op >= 32)
1022 errh->warning("%s: unknown operator %<12 %d%>", dict_name, op - 32);
1023 else
1024 errh->warning("%s: unknown operator %<%d%>", dict_name, op);
1025 continue;
1026
1027 case tSID:
1028 if (arity != 1 || num != truncnum || num < 0 || num > _cff->max_sid())
1029 goto bad_data;
1030 break;
1031
1032 case tFontNumber:
1033 if (arity != 1 || num != truncnum || num < 0 || num >= _cff->nfonts())
1034 goto bad_data;
1035 break;
1036
1037 case tBoolean:
1038 if (arity != 1)
1039 goto bad_data;
1040 else if (num != 0 && num != 1)
1041 errh->warning("%s: data for Boolean operator %<%s%> not 0 or 1", dict_name, operator_names[op]);
1042 break;
1043
1044 case tNumber:
1045 if (arity != 1)
1046 goto bad_data;
1047 break;
1048
1049 case tOffset:
1050 if (arity != 1 || num != truncnum || num < 0 || num >= _cff->length())
1051 goto bad_data;
1052 break;
1053
1054 case tLocalOffset:
1055 if (arity != 1 || num != truncnum || _pos + num < 0 || _pos + num >= _cff->length())
1056 goto bad_data;
1057 break;
1058
1059 case tPrivateType: {
1060 if (arity != 2 || num != truncnum || num < 0)
1061 goto bad_data;
1062 double off = _operands[_pointers[i] + 1];
1063 if (off < 0 || off + num > _cff->length())
1064 goto bad_data;
1065 break;
1066 }
1067
1068 case tArray2: case tArray3: case tArray4:
1069 case tArray5: case tArray6:
1070 if (arity != (type & tTypeMask) - tArray2 + 2)
1071 goto bad_data;
1072 break;
1073
1074 case tArray:
1075 break;
1076
1077 }
1078
1079 // check dict location
1080 if (((type & tPrivate) != 0) != is_private)
1081 errh->warning("%s: operator %<%s%> in wrong DICT", dict_name, operator_names[op]);
1082
1083 continue;
1084
1085 bad_data:
1086 errh->error("%s: bad data for operator %<%s%>", dict_name, operator_names[op]);
1087 }
1088
1089 return (errh->nerrors() != before_nerrors ? -1 : 0);
1090 }
1091
1092 bool
has(DictOperator op) const1093 Cff::Dict::has(DictOperator op) const
1094 {
1095 for (int i = 0; i < _operators.size(); i++)
1096 if (_operators[i] == op)
1097 return true;
1098 return false;
1099 }
1100
1101 bool
xvalue(DictOperator op,Vector<double> & out) const1102 Cff::Dict::xvalue(DictOperator op, Vector<double> &out) const
1103 {
1104 out.clear();
1105 for (int i = 0; i < _operators.size(); i++)
1106 if (_operators[i] == op) {
1107 for (int j = _pointers[i]; j < _pointers[i+1]; j++)
1108 out.push_back(_operands[j]);
1109 return true;
1110 }
1111 return false;
1112 }
1113
1114 bool
xvalue(DictOperator op,int * val) const1115 Cff::Dict::xvalue(DictOperator op, int *val) const
1116 {
1117 for (int i = 0; i < _operators.size(); i++)
1118 if (_operators[i] == op && _pointers[i] + 1 == _pointers[i+1]) {
1119 *val = (int) _operands[_pointers[i]];
1120 return true;
1121 }
1122 return false;
1123 }
1124
1125 bool
xvalue(DictOperator op,double * val) const1126 Cff::Dict::xvalue(DictOperator op, double *val) const
1127 {
1128 for (int i = 0; i < _operators.size(); i++)
1129 if (_operators[i] == op && _pointers[i] + 1 == _pointers[i+1]) {
1130 *val = _operands[_pointers[i]];
1131 return true;
1132 }
1133 return false;
1134 }
1135
1136 bool
value(DictOperator op,Vector<double> & out) const1137 Cff::Dict::value(DictOperator op, Vector<double> &out) const
1138 {
1139 return xvalue(op, out) || default_dict().xvalue(op, out);
1140 }
1141
1142 bool
value(DictOperator op,int * val) const1143 Cff::Dict::value(DictOperator op, int *val) const
1144 {
1145 return xvalue(op, val) || default_dict().xvalue(op, val);
1146 }
1147
1148 bool
value(DictOperator op,double * val) const1149 Cff::Dict::value(DictOperator op, double *val) const
1150 {
1151 return xvalue(op, val) || default_dict().xvalue(op, val);
1152 }
1153
1154 void
unparse(ErrorHandler * errh,const char * dict_name) const1155 Cff::Dict::unparse(ErrorHandler *errh, const char *dict_name) const
1156 {
1157 StringAccum sa;
1158 for (int i = 0; i < _operators.size(); i++) {
1159 sa.clear();
1160 if (_pointers[i] + 1 == _pointers[i+1])
1161 sa << _operands[_pointers[i]];
1162 else {
1163 sa << "[";
1164 for (int j = _pointers[i]; j < _pointers[i+1]; j++)
1165 sa << _operands[j] << ' ';
1166 sa.pop_back();
1167 sa << "]";
1168 }
1169 errh->message("%s: %s %s", dict_name, operator_names[_operators[i]], sa.c_str());
1170 }
1171 }
1172
1173
1174 /*****
1175 * CffFontParent
1176 **/
1177
1178 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)1179 handle_private(Cff *cff, const Cff::Dict &top_dict, Cff::Dict &private_dict,
1180 double &default_width_x, double &nominal_width_x,
1181 Cff::IndexIterator &subrs_index, Vector<Charstring *> &subrs_cs,
1182 ErrorHandler *errh)
1183 {
1184 Vector<double> private_info;
1185 top_dict.value(Cff::oPrivate, private_info);
1186 int private_offset = (int) private_info[1];
1187 private_dict.assign(cff, private_offset, (int) private_info[0], errh, "Private DICT");
1188 if (private_dict.error() < 0)
1189 return private_dict.error();
1190 else if (private_dict.check(true, errh, "Private DICT") < 0)
1191 return -EINVAL;
1192 //private_dict.unparse(errh, "Private DICT");
1193
1194 private_dict.value(Cff::oDefaultWidthX, &default_width_x);
1195 private_dict.value(Cff::oNominalWidthX, &nominal_width_x);
1196 if (private_dict.has(Cff::oSubrs)) {
1197 int subrs_offset = 0;
1198 private_dict.value(Cff::oSubrs, &subrs_offset);
1199 subrs_index = Cff::IndexIterator(cff->data(), private_offset + subrs_offset, cff->length(), errh, "Subrs INDEX");
1200 if (subrs_index.error() < 0)
1201 return subrs_index.error();
1202 }
1203 subrs_cs.assign(subrs_index.nitems(), 0);
1204 return 0;
1205 }
1206
1207
FontParent(Cff * cff)1208 Cff::FontParent::FontParent(Cff* cff)
1209 : CharstringProgram(cff->units_per_em()), _cff(cff), _error(-1)
1210 {
1211 }
1212
1213 Charstring *
charstring(const IndexIterator & iiter,int which) const1214 Cff::FontParent::charstring(const IndexIterator &iiter, int which) const
1215 {
1216 const uint8_t *s1 = iiter[which];
1217 int slen = iiter[which + 1] - s1;
1218 String cs = _cff->data_string().substring(s1 - _cff->data(), slen);
1219 if (slen == 0)
1220 return 0;
1221 else if (_charstring_type == 1)
1222 return new Type1Charstring(cs);
1223 else
1224 return new Type2Charstring(cs);
1225 }
1226
1227 Charstring *
gsubr(int i) const1228 Cff::FontParent::gsubr(int i) const
1229 {
1230 return _cff->gsubr(i);
1231 }
1232
1233 int
gsubr_bias() const1234 Cff::FontParent::gsubr_bias() const
1235 {
1236 return Efont::subr_bias(2, ngsubrs_x());
1237 }
1238
1239
1240 /*****
1241 * CffFont
1242 **/
1243
Font(Cff * cff,PermString font_name,const Dict & top_dict,ErrorHandler * errh)1244 Cff::Font::Font(Cff *cff, PermString font_name, const Dict &top_dict, ErrorHandler *errh)
1245 : ChildFont(cff, 0, 2, top_dict, errh), _font_name(font_name),
1246 _t1encoding(0)
1247 {
1248 assert(!_top_dict.has_first(oROS));
1249 if (_error < 0)
1250 return;
1251
1252 // extract CharStrings
1253 // must use xvalue because we could be creating the default dict!
1254 int charstrings_offset = 0;
1255 _top_dict.xvalue(oCharStrings, &charstrings_offset);
1256 _charstrings_index = Cff::IndexIterator(cff->data(), charstrings_offset, cff->length(), errh, "CharStrings INDEX");
1257 if (_charstrings_index.error() < 0) {
1258 _error = _charstrings_index.error();
1259 return;
1260 }
1261 _charstrings_cs.assign(_charstrings_index.nitems(), 0);
1262
1263 int charset = 0;
1264 _top_dict.xvalue(oCharset, &charset);
1265 _charset.assign(cff, charset, _charstrings_index.nitems(), cff->max_sid(), errh);
1266 if (_charset.error() < 0) {
1267 _error = _charset.error();
1268 return;
1269 }
1270
1271 int Encoding = 0;
1272 _top_dict.xvalue(oEncoding, &Encoding);
1273 if (parse_encoding(Encoding, errh) < 0)
1274 return;
1275
1276 // success!
1277 _error = 0;
1278 }
1279
~Font()1280 Cff::Font::~Font()
1281 {
1282 for (int i = 0; i < _charstrings_cs.size(); i++)
1283 delete _charstrings_cs[i];
1284 delete _t1encoding;
1285 }
1286
1287 int
parse_encoding(int pos,ErrorHandler * errh)1288 Cff::Font::parse_encoding(int pos, ErrorHandler *errh)
1289 {
1290 _encoding_pos = pos;
1291 for (int i = 0; i < 256; i++)
1292 _encoding[i] = 0;
1293
1294 // check for standard encodings
1295 if (pos == 0)
1296 return assign_standard_encoding(standard_encoding);
1297 else if (pos == 1)
1298 return assign_standard_encoding(expert_encoding);
1299
1300 // otherwise, a custom encoding
1301 const uint8_t *data = _cff->data();
1302 int len = _cff->length();
1303 if (pos + 1 > len)
1304 return errh->error("Encoding position out of range"), -EFAULT;
1305 bool supplemented = (data[pos] & 0x80) != 0;
1306 int format = (data[pos] & 0x7F);
1307
1308 int retval = 0;
1309 int endpos, g = 1;
1310 if (format == 0) {
1311 endpos = pos + 2 + data[pos + 1];
1312 if (endpos > len)
1313 return errh->error("Encoding[0] out of range"), -EFAULT;
1314 const uint8_t *p = data + pos + 2;
1315 int n = data[pos + 1];
1316 for (; g <= n; g++, p++) {
1317 int e = p[0];
1318 if (_encoding[e])
1319 retval = 1;
1320 _encoding[e] = g;
1321 }
1322
1323 } else if (format == 1) {
1324 endpos = pos + 2 + data[pos + 1] * 2;
1325 if (endpos > len)
1326 return errh->error("Encoding[1] out of range"), -EFAULT;
1327 const uint8_t *p = data + pos + 2;
1328 int n = data[pos + 1];
1329 for (int i = 0; i < n; i++, p += 2) {
1330 int first = p[0];
1331 int nLeft = p[1];
1332 for (int e = first; e <= first + nLeft; e++) {
1333 if (_encoding[e])
1334 retval = 1;
1335 _encoding[e] = g++;
1336 }
1337 }
1338
1339 } else
1340 return errh->error("unknown Encoding format %d", format), -EINVAL;
1341
1342 if (g > _charset.nglyphs())
1343 return errh->error("Encoding glyph %d out of range", g), -EINVAL;
1344
1345 // check supplements
1346 if (supplemented) {
1347 if (endpos + data[endpos] * 3 > len)
1348 return -EINVAL;
1349 const uint8_t *p = data + endpos + 1;
1350 int n = data[endpos];
1351 for (int i = 0; i < n; i++, p += 3) {
1352 int e = p[0];
1353 int s = (p[1] << 8) | p[2];
1354 int g = _charset.sid_to_gid(s);
1355 if (_encoding[e])
1356 retval = 1;
1357 if (g < 0 || g >= _charset.nglyphs())
1358 return errh->error("Encoding glyph %d out of range", g), -EINVAL;
1359 _encoding[e] = g;
1360 }
1361 }
1362
1363 // successfully done
1364 return retval;
1365 }
1366
1367 int
assign_standard_encoding(const int * standard_encoding)1368 Cff::Font::assign_standard_encoding(const int *standard_encoding)
1369 {
1370 for (int i = 0; i < 256; i++)
1371 _encoding[i] = _charset.sid_to_gid(standard_encoding[i]);
1372 return 0;
1373 }
1374
1375 void
font_matrix(double matrix[6]) const1376 Cff::Font::font_matrix(double matrix[6]) const
1377 {
1378 Vector<double> t1d_matrix;
1379 if (dict_value(oFontMatrix, t1d_matrix) && t1d_matrix.size() == 6)
1380 memcpy(&matrix[0], &t1d_matrix[0], sizeof(double) * 6);
1381 else {
1382 matrix[0] = matrix[3] = 0.001;
1383 matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0;
1384 }
1385 }
1386
1387 PermString
glyph_name(int gid) const1388 Cff::Font::glyph_name(int gid) const
1389 {
1390 if (gid >= 0 && gid < nglyphs())
1391 return _cff->sid_permstring(_charset.gid_to_sid(gid));
1392 else
1393 return PermString();
1394 }
1395
1396 void
glyph_names(Vector<PermString> & gnames) const1397 Cff::Font::glyph_names(Vector<PermString> &gnames) const
1398 {
1399 gnames.resize(nglyphs());
1400 for (int i = 0; i < nglyphs(); i++)
1401 gnames[i] = _cff->sid_permstring(_charset.gid_to_sid(i));
1402 }
1403
1404 Charstring *
glyph(int gid) const1405 Cff::Font::glyph(int gid) const
1406 {
1407 if (gid < 0 || gid >= nglyphs())
1408 return 0;
1409 if (!_charstrings_cs[gid])
1410 _charstrings_cs[gid] = charstring(_charstrings_index, gid);
1411 return _charstrings_cs[gid];
1412 }
1413
1414 Charstring *
glyph(PermString name) const1415 Cff::Font::glyph(PermString name) const
1416 {
1417 int gid = _charset.sid_to_gid(_cff->sid(name));
1418 if (gid < 0)
1419 return 0;
1420 if (!_charstrings_cs[gid])
1421 _charstrings_cs[gid] = charstring(_charstrings_index, gid);
1422 return _charstrings_cs[gid];
1423 }
1424
1425 int
glyphid(PermString name) const1426 Cff::Font::glyphid(PermString name) const
1427 {
1428 return _charset.sid_to_gid(_cff->sid(name));
1429 }
1430
1431 Type1Encoding *
type1_encoding() const1432 Cff::Font::type1_encoding() const
1433 {
1434 if (_encoding_pos == 0)
1435 return Type1Encoding::standard_encoding();
1436 if (!_t1encoding)
1437 _t1encoding = type1_encoding_copy();
1438 return _t1encoding;
1439 }
1440
1441 Type1Encoding *
type1_encoding_copy() const1442 Cff::Font::type1_encoding_copy() const
1443 {
1444 if (_encoding_pos == 0)
1445 return Type1Encoding::standard_encoding();
1446 Type1Encoding *e = new Type1Encoding;
1447 for (int i = 0; i < 256; i++)
1448 if (_encoding[i])
1449 e->put(i, _cff->sid_permstring(_charset.gid_to_sid(_encoding[i])));
1450 return e;
1451 }
1452
1453 bool
dict_has(DictOperator op) const1454 Cff::Font::dict_has(DictOperator op) const
1455 {
1456 return dict_of(op).has(op);
1457 }
1458
1459 String
dict_string(DictOperator op) const1460 Cff::Font::dict_string(DictOperator op) const
1461 {
1462 Vector<double> vec;
1463 dict_of(op).value(op, vec);
1464 if (vec.size() == 1 && vec[0] >= 0 && vec[0] <= _cff->max_sid())
1465 return _cff->sid_string((int) vec[0]);
1466 else
1467 return String();
1468 }
1469
1470
1471 /*****
1472 * Cff::CIDFont
1473 **/
1474
CIDFont(Cff * cff,PermString font_name,const Dict & top_dict,ErrorHandler * errh)1475 Cff::CIDFont::CIDFont(Cff *cff, PermString font_name, const Dict &top_dict, ErrorHandler *errh)
1476 : FontParent(cff), _font_name(font_name), _top_dict(top_dict)
1477 {
1478 assert(_top_dict.has_first(oROS));
1479
1480 // parse top DICT
1481 _error = -EINVAL;
1482 if (_top_dict.check(false, errh, "Top DICT") < 0)
1483 return;
1484 else if (!_top_dict.has(oCharStrings)) {
1485 errh->error("font has no CharStrings dictionary");
1486 return;
1487 }
1488 //_top_dict.unparse(errh, "Top DICT");
1489
1490 // extract offsets and information from TOP DICT
1491 _top_dict.value(oCharstringType, &_charstring_type);
1492 if (_charstring_type != 1 && _charstring_type != 2) {
1493 errh->error("unknown CharString type %d", _charstring_type);
1494 return;
1495 }
1496
1497 int charstrings_offset = 0;
1498 _top_dict.value(oCharStrings, &charstrings_offset);
1499 _charstrings_index = Cff::IndexIterator(cff->data(), charstrings_offset, cff->length(), errh, "CharStrings INDEX");
1500 if (_charstrings_index.error() < 0) {
1501 _error = _charstrings_index.error();
1502 return;
1503 }
1504 _charstrings_cs.assign(_charstrings_index.nitems(), 0);
1505
1506 int charset = 0;
1507 _top_dict.value(oCharset, &charset);
1508 _charset.assign(cff, charset, _charstrings_index.nitems(), -1, errh);
1509 if (_charset.error() < 0) {
1510 _error = _charset.error();
1511 return;
1512 }
1513
1514 // extract information about child fonts
1515 int fdarray_offset = 0;
1516 if (!_top_dict.value(oFDArray, &fdarray_offset)) {
1517 errh->error("CID-keyed font missing FDArray");
1518 return;
1519 }
1520 IndexIterator fdarray_index(cff->data(), fdarray_offset, cff->length(), errh, "FDArray INDEX");
1521 for (; fdarray_index; fdarray_index++) {
1522 Dict d(cff, fdarray_index[0] - cff->data(), fdarray_index[1] - fdarray_index[0], errh, "Top DICT");
1523 if (!d.ok() || d.check(false, errh, "Top DICT") < 0) {
1524 _error = d.error();
1525 return;
1526 }
1527 _child_fonts.push_back(new ChildFont(cff, this, _charstring_type, d, errh));
1528 if (!_child_fonts.back()->ok())
1529 return;
1530 }
1531
1532 int fdselect_offset = 0;
1533 if (!_top_dict.value(oFDSelect, &fdselect_offset)) {
1534 errh->error("CID-keyed font missing FDSelect");
1535 return;
1536 }
1537 _fdselect.assign(cff, fdselect_offset, _charstrings_cs.size(), errh);
1538 if (_fdselect.error() < 0)
1539 return;
1540
1541 // success!
1542 _error = 0;
1543 set_parent_program(true);
1544 }
1545
~CIDFont()1546 Cff::CIDFont::~CIDFont()
1547 {
1548 for (int i = 0; i < _charstrings_cs.size(); i++)
1549 delete _charstrings_cs[i];
1550 for (int i = 0; i < _child_fonts.size(); i++)
1551 delete _child_fonts[i];
1552 }
1553
1554 void
font_matrix(double matrix[6]) const1555 Cff::CIDFont::font_matrix(double matrix[6]) const
1556 {
1557 // XXX
1558 matrix[0] = matrix[3] = 0.001;
1559 matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0;
1560 }
1561
1562 const CharstringProgram *
child_program(int gid) const1563 Cff::CIDFont::child_program(int gid) const
1564 {
1565 int fd = _fdselect.gid_to_fd(gid);
1566 if (fd >= 0 && fd < _child_fonts.size())
1567 return _child_fonts.at_u(fd);
1568 else
1569 return 0;
1570 }
1571
1572 PermString
glyph_name(int gid) const1573 Cff::CIDFont::glyph_name(int gid) const
1574 {
1575 if (gid >= 0 && gid < nglyphs())
1576 return permprintf("#%d", _charset.gid_to_sid(gid));
1577 else
1578 return PermString();
1579 }
1580
1581 void
glyph_names(Vector<PermString> & gnames) const1582 Cff::CIDFont::glyph_names(Vector<PermString> &gnames) const
1583 {
1584 gnames.resize(nglyphs());
1585 for (int i = 0; i < nglyphs(); i++)
1586 gnames[i] = permprintf("#%d", _charset.gid_to_sid(i));
1587 }
1588
1589 Charstring *
glyph(int gid) const1590 Cff::CIDFont::glyph(int gid) const
1591 {
1592 if (gid < 0 || gid >= nglyphs())
1593 return 0;
1594 if (!_charstrings_cs[gid])
1595 _charstrings_cs[gid] = charstring(_charstrings_index, gid);
1596 return _charstrings_cs[gid];
1597 }
1598
1599 int
glyphid(PermString name) const1600 Cff::CIDFont::glyphid(PermString name) const
1601 {
1602 if (name.length() <= 1 || name[0] != '#' || !isdigit((unsigned char) name[1]))
1603 return -1;
1604 char *endptr;
1605 long cid = strtol(name.c_str() + 1, &endptr, 10);
1606 if (*endptr != 0)
1607 return -1;
1608 return _charset.sid_to_gid(cid);
1609 }
1610
1611 Charstring *
glyph(PermString name) const1612 Cff::CIDFont::glyph(PermString name) const
1613 {
1614 return CIDFont::glyph(CIDFont::glyphid(name));
1615 }
1616
1617
1618 /*****
1619 * ChildFont
1620 **/
1621
ChildFont(Cff * cff,Cff::CIDFont * parent,int charstring_type,const Dict & top_dict,ErrorHandler * errh)1622 Cff::ChildFont::ChildFont(Cff *cff, Cff::CIDFont *parent, int charstring_type, const Dict &top_dict, ErrorHandler *errh)
1623 : FontParent(cff), _parent(parent), _top_dict(top_dict)
1624 {
1625 if (!errh)
1626 errh = ErrorHandler::silent_handler();
1627
1628 if (!cff->ok() || !_top_dict.ok()) {
1629 errh->error("invalid CFF");
1630 _error = -EINVAL;
1631 return;
1632 }
1633
1634 // extract offsets and information from TOP DICT
1635 _charstring_type = charstring_type;
1636 _top_dict.value(oCharstringType, &_charstring_type);
1637 if (_charstring_type != 1 && _charstring_type != 2) {
1638 errh->error("unknown CharString type %d", _charstring_type);
1639 return;
1640 }
1641
1642 // extract information from Private DICT
1643 if (_top_dict.has(oPrivate)
1644 && (_error = handle_private(cff, _top_dict, _private_dict, _default_width_x, _nominal_width_x, _subrs_index, _subrs_cs, errh)) < 0)
1645 return;
1646
1647 // success!
1648 _error = 0;
1649 }
1650
~ChildFont()1651 Cff::ChildFont::~ChildFont()
1652 {
1653 for (int i = 0; i < _subrs_cs.size(); i++)
1654 delete _subrs_cs[i];
1655 }
1656
1657 Charstring *
charstring(const IndexIterator & iiter,int which) const1658 Cff::ChildFont::charstring(const IndexIterator &iiter, int which) const
1659 {
1660 const uint8_t *s1 = iiter[which];
1661 int slen = iiter[which + 1] - s1;
1662 String cs = _cff->data_string().substring(s1 - _cff->data(), slen);
1663 if (slen == 0)
1664 return 0;
1665 else if (_charstring_type == 1)
1666 return new Type1Charstring(cs);
1667 else
1668 return new Type2Charstring(cs);
1669 }
1670
1671 Charstring *
subr(int i) const1672 Cff::ChildFont::subr(int i) const
1673 {
1674 i += Efont::subr_bias(_charstring_type, nsubrs_x());
1675 if (i < 0 || i >= nsubrs_x())
1676 return 0;
1677 if (!_subrs_cs[i])
1678 _subrs_cs[i] = charstring(_subrs_index, i);
1679 return _subrs_cs[i];
1680 }
1681
1682 int
subr_bias() const1683 Cff::ChildFont::subr_bias() const
1684 {
1685 return Efont::subr_bias(_charstring_type, nsubrs_x());
1686 }
1687
1688 double
global_width_x(bool is_nominal) const1689 Cff::ChildFont::global_width_x(bool is_nominal) const
1690 {
1691 return (is_nominal ? _nominal_width_x : _default_width_x);
1692 }
1693
1694 }
1695