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