Discussion:
[gs-code-review] Preliminary version of CFF parser
Alex Cherepanov
2009-02-03 16:01:52 UTC
Permalink
This is a preliminary version of CFF parser in C.
The code in mainly intended for reading -- it is not called
from anywhere nor tested on more than a few samples.

Currently, final results are stored in a PostScript dictionary.
This approach simplifies replacement of existing parsers coded
in PostScript but won't work for non-postscript products.
The change to other collection classes should not be difficult.

I plan to implement other parsers in the same style.
This is the time to suggest better data structures
or algorithms.

The code seems quite straightforward to me. Please contact me
if you want to clarify any details.

Regards,
Alex Cherepanov
-------------- next part --------------
Index: gs/psi/zfont2.c
===================================================================
--- gs/psi/zfont2.c (revision 9383)
+++ gs/psi/zfont2.c (working copy)
@@ -106,10 +106,2402 @@
&data1, bf_notdef_required);
}

+/********* CFF parser ***********/
+#include "iname.h"
+#include "iddict.h"
+#include "store.h"
+#include "string_.h"
+
+#define STR2MEM(s) s, (sizeof(s) - 1)
+#define MAXOP 48 /* Max value according to TN 5176 */
+
+static const char * const standard_strings[] = {
+ /* 0 */ ".notdef",
+ /* 1 */ "space",
+ /* 2 */ "exclam",
+ /* 3 */ "quotedbl",
+ /* 4 */ "numbersign",
+ /* 5 */ "dollar",
+ /* 6 */ "percent",
+ /* 7 */ "ampersand",
+ /* 8 */ "quoteright",
+ /* 9 */ "parenleft",
+ /* 10 */ "parenright",
+ /* 11 */ "asterisk",
+ /* 12 */ "plus",
+ /* 13 */ "comma",
+ /* 14 */ "hyphen",
+ /* 15 */ "period",
+ /* 16 */ "slash",
+ /* 17 */ "zero",
+ /* 18 */ "one",
+ /* 19 */ "two",
+ /* 20 */ "three",
+ /* 21 */ "four",
+ /* 22 */ "five",
+ /* 23 */ "six",
+ /* 24 */ "seven",
+ /* 25 */ "eight",
+ /* 26 */ "nine",
+ /* 27 */ "colon",
+ /* 28 */ "semicolon",
+ /* 29 */ "less",
+ /* 30 */ "equal",
+ /* 31 */ "greater",
+ /* 32 */ "question",
+ /* 33 */ "at",
+ /* 34 */ "A",
+ /* 35 */ "B",
+ /* 36 */ "C",
+ /* 37 */ "D",
+ /* 38 */ "E",
+ /* 39 */ "F",
+ /* 40 */ "G",
+ /* 41 */ "H",
+ /* 42 */ "I",
+ /* 43 */ "J",
+ /* 44 */ "K",
+ /* 45 */ "L",
+ /* 46 */ "M",
+ /* 47 */ "N",
+ /* 48 */ "O",
+ /* 49 */ "P",
+ /* 50 */ "Q",
+ /* 51 */ "R",
+ /* 52 */ "S",
+ /* 53 */ "T",
+ /* 54 */ "U",
+ /* 55 */ "V",
+ /* 56 */ "W",
+ /* 57 */ "X",
+ /* 58 */ "Y",
+ /* 59 */ "Z",
+ /* 60 */ "bracketleft",
+ /* 61 */ "backslash",
+ /* 62 */ "bracketright",
+ /* 63 */ "asciicircum",
+ /* 64 */ "underscore",
+ /* 65 */ "quoteleft",
+ /* 66 */ "a",
+ /* 67 */ "b",
+ /* 68 */ "c",
+ /* 69 */ "d",
+ /* 70 */ "e",
+ /* 71 */ "f",
+ /* 72 */ "g",
+ /* 73 */ "h",
+ /* 74 */ "i",
+ /* 75 */ "j",
+ /* 76 */ "k",
+ /* 77 */ "l",
+ /* 78 */ "m",
+ /* 79 */ "n",
+ /* 80 */ "o",
+ /* 81 */ "p",
+ /* 82 */ "q",
+ /* 83 */ "r",
+ /* 84 */ "s",
+ /* 85 */ "t",
+ /* 86 */ "u",
+ /* 87 */ "v",
+ /* 88 */ "w",
+ /* 89 */ "x",
+ /* 90 */ "y",
+ /* 91 */ "z",
+ /* 92 */ "braceleft",
+ /* 93 */ "bar",
+ /* 94 */ "braceright",
+ /* 95 */ "asciitilde",
+ /* 96 */ "exclamdown",
+ /* 97 */ "cent",
+ /* 98 */ "sterling",
+ /* 99 */ "fraction",
+ /* 100 */ "yen",
+ /* 101 */ "florin",
+ /* 102 */ "section",
+ /* 103 */ "currency",
+ /* 104 */ "quotesingle",
+ /* 105 */ "quotedblleft",
+ /* 106 */ "guillemotleft",
+ /* 107 */ "guilsinglleft",
+ /* 108 */ "guilsinglright",
+ /* 109 */ "fi",
+ /* 110 */ "fl",
+ /* 111 */ "endash",
+ /* 112 */ "dagger",
+ /* 113 */ "daggerdbl",
+ /* 114 */ "periodcentered",
+ /* 115 */ "paragraph",
+ /* 116 */ "bullet",
+ /* 117 */ "quotesinglbase",
+ /* 118 */ "quotedblbase",
+ /* 119 */ "quotedblright",
+ /* 120 */ "guillemotright",
+ /* 121 */ "ellipsis",
+ /* 122 */ "perthousand",
+ /* 123 */ "questiondown",
+ /* 124 */ "grave",
+ /* 125 */ "acute",
+ /* 126 */ "circumflex",
+ /* 127 */ "tilde",
+ /* 128 */ "macron",
+ /* 129 */ "breve",
+ /* 130 */ "dotaccent",
+ /* 131 */ "dieresis",
+ /* 132 */ "ring",
+ /* 133 */ "cedilla",
+ /* 134 */ "hungarumlaut",
+ /* 135 */ "ogonek",
+ /* 136 */ "caron",
+ /* 137 */ "emdash",
+ /* 138 */ "AE",
+ /* 139 */ "ordfeminine",
+ /* 140 */ "Lslash",
+ /* 141 */ "Oslash",
+ /* 142 */ "OE",
+ /* 143 */ "ordmasculine",
+ /* 144 */ "ae",
+ /* 145 */ "dotlessi",
+ /* 146 */ "lslash",
+ /* 147 */ "oslash",
+ /* 148 */ "oe",
+ /* 149 */ "germandbls",
+ /* 150 */ "onesuperior",
+ /* 151 */ "logicalnot",
+ /* 152 */ "mu",
+ /* 153 */ "trademark",
+ /* 154 */ "Eth",
+ /* 155 */ "onehalf",
+ /* 156 */ "plusminus",
+ /* 157 */ "Thorn",
+ /* 158 */ "onequarter",
+ /* 159 */ "divide",
+ /* 160 */ "brokenbar",
+ /* 161 */ "degree",
+ /* 162 */ "thorn",
+ /* 163 */ "threequarters",
+ /* 164 */ "twosuperior",
+ /* 165 */ "registered",
+ /* 166 */ "minus",
+ /* 167 */ "eth",
+ /* 168 */ "multiply",
+ /* 169 */ "threesuperior",
+ /* 170 */ "copyright",
+ /* 171 */ "Aacute",
+ /* 172 */ "Acircumflex",
+ /* 173 */ "Adieresis",
+ /* 174 */ "Agrave",
+ /* 175 */ "Aring",
+ /* 176 */ "Atilde",
+ /* 177 */ "Ccedilla",
+ /* 178 */ "Eacute",
+ /* 179 */ "Ecircumflex",
+ /* 180 */ "Edieresis",
+ /* 181 */ "Egrave",
+ /* 182 */ "Iacute",
+ /* 183 */ "Icircumflex",
+ /* 184 */ "Idieresis",
+ /* 185 */ "Igrave",
+ /* 186 */ "Ntilde",
+ /* 187 */ "Oacute",
+ /* 188 */ "Ocircumflex",
+ /* 189 */ "Odieresis",
+ /* 190 */ "Ograve",
+ /* 191 */ "Otilde",
+ /* 192 */ "Scaron",
+ /* 193 */ "Uacute",
+ /* 194 */ "Ucircumflex",
+ /* 195 */ "Udieresis",
+ /* 196 */ "Ugrave",
+ /* 197 */ "Yacute",
+ /* 198 */ "Ydieresis",
+ /* 199 */ "Zcaron",
+ /* 200 */ "aacute",
+ /* 201 */ "acircumflex",
+ /* 202 */ "adieresis",
+ /* 203 */ "agrave",
+ /* 204 */ "aring",
+ /* 205 */ "atilde",
+ /* 206 */ "ccedilla",
+ /* 207 */ "eacute",
+ /* 208 */ "ecircumflex",
+ /* 209 */ "edieresis",
+ /* 210 */ "egrave",
+ /* 211 */ "iacute",
+ /* 212 */ "icircumflex",
+ /* 213 */ "idieresis",
+ /* 214 */ "igrave",
+ /* 215 */ "ntilde",
+ /* 216 */ "oacute",
+ /* 217 */ "ocircumflex",
+ /* 218 */ "odieresis",
+ /* 219 */ "ograve",
+ /* 220 */ "otilde",
+ /* 221 */ "scaron",
+ /* 222 */ "uacute",
+ /* 223 */ "ucircumflex",
+ /* 224 */ "udieresis",
+ /* 225 */ "ugrave",
+ /* 226 */ "yacute",
+ /* 227 */ "ydieresis",
+ /* 228 */ "zcaron",
+ /* 229 */ "exclamsmall",
+ /* 230 */ "Hungarumlautsmall",
+ /* 231 */ "dollaroldstyle",
+ /* 232 */ "dollarsuperior",
+ /* 233 */ "ampersandsmall",
+ /* 234 */ "Acutesmall",
+ /* 235 */ "parenleftsuperior",
+ /* 236 */ "parenrightsuperior",
+ /* 237 */ "twodotenleader",
+ /* 238 */ "onedotenleader",
+ /* 239 */ "zerooldstyle",
+ /* 240 */ "oneoldstyle",
+ /* 241 */ "twooldstyle",
+ /* 242 */ "threeoldstyle",
+ /* 243 */ "fouroldstyle",
+ /* 244 */ "fiveoldstyle",
+ /* 245 */ "sixoldstyle",
+ /* 246 */ "sevenoldstyle",
+ /* 247 */ "eightoldstyle",
+ /* 248 */ "nineoldstyle",
+ /* 249 */ "commasuperior",
+ /* 250 */ "threequartersemdash",
+ /* 251 */ "periodsuperior",
+ /* 252 */ "questionsmall",
+ /* 253 */ "asuperior",
+ /* 254 */ "bsuperior",
+ /* 255 */ "centsuperior",
+ /* 256 */ "dsuperior",
+ /* 257 */ "esuperior",
+ /* 258 */ "isuperior",
+ /* 259 */ "lsuperior",
+ /* 260 */ "msuperior",
+ /* 261 */ "nsuperior",
+ /* 262 */ "osuperior",
+ /* 263 */ "rsuperior",
+ /* 264 */ "ssuperior",
+ /* 265 */ "tsuperior",
+ /* 266 */ "ff",
+ /* 267 */ "ffi",
+ /* 268 */ "ffl",
+ /* 269 */ "parenleftinferior",
+ /* 270 */ "parenrightinferior",
+ /* 271 */ "Circumflexsmall",
+ /* 272 */ "hyphensuperior",
+ /* 273 */ "Gravesmall",
+ /* 274 */ "Asmall",
+ /* 275 */ "Bsmall",
+ /* 276 */ "Csmall",
+ /* 277 */ "Dsmall",
+ /* 278 */ "Esmall",
+ /* 279 */ "Fsmall",
+ /* 280 */ "Gsmall",
+ /* 281 */ "Hsmall",
+ /* 282 */ "Ismall",
+ /* 283 */ "Jsmall",
+ /* 284 */ "Ksmall",
+ /* 285 */ "Lsmall",
+ /* 286 */ "Msmall",
+ /* 287 */ "Nsmall",
+ /* 288 */ "Osmall",
+ /* 289 */ "Psmall",
+ /* 290 */ "Qsmall",
+ /* 291 */ "Rsmall",
+ /* 292 */ "Ssmall",
+ /* 293 */ "Tsmall",
+ /* 294 */ "Usmall",
+ /* 295 */ "Vsmall",
+ /* 296 */ "Wsmall",
+ /* 297 */ "Xsmall",
+ /* 298 */ "Ysmall",
+ /* 299 */ "Zsmall",
+ /* 300 */ "colonmonetary",
+ /* 301 */ "onefitted",
+ /* 302 */ "rupiah",
+ /* 303 */ "Tildesmall",
+ /* 304 */ "exclamdownsmall",
+ /* 305 */ "centoldstyle",
+ /* 306 */ "Lslashsmall",
+ /* 307 */ "Scaronsmall",
+ /* 308 */ "Zcaronsmall",
+ /* 309 */ "Dieresissmall",
+ /* 310 */ "Brevesmall",
+ /* 311 */ "Caronsmall",
+ /* 312 */ "Dotaccentsmall",
+ /* 313 */ "Macronsmall",
+ /* 314 */ "figuredash",
+ /* 315 */ "hypheninferior",
+ /* 316 */ "Ogoneksmall",
+ /* 317 */ "Ringsmall",
+ /* 318 */ "Cedillasmall",
+ /* 319 */ "questiondownsmall",
+ /* 320 */ "oneeighth",
+ /* 321 */ "threeeighths",
+ /* 322 */ "fiveeighths",
+ /* 323 */ "seveneighths",
+ /* 324 */ "onethird",
+ /* 325 */ "twothirds",
+ /* 326 */ "zerosuperior",
+ /* 327 */ "foursuperior",
+ /* 328 */ "fivesuperior",
+ /* 329 */ "sixsuperior",
+ /* 330 */ "sevensuperior",
+ /* 331 */ "eightsuperior",
+ /* 332 */ "ninesuperior",
+ /* 333 */ "zeroinferior",
+ /* 334 */ "oneinferior",
+ /* 335 */ "twoinferior",
+ /* 336 */ "threeinferior",
+ /* 337 */ "fourinferior",
+ /* 338 */ "fiveinferior",
+ /* 339 */ "sixinferior",
+ /* 340 */ "seveninferior",
+ /* 341 */ "eightinferior",
+ /* 342 */ "nineinferior",
+ /* 343 */ "centinferior",
+ /* 344 */ "dollarinferior",
+ /* 345 */ "periodinferior",
+ /* 346 */ "commainferior",
+ /* 347 */ "Agravesmall",
+ /* 348 */ "Aacutesmall",
+ /* 349 */ "Acircumflexsmall",
+ /* 350 */ "Atildesmall",
+ /* 351 */ "Adieresissmall",
+ /* 352 */ "Aringsmall",
+ /* 353 */ "AEsmall",
+ /* 354 */ "Ccedillasmall",
+ /* 355 */ "Egravesmall",
+ /* 356 */ "Eacutesmall",
+ /* 357 */ "Ecircumflexsmall",
+ /* 358 */ "Edieresissmall",
+ /* 359 */ "Igravesmall",
+ /* 360 */ "Iacutesmall",
+ /* 361 */ "Icircumflexsmall",
+ /* 362 */ "Idieresissmall",
+ /* 363 */ "Ethsmall",
+ /* 364 */ "Ntildesmall",
+ /* 365 */ "Ogravesmall",
+ /* 366 */ "Oacutesmall",
+ /* 367 */ "Ocircumflexsmall",
+ /* 368 */ "Otildesmall",
+ /* 369 */ "Odieresissmall",
+ /* 370 */ "OEsmall",
+ /* 371 */ "Oslashsmall",
+ /* 372 */ "Ugravesmall",
+ /* 373 */ "Uacutesmall",
+ /* 374 */ "Ucircumflexsmall",
+ /* 375 */ "Udieresissmall",
+ /* 376 */ "Yacutesmall",
+ /* 377 */ "Thornsmall",
+ /* 378 */ "Ydieresissmall",
+ /* 379 */ "001.000",
+ /* 380 */ "001.001",
+ /* 381 */ "001.002",
+ /* 382 */ "001.003",
+ /* 383 */ "Black",
+ /* 384 */ "Bold",
+ /* 385 */ "Book",
+ /* 386 */ "Light",
+ /* 387 */ "Medium",
+ /* 388 */ "Regular",
+ /* 389 */ "Roman",
+ /* 390 */ "Semibold"
+};
+
+const static unsigned short expert_charset[] = {
+ 1, /* space */
+ 229, /* exclamsmall */
+ 230, /* Hungarumlautsmall */
+ 231, /* dollaroldstyle */
+ 232, /* dollarsuperior */
+ 233, /* ampersandsmall */
+ 234, /* Acutesmall */
+ 235, /* parenleftsuperior */
+ 236, /* parenrightsuperior */
+ 237, /* twodotenleader */
+ 238, /* onedotenleader */
+ 13, /* comma */
+ 14, /* hyphen */
+ 15, /* period */
+ 99, /* fraction */
+ 239, /* zerooldstyle */
+ 240, /* oneoldstyle */
+ 241, /* twooldstyle */
+ 242, /* threeoldstyle */
+ 243, /* fouroldstyle */
+ 244, /* fiveoldstyle */
+ 245, /* sixoldstyle */
+ 246, /* sevenoldstyle */
+ 247, /* eightoldstyle */
+ 248, /* nineoldstyle */
+ 27, /* colon */
+ 28, /* semicolon */
+ 249, /* commasuperior */
+ 250, /* threequartersemdash */
+ 251, /* periodsuperior */
+ 252, /* questionsmall */
+ 253, /* asuperior */
+ 254, /* bsuperior */
+ 255, /* centsuperior */
+ 256, /* dsuperior */
+ 257, /* esuperior */
+ 258, /* isuperior */
+ 259, /* lsuperior */
+ 260, /* msuperior */
+ 261, /* nsuperior */
+ 262, /* osuperior */
+ 263, /* rsuperior */
+ 264, /* ssuperior */
+ 265, /* tsuperior */
+ 266, /* ff */
+ 109, /* fi */
+ 110, /* fl */
+ 267, /* ffi */
+ 268, /* ffl */
+ 269, /* parenleftinferior */
+ 270, /* parenrightinferior */
+ 271, /* Circumflexsmall */
+ 272, /* hyphensuperior */
+ 273, /* Gravesmall */
+ 274, /* Asmall */
+ 275, /* Bsmall */
+ 276, /* Csmall */
+ 277, /* Dsmall */
+ 278, /* Esmall */
+ 279, /* Fsmall */
+ 280, /* Gsmall */
+ 281, /* Hsmall */
+ 282, /* Ismall */
+ 283, /* Jsmall */
+ 284, /* Ksmall */
+ 285, /* Lsmall */
+ 286, /* Msmall */
+ 287, /* Nsmall */
+ 288, /* Osmall */
+ 289, /* Psmall */
+ 290, /* Qsmall */
+ 291, /* Rsmall */
+ 292, /* Ssmall */
+ 293, /* Tsmall */
+ 294, /* Usmall */
+ 295, /* Vsmall */
+ 296, /* Wsmall */
+ 297, /* Xsmall */
+ 298, /* Ysmall */
+ 299, /* Zsmall */
+ 300, /* colonmonetary */
+ 301, /* onefitted */
+ 302, /* rupiah */
+ 303, /* Tildesmall */
+ 304, /* exclamdownsmall */
+ 305, /* centoldstyle */
+ 306, /* Lslashsmall */
+ 307, /* Scaronsmall */
+ 308, /* Zcaronsmall */
+ 309, /* Dieresissmall */
+ 310, /* Brevesmall */
+ 311, /* Caronsmall */
+ 312, /* Dotaccentsmall */
+ 313, /* Macronsmall */
+ 314, /* figuredash */
+ 315, /* hypheninferior */
+ 316, /* Ogoneksmall */
+ 317, /* Ringsmall */
+ 318, /* Cedillasmall */
+ 158, /* onequarter */
+ 155, /* onehalf */
+ 163, /* threequarters */
+ 319, /* questiondownsmall */
+ 320, /* oneeighth */
+ 321, /* threeeighths */
+ 322, /* fiveeighths */
+ 323, /* seveneighths */
+ 324, /* onethird */
+ 325, /* twothirds */
+ 326, /* zerosuperior */
+ 150, /* onesuperior */
+ 164, /* twosuperior */
+ 169, /* threesuperior */
+ 327, /* foursuperior */
+ 328, /* fivesuperior */
+ 329, /* sixsuperior */
+ 330, /* sevensuperior */
+ 331, /* eightsuperior */
+ 332, /* ninesuperior */
+ 333, /* zeroinferior */
+ 334, /* oneinferior */
+ 335, /* twoinferior */
+ 336, /* threeinferior */
+ 337, /* fourinferior */
+ 338, /* fiveinferior */
+ 339, /* sixinferior */
+ 340, /* seveninferior */
+ 341, /* eightinferior */
+ 342, /* nineinferior */
+ 343, /* centinferior */
+ 344, /* dollarinferior */
+ 345, /* periodinferior */
+ 346, /* commainferior */
+ 347, /* Agravesmall */
+ 348, /* Aacutesmall */
+ 349, /* Acircumflexsmall */
+ 350, /* Atildesmall */
+ 351, /* Adieresissmall */
+ 352, /* Aringsmall */
+ 353, /* AEsmall */
+ 354, /* Ccedillasmall */
+ 355, /* Egravesmall */
+ 356, /* Eacutesmall */
+ 357, /* Ecircumflexsmall */
+ 358, /* Edieresissmall */
+ 359, /* Igravesmall */
+ 360, /* Iacutesmall */
+ 361, /* Icircumflexsmall */
+ 362, /* Idieresissmall */
+ 363, /* Ethsmall */
+ 364, /* Ntildesmall */
+ 365, /* Ogravesmall */
+ 366, /* Oacutesmall */
+ 367, /* Ocircumflexsmall */
+ 368, /* Otildesmall */
+ 369, /* Odieresissmall */
+ 370, /* OEsmall */
+ 371, /* Oslashsmall */
+ 372, /* Ugravesmall */
+ 373, /* Uacutesmall */
+ 374, /* Ucircumflexsmall */
+ 375, /* Udieresissmall */
+ 376, /* Yacutesmall */
+ 377, /* Thornsmall */
+ 378 /* Ydieresissmall */
+};
+
+const static unsigned short expert_subset_charset[] = {
+ 1, /*space */
+ 231, /*dollaroldstyle */
+ 232, /*dollarsuperior */
+ 235, /*parenleftsuperior */
+ 236, /*parenrightsuperior */
+ 237, /*twodotenleader */
+ 238, /*onedotenleader */
+ 13, /*comma */
+ 14, /*hyphen */
+ 15, /*period */
+ 99, /*fraction */
+ 239, /*zerooldstyle */
+ 240, /*oneoldstyle */
+ 241, /*twooldstyle */
+ 242, /*threeoldstyle */
+ 243, /*fouroldstyle */
+ 244, /*fiveoldstyle */
+ 245, /*sixoldstyle */
+ 246, /*sevenoldstyle */
+ 247, /*eightoldstyle */
+ 248, /*nineoldstyle */
+ 27, /*colon */
+ 28, /*semicolon */
+ 249, /*commasuperior */
+ 250, /*threequartersemdash */
+ 251, /*periodsuperior */
+ 253, /*asuperior */
+ 254, /*bsuperior */
+ 255, /*centsuperior */
+ 256, /*dsuperior */
+ 257, /*esuperior */
+ 258, /*isuperior */
+ 259, /*lsuperior */
+ 260, /*msuperior */
+ 261, /*nsuperior */
+ 262, /*osuperior */
+ 263, /*rsuperior */
+ 264, /*ssuperior */
+ 265, /*tsuperior */
+ 266, /*ff */
+ 109, /*fi */
+ 110, /*fl */
+ 267, /*ffi */
+ 268, /*ffl */
+ 269, /*parenleftinferior */
+ 270, /*parenrightinferior */
+ 272, /*hyphensuperior */
+ 300, /*colonmonetary */
+ 301, /*onefitted */
+ 302, /*rupiah */
+ 305, /*centoldstyle */
+ 314, /*figuredash */
+ 315, /*hypheninferior */
+ 158, /*onequarter */
+ 155, /*onehalf */
+ 163, /*threequarters */
+ 320, /*oneeighth */
+ 321, /*threeeighths */
+ 322, /*fiveeighths */
+ 323, /*seveneighths */
+ 324, /*onethird */
+ 325, /*twothirds */
+ 326, /*zerosuperior */
+ 150, /*onesuperior */
+ 164, /*twosuperior */
+ 169, /*threesuperior */
+ 327, /*foursuperior */
+ 328, /*fivesuperior */
+ 329, /*sixsuperior */
+ 330, /*sevensuperior */
+ 331, /*eightsuperior */
+ 332, /*ninesuperior */
+ 333, /*zeroinferior */
+ 334, /*oneinferior */
+ 335, /*twoinferior */
+ 336, /*threeinferior */
+ 337, /*fourinferior */
+ 338, /*fiveinferior */
+ 339, /*sixinferior */
+ 340, /*seveninferior */
+ 341, /*eightinferior */
+ 342, /*nineinferior */
+ 343, /*centinferior */
+ 344, /*dollarinferior */
+ 345, /*periodinferior */
+ 346 /*commainferior */
+};
+
+static const unsigned short standard_encoding[] = {
+ /* 0 */ 0, /* .notdef */
+ /* 1 */ 0, /* .notdef */
+ /* 2 */ 0, /* .notdef */
+ /* 3 */ 0, /* .notdef */
+ /* 4 */ 0, /* .notdef */
+ /* 5 */ 0, /* .notdef */
+ /* 6 */ 0, /* .notdef */
+ /* 7 */ 0, /* .notdef */
+ /* 8 */ 0, /* .notdef */
+ /* 9 */ 0, /* .notdef */
+ /* 10 */ 0, /* .notdef */
+ /* 11 */ 0, /* .notdef */
+ /* 12 */ 0, /* .notdef */
+ /* 13 */ 0, /* .notdef */
+ /* 14 */ 0, /* .notdef */
+ /* 15 */ 0, /* .notdef */
+ /* 16 */ 0, /* .notdef */
+ /* 17 */ 0, /* .notdef */
+ /* 18 */ 0, /* .notdef */
+ /* 19 */ 0, /* .notdef */
+ /* 20 */ 0, /* .notdef */
+ /* 21 */ 0, /* .notdef */
+ /* 22 */ 0, /* .notdef */
+ /* 23 */ 0, /* .notdef */
+ /* 24 */ 0, /* .notdef */
+ /* 25 */ 0, /* .notdef */
+ /* 26 */ 0, /* .notdef */
+ /* 27 */ 0, /* .notdef */
+ /* 28 */ 0, /* .notdef */
+ /* 29 */ 0, /* .notdef */
+ /* 30 */ 0, /* .notdef */
+ /* 31 */ 0, /* .notdef */
+ /* 32 */ 1, /* space */
+ /* 33 */ 2, /* exclam */
+ /* 34 */ 3, /* quotedbl */
+ /* 35 */ 4, /* numbersign */
+ /* 36 */ 5, /* dollar */
+ /* 37 */ 6, /* percent */
+ /* 38 */ 7, /* ampersand */
+ /* 39 */ 8, /* quoteright */
+ /* 40 */ 9, /* parenleft */
+ /* 41 */ 10, /* parenright */
+ /* 42 */ 11, /* asterisk */
+ /* 43 */ 12, /* plus */
+ /* 44 */ 13, /* comma */
+ /* 45 */ 14, /* hyphen */
+ /* 46 */ 15, /* period */
+ /* 47 */ 16, /* slash */
+ /* 48 */ 17, /* zero */
+ /* 49 */ 18, /* one */
+ /* 50 */ 19, /* two */
+ /* 51 */ 20, /* three */
+ /* 52 */ 21, /* four */
+ /* 53 */ 22, /* five */
+ /* 54 */ 23, /* six */
+ /* 55 */ 24, /* seven */
+ /* 56 */ 25, /* eight */
+ /* 57 */ 26, /* nine */
+ /* 58 */ 27, /* colon */
+ /* 59 */ 28, /* semicolon */
+ /* 60 */ 29, /* less */
+ /* 61 */ 30, /* equal */
+ /* 62 */ 31, /* greater */
+ /* 63 */ 32, /* question */
+ /* 64 */ 33, /* at */
+ /* 65 */ 34, /* A */
+ /* 66 */ 35, /* B */
+ /* 67 */ 36, /* C */
+ /* 68 */ 37, /* D */
+ /* 69 */ 38, /* E */
+ /* 70 */ 39, /* F */
+ /* 71 */ 40, /* G */
+ /* 72 */ 41, /* H */
+ /* 73 */ 42, /* I */
+ /* 74 */ 43, /* J */
+ /* 75 */ 44, /* K */
+ /* 76 */ 45, /* L */
+ /* 77 */ 46, /* M */
+ /* 78 */ 47, /* N */
+ /* 79 */ 48, /* O */
+ /* 80 */ 49, /* P */
+ /* 81 */ 50, /* Q */
+ /* 82 */ 51, /* R */
+ /* 83 */ 52, /* S */
+ /* 84 */ 53, /* T */
+ /* 85 */ 54, /* U */
+ /* 86 */ 55, /* V */
+ /* 87 */ 56, /* W */
+ /* 88 */ 57, /* X */
+ /* 89 */ 58, /* Y */
+ /* 90 */ 59, /* Z */
+ /* 91 */ 60, /* bracketleft */
+ /* 92 */ 61, /* backslash */
+ /* 93 */ 62, /* bracketright */
+ /* 94 */ 63, /* asciicircum */
+ /* 95 */ 64, /* underscore */
+ /* 96 */ 65, /* quoteleft */
+ /* 97 */ 66, /* a */
+ /* 98 */ 67, /* b */
+ /* 99 */ 68, /* c */
+ /* 100 */ 69, /* d */
+ /* 101 */ 70, /* e */
+ /* 102 */ 71, /* f */
+ /* 103 */ 72, /* g */
+ /* 104 */ 73, /* h */
+ /* 105 */ 74, /* i */
+ /* 106 */ 75, /* j */
+ /* 107 */ 76, /* k */
+ /* 108 */ 77, /* l */
+ /* 109 */ 78, /* m */
+ /* 110 */ 79, /* n */
+ /* 111 */ 80, /* o */
+ /* 112 */ 81, /* p */
+ /* 113 */ 82, /* q */
+ /* 114 */ 83, /* r */
+ /* 115 */ 84, /* s */
+ /* 116 */ 85, /* t */
+ /* 117 */ 86, /* u */
+ /* 118 */ 87, /* v */
+ /* 119 */ 88, /* w */
+ /* 120 */ 89, /* x */
+ /* 121 */ 90, /* y */
+ /* 122 */ 91, /* z */
+ /* 123 */ 92, /* braceleft */
+ /* 124 */ 93, /* bar */
+ /* 125 */ 94, /* braceright */
+ /* 126 */ 95, /* asciitilde */
+ /* 127 */ 0, /* .notdef */
+ /* 128 */ 0, /* .notdef */
+ /* 129 */ 0, /* .notdef */
+ /* 130 */ 0, /* .notdef */
+ /* 131 */ 0, /* .notdef */
+ /* 132 */ 0, /* .notdef */
+ /* 133 */ 0, /* .notdef */
+ /* 134 */ 0, /* .notdef */
+ /* 135 */ 0, /* .notdef */
+ /* 136 */ 0, /* .notdef */
+ /* 137 */ 0, /* .notdef */
+ /* 138 */ 0, /* .notdef */
+ /* 139 */ 0, /* .notdef */
+ /* 140 */ 0, /* .notdef */
+ /* 141 */ 0, /* .notdef */
+ /* 142 */ 0, /* .notdef */
+ /* 143 */ 0, /* .notdef */
+ /* 144 */ 0, /* .notdef */
+ /* 145 */ 0, /* .notdef */
+ /* 146 */ 0, /* .notdef */
+ /* 147 */ 0, /* .notdef */
+ /* 148 */ 0, /* .notdef */
+ /* 149 */ 0, /* .notdef */
+ /* 150 */ 0, /* .notdef */
+ /* 151 */ 0, /* .notdef */
+ /* 152 */ 0, /* .notdef */
+ /* 153 */ 0, /* .notdef */
+ /* 154 */ 0, /* .notdef */
+ /* 155 */ 0, /* .notdef */
+ /* 156 */ 0, /* .notdef */
+ /* 157 */ 0, /* .notdef */
+ /* 158 */ 0, /* .notdef */
+ /* 159 */ 0, /* .notdef */
+ /* 160 */ 0, /* .notdef */
+ /* 161 */ 96, /* exclamdown */
+ /* 162 */ 97, /* cent */
+ /* 163 */ 98, /* sterling */
+ /* 164 */ 99, /* fraction */
+ /* 165 */ 100, /* yen */
+ /* 166 */ 101, /* florin */
+ /* 167 */ 102, /* section */
+ /* 168 */ 103, /* currency */
+ /* 169 */ 104, /* quotesingle */
+ /* 170 */ 105, /* quotedblleft */
+ /* 171 */ 106, /* guillemotleft */
+ /* 172 */ 107, /* guilsinglleft */
+ /* 173 */ 108, /* guilsinglright */
+ /* 174 */ 109, /* fi */
+ /* 175 */ 110, /* fl */
+ /* 176 */ 0, /* .notdef */
+ /* 177 */ 111, /* endash */
+ /* 178 */ 112, /* dagger */
+ /* 179 */ 113, /* daggerdbl */
+ /* 180 */ 114, /* periodcentered */
+ /* 181 */ 0, /* .notdef */
+ /* 182 */ 115, /* paragraph */
+ /* 183 */ 116, /* bullet */
+ /* 184 */ 117, /* quotesinglbase */
+ /* 185 */ 118, /* quotedblbase */
+ /* 186 */ 119, /* quotedblright */
+ /* 187 */ 120, /* guillemotright */
+ /* 188 */ 121, /* ellipsis */
+ /* 189 */ 122, /* perthousand */
+ /* 190 */ 0, /* .notdef */
+ /* 191 */ 123, /* questiondown */
+ /* 192 */ 0, /* .notdef */
+ /* 193 */ 124, /* grave */
+ /* 194 */ 125, /* acute */
+ /* 195 */ 126, /* circumflex */
+ /* 196 */ 127, /* tilde */
+ /* 197 */ 128, /* macron */
+ /* 198 */ 129, /* breve */
+ /* 199 */ 130, /* dotaccent */
+ /* 200 */ 131, /* dieresis */
+ /* 201 */ 0, /* .notdef */
+ /* 202 */ 132, /* ring */
+ /* 203 */ 133, /* cedilla */
+ /* 204 */ 0, /* .notdef */
+ /* 205 */ 134, /* hungarumlaut */
+ /* 206 */ 135, /* ogonek */
+ /* 207 */ 136, /* caron */
+ /* 208 */ 137, /* emdash */
+ /* 209 */ 0, /* .notdef */
+ /* 210 */ 0, /* .notdef */
+ /* 211 */ 0, /* .notdef */
+ /* 212 */ 0, /* .notdef */
+ /* 213 */ 0, /* .notdef */
+ /* 214 */ 0, /* .notdef */
+ /* 215 */ 0, /* .notdef */
+ /* 216 */ 0, /* .notdef */
+ /* 217 */ 0, /* .notdef */
+ /* 218 */ 0, /* .notdef */
+ /* 219 */ 0, /* .notdef */
+ /* 220 */ 0, /* .notdef */
+ /* 221 */ 0, /* .notdef */
+ /* 222 */ 0, /* .notdef */
+ /* 223 */ 0, /* .notdef */
+ /* 224 */ 0, /* .notdef */
+ /* 225 */ 138, /* AE */
+ /* 226 */ 0, /* .notdef */
+ /* 227 */ 139, /* ordfeminine */
+ /* 228 */ 0, /* .notdef */
+ /* 229 */ 0, /* .notdef */
+ /* 230 */ 0, /* .notdef */
+ /* 231 */ 0, /* .notdef */
+ /* 232 */ 140, /* Lslash */
+ /* 233 */ 141, /* Oslash */
+ /* 234 */ 142, /* OE */
+ /* 235 */ 143, /* ordmasculine */
+ /* 236 */ 0, /* .notdef */
+ /* 237 */ 0, /* .notdef */
+ /* 238 */ 0, /* .notdef */
+ /* 239 */ 0, /* .notdef */
+ /* 240 */ 0, /* .notdef */
+ /* 241 */ 144, /* ae */
+ /* 242 */ 0, /* .notdef */
+ /* 243 */ 0, /* .notdef */
+ /* 244 */ 0, /* .notdef */
+ /* 245 */ 145, /* dotlessi */
+ /* 246 */ 0, /* .notdef */
+ /* 247 */ 0, /* .notdef */
+ /* 248 */ 146, /* lslash */
+ /* 249 */ 147, /* oslash */
+ /* 250 */ 148, /* oe */
+ /* 251 */ 149, /* germandbls */
+ /* 252 */ 0, /* .notdef */
+ /* 253 */ 0, /* .notdef */
+ /* 254 */ 0, /* .notdef */
+ /* 255 */ 0 /* .notdef */
+};
+
+static const unsigned short expert_encoding[] = {
+ /* 0 */ 0, /* .notdef */
+ /* 1 */ 0, /* .notdef */
+ /* 2 */ 0, /* .notdef */
+ /* 3 */ 0, /* .notdef */
+ /* 4 */ 0, /* .notdef */
+ /* 5 */ 0, /* .notdef */
+ /* 6 */ 0, /* .notdef */
+ /* 7 */ 0, /* .notdef */
+ /* 8 */ 0, /* .notdef */
+ /* 9 */ 0, /* .notdef */
+ /* 10 */ 0, /* .notdef */
+ /* 11 */ 0, /* .notdef */
+ /* 12 */ 0, /* .notdef */
+ /* 13 */ 0, /* .notdef */
+ /* 14 */ 0, /* .notdef */
+ /* 15 */ 0, /* .notdef */
+ /* 16 */ 0, /* .notdef */
+ /* 17 */ 0, /* .notdef */
+ /* 18 */ 0, /* .notdef */
+ /* 19 */ 0, /* .notdef */
+ /* 20 */ 0, /* .notdef */
+ /* 21 */ 0, /* .notdef */
+ /* 22 */ 0, /* .notdef */
+ /* 23 */ 0, /* .notdef */
+ /* 24 */ 0, /* .notdef */
+ /* 25 */ 0, /* .notdef */
+ /* 26 */ 0, /* .notdef */
+ /* 27 */ 0, /* .notdef */
+ /* 28 */ 0, /* .notdef */
+ /* 29 */ 0, /* .notdef */
+ /* 30 */ 0, /* .notdef */
+ /* 31 */ 0, /* .notdef */
+ /* 32 */ 1, /* space */
+ /* 33 */ 229, /* exclamsmall */
+ /* 34 */ 230, /* Hungarumlautsmall */
+ /* 35 */ 0, /* .notdef */
+ /* 36 */ 231, /* dollaroldstyle */
+ /* 37 */ 232, /* dollarsuperior */
+ /* 38 */ 233, /* ampersandsmall */
+ /* 39 */ 234, /* Acutesmall */
+ /* 40 */ 235, /* parenleftsuperior */
+ /* 41 */ 236, /* parenrightsuperior */
+ /* 42 */ 237, /* twodotenleader */
+ /* 43 */ 238, /* onedotenleader */
+ /* 44 */ 13, /* comma */
+ /* 45 */ 14, /* hyphen */
+ /* 46 */ 15, /* period */
+ /* 47 */ 99, /* fraction */
+ /* 48 */ 239, /* zerooldstyle */
+ /* 49 */ 240, /* oneoldstyle */
+ /* 50 */ 241, /* twooldstyle */
+ /* 51 */ 242, /* threeoldstyle */
+ /* 52 */ 243, /* fouroldstyle */
+ /* 53 */ 244, /* fiveoldstyle */
+ /* 54 */ 245, /* sixoldstyle */
+ /* 55 */ 246, /* sevenoldstyle */
+ /* 56 */ 247, /* eightoldstyle */
+ /* 57 */ 248, /* nineoldstyle */
+ /* 58 */ 27, /* colon */
+ /* 59 */ 28, /* semicolon */
+ /* 60 */ 249, /* commasuperior */
+ /* 61 */ 250, /* threequartersemdash */
+ /* 62 */ 251, /* periodsuperior */
+ /* 63 */ 252, /* questionsmall */
+ /* 64 */ 0, /* .notdef */
+ /* 65 */ 253, /* asuperior */
+ /* 66 */ 254, /* bsuperior */
+ /* 67 */ 255, /* centsuperior */
+ /* 68 */ 256, /* dsuperior */
+ /* 69 */ 257, /* esuperior */
+ /* 70 */ 0, /* .notdef */
+ /* 71 */ 0, /* .notdef */
+ /* 72 */ 0, /* .notdef */
+ /* 73 */ 258, /* isuperior */
+ /* 74 */ 0, /* .notdef */
+ /* 75 */ 0, /* .notdef */
+ /* 76 */ 259, /* lsuperior */
+ /* 77 */ 260, /* msuperior */
+ /* 78 */ 261, /* nsuperior */
+ /* 79 */ 262, /* osuperior */
+ /* 80 */ 0, /* .notdef */
+ /* 81 */ 0, /* .notdef */
+ /* 82 */ 263, /* rsuperior */
+ /* 83 */ 264, /* ssuperior */
+ /* 84 */ 265, /* tsuperior */
+ /* 85 */ 0, /* .notdef */
+ /* 86 */ 266, /* ff */
+ /* 87 */ 109, /* fi */
+ /* 88 */ 110, /* fl */
+ /* 89 */ 267, /* ffi */
+ /* 90 */ 268, /* ffl */
+ /* 91 */ 269, /* parenleftinferior */
+ /* 92 */ 0, /* .notdef */
+ /* 93 */ 270, /* parenrightinferior */
+ /* 94 */ 271, /* Circumflexsmall */
+ /* 95 */ 272, /* hyphensuperior */
+ /* 96 */ 273, /* Gravesmall */
+ /* 97 */ 274, /* Asmall */
+ /* 98 */ 275, /* Bsmall */
+ /* 99 */ 276, /* Csmall */
+ /* 100 */ 277, /* Dsmall */
+ /* 101 */ 278, /* Esmall */
+ /* 102 */ 279, /* Fsmall */
+ /* 103 */ 280, /* Gsmall */
+ /* 104 */ 281, /* Hsmall */
+ /* 105 */ 282, /* Ismall */
+ /* 106 */ 283, /* Jsmall */
+ /* 107 */ 284, /* Ksmall */
+ /* 108 */ 285, /* Lsmall */
+ /* 109 */ 286, /* Msmall */
+ /* 110 */ 287, /* Nsmall */
+ /* 111 */ 288, /* Osmall */
+ /* 112 */ 289, /* Psmall */
+ /* 113 */ 290, /* Qsmall */
+ /* 114 */ 291, /* Rsmall */
+ /* 115 */ 292, /* Ssmall */
+ /* 116 */ 293, /* Tsmall */
+ /* 117 */ 294, /* Usmall */
+ /* 118 */ 295, /* Vsmall */
+ /* 119 */ 296, /* Wsmall */
+ /* 120 */ 297, /* Xsmall */
+ /* 121 */ 298, /* Ysmall */
+ /* 122 */ 299, /* Zsmall */
+ /* 123 */ 300, /* colonmonetary */
+ /* 124 */ 301, /* onefitted */
+ /* 125 */ 302, /* rupiah */
+ /* 126 */ 303, /* Tildesmall */
+ /* 127 */ 0, /* .notdef */
+ /* 128 */ 0, /* .notdef */
+ /* 129 */ 0, /* .notdef */
+ /* 130 */ 0, /* .notdef */
+ /* 131 */ 0, /* .notdef */
+ /* 132 */ 0, /* .notdef */
+ /* 133 */ 0, /* .notdef */
+ /* 134 */ 0, /* .notdef */
+ /* 135 */ 0, /* .notdef */
+ /* 136 */ 0, /* .notdef */
+ /* 137 */ 0, /* .notdef */
+ /* 138 */ 0, /* .notdef */
+ /* 139 */ 0, /* .notdef */
+ /* 140 */ 0, /* .notdef */
+ /* 141 */ 0, /* .notdef */
+ /* 142 */ 0, /* .notdef */
+ /* 143 */ 0, /* .notdef */
+ /* 144 */ 0, /* .notdef */
+ /* 145 */ 0, /* .notdef */
+ /* 146 */ 0, /* .notdef */
+ /* 147 */ 0, /* .notdef */
+ /* 148 */ 0, /* .notdef */
+ /* 149 */ 0, /* .notdef */
+ /* 150 */ 0, /* .notdef */
+ /* 151 */ 0, /* .notdef */
+ /* 152 */ 0, /* .notdef */
+ /* 153 */ 0, /* .notdef */
+ /* 154 */ 0, /* .notdef */
+ /* 155 */ 0, /* .notdef */
+ /* 156 */ 0, /* .notdef */
+ /* 157 */ 0, /* .notdef */
+ /* 158 */ 0, /* .notdef */
+ /* 159 */ 0, /* .notdef */
+ /* 160 */ 0, /* .notdef */
+ /* 161 */ 304, /* exclamdownsmall */
+ /* 162 */ 305, /* centoldstyle */
+ /* 163 */ 306, /* Lslashsmall */
+ /* 164 */ 0, /* .notdef */
+ /* 165 */ 0, /* .notdef */
+ /* 166 */ 307, /* Scaronsmall */
+ /* 167 */ 308, /* Zcaronsmall */
+ /* 168 */ 309, /* Dieresissmall */
+ /* 169 */ 310, /* Brevesmall */
+ /* 170 */ 311, /* Caronsmall */
+ /* 171 */ 0, /* .notdef */
+ /* 172 */ 312, /* Dotaccentsmall */
+ /* 173 */ 0, /* .notdef */
+ /* 174 */ 0, /* .notdef */
+ /* 175 */ 313, /* Macronsmall */
+ /* 176 */ 0, /* .notdef */
+ /* 177 */ 0, /* .notdef */
+ /* 178 */ 314, /* figuredash */
+ /* 179 */ 315, /* hypheninferior */
+ /* 180 */ 0, /* .notdef */
+ /* 181 */ 0, /* .notdef */
+ /* 182 */ 316, /* Ogoneksmall */
+ /* 183 */ 317, /* Ringsmall */
+ /* 184 */ 318, /* Cedillasmall */
+ /* 185 */ 0, /* .notdef */
+ /* 186 */ 0, /* .notdef */
+ /* 187 */ 0, /* .notdef */
+ /* 188 */ 158, /* onequarter */
+ /* 189 */ 155, /* onehalf */
+ /* 190 */ 163, /* threequarters */
+ /* 191 */ 319, /* questiondownsmall */
+ /* 192 */ 320, /* oneeighth */
+ /* 193 */ 321, /* threeeighths */
+ /* 194 */ 322, /* fiveeighths */
+ /* 195 */ 323, /* seveneighths */
+ /* 196 */ 324, /* onethird */
+ /* 197 */ 325, /* twothirds */
+ /* 198 */ 0, /* .notdef */
+ /* 199 */ 0, /* .notdef */
+ /* 200 */ 326, /* zerosuperior */
+ /* 201 */ 150, /* onesuperior */
+ /* 202 */ 164, /* twosuperior */
+ /* 203 */ 169, /* threesuperior */
+ /* 204 */ 327, /* foursuperior */
+ /* 205 */ 328, /* fivesuperior */
+ /* 206 */ 329, /* sixsuperior */
+ /* 207 */ 330, /* sevensuperior */
+ /* 208 */ 331, /* eightsuperior */
+ /* 209 */ 332, /* ninesuperior */
+ /* 210 */ 333, /* zeroinferior */
+ /* 211 */ 334, /* oneinferior */
+ /* 212 */ 335, /* twoinferior */
+ /* 213 */ 336, /* threeinferior */
+ /* 214 */ 337, /* fourinferior */
+ /* 215 */ 338, /* fiveinferior */
+ /* 216 */ 339, /* sixinferior */
+ /* 217 */ 340, /* seveninferior */
+ /* 218 */ 341, /* eightinferior */
+ /* 219 */ 342, /* nineinferior */
+ /* 220 */ 343, /* centinferior */
+ /* 221 */ 344, /* dollarinferior */
+ /* 222 */ 345, /* periodinferior */
+ /* 223 */ 346, /* commainferior */
+ /* 224 */ 347, /* Agravesmall */
+ /* 225 */ 348, /* Aacutesmall */
+ /* 226 */ 349, /* Acircumflexsmall */
+ /* 227 */ 350, /* Atildesmall */
+ /* 228 */ 351, /* Adieresissmall */
+ /* 229 */ 352, /* Aringsmall */
+ /* 230 */ 353, /* AEsmall */
+ /* 231 */ 354, /* Ccedillasmall */
+ /* 232 */ 355, /* Egravesmall */
+ /* 233 */ 356, /* Eacutesmall */
+ /* 234 */ 357, /* Ecircumflexsmall */
+ /* 235 */ 358, /* Edieresissmall */
+ /* 236 */ 359, /* Igravesmall */
+ /* 237 */ 360, /* Iacutesmall */
+ /* 238 */ 361, /* Icircumflexsmall */
+ /* 239 */ 362, /* Idieresissmall */
+ /* 240 */ 363, /* Ethsmall */
+ /* 241 */ 364, /* Ntildesmall */
+ /* 242 */ 365, /* Ogravesmall */
+ /* 243 */ 366, /* Oacutesmall */
+ /* 244 */ 367, /* Ocircumflexsmall */
+ /* 245 */ 368, /* Otildesmall */
+ /* 246 */ 369, /* Odieresissmall */
+ /* 247 */ 370, /* OEsmall */
+ /* 248 */ 371, /* Oslashsmall */
+ /* 249 */ 372, /* Ugravesmall */
+ /* 250 */ 373, /* Uacutesmall */
+ /* 251 */ 374, /* Ucircumflexsmall */
+ /* 252 */ 375, /* Udieresissmall */
+ /* 253 */ 376, /* Yacutesmall */
+ /* 254 */ 377, /* Thornsmall */
+ /* 255 */ 378 /* Ydieresissmall */
+};
+
+typedef struct tag_cff_index_t {
+ const unsigned char *start, *end, *data;
+ unsigned int offsize, count;
+} cff_index_t;
+
+static int
+card0(unsigned int *u, const unsigned char *p, const unsigned char *pe)
+{
+ return_error(e_rangecheck); /* invalid offset size */
+}
+static int
+card8(unsigned int *u, const unsigned char *p, const unsigned char *pe)
+{
+ if (p + 1 > pe)
+ return_error(e_rangecheck); /* out of range access */
+ *u = *p;
+ return 0;
+}
+static int
+card16(unsigned int *u, const unsigned char *p, const unsigned char *pe)
+{
+ if (p + 2 > pe)
+ return_error(e_rangecheck); /* out of range access */
+ *u = p[0] << 8 | p[1];
+ return 0;
+}
+static int
+card24(unsigned int *u, const unsigned char *p, const unsigned char *pe)
+{
+ if (p + 3 > pe)
+ return_error(e_rangecheck); /* out of range access */
+ *u = p[0] << 16 | p[1] << 8 | p[2];
+ return 0;
+}
+static int
+card32(unsigned int *u, const unsigned char *p, const unsigned char *pe)
+{
+ if (p + 4 > pe)
+ return_error(e_rangecheck); /* out of range access */
+ *u = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
+ return 0;
+}
+
+static const int (*offset_procs[])(unsigned int *, const unsigned char *, const unsigned char *) = {
+ card0, card8, card16, card24, card32
+};
+
+static int
+parse_index(cff_index_t *x, const unsigned char *p, const unsigned char *pe)
+{ int code;
+
+ if (p == 0) {
+ memset(x, 0, sizeof(*x));
+ return 0;
+ }
+ x->start = p;
+ if ((code = card16(&x->count, p, pe)) < 0)
+ return code;
+ if (x->count) {
+ unsigned int eod;
+
+ if ((code = card8(&x->offsize, p + 2, pe)) < 0)
+ return code;
+ if (x->offsize == 0 || x->offsize > 4)
+ return_error(e_rangecheck); /* Invalid offest size*/
+ x->data = p + 2 + x->offsize*(x->count+1);
+ code = (*offset_procs[x->offsize])(&eod, p + 3 + x->offsize*x->count, pe);
+ if (code < 0)
+ return code;
+ x->end = x->data + eod;
+ } else {
+ x->offsize = 0;
+ x->data = 0;
+ x->end = p + 2;
+ }
+ return 0;
+}
+
+static int
+peek_index(const unsigned char **pp, unsigned int *len, const cff_index_t *x, unsigned int i)
+{
+ int code;
+ unsigned int off1, off2;
+
+ if (i >= x->count)
+ return_error(e_rangecheck); /* wrong index */
+ if((code = (*offset_procs[x->offsize])(&off1, x->start + 3 + x->offsize*i, x->end)) < 0)
+ return code;
+ if((code = (*offset_procs[x->offsize])(&off2, x->start + 3 + x->offsize*(i + 1), x->end)) < 0)
+ return code;
+ if (off2 < off1)
+ return_error(e_rangecheck); /* Decreasing offsets */
+ if (x->data + off2 > x->end)
+ return_error(e_rangecheck); /* Element exceeds index size */
+ *len = off2 - off1;
+ *pp = x->data + off1;
+ return 0;
+}
+
+static int
+get_int(int *v, const unsigned char *p, const unsigned char *pe)
+{
+ unsigned int c;
+ const int ext16 = ~0 << 15; /* sign extension constant */
+ const int ext32 = ~0 << 31; /* sign extension constant */
+
+ if (p >= pe)
+ return_error(e_rangecheck); /* out of data */
+ c = *p;
+ if (c == 28) {
+ if (p + 3 >= pe)
+ return_error(e_rangecheck); /* out of data */
+ *v = ((p[1] << 8 | p[2]) + ext16) ^ ext16;
+ return 3;
+ }
+ if (c == 29) {
+ if (p + 5 >= pe)
+ return_error(e_rangecheck); /* out of data */
+ *v = ((p[1] << 24 | p[2] << 16 | p[3] << 8 | p[4]) + ext32) ^ ext32;
+ return 5;
+ }
+ if (c < 32)
+ return_error(e_rangecheck); /* out of range */
+ if (c < 247) {
+ *v = (c - 139);
+ return 1;
+ }
+ if (c < 251) {
+ if (p + 1 >= pe)
+ return_error(e_rangecheck); /* out of data */
+ *v = (c - 247)*256 + p[1] + 108;
+ return 2;
+ }
+ if (c < 255) {
+ if (p + 1 >= pe)
+ return_error(e_rangecheck); /* out of data */
+ *v = -((int)c - 251)*256 - p[1] - 108;
+ return 2;
+ }
+ return_error(e_rangecheck); /* out of range */
+}
+
+static int
+get_float(float *v, const unsigned char *p, const unsigned char *pe)
+{
+ unsigned int c, i;
+ char buf[80];
+ char *q = buf;
+
+ while(p < pe) {
+ c = *p;
+ for (i=0; i<2 && q < buf + sizeof(buf) - 1; i++) {
+ switch(c & 15) {
+ case 0: case 1: case 2: case 3: case 4: /* 0 .. 9 */
+ case 5: case 6: case 7: case 8: case 9:
+ *q++ = '0' + (c & 15);
+ break;
+ case 10: /* . */
+ *q++ = '.';
+ break;
+ case 11: /* E */
+ *q++ = 'e';
+ break;
+ case 12: /* E- */
+ *q++ = 'e';
+ *q++ = '-';
+ break;
+ case 13: /* invalid, skip */
+ break;
+ case 14: /* - */
+ *q++ = '-';
+ break;
+ case 15: { /* end */
+ int scanned;
+
+ *q = 0;
+ sscanf(buf, "%f%n", v, &scanned);
+ if (scanned == q - buf)
+ return scanned;
+ else
+ return_error(e_rangecheck);
+ }
+ break;
+ }
+ c >>= 4;
+ }
+
+ }
+ return_error(e_rangecheck); /* out of data */
+}
+
+static int
+idict_put_c_name(i_ctx_t *i_ctx_p, ref *dst, const char *c_name, unsigned int len, const ref *src)
+{
+ int code;
+ ref ps_name;
+
+ if ((code = name_ref(imemory, (const unsigned char *)c_name, len, &ps_name, 0)) < 0)
+ return code;
+ return idict_put(dst, &ps_name, src);
+}
+
+static int
+make_string_from_index(i_ctx_t *i_ctx_p, ref *dst, const cff_index_t *index, unsigned int id)
+{
+ int code;
+ unsigned int len;
+ byte *sbody, *data;
+
+ if ((code = peek_index(&data, &len, index, id)) < 0)
+ return code;
+ if (len > 65535)
+ return_error(e_limitcheck);
+ if ((sbody = ialloc_string(len, "make_string_from_index")) == 0)
+ return_error(e_VMerror);
+ make_string(dst, icurrent_space | a_readonly, len, sbody);
+ memcpy(sbody, data, len);
+ return 0;
+}
+
+static int
+make_string_from_sid(i_ctx_t *i_ctx_p, ref *dst, const cff_index_t *strings, unsigned int sid)
+{
+ const unsigned int stsz = sizeof(standard_strings)/sizeof(*standard_strings);
+
+ if (sid < stsz) {
+ make_string(dst, avm_foreign | a_readonly,
+ strlen(standard_strings[sid]), (unsigned char *)standard_strings[sid]); /* break const */
+ return 0;
+ } else
+ return make_string_from_index(i_ctx_p, dst, strings, sid - stsz);
+}
+
+
+static int
+make_name_from_sid(i_ctx_t *i_ctx_p, ref *dst, const cff_index_t *strings, unsigned int sid)
+{
+ const unsigned int stsz = sizeof(standard_strings)/sizeof(*standard_strings);
+
+ if (sid < stsz) {
+ return name_ref(imemory, (const unsigned char *)standard_strings[sid],
+ strlen(standard_strings[sid]), dst, 0);
+ } else {
+ int code;
+ unsigned int len;
+ byte *data;
+
+ if ((code = peek_index(&data, &len, strings, sid - stsz)) < 0)
+ return code;
+ return name_ref(imemory, data, len, dst, 1);
+ }
+}
+
+static int
+make_stringarray_from_index(i_ctx_t *i_ctx_p, ref *dst, const cff_index_t *index)
+{
+ int code;
+ unsigned int i;
+
+ if ((code = ialloc_ref_array(dst, a_readonly, index->count, "make_stringarray_from_index")) < 0)
+ return code;
+ for (i = 0; i < index->count; i++) {
+ unsigned char *subr;
+ unsigned int len;
+
+ if ((code = peek_index(&subr, &len, index, i)) < 0)
+ return code;
+ if ((code = make_string_from_index(i_ctx_p, dst->value.refs + i, index, i)) < 0)
+ return code;
+ }
+ return 0;
+}
+
+static void
+undelta(ref *ops, unsigned int cnt)
+{
+ unsigned int i;
+ bool has_real = false;
+
+ for (i = 0; i < cnt; i++) {
+ if (r_has_type(&ops[i], t_real)) {
+ has_real = true;
+ break;
+ }
+ }
+ if (has_real) {
+ if (!r_has_type(&ops[0], t_real))
+ make_real(&ops[0], (float)ops[0].value.intval);
+ for (i = 1; i < cnt; i++) {
+ if (!r_has_type(&ops[i], t_real))
+ make_real(&ops[i], (float)ops[i].value.intval + ops[i - 1].value.realval);
+ else
+ make_real(&ops[i], ops[i].value.realval + ops[i - 1].value.realval);
+ }
+ } else {
+ for (i = 1; i < cnt; i++) {
+ make_real(&ops[i], (float)ops[i].value.intval + ops[i - 1].value.intval);
+ }
+ }
+}
+
+static int
+iso_adobe_charset_proc(const unsigned char *p, const unsigned char *pe, unsigned int i)
+{
+ if (i < 228)
+ return i;
+ else
+ return_error(e_rangecheck);
+}
+
+static int
+expert_charset_proc(const unsigned char *p, const unsigned char *pe, unsigned int i)
+{
+ if (i < sizeof(expert_charset)/sizeof(*expert_charset))
+ return expert_charset[i];
+ else
+ return_error(e_rangecheck);
+}
+
+static int
+expert_subset_charset_proc(const unsigned char *p, const unsigned char *pe, unsigned int i)
+{
+ if (i < sizeof(expert_subset_charset)/sizeof(*expert_subset_charset))
+ return expert_subset_charset[i];
+ else
+ return_error(e_rangecheck);
+}
+
+static int
+format0_charset_proc(const unsigned char *p, const unsigned char *pe, unsigned int i)
+{
+ if ( p + 2*i + 1 < pe)
+ return p[2*i] << 8 | p[2*i + 1];
+ else
+ return_error(e_rangecheck);
+}
+
+static int
+format1_charset_proc(const unsigned char *p, const unsigned char *pe, unsigned int i)
+{
+ unsigned int cid = 0;
+ while( p < pe - 3) {
+ unsigned int first = p[0] << 8 | p[1];
+ unsigned int count = p[2] + 1;
+
+ if (i < cid + count)
+ return first + i;
+ p += 3;
+ }
+ return_error(e_rangecheck);
+}
+
+static int
+format2_charset_proc(const unsigned char *p, const unsigned char *pe, unsigned int i)
+{
+ unsigned int cid = 0;
+ while( p < pe - 3) {
+ unsigned int first = p[0] << 8 | p[1];
+ unsigned int count = (p[2] << 8 | p[3]) + 1;
+
+ if (i < cid + count)
+ return first + i;
+ p += 4;
+ }
+ return_error(e_rangecheck);
+}
+
+
+static int
+find_font_dict(i_ctx_t *i_ctx_p, ref *topdict, ref **fontdict, const char *key)
+{
+ int code;
+ ref val;
+
+ if (*fontdict)
+ return 0;
+ if (dict_find_string(topdict, key, fontdict) > 0)
+ return 0;
+ if ((code = dict_create(8, &val)) < 0)
+ return code;
+ if ((code = idict_put_c_name(i_ctx_p, topdict, key, strlen(key), &val)) < 0)
+ return code;
+ if ((code = dict_find_string(topdict, key, fontdict)) == 0)
+ return_error(e_undefined); /* can't happen */
+ return code;
+}
+
+#define DEFINE_KEYS(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z, \
+ A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) \
+static const char * const font_keys[] = { \
+ #a,#b,#c,#d,#e,#f,#g,#h,#i,#j,#k,#l,#m,#n,#o,#p,#q,#r,#s,#t,#u,#v,#w,#x,#y,#z, \
+ #A,#B,#C,#D,#E,#F,#G,#H,#I,#J,#K,#L,#M,#N,#O,#P,#Q,#R,#S,#T \
+}; \
+static const short font_keys_sz[] = { \
+ sizeof(#a)-1, sizeof(#b)-1, sizeof(#c)-1, sizeof(#d)-1, sizeof(#e)-1, \
+ sizeof(#f)-1, sizeof(#g)-1, sizeof(#h)-1, sizeof(#i)-1, sizeof(#j)-1, \
+ sizeof(#k)-1, sizeof(#l)-1, sizeof(#m)-1, sizeof(#n)-1, sizeof(#o)-1, \
+ sizeof(#p)-1, sizeof(#q)-1, sizeof(#r)-1, sizeof(#s)-1, sizeof(#t)-1, \
+ sizeof(#u)-1, sizeof(#v)-1, sizeof(#w)-1, sizeof(#x)-1, sizeof(#y)-1, \
+ sizeof(#z)-1, sizeof(#A)-1, sizeof(#B)-1, sizeof(#C)-1, sizeof(#D)-1, \
+ sizeof(#E)-1, sizeof(#F)-1, sizeof(#G)-1, sizeof(#H)-1, sizeof(#I)-1, \
+ sizeof(#J)-1, sizeof(#K)-1, sizeof(#L)-1, sizeof(#M)-1, sizeof(#N)-1, \
+ sizeof(#O)-1, sizeof(#P)-1, sizeof(#Q)-1, sizeof(#R)-1, sizeof(#S)-1, \
+ sizeof(#T)-1 \
+}; \
+typedef enum { \
+ k_##a = 0, k_##b, k_##c, k_##d, k_##e, k_##f, k_##g, k_##h, k_##i, k_##j, k_##k, k_##l, k_##m, \
+ k_##n, k_##o, k_##p, k_##q, k_##r, k_##s, k_##t, k_##u, k_##v, k_##w, k_##x, k_##y, k_##z, \
+ k_##A, k_##B, k_##C, k_##D, k_##E, k_##F, k_##G, k_##H, k_##I, k_##J, k_##K, k_##L, k_##M, \
+ k_##N, k_##O, k_##P, k_##Q, k_##R, k_##S, k_##T \
+} font_keys_dummy_t;
+
+DEFINE_KEYS(
+ version,
+ Notice,
+ FullName,
+ FamilyName,
+ Weight,
+ FontBBox,
+ BlueValues,
+ OtherBlues,
+ FamilyBlues,
+ FamilyOtherBlues,
+ StdHW,
+ StdVW,
+ Copyright,
+ isFixedPitch,
+ ItalicAngle,
+ UnderlinePosition,
+ UnderlineThickness,
+ PaintType,
+ CharstringType,
+ FontMatrix,
+ StrokeWidth,
+ BlueScale,
+ BlueShift,
+ BlueFuzz,
+ StemSnapH,
+ StemSnapV,
+ ForceBold,
+ LanguageGroup,
+ ExpansionFactor,
+ initialRandomSeed,
+ SyntheticBase,
+ PostScript,
+ BaseFontName,
+ BaseFontBlend,
+ CIDFontVersion,
+ CIDFontRevision,
+ CIDFontType,
+ CIDCount,
+ UIDBase,
+ FDArray,
+ FDSelect,
+ FontName,
+ UniqueID,
+ XUID,
+ defaultWidthX,
+ nominalWidthX
+)
+#undef DEFINE_KEYS
+
+typedef enum { \
+ k_topdict = 0, k_fontinfodict = 0x10000, k_privatedict = 0x20000, k_sid = 0x40000,
+ k_array = 0x80000, k_delta = 0x100000, k_int = 0x200000, k_bool=0x400000
+} font_flags_dummy_t;
+
+#define CONTROL(id, n_op, flags) ((flags) | (n_op) | ((k_##id) << 8))
+
+
+typedef enum { \
+ k_0, k_1, k_2, k_7, k_50, k_neg_100, k_8720, k_0_039625, k_0_06, k_false, k_box, k_matrix
+} font_defaults_dummy_t;
+
+typedef struct tag_font_defaults {
+ unsigned short key;
+ unsigned short value;
+} font_defaults_t;
+
+static const font_defaults_t fontinfo_font_defaults[] = {
+ { k_isFixedPitch, k_false },
+ { k_ItalicAngle, k_0 },
+ { k_UnderlinePosition, k_neg_100 },
+ { k_UnderlineThickness, k_50 }
+};
+
+static const font_defaults_t top_font_defaults[] = {
+ { k_PaintType, k_0 },
+ { k_CharstringType, k_2 },
+ { k_FontMatrix, k_matrix }, /* 0.001 0 0 0.001 0 0 */
+ { k_FontBBox, k_box }, /* 0 0 0 0 */
+ { k_StrokeWidth, k_0 }
+};
+
+static const font_defaults_t cid_font_defaults[] = {
+ { k_CIDFontVersion, k_0 },
+ { k_CIDFontRevision, k_0 },
+ { k_CIDFontType, k_0 },
+ { k_CIDCount, k_8720 }
+};
+
+static const font_defaults_t private_font_defaults[] = {
+ { k_BlueScale, k_0_039625 },
+ { k_BlueShift, k_7 },
+ { k_BlueFuzz, k_1 },
+ { k_ForceBold, k_false },
+ { k_LanguageGroup, k_0 },
+ { k_ExpansionFactor, k_0_06 },
+ { k_initialRandomSeed, k_0 },
+ { k_defaultWidthX, k_0 },
+ { k_nominalWidthX, k_0 }
+};
+
+static int
+set_defaults(i_ctx_t *i_ctx_p, ref *dest, const font_defaults_t *def, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ ref name, *dummy, value;
+ int code;
+
+ if ((code = name_ref(imemory, (const unsigned char *)font_keys[def[i].key],
+ font_keys_sz[def[i].key], &name, 0)) < 0)
+ return code;
+ if (dict_find(dest, &name, &dummy) <= 0) {
+ switch (def[i].value) {
+ default:
+ case k_0:
+ make_int(&value, 0);
+ break;
+ case k_1:
+ make_int(&value, 1);
+ break;
+ case k_2:
+ make_int(&value, 2);
+ break;
+ case k_7:
+ make_int(&value, 7);
+ break;
+ case k_50:
+ make_int(&value, 50);
+ break;
+ case k_neg_100:
+ make_int(&value, -100);
+ break;
+ case k_8720:
+ make_int(&value, 8720);
+ break;
+ case k_0_039625:
+ make_real(&value, (float)0.039625);
+ break;
+ case k_0_06:
+ make_real(&value, (float)0.06);
+ break;
+ case k_false:
+ make_bool(&value, 0);
+ break;
+ case k_box:
+ if ((code = ialloc_ref_array(&value, a_readonly, 4, "parsecff.default_bbox")) < 0)
+ return code;
+ make_int(&value.value.refs[0], 0);
+ value.value.refs[1] = value.value.refs[2] = value.value.refs[3] = value.value.refs[0];
+ break;
+ case k_matrix:
+ if ((code = ialloc_ref_array(&value, a_readonly, 6, "parsecff.default_bbox")) < 0)
+ return code;
+ make_real(&value.value.refs[0], (float)0.001);
+ value.value.refs[3] = value.value.refs[0];
+ make_real(&value.value.refs[1], (float)0.);
+ value.value.refs[2] = value.value.refs[4] = value.value.refs[5] = value.value.refs[1];
+ break;
+ }
+ if ((code = idict_put(dest, &name, &value)) < 0)
+ return code;
+ }
+ }
+ return 0;
+}
+
+typedef struct tag_font_offsets_t {
+ unsigned int fdarray_off;
+ unsigned int fdselect_off;
+ unsigned int charset_off;
+ unsigned int encoding_off;
+ unsigned int private_off;
+ unsigned int charstrings_off;
+ unsigned int local_subrs_off;
+ unsigned int private_size;
+ bool have_ros;
+} font_offsets_t;
+
+static int
+parse_dict(i_ctx_t *i_ctx_p, ref *topdict, font_offsets_t *offsets,
+ const cff_index_t *strings,
+ const unsigned char * const p0, const unsigned char * const pe)
+{
+ ref *fontinfodict = 0, *privatedict = 0, arg, ops[MAXOP];
+ unsigned int op_i = 0;
+
+ unsigned char c;
+ unsigned const char *p = p0;
+ unsigned int control;
+ int code;
+
+ while(p < pe) {
+ c = *p++;
+ switch(c) {
+ case 0: /* version 0 SID -, FontInfo */
+ control = CONTROL(version, 1, k_fontinfodict | k_sid);
+ break;
+ case 1: /* Notice 1 SID -, FontInfo */
+ control = CONTROL(Notice, 1, k_fontinfodict | k_sid);
+ break;
+ case 2: /* FullName 2 SID -, FontInfo */
+ control = CONTROL(FullName, 1, k_fontinfodict | k_sid);
+ break;
+ case 3: /* FamilyName 3 SID -, FontInfo */
+ control = CONTROL(FamilyName, 1, k_fontinfodict | k_sid);
+ break;
+ case 4: /* Weight 4 SID -, FontInfo */
+ control = CONTROL(FamilyName, 1, k_fontinfodict | k_sid);
+ break;
+ case 5: /* FontBBox 5 array 0 0 0 0 */
+ control = CONTROL(FontBBox, 4, k_topdict | k_array);
+ break;
+ case 6: /* BlueValues 6 delta -, Private */
+ control = CONTROL(BlueValues, 0, k_privatedict | k_array | k_delta);
+ break;
+ case 7: /* OtherBlues 7 delta -, Private */
+ control = CONTROL(OtherBlues, 0, k_privatedict | k_array | k_delta);
+ break;
+ case 8: /* FamilyBlues 8 delta -, Private */
+ control = CONTROL(FamilyBlues, 0, k_privatedict | k_array | k_delta);
+ break;
+ case 9: /* FamilyOtherBlues 9 delta -, Private */
+ control = CONTROL(FamilyOtherBlues, 0, k_privatedict | k_array | k_delta);
+ break;
+ case 10: /* StdHW 10 number -, Private */
+ control = CONTROL(StdHW, 1, k_privatedict);
+ break;
+ case 11: /* StdVW 11 number -, Private */
+ control = CONTROL(StdVW, 1, k_privatedict);
+ break;
+ case 12:
+ if (p >= pe)
+ goto done;
+ c = *p++;
+ switch(c) {
+ case 0: /* Copyright 12 0 SID -, FontInfo */
+ control = CONTROL(Copyright, 1, k_fontinfodict | k_sid);
+ break;
+ case 1: /* isFixedPitch 12 1 boolean 0 (false), FontInfo */
+ control = CONTROL(isFixedPitch, 1, k_fontinfodict | k_int | k_bool);
+ break;
+ case 2: /* ItalicAngle 12 2 number 0, FontInfo */
+ control = CONTROL(ItalicAngle, 1, k_fontinfodict);
+ break;
+ case 3: /* UnderlinePosition 12 3 number -100, FontInfo */
+ control = CONTROL(UnderlinePosition, 1, k_fontinfodict);
+ break;
+ case 4: /* UnderlineThickness 12 4 number 50, FontInfo */
+ control = CONTROL(UnderlineThickness, 1, k_fontinfodict);
+ break;
+ case 5: /* PaintType 12 5 number 0 */
+ control = CONTROL(PaintType, 1, k_fontinfodict);
+ break;
+ case 6: /* CharstringType 12 6 number 2 */
+ control = CONTROL(CharstringType, 1, k_fontinfodict | k_int);
+ break;
+ case 7: /* FontMatrix 12 7 array 0.001 0 0 0.001 0 0 */
+ control = CONTROL(FontMatrix, 6, k_topdict | k_array);
+ break;
+ case 8: /* StrokeWidth 12 8 number 0 */
+ control = CONTROL(StrokeWidth, 1, k_topdict);
+ break;
+ case 9: /* BlueScale 12 9 number 0.039625, Provate */
+ control = CONTROL(BlueScale, 1, k_privatedict);
+ break;
+ case 10: /* BlueShift 12 10 number 7, Provate */
+ control = CONTROL(BlueShift, 1, k_privatedict);
+ break;
+ case 11: /* BlueFuzz 12 11 number 1, Provate */
+ control = CONTROL(BlueFuzz, 1, k_privatedict);
+ break;
+ case 12: /* StemSnapH 12 12 delta -, Provate */
+ control = CONTROL(StemSnapH, 0, k_privatedict | k_array | k_delta);
+ break;
+ case 13: /* StemSnapV 12 13 delta -, Provate */
+ control = CONTROL(StemSnapV, 0, k_privatedict | k_array | k_delta);
+ break;
+ case 14: /* ForceBold 12 14 boolean false, Provate */
+ control = CONTROL(ForceBold, 1, k_privatedict | k_int | k_bool);
+ break;
+ case 17: /* LanguageGroup 12 17 number 0, Provate */
+ control = CONTROL(LanguageGroup, 1, k_privatedict | k_int);
+ break;
+ case 18: /* ExpansionFactor 12 18 number 0.06, Provate */
+ control = CONTROL(ExpansionFactor, 1, k_privatedict);
+ break;
+ case 19: /* initialRandomSeed 12 19 number 0, Provate */
+ control = CONTROL(initialRandomSeed, 1, k_privatedict | k_int);
+ break;
+ case 20: /* SyntheticBase 12 20 number -, synthetic base font index */
+ control = CONTROL(SyntheticBase, 1, k_privatedict | k_int);
+ break;
+ case 21: /* PostScript 12 21 SID -, embedded PostScript language code */
+ control = CONTROL(PostScript, 1, k_topdict | k_int | k_sid);
+ break;
+ case 22: /* BaseFontName 12 22 SID -, (added as needed by Adobe-based technology) */
+ control = CONTROL(BaseFontName, 1, k_topdict | k_int | k_sid);
+ break;
+ case 23: /* BaseFontBlend 12 23 delta -, (added as needed by Adobe-based technology) */
+ control = CONTROL(BaseFontBlend, 0, k_topdict | k_array | k_delta);
+ break;
+
+ /* CIDFont */
+ case 30: {/* ROS 12 30 SID SID number -, Registry Ordering Supplement */
+ ref ros;
+
+ if (op_i -= 3 < 0)
+ return_error(e_stackunderflow);
+ if ((code = dict_create(3, &ros)) < 0)
+ return code;
+ check_type(ops[op_i], t_integer);
+ if ((code = make_string_from_sid(i_ctx_p, &arg, strings, ops[op_i].value.intval)) < 0)
+ return code;
+ if ((code = idict_put_c_name(i_ctx_p, &ros, STR2MEM("Registery"), &arg)) < 0)
+ return code;
+ if ((code = make_string_from_sid(i_ctx_p, &arg, strings, ops[op_i + 1].value.intval)) < 0)
+ return code;
+ if ((code = idict_put_c_name(i_ctx_p, &ros, STR2MEM("Ordering"), &arg)) < 0)
+ return code;
+ if ((code = idict_put_c_name(i_ctx_p, &ros, STR2MEM("Supplement"), &ops[op_i + 2])) < 0)
+ return code;
+ if ((code = idict_put_c_name(i_ctx_p, topdict, STR2MEM("CIDSystemInfo"), &ros)) < 0)
+ return code;
+ offsets->have_ros = true;
+ }
+ continue;
+ case 31: /* CIDFontVersion 12 31 number 0 */
+ control = CONTROL(CIDFontVersion, 1, k_topdict);
+ break;
+ case 32: /* CIDFontRevision 12 32 number 0 */
+ control = CONTROL(CIDFontRevision, 1, k_topdict);
+ break;
+ case 33: /* CIDFontType 12 33 number 0 */
+ control = CONTROL(CIDFontType, 1, k_topdict | k_int);
+ break;
+ case 34: /* CIDCount 12 34 number 8720 */
+ control = CONTROL(CIDCount, 1, k_topdict | k_int);
+ break;
+ case 35: /* UIDBase 12 35 number - */
+ control = CONTROL(UIDBase, 1, k_topdict | k_int);
+ break;
+ case 36: /* FDArray 12 36 number -, Font DICT (FD) INDEX offset (0) */
+ control = 0;
+ if (--op_i < 0)
+ return_error(e_stackunderflow);
+ check_type(ops[op_i], t_integer);
+ offsets->fdarray_off = ops[op_i].value.intval;
+ continue;
+ case 37: /* FDSelect 12 37 number -, FDSelect offset (0) */
+ control = 0;
+ if (--op_i < 0)
+ return_error(e_stackunderflow);
+ check_type(ops[op_i], t_integer);
+ offsets->fdselect_off = ops[op_i].value.intval;
+ continue;
+ case 38: /* FontName 12 38 SID -, FD FontName */
+ control = CONTROL(FontName, 1, k_topdict | k_int | k_sid);
+ break;
+ default:
+ continue;
+ }
+ break;
+ case 13: /* UniqueID 13 number - */
+ control = CONTROL(UniqueID, 1, k_topdict | k_int);
+ break;
+ case 14: /* XUID 14 array - */
+ control = CONTROL(XUID, 0, k_topdict | k_array);
+ break;
+ case 15: /* charset 15 number 0, charset offset (0) */
+ if (--op_i < 0)
+ return_error(e_stackunderflow);
+ check_type(ops[op_i], t_integer);
+ offsets->charset_off = ops[op_i].value.intval;
+ continue;
+ case 16: /* Encoding 16 number 0, encoding offset (0) */
+ if (--op_i < 0)
+ return_error(e_stackunderflow);
+ check_type(ops[op_i], t_integer);
+ offsets->encoding_off = ops[op_i].value.intval;
+ continue;
+ case 17: /* CharStrings 17 number -, CharStrings offset (0) */
+ if (--op_i < 0)
+ return_error(e_stackunderflow);
+ check_type(ops[op_i], t_integer);
+ offsets->charstrings_off = ops[op_i].value.intval;
+ continue;
+ case 18: /* Private 18 number, number -, Private DICT size and offset (0)*/
+ if ((op_i -= 2) < 0)
+ return_error(e_stackunderflow);
+ check_type(ops[op_i], t_integer);
+ check_type(ops[op_i + 1], t_integer);
+ offsets->private_size = ops[op_i].value.intval;
+ offsets->private_off = ops[op_i + 1].value.intval;
+ continue;
+ case 19: /* Local Subrs 19 number -, Offset (self) to local subrs */
+ if (--op_i < 0)
+ return_error(e_stackunderflow);
+ check_type(ops[op_i], t_integer);
+ offsets->local_subrs_off = ops[op_i].value.intval;
+ continue;
+ case 20: /* defaultWidthX 20 number 0 */
+ control = CONTROL(defaultWidthX, 1, k_privatedict);
+ break;
+ case 21: /* nominalWidthX 21 number 0 */
+ control = CONTROL(nominalWidthX, 1, k_privatedict);
+ break;
+ case 22: case 23: case 24: case 25: case 26: case 27: /* reserved */
+ continue;
+ case 30: { /* float operand */
+ float f;
+
+ if (op_i >= MAXOP)
+ return_error(e_limitcheck);
+ if ((code = get_float(&f, p, pe)) < 0)
+ return code;
+ make_real(&ops[op_i], f);
+ op_i++;
+ p += code;
+ }
+ continue;
+ case 31: case 255: /* reserved */
+ continue;
+ default:
+ { int n; /* int operand */
+
+ if (op_i >= MAXOP)
+ return_error(e_limitcheck);
+ if ((code = get_int(&n, p - 1, pe)) < 0)
+ return code;
+ make_int(&ops[op_i], n);
+ op_i++;
+ p += code - 1;
+ }
+ continue;
+ }
+ {
+ unsigned int n_op = control & 255;
+ unsigned int string_id = (control >> 8) & 255;
+ ref arg, *dict;
+
+ if (n_op == 0)
+ n_op = op_i;
+ if (control & k_delta)
+ undelta(ops, op_i);
+ if ((op_i -= n_op) < 0)
+ return_error(e_stackunderflow);
+ if (control & (k_sid | k_int | k_bool))
+ check_type(ops[op_i], t_integer);
+ if (control & k_bool)
+ make_bool(&arg, !!ops[op_i].value.intval);
+ if (control & k_sid) {
+ if ((code = make_string_from_sid(i_ctx_p, &arg, strings, ops[op_i].value.intval)) < 0)
+ return code;
+ }
+ if (control & k_array) {
+ if ((code = ialloc_ref_array(&arg, a_readonly, n_op, "parsecff.array")) < 0)
+ return code;
+ memcpy(arg.value.refs, ops + op_i, n_op*sizeof(ref));
+ }
+ if (control & k_privatedict) {
+ if ((code = find_font_dict(i_ctx_p, topdict, &privatedict, "Private")) < 0)
+ return code;
+ dict = privatedict;
+ } else if (control & k_fontinfodict) {
+ if ((code = find_font_dict(i_ctx_p, topdict, &fontinfodict, "FontInfo")) < 0)
+ return code;
+ dict = fontinfodict;
+ } else
+ dict = topdict;
+ code = idict_put_c_name(i_ctx_p, dict, font_keys[string_id], font_keys_sz[string_id],
+ (control & (k_bool | k_sid | k_array) == 0 ? &ops[op_i] : &arg));
+ if (code < 0)
+ return code;
+ }
+ }
+ done:
+ return 0;
+}
+
+static int
+parse_font(i_ctx_t *i_ctx_p, ref *topdict,
+ const cff_index_t *strings, const ref *global_subrs,
+ const unsigned char * const p_top, const unsigned char * const pe_top,
+ const unsigned char * const p_all, const unsigned char * const pe_all)
+{
+ int code = 0;
+ ref *privatedict = 0, *fontinfodict = 0;
+ cff_index_t local_subrs, charstrings_index;
+ int (*peek_charset_proc)(const unsigned char *p, const unsigned char *pe, unsigned int i);
+ font_offsets_t offsets;
+
+ memset(&offsets, 0, sizeof(offsets)); /* set defaults for charset_off, encoding_off */
+
+ if ((code = parse_dict(i_ctx_p, topdict, &offsets, strings, p_top, pe_top) < 0))
+ return code;
+ if ((code = parse_dict(i_ctx_p, topdict, &offsets, strings,
+ p_all + offsets.private_off,
+ p_all + offsets.private_off + offsets.private_size) < 0))
+ return code;
+ if ((code = parse_index(&local_subrs,
+ (offsets.local_subrs_off ? p_all + offsets.private_off + offsets.local_subrs_off : 0),
+ pe_all)) < 0)
+ return code;
+
+ if ((code = find_font_dict(i_ctx_p, topdict, &privatedict, "Private")) < 0)
+ return code;
+ if ((code = find_font_dict(i_ctx_p, topdict, &fontinfodict, "FontInfo")) < 0)
+ return code;
+ if (local_subrs.count) {
+ ref r;
+
+ if (( code = make_stringarray_from_index(i_ctx_p, &r, &local_subrs)) < 0)
+ return code;
+ if ((code = idict_put_c_name(i_ctx_p, privatedict, STR2MEM("Subrs"), &r)) < 0)
+ return code;
+ }
+ if (global_subrs) {
+ if ((code = idict_put_c_name(i_ctx_p, privatedict, STR2MEM("GlobalSubrs"), global_subrs)) < 0)
+ return code;
+ }
+ if (offsets.charstrings_off <= 0)
+ return_error(e_rangecheck);
+ if ((code = parse_index(&charstrings_index, p_all + offsets.charstrings_off, pe_all)) < 0)
+ return code;
+
+ switch (offsets.charset_off) {
+ case 0:
+ peek_charset_proc = iso_adobe_charset_proc;
+ break;
+ case 1:
+ peek_charset_proc = expert_charset_proc;
+ break;
+ case 2:
+ peek_charset_proc = expert_subset_charset_proc;
+ break;
+ default:
+ if (p_all + offsets.charstrings_off >= pe_all)
+ return_error(e_rangecheck);
+ switch (p_all[offsets.charstrings_off]) {
+ case 0:
+ peek_charset_proc = format0_charset_proc;
+ break;
+ case 1:
+ peek_charset_proc = format1_charset_proc;
+ break;
+ case 2:
+ peek_charset_proc = format2_charset_proc;
+ break;
+ default:
+ return_error(e_rangecheck);
+ }
+ }
+
+ if (offsets.have_ros) { /* CIDFont */
+ unsigned int i;
+ cff_index_t fdarray;
+ ref fdarray_ref, fdselect_ref;
+ unsigned int fdselect_off = offsets.fdselect_off;
+
+ if (offsets.fdarray_off == 0 || fdselect_off == 0)
+ return_error(e_rangecheck);
+ if ((code = parse_index(&fdarray, p_all + offsets.fdarray_off, pe_all)) < 0)
+ return code;
+ if ((code = ialloc_ref_array(&fdarray_ref, a_readonly, fdarray.count, "parsecff.fdarray")) < 0)
+ return code;
+ if ((code = idict_put_c_name(i_ctx_p, topdict, STR2MEM("FDArray"), &fdarray_ref)) < 0)
+ return code;
+ for (i = 0; i < fdarray.count; i++) {
+ unsigned int len;
+ byte *data;
+ ref *fdprivate, *fdfont = &fdarray_ref.value.refs[i];
+
+ if ((code = peek_index(&data, &len, &fdarray, i)) < 0)
+ return code;
+ if ((code = dict_create(5, fdfont)) < 0)
+ return code;
+ if ((code = parse_dict(i_ctx_p, fdfont, &offsets, strings, data, data + len) < 0))
+ return code;
+ if ((code = set_defaults(i_ctx_p, fdfont, top_font_defaults, count_of(top_font_defaults))) < 0)
+ return code;
+ if ((code = find_font_dict(i_ctx_p, fdfont, &fdprivate, "Private")) < 0)
+ return code;
+ if ((code = set_defaults(i_ctx_p, fdprivate, private_font_defaults, count_of(private_font_defaults))) < 0)
+ return code;
+ }
+ if (p_all + fdselect_off + 1 > pe_all)
+ return_error(e_rangecheck);
+ if (p_all[fdselect_off] != 0 && p_all[fdselect_off] != 3)
+ return_error(e_rangecheck);
+ if ((code = ialloc_ref_array(&fdselect_ref, a_readonly, charstrings_index.count, "parsecff.fdselect")) < 0)
+ return code;
+ if ((code = idict_put_c_name(i_ctx_p, topdict, STR2MEM("FDSelect"), &fdselect_ref)) < 0)
+ return code;
+ if (p_all[fdselect_off] == 0) {
+ if (p_all + fdselect_off + 1 + charstrings_index.count > pe_all)
+ return_error(e_rangecheck);
+ for (i = 0; i < charstrings_index.count; i++)
+ make_int(&fdselect_ref.value.refs[i], p_all[fdselect_off + 1 + i]);
+ } else {
+ unsigned int n_ranges;
+
+ if ((code == card16(&n_ranges, p_all + fdselect_off + 1, pe_all)) < 0)
+ return code;
+ for (i = 0; i < n_ranges; i++) {
+ unsigned int first, last, fd;
+
+ if ((code = card16(&first, p_all + fdselect_off + 3 + 3*i, pe_all)) < 0)
+ return code;
+ if ((code = card8(&fd, p_all + fdselect_off + 5 + 3*i, pe_all)) < 0)
+ return code;
+ if ((code = card16(&last, p_all + fdselect_off + 6 + 3*i, pe_all)) < 0)
+ return code;
+ for ( ; first < last; first++)
+ make_int(&fdselect_ref.value.refs[first], fd);
+ }
+ }
+ if ((code = set_defaults(i_ctx_p, topdict, cid_font_defaults, count_of(cid_font_defaults))) < 0)
+ return code;
+ } else { /* Simple font */
+ unsigned int i, gid, enc_format;
+ int sid;
+ ref name, cstr, charstrings_dict, encoding, notdef;
+ unsigned char gid2char[256];
+ const unsigned char *supp_enc_offset;
+
+ if ((code = name_ref(imemory, (const unsigned char *)".notdef", 7, &notdef, 0)) < 0)
+ return code;
+ if ((code = make_string_from_index(i_ctx_p, &cstr, &charstrings_index, 0)) < 0)
+ return code;
+ if ((code = dict_create(charstrings_index.count, &charstrings_dict)) < 0)
+ return code;
+ if ((code = idict_put_c_name(i_ctx_p, topdict, STR2MEM("CharStrings"), &charstrings_dict)) < 0)
+ return code;
+ if ((code = idict_put(&charstrings_dict, &notdef, &cstr)) < 0)
+ return code;
+ if (offsets.encoding_off <= 1) {
+ if ((code = ialloc_ref_array(&encoding, a_readonly, 256, "cff_parser.encoding")) < 0)
+ return code;
+ for (i = 0; i < 256; i++) {
+ if ((code = make_name_from_sid(i_ctx_p, &encoding.value.refs[i],
+ strings, (offsets.encoding_off ? expert_encoding : standard_encoding)[i])) < 0)
+ return code;
+ }
+ } else {
+ if ((code = ialloc_ref_array(&encoding, a_readonly, 256, "cff_parser.encoding")) < 0)
+ return code;
+ for (i = 0; i < 256; i++)
+ encoding.value.refs[i] = notdef;
+ if ((code = card8(&enc_format, p_all + offsets.encoding_off, pe_all)) < 0)
+ return code;
+ if (enc_format & 0x7f == 0) {
+ unsigned int n_codes;
+
+ if ((code = card8(&n_codes, p_all + offsets.encoding_off + 1, pe_all)) < 0)
+ return code;
+ gid2char[0] = 0;
+ for (i = 1; i <= n_codes; i++) {
+ unsigned int charcode;
+
+ if ((code = card8(&charcode, p_all + offsets.encoding_off + 2 + i, pe_all)) < 0)
+ return code;
+ gid2char[i] = charcode;
+ }
+ memset(gid2char + n_codes + 1, 0, sizeof(gid2char) - n_codes - 1);
+ supp_enc_offset = p_all + offsets.encoding_off + 2 + n_codes;
+ } if (enc_format & 0x7f == 0) {
+ unsigned int n_ranges, first, left, j, k = 1;
+
+ if ((code = card8(&n_ranges, p_all + offsets.encoding_off + 1, pe_all)) < 0)
+ return code;
+ gid2char[0] = 0;
+ for (i = 0; i < n_ranges; i++) {
+ if ((code = card8(&first, p_all + offsets.encoding_off + 2 + 2*i, pe_all)) < 0)
+ return code;
+ if ((code = card8(&left, p_all + offsets.encoding_off + 3 + 2*i, pe_all)) < 0)
+ return code;
+ for (j = 0; j <= left && k < 256; j++)
+ gid2char[k++] = first + j;
+ }
+ memset(gid2char + k, 0, sizeof(gid2char) - k);
+ supp_enc_offset = p_all + offsets.encoding_off + 2*n_ranges + 2;
+ } else
+ return_error(e_rangecheck);
+ }
+ if ((code = idict_put_c_name(i_ctx_p, topdict, STR2MEM("Encoding"), &encoding)) < 0)
+ return code;
+ for (gid = 1; gid < charstrings_index.count; gid++) {
+ if ((code = make_string_from_index(i_ctx_p, &cstr, &charstrings_index, gid)) < 0)
+ return code;
+ sid = (*peek_charset_proc)(p_all + offsets.charstrings_off + 1, pe_all, gid);
+ if (sid < 0)
+ return sid;
+ if ((code = make_name_from_sid(i_ctx_p, &name, strings, sid)) < 0)
+ return code;
+ if ((code = idict_put(&charstrings_dict, &name, &cstr)) < 0)
+ return code;
+ if (offsets.encoding_off > 1 && gid < 256) {
+ if (gid2char[i])
+ encoding.value.refs[gid2char[i]] = name;
+ }
+ }
+ if (offsets.encoding_off & 0x80) {
+ unsigned int n_supp, charcode, sid;
+
+ if ((code = card8(&n_supp, supp_enc_offset, pe_all)) < 0)
+ return code;
+ for (i = 0; i < n_supp; i++) {
+ if ((code = card8(&charcode, supp_enc_offset + 1 + 3*i, pe_all)) < 0)
+ return code;
+ if ((code = card16(&sid, supp_enc_offset + 2 + 3*i, pe_all)) < 0)
+ return code;
+ if ((code = make_name_from_sid(i_ctx_p, &encoding.value.refs[charcode], strings, sid)) < 0)
+ return code;
+ }
+ }
+ }
+ if ((code = set_defaults(i_ctx_p, fontinfodict, fontinfo_font_defaults, count_of(fontinfo_font_defaults))) < 0)
+ return code;
+ if ((code = set_defaults(i_ctx_p, privatedict, private_font_defaults, count_of(private_font_defaults))) < 0)
+ return code;
+ if ((code = set_defaults(i_ctx_p, topdict, top_font_defaults, count_of(top_font_defaults))) < 0)
+ return code;
+
+ return 0;
+}
+
+/* <string> .parsecff <dict> */
+/* Parse CFF font stored in a single string */
+static int
+zparsecff(i_ctx_t *i_ctx_p)
+{
+ os_ptr op = osp;
+ const unsigned char *p;
+ const unsigned char *pe;
+ unsigned int hdr_size, off_size;
+ cff_index_t names, topdicts, strings, gsubrs;
+ int code;
+ unsigned int i_font;
+ ref gsubrs_array, fontset;
+
+ check_read_type(*op, t_string);
+ p = op->value.bytes;
+ pe = p + r_size(op);
+
+ if (p + 4 >= pe)
+ return_error(e_rangecheck); /* No room for the header */
+ if (p[0] != 1)
+ return_error(e_rangecheck); /* Unsupported version. */
+ hdr_size = p[2];
+ off_size = p[3];
+
+ if ((code = parse_index(&names, p + hdr_size, pe)) < 0)
+ return code;
+ if ((code = parse_index(&topdicts, names.end, pe)) < 0)
+ return code;
+ if ((code = parse_index(&strings, topdicts.end, pe)) < 0)
+ return code;
+ if ((code = parse_index(&gsubrs, strings.end, pe)) < 0)
+ return code;
+ if (gsubrs.count) {
+ if (( code = make_stringarray_from_index(i_ctx_p, &gsubrs_array, &gsubrs)) < 0)
+ return code;
+ }
+ if (names.count >= 65535)
+ return_error(e_limitcheck);
+ if ((code = dict_create(names.count, &fontset)) < 0)
+ return code;
+
+ for (i_font = 0; i_font < names.count; i_font++) {
+ const unsigned char *name_data;
+ unsigned int name_len;
+ ref name;
+ const unsigned char *topdict_data;
+ unsigned int topdict_len;
+ ref topdict;
+
+ if ((code = peek_index(&name_data, &name_len, &names, i_font)) < 0)
+ return code;
+ if (name_len == 0 || *name_data == 0) /* deleted entry */
+ continue;
+ if ((code = name_ref(imemory, name_data, name_len, &name, 1)) < 0)
+ return code;
+ if ((code = peek_index(&topdict_data, &topdict_len, &topdicts, i_font)) < 0)
+ return code;
+
+ if ((code = dict_create(20, &topdict)) < 0)
+ return code;
+
+ if ((code = idict_put(&fontset, &name, &topdict)) < 0)
+ return code;
+
+ if ((code = parse_font(i_ctx_p, &topdict, &strings, (gsubrs.count ? &gsubrs_array : 0),
+ topdict_data, topdict_data + topdict_len, p, pe)) < 0)
+ return code;
+ }
+ ref_assign(op, &fontset);
+ return 0;
+}
+
/* ------ Initialization procedure ------ */

const op_def zfont2_op_defs[] =
{
{"2.buildfont2", zbuildfont2},
+ {"1.parsecff", zparsecff},
op_def_end(0)
};

Loading...