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