From 8e0f3683f461a099dbeb3c9487ff365e9b552bb4 Mon Sep 17 00:00:00 2001 From: kramm Date: Fri, 17 Sep 2004 16:56:43 +0000 Subject: [PATCH] *** empty log message *** --- pdf2swf/xpdf/CompactFontTables.h | 464 ----- pdf2swf/xpdf/DisplayFontTable.h | 29 - pdf2swf/xpdf/FontFile.cc | 3681 -------------------------------------- pdf2swf/xpdf/FontFile.h | 215 --- 4 files changed, 4389 deletions(-) delete mode 100644 pdf2swf/xpdf/CompactFontTables.h delete mode 100644 pdf2swf/xpdf/DisplayFontTable.h delete mode 100644 pdf2swf/xpdf/FontFile.cc delete mode 100644 pdf2swf/xpdf/FontFile.h diff --git a/pdf2swf/xpdf/CompactFontTables.h b/pdf2swf/xpdf/CompactFontTables.h deleted file mode 100644 index 62d6f5a..0000000 --- a/pdf2swf/xpdf/CompactFontTables.h +++ /dev/null @@ -1,464 +0,0 @@ -//======================================================================== -// -// CompactFontTables.h -// -// Copyright 1999-2002 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef COMPACTFONTINFO_H -#define COMPACTFONTINFO_H - -static char *type1CStdStrings[391] = { - ".notdef", - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quoteright", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "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", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "quoteleft", - "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", - "braceleft", - "bar", - "braceright", - "asciitilde", - "exclamdown", - "cent", - "sterling", - "fraction", - "yen", - "florin", - "section", - "currency", - "quotesingle", - "quotedblleft", - "guillemotleft", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - "endash", - "dagger", - "daggerdbl", - "periodcentered", - "paragraph", - "bullet", - "quotesinglbase", - "quotedblbase", - "quotedblright", - "guillemotright", - "ellipsis", - "perthousand", - "questiondown", - "grave", - "acute", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "dieresis", - "ring", - "cedilla", - "hungarumlaut", - "ogonek", - "caron", - "emdash", - "AE", - "ordfeminine", - "Lslash", - "Oslash", - "OE", - "ordmasculine", - "ae", - "dotlessi", - "lslash", - "oslash", - "oe", - "germandbls", - "onesuperior", - "logicalnot", - "mu", - "trademark", - "Eth", - "onehalf", - "plusminus", - "Thorn", - "onequarter", - "divide", - "brokenbar", - "degree", - "thorn", - "threequarters", - "twosuperior", - "registered", - "minus", - "eth", - "multiply", - "threesuperior", - "copyright", - "Aacute", - "Acircumflex", - "Adieresis", - "Agrave", - "Aring", - "Atilde", - "Ccedilla", - "Eacute", - "Ecircumflex", - "Edieresis", - "Egrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Igrave", - "Ntilde", - "Oacute", - "Ocircumflex", - "Odieresis", - "Ograve", - "Otilde", - "Scaron", - "Uacute", - "Ucircumflex", - "Udieresis", - "Ugrave", - "Yacute", - "Ydieresis", - "Zcaron", - "aacute", - "acircumflex", - "adieresis", - "agrave", - "aring", - "atilde", - "ccedilla", - "eacute", - "ecircumflex", - "edieresis", - "egrave", - "iacute", - "icircumflex", - "idieresis", - "igrave", - "ntilde", - "oacute", - "ocircumflex", - "odieresis", - "ograve", - "otilde", - "scaron", - "uacute", - "ucircumflex", - "udieresis", - "ugrave", - "yacute", - "ydieresis", - "zcaron", - "exclamsmall", - "Hungarumlautsmall", - "dollaroldstyle", - "dollarsuperior", - "ampersandsmall", - "Acutesmall", - "parenleftsuperior", - "parenrightsuperior", - "twodotenleader", - "onedotenleader", - "zerooldstyle", - "oneoldstyle", - "twooldstyle", - "threeoldstyle", - "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", - "sevenoldstyle", - "eightoldstyle", - "nineoldstyle", - "commasuperior", - "threequartersemdash", - "periodsuperior", - "questionsmall", - "asuperior", - "bsuperior", - "centsuperior", - "dsuperior", - "esuperior", - "isuperior", - "lsuperior", - "msuperior", - "nsuperior", - "osuperior", - "rsuperior", - "ssuperior", - "tsuperior", - "ff", - "ffi", - "ffl", - "parenleftinferior", - "parenrightinferior", - "Circumflexsmall", - "hyphensuperior", - "Gravesmall", - "Asmall", - "Bsmall", - "Csmall", - "Dsmall", - "Esmall", - "Fsmall", - "Gsmall", - "Hsmall", - "Ismall", - "Jsmall", - "Ksmall", - "Lsmall", - "Msmall", - "Nsmall", - "Osmall", - "Psmall", - "Qsmall", - "Rsmall", - "Ssmall", - "Tsmall", - "Usmall", - "Vsmall", - "Wsmall", - "Xsmall", - "Ysmall", - "Zsmall", - "colonmonetary", - "onefitted", - "rupiah", - "Tildesmall", - "exclamdownsmall", - "centoldstyle", - "Lslashsmall", - "Scaronsmall", - "Zcaronsmall", - "Dieresissmall", - "Brevesmall", - "Caronsmall", - "Dotaccentsmall", - "Macronsmall", - "figuredash", - "hypheninferior", - "Ogoneksmall", - "Ringsmall", - "Cedillasmall", - "questiondownsmall", - "oneeighth", - "threeeighths", - "fiveeighths", - "seveneighths", - "onethird", - "twothirds", - "zerosuperior", - "foursuperior", - "fivesuperior", - "sixsuperior", - "sevensuperior", - "eightsuperior", - "ninesuperior", - "zeroinferior", - "oneinferior", - "twoinferior", - "threeinferior", - "fourinferior", - "fiveinferior", - "sixinferior", - "seveninferior", - "eightinferior", - "nineinferior", - "centinferior", - "dollarinferior", - "periodinferior", - "commainferior", - "Agravesmall", - "Aacutesmall", - "Acircumflexsmall", - "Atildesmall", - "Adieresissmall", - "Aringsmall", - "AEsmall", - "Ccedillasmall", - "Egravesmall", - "Eacutesmall", - "Ecircumflexsmall", - "Edieresissmall", - "Igravesmall", - "Iacutesmall", - "Icircumflexsmall", - "Idieresissmall", - "Ethsmall", - "Ntildesmall", - "Ogravesmall", - "Oacutesmall", - "Ocircumflexsmall", - "Otildesmall", - "Odieresissmall", - "OEsmall", - "Oslashsmall", - "Ugravesmall", - "Uacutesmall", - "Ucircumflexsmall", - "Udieresissmall", - "Yacutesmall", - "Thornsmall", - "Ydieresissmall", - "001.000", - "001.001", - "001.002", - "001.003", - "Black", - "Bold", - "Book", - "Light", - "Medium", - "Regular", - "Roman", - "Semibold" -}; - -static Gushort type1CISOAdobeCharset[229] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228 -}; - -static Gushort type1CExpertCharset[166] = { - 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, - 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, - 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378 -}; - -static Gushort type1CExpertSubsetCharset[87] = { - 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, - 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 27, 28, 249, 250, 251, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 109, 110, 267, 268, 269, 270, 272, 300, 301, - 302, 305, 314, 315, 158, 155, 163, 320, 321, 322, - 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, - 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346 -}; - -#endif diff --git a/pdf2swf/xpdf/DisplayFontTable.h b/pdf2swf/xpdf/DisplayFontTable.h deleted file mode 100644 index 4606031..0000000 --- a/pdf2swf/xpdf/DisplayFontTable.h +++ /dev/null @@ -1,29 +0,0 @@ -//======================================================================== -// -// DisplayFontTable.h -// -// Copyright 2001-2002 Glyph & Cog, LLC -// -//======================================================================== - -static struct { - char *name; - char *xlfd; - char *encoding; -} displayFontTab[] = { - {"Courier", "-*-courier-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Courier-Bold", "-*-courier-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Courier-BoldOblique", "-*-courier-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Courier-Oblique", "-*-courier-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Helvetica", "-*-helvetica-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Helvetica-Bold", "-*-helvetica-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Helvetica-BoldOblique", "-*-helvetica-bold-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Helvetica-Oblique", "-*-helvetica-medium-o-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Symbol", "-*-symbol-medium-r-normal-*-%s-*-*-*-*-*-adobe-fontspecific", "Symbol"}, - {"Times-Bold", "-*-times-bold-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Times-BoldItalic", "-*-times-bold-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Times-Italic", "-*-times-medium-i-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"Times-Roman", "-*-times-medium-r-normal-*-%s-*-*-*-*-*-iso8859-1", "Latin1"}, - {"ZapfDingbats", "-*-zapfdingbats-medium-r-normal-*-%s-*-*-*-*-*-*-*", "ZapfDingbats"}, - {NULL} -}; diff --git a/pdf2swf/xpdf/FontFile.cc b/pdf2swf/xpdf/FontFile.cc deleted file mode 100644 index ae58547..0000000 --- a/pdf2swf/xpdf/FontFile.cc +++ /dev/null @@ -1,3681 +0,0 @@ -//======================================================================== -// -// FontFile.cc -// -// Copyright 1999-2002 Glyph & Cog, LLC -// -//======================================================================== - -#ifdef __GNUC__ -#pragma implementation -#endif - -#include -#include -#include -#include -#include -#include -#include "gmem.h" -#include "Error.h" -#include "GlobalParams.h" -#include "CharCodeToUnicode.h" -#include "FontEncodingTables.h" -#include "FontFile.h" - -#include "CompactFontTables.h" - -//------------------------------------------------------------------------ - -static inline char *nextLine(char *line, char *end) { - while (line < end && *line != '\n' && *line != '\r') - ++line; - while (line < end && *line == '\n' || *line == '\r') - ++line; - return line; -} - -static char hexChars[17] = "0123456789ABCDEF"; - -//------------------------------------------------------------------------ -// FontFile -//------------------------------------------------------------------------ - -FontFile::FontFile() { -} - -FontFile::~FontFile() { -} - -//------------------------------------------------------------------------ -// Type1FontFile -//------------------------------------------------------------------------ - -Type1FontFile::Type1FontFile(char *file, int len) { - char *line, *line1, *p, *p2; - GBool haveEncoding; - char buf[256]; - char c; - int n, code, i, j; - - name = NULL; - encoding = (char **)gmalloc(256 * sizeof(char *)); - for (i = 0; i < 256; ++i) { - encoding[i] = NULL; - } - haveEncoding = gFalse; - - for (i = 1, line = file; - i <= 100 && line < file + len && !haveEncoding; - ++i) { - - // get font name - if (!strncmp(line, "/FontName", 9)) { - strncpy(buf, line, 255); - buf[255] = '\0'; - if ((p = strchr(buf+9, '/')) && - (p = strtok(p+1, " \t\n\r"))) { - name = copyString(p); - } - line = nextLine(line, file + len); - - // get encoding - } else if (!strncmp(line, "/Encoding StandardEncoding def", 30)) { - for (j = 0; j < 256; ++j) { - if (standardEncoding[j]) { - encoding[j] = copyString(standardEncoding[j]); - } - } - haveEncoding = gTrue; - } else if (!strncmp(line, "/Encoding 256 array", 19)) { - for (j = 0; j < 300; ++j) { - line1 = nextLine(line, file + len); - if ((n = line1 - line) > 255) { - n = 255; - } - strncpy(buf, line, n); - buf[n] = '\0'; - for (p = buf; *p == ' ' || *p == '\t'; ++p) ; - if (!strncmp(p, "dup", 3)) { - for (p += 3; *p == ' ' || *p == '\t'; ++p) ; - for (p2 = p; *p2 >= '0' && *p2 <= '9'; ++p2) ; - if (*p2) { - c = *p2; - *p2 = '\0'; - if ((code = atoi(p)) < 256) { - *p2 = c; - for (p = p2; *p == ' ' || *p == '\t'; ++p) ; - if (*p == '/') { - ++p; - for (p2 = p; *p2 && *p2 != ' ' && *p2 != '\t'; ++p2) ; - *p2 = '\0'; - encoding[code] = copyString(p); - } - } - } - } else { - if (strtok(buf, " \t") && - (p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) { - break; - } - } - line = line1; - } - //~ check for getinterval/putinterval junk - haveEncoding = gTrue; - - } else { - line = nextLine(line, file + len); - } - } -} - -Type1FontFile::~Type1FontFile() { - int i; - - if (name) { - gfree(name); - } - for (i = 0; i < 256; ++i) { - gfree(encoding[i]); - } - gfree(encoding); -} - -//------------------------------------------------------------------------ -// Type1CFontFile -//------------------------------------------------------------------------ - -struct Type1CTopDict { - int version; - int notice; - int copyright; - int fullName; - int familyName; - int weight; - int isFixedPitch; - double italicAngle; - double underlinePosition; - double underlineThickness; - int paintType; - int charstringType; - double fontMatrix[6]; - int uniqueID; - double fontBBox[4]; - double strokeWidth; - int charset; - int encoding; - int charStrings; - int privateSize; - int privateOffset; - - //----- CIDFont entries - int registry; - int ordering; - int supplement; - int fdArrayOffset; - int fdSelectOffset; -}; - -struct Type1CPrivateDict { - GString *dictData; - int subrsOffset; - double defaultWidthX; - GBool defaultWidthXFP; - double nominalWidthX; - GBool nominalWidthXFP; -}; - -Type1CFontFile::Type1CFontFile(char *fileA, int lenA) { - Guchar *nameIdxPtr, *idxPtr0, *idxPtr1; - - file = fileA; - len = lenA; - name = NULL; - encoding = NULL; - - // some tools embed Type 1C fonts with an extra whitespace char at - // the beginning - if (file[0] != '\x01') { - ++file; - } - - // read header - topOffSize = file[3] & 0xff; - - // read name index (first font only) - nameIdxPtr = (Guchar *)file + (file[2] & 0xff); - idxPtr0 = getIndexValPtr(nameIdxPtr, 0); - idxPtr1 = getIndexValPtr(nameIdxPtr, 1); - name = new GString((char *)idxPtr0, idxPtr1 - idxPtr0); - - topDictIdxPtr = getIndexEnd(nameIdxPtr); - stringIdxPtr = getIndexEnd(topDictIdxPtr); - gsubrIdxPtr = getIndexEnd(stringIdxPtr); -} - -Type1CFontFile::~Type1CFontFile() { - int i; - - delete name; - if (encoding) { - for (i = 0; i < 256; ++i) { - gfree(encoding[i]); - } - gfree(encoding); - } -} - -char *Type1CFontFile::getName() { - return name->getCString(); -} - -char **Type1CFontFile::getEncoding() { - if (!encoding) { - readNameAndEncoding(); - } - return encoding; -} - -void Type1CFontFile::readNameAndEncoding() { - char buf[256]; - Guchar *idxPtr0, *idxPtr1, *ptr; - int nGlyphs; - int nCodes, nRanges, nLeft, nSups; - Gushort *glyphNames; - int charset, enc, charstrings; - int encFormat; - int c, sid; - double x; - GBool isFP; - int key; - int i, j; - - encoding = (char **)gmalloc(256 * sizeof(char *)); - for (i = 0; i < 256; ++i) { - encoding[i] = NULL; - } - - // read top dict (first font only) - idxPtr0 = getIndexValPtr(topDictIdxPtr, 0); - idxPtr1 = getIndexValPtr(topDictIdxPtr, 1); - charset = enc = charstrings = 0; - i = 0; - ptr = idxPtr0; - while (ptr < idxPtr1) { - if (*ptr <= 27 || *ptr == 31) { - key = *ptr++; - if (key == 0x0c) { - key = (key << 8) | *ptr++; - } - if (key == 0x0f) { // charset - charset = (int)op[0]; - } else if (key == 0x10) { // encoding - enc = (int)op[0]; - } else if (key == 0x11) { // charstrings - charstrings = (int)op[0]; - } - i = 0; - } else { - x = getNum(&ptr, &isFP); - if (i < 48) { - op[i++] = x; - } - } - } - - // get number of glyphs from charstrings index - nGlyphs = getIndexLen((Guchar *)file + charstrings); - - // read charset (GID -> name mapping) - glyphNames = readCharset(charset, nGlyphs); - - // read encoding (GID -> code mapping) - if (enc == 0) { - for (i = 0; i < 256; ++i) { - if (standardEncoding[i]) { - encoding[i] = copyString(standardEncoding[i]); - } - } - } else if (enc == 1) { - for (i = 0; i < 256; ++i) { - if (expertEncoding[i]) { - encoding[i] = copyString(expertEncoding[i]); - } - } - } else { - ptr = (Guchar *)file + enc; - encFormat = *ptr++; - if ((encFormat & 0x7f) == 0) { - nCodes = 1 + *ptr++; - if (nCodes > nGlyphs) { - nCodes = nGlyphs; - } - for (i = 1; i < nCodes; ++i) { - c = *ptr++; - encoding[c] = copyString(getString(glyphNames[i], buf)); - } - } else if ((encFormat & 0x7f) == 1) { - nRanges = *ptr++; - nCodes = 1; - for (i = 0; i < nRanges; ++i) { - c = *ptr++; - nLeft = *ptr++; - for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) { - encoding[c] = copyString(getString(glyphNames[nCodes], buf)); - ++nCodes; - ++c; - } - } - } - if (encFormat & 0x80) { - nSups = *ptr++; - for (i = 0; i < nSups; ++i) { - c = *ptr++; - sid = getWord(ptr, 2); - ptr += 2; - encoding[c] = copyString(getString(sid, buf)); - } - } - } - - if (charset > 2) { - gfree(glyphNames); - } -} - -void Type1CFontFile::convertToType1(FILE *outA) { - Type1CTopDict dict; - Type1CPrivateDict privateDict; - char buf[256], eBuf[256]; - Guchar *idxPtr0, *idxPtr1, *subrsIdxPtr, *charStringsIdxPtr, *ptr; - int nGlyphs, nCodes, nRanges, nLeft, nSups; - Gushort *glyphNames; - int encFormat, nSubrs, nCharStrings; - int c, sid; - int i, j, n; - - out = outA; - - // read top dict (first font only) - readTopDict(&dict); - - // get global subrs - //~ ... global subrs are unimplemented - - // write header and font dictionary, up to encoding - fprintf(out, "%%!FontType1-1.0: %s", name->getCString()); - if (dict.version != 0) { - fprintf(out, "%s", getString(dict.version, buf)); - } - fprintf(out, "\n"); - fprintf(out, "11 dict begin\n"); - fprintf(out, "/FontInfo 10 dict dup begin\n"); - if (dict.version != 0) { - fprintf(out, "/version (%s) readonly def\n", - getString(dict.version, buf)); - } - if (dict.notice != 0) { - fprintf(out, "/Notice (%s) readonly def\n", - getString(dict.notice, buf)); - } - if (dict.copyright != 0) { - fprintf(out, "/Copyright (%s) readonly def\n", - getString(dict.copyright, buf)); - } - if (dict.fullName != 0) { - fprintf(out, "/FullName (%s) readonly def\n", - getString(dict.fullName, buf)); - } - if (dict.familyName != 0) { - fprintf(out, "/FamilyName (%s) readonly def\n", - getString(dict.familyName, buf)); - } - if (dict.weight != 0) { - fprintf(out, "/Weight (%s) readonly def\n", - getString(dict.weight, buf)); - } - fprintf(out, "/isFixedPitch %s def\n", dict.isFixedPitch ? "true" : "false"); - fprintf(out, "/ItalicAngle %g def\n", dict.italicAngle); - fprintf(out, "/UnderlinePosition %g def\n", dict.underlinePosition); - fprintf(out, "/UnderlineThickness %g def\n", dict.underlineThickness); - fprintf(out, "end readonly def\n"); - fprintf(out, "/FontName /%s def\n", name->getCString()); - fprintf(out, "/PaintType %d def\n", dict.paintType); - fprintf(out, "/FontType 1 def\n"); - fprintf(out, "/FontMatrix [%g %g %g %g %g %g] readonly def\n", - dict.fontMatrix[0], dict.fontMatrix[1], dict.fontMatrix[2], - dict.fontMatrix[3], dict.fontMatrix[4], dict.fontMatrix[5]); - fprintf(out, "/FontBBox [%g %g %g %g] readonly def\n", - dict.fontBBox[0], dict.fontBBox[1], - dict.fontBBox[2], dict.fontBBox[3]); - fprintf(out, "/StrokeWidth %g def\n", dict.strokeWidth); - if (dict.uniqueID != 0) { - fprintf(out, "/UniqueID %d def\n", dict.uniqueID); - } - - // get number of glyphs from charstrings index - nGlyphs = getIndexLen((Guchar *)file + dict.charStrings); - - // read charset - glyphNames = readCharset(dict.charset, nGlyphs); - - // read encoding (glyph -> code mapping), write Type 1 encoding - fprintf(out, "/Encoding "); - if (dict.encoding == 0) { - fprintf(out, "StandardEncoding def\n"); - } else { - fprintf(out, "256 array\n"); - fprintf(out, "0 1 255 {1 index exch /.notdef put} for\n"); - if (dict.encoding == 1) { - for (i = 0; i < 256; ++i) { - if (expertEncoding[i]) { - fprintf(out, "dup %d /%s put\n", i, expertEncoding[i]); - } - } - } else { - ptr = (Guchar *)file + dict.encoding; - encFormat = *ptr++; - if ((encFormat & 0x7f) == 0) { - nCodes = 1 + *ptr++; - if (nCodes > nGlyphs) { - nCodes = nGlyphs; - } - for (i = 1; i < nCodes; ++i) { - c = *ptr++; - fprintf(out, "dup %d /%s put\n", - c, getString(glyphNames[i], buf)); - } - } else if ((encFormat & 0x7f) == 1) { - nRanges = *ptr++; - nCodes = 1; - for (i = 0; i < nRanges; ++i) { - c = *ptr++; - nLeft = *ptr++; - for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) { - fprintf(out, "dup %d /%s put\n", - c, getString(glyphNames[nCodes], buf)); - ++nCodes; - ++c; - } - } - } - if (encFormat & 0x80) { - nSups = *ptr++; - for (i = 0; i < nSups; ++i) { - c = *ptr++; - sid = getWord(ptr, 2); - ptr += 2; - fprintf(out, "dup %d /%s put\n", c, getString(sid, buf)); - } - } - } - fprintf(out, "readonly def\n"); - } - fprintf(out, "currentdict end\n"); - - // start the binary section - fprintf(out, "currentfile eexec\n"); - r1 = 55665; - line = 0; - - // get private dictionary - eexecWrite("\x83\xca\x73\xd5"); - eexecWrite("dup /Private 32 dict dup begin\n"); - eexecWrite("/RD {string currentfile exch readstring pop} executeonly def\n"); - eexecWrite("/ND {noaccess def} executeonly def\n"); - eexecWrite("/NP {noaccess put} executeonly def\n"); - eexecWrite("/MinFeature {16 16} ND\n"); - readPrivateDict(&privateDict, dict.privateOffset, dict.privateSize); - eexecWrite(privateDict.dictData->getCString()); - defaultWidthX = privateDict.defaultWidthX; - defaultWidthXFP = privateDict.defaultWidthXFP; - nominalWidthX = privateDict.nominalWidthX; - nominalWidthXFP = privateDict.nominalWidthXFP; - - // get subrs - if (privateDict.subrsOffset != 0) { - subrsIdxPtr = (Guchar *)file + dict.privateOffset + - privateDict.subrsOffset; - nSubrs = getIndexLen(subrsIdxPtr); - sprintf(eBuf, "/Subrs %d array\n", nSubrs); - eexecWrite(eBuf); - idxPtr1 = getIndexValPtr(subrsIdxPtr, 0); - for (i = 0; i < nSubrs; ++i) { - idxPtr0 = idxPtr1; - idxPtr1 = getIndexValPtr(subrsIdxPtr, i+1); - n = idxPtr1 - idxPtr0; -#if 1 //~ Type 2 subrs are unimplemented - error(-1, "Unimplemented Type 2 subrs"); -#else - sprintf(eBuf, "dup %d %d RD ", i, n); - eexecWrite(eBuf); - eexecCvtGlyph(idxPtr0, n); - eexecWrite(" NP\n"); -#endif - } - eexecWrite("ND\n"); - } - - // get CharStrings - charStringsIdxPtr = (Guchar *)file + dict.charStrings; - nCharStrings = getIndexLen(charStringsIdxPtr); - sprintf(eBuf, "2 index /CharStrings %d dict dup begin\n", nCharStrings); - eexecWrite(eBuf); - idxPtr1 = getIndexValPtr(charStringsIdxPtr, 0); - for (i = 0; i < nCharStrings; ++i) { - idxPtr0 = idxPtr1; - idxPtr1 = getIndexValPtr(charStringsIdxPtr, i+1); - n = idxPtr1 - idxPtr0; - eexecCvtGlyph(getString(glyphNames[i], buf), idxPtr0, n); - } - eexecWrite("end\n"); - eexecWrite("end\n"); - eexecWrite("readonly put\n"); - eexecWrite("noaccess put\n"); - eexecWrite("dup /FontName get exch definefont pop\n"); - eexecWrite("mark currentfile closefile\n"); - - // trailer - if (line > 0) { - fputc('\n', out); - } - for (i = 0; i < 8; ++i) { - fprintf(out, "0000000000000000000000000000000000000000000000000000000000000000\n"); - } - fprintf(out, "cleartomark\n"); - - // clean up - delete privateDict.dictData; - if (dict.charset > 2) { - gfree(glyphNames); - } -} - -void Type1CFontFile::convertToCIDType0(char *psName, FILE *outA) { - Type1CTopDict dict; - Type1CPrivateDict *privateDicts; - GString *charStrings; - int *charStringOffsets; - Gushort *charset; - int *cidMap; - Guchar *fdSelect; - Guchar *charStringsIdxPtr, *fdArrayIdx, *idxPtr0, *idxPtr1, *ptr; - char buf[256]; - int nGlyphs, nCIDs, gdBytes, nFDs; - int fdSelectFmt, nRanges, gid0, gid1, fd, offset; - int key; - double x; - GBool isFP; - int i, j, k, n; - - out = outA; - - fprintf(out, "/CIDInit /ProcSet findresource begin\n"); - - // read top dict (first font only) - readTopDict(&dict); - - // read the FDArray dictionaries and Private dictionaries - if (dict.fdArrayOffset == 0) { - nFDs = 1; - privateDicts = (Type1CPrivateDict *) - gmalloc(nFDs * sizeof(Type1CPrivateDict)); - privateDicts[0].dictData = new GString(); - privateDicts[0].subrsOffset = 0; - privateDicts[0].defaultWidthX = 0; - privateDicts[0].defaultWidthXFP = gFalse; - privateDicts[0].nominalWidthX = 0; - privateDicts[0].nominalWidthXFP = gFalse; - } else { - fdArrayIdx = (Guchar *)file + dict.fdArrayOffset; - nFDs = getIndexLen(fdArrayIdx); - privateDicts = (Type1CPrivateDict *) - gmalloc(nFDs * sizeof(Type1CPrivateDict)); - idxPtr1 = getIndexValPtr(fdArrayIdx, 0); - for (i = 0; i < nFDs; ++i) { - privateDicts[i].dictData = NULL; - idxPtr0 = idxPtr1; - idxPtr1 = getIndexValPtr(fdArrayIdx, i + 1); - ptr = idxPtr0; - j = 0; - while (ptr < idxPtr1) { - if (*ptr <= 27 || *ptr == 31) { - key = *ptr++; - if (key == 0x0c) { - key = (key << 8) | *ptr++; - } - if (key == 0x0012) { - readPrivateDict(&privateDicts[i], (int)op[1], (int)op[0]); - } - j = 0; - } else { - x = getNum(&ptr, &isFP); - if (j < 48) { - op[j] = x; - fp[j++] = isFP; - } - } - } - if (!privateDicts[i].dictData) { - privateDicts[i].dictData = new GString(); - privateDicts[i].subrsOffset = 0; - privateDicts[i].defaultWidthX = 0; - privateDicts[i].defaultWidthXFP = gFalse; - privateDicts[i].nominalWidthX = 0; - privateDicts[i].nominalWidthXFP = gFalse; - } - } - } - - // get the glyph count - charStringsIdxPtr = (Guchar *)file + dict.charStrings; - nGlyphs = getIndexLen(charStringsIdxPtr); - - // read the FDSelect table - fdSelect = (Guchar *)gmalloc(nGlyphs); - if (dict.fdSelectOffset == 0) { - for (i = 0; i < nGlyphs; ++i) { - fdSelect[i] = 0; - } - } else { - ptr = (Guchar *)file + dict.fdSelectOffset; - fdSelectFmt = *ptr++; - if (fdSelectFmt == 0) { - memcpy(fdSelect, ptr, nGlyphs); - } else if (fdSelectFmt == 3) { - nRanges = getWord(ptr, 2); - ptr += 2; - gid0 = getWord(ptr, 2); - ptr += 2; - for (i = 1; i <= nRanges; ++i) { - fd = *ptr++; - gid1 = getWord(ptr, 2); - ptr += 2; - for (j = gid0; j < gid1; ++j) { - fdSelect[j] = fd; - } - gid0 = gid1; - } - } else { - error(-1, "Unknown FDSelect table format in CID font"); - for (i = 0; i < nGlyphs; ++i) { - fdSelect[i] = 0; - } - } - } - - // read the charset, compute the CID-to-GID mapping - charset = readCharset(dict.charset, nGlyphs); - nCIDs = 0; - for (i = 0; i < nGlyphs; ++i) { - if (charset[i] >= nCIDs) { - nCIDs = charset[i] + 1; - } - } - cidMap = (int *)gmalloc(nCIDs * sizeof(int)); - for (i = 0; i < nCIDs; ++i) { - cidMap[i] = -1; - } - for (i = 0; i < nGlyphs; ++i) { - cidMap[charset[i]] = i; - } - - // build the charstrings - charStrings = new GString(); - charStringOffsets = (int *)gmalloc((nCIDs + 1) * sizeof(int)); - for (i = 0; i < nCIDs; ++i) { - charStringOffsets[i] = charStrings->getLength(); - if (cidMap[i] >= 0) { - idxPtr0 = getIndexValPtr(charStringsIdxPtr, cidMap[i]); - idxPtr1 = getIndexValPtr(charStringsIdxPtr, cidMap[i]+1); - n = idxPtr1 - idxPtr0; - j = fdSelect[cidMap[i]]; - defaultWidthX = privateDicts[j].defaultWidthX; - defaultWidthXFP = privateDicts[j].defaultWidthXFP; - nominalWidthX = privateDicts[j].nominalWidthX; - nominalWidthXFP = privateDicts[j].nominalWidthXFP; - cvtGlyph(idxPtr0, n); - charStrings->append(charBuf); - delete charBuf; - } - } - charStringOffsets[nCIDs] = charStrings->getLength(); - - // compute gdBytes = number of bytes needed for charstring offsets - // (offset size needs to account for the charstring offset table, - // with a worst case of five bytes per entry, plus the charstrings - // themselves) - i = (nCIDs + 1) * 5 + charStrings->getLength(); - if (i < 0x100) { - gdBytes = 1; - } else if (i < 0x10000) { - gdBytes = 2; - } else if (i < 0x1000000) { - gdBytes = 3; - } else { - gdBytes = 4; - } - - // begin the font dictionary - fprintf(out, "20 dict begin\n"); - fprintf(out, "/CIDFontName /%s def\n", psName); - fprintf(out, "/CIDFontType 0 def\n"); - fprintf(out, "/CIDSystemInfo 3 dict dup begin\n"); - if (dict.registry > 0 && dict.ordering > 0) { - fprintf(out, " /Registry (%s) def\n", getString(dict.registry, buf)); - fprintf(out, " /Ordering (%s) def\n", getString(dict.ordering, buf)); - } else { - fprintf(out, " /Registry (Adobe) def\n"); - fprintf(out, " /Ordering (Identity) def\n"); - } - fprintf(out, " /Supplement %d def\n", dict.supplement); - fprintf(out, "end def\n"); - fprintf(out, "/FontMatrix [%g %g %g %g %g %g] def\n", - dict.fontMatrix[0], dict.fontMatrix[1], dict.fontMatrix[2], - dict.fontMatrix[3], dict.fontMatrix[4], dict.fontMatrix[5]); - fprintf(out, "/FontBBox [%g %g %g %g] def\n", - dict.fontBBox[0], dict.fontBBox[1], - dict.fontBBox[2], dict.fontBBox[3]); - fprintf(out, "/FontInfo 1 dict dup begin\n"); - fprintf(out, " /FSType 8 def\n"); - fprintf(out, "end def\n"); - - // CIDFont-specific entries - fprintf(out, "/CIDCount %d def\n", nCIDs); - fprintf(out, "/FDBytes 1 def\n"); - fprintf(out, "/GDBytes %d def\n", gdBytes); - fprintf(out, "/CIDMapOffset 0 def\n"); - if (dict.paintType != 0) { - fprintf(out, "/PaintType %d def\n", dict.paintType); - fprintf(out, "/StrokeWidth %g def\n", dict.strokeWidth); - } - - // FDArray entry - fprintf(out, "/FDArray %d array\n", nFDs); - for (i = 0; i < nFDs; ++i) { - fprintf(out, "dup %d 10 dict begin\n", i); - fprintf(out, "/FontType 1 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/PaintType %d def\n", dict.paintType); - fprintf(out, "/Private 32 dict begin\n"); - fwrite(privateDicts[i].dictData->getCString(), 1, - privateDicts[i].dictData->getLength(), out); - fprintf(out, "currentdict end def\n"); - fprintf(out, "currentdict end put\n"); - } - fprintf(out, "def\n"); - - //~ need to deal with subrs - - // start the binary section - offset = (nCIDs + 1) * (1 + gdBytes); - fprintf(out, "(Hex) %d StartData\n", - offset + charStrings->getLength()); - - // write the charstring offset (CIDMap) table - for (i = 0; i <= nCIDs; i += 6) { - for (j = 0; j < 6 && i+j <= nCIDs; ++j) { - if (cidMap[i+j] >= 0) { - buf[0] = (char)fdSelect[cidMap[i+j]]; - } else { - buf[0] = (char)0; - } - n = offset + charStringOffsets[i+j]; - for (k = gdBytes; k >= 1; --k) { - buf[k] = (char)(n & 0xff); - n >>= 8; - } - for (k = 0; k <= gdBytes; ++k) { - fprintf(out, "%02x", buf[k] & 0xff); - } - } - fputc('\n', out); - } - - // write the charstring data - n = charStrings->getLength(); - for (i = 0; i < n; i += 32) { - for (j = 0; j < 32 && i+j < n; ++j) { - fprintf(out, "%02x", charStrings->getChar(i+j) & 0xff); - } - if (i + 32 >= n) { - fputc('>', out); - } - fputc('\n', out); - } - - for (i = 0; i < nFDs; ++i) { - delete privateDicts[i].dictData; - } - gfree(privateDicts); - gfree(cidMap); - gfree(charset); - gfree(charStringOffsets); - delete charStrings; - gfree(fdSelect); -} - -void Type1CFontFile::convertToType0(char *psName, FILE *outA) { - Type1CTopDict dict; - Type1CPrivateDict *privateDicts; - Gushort *charset; - int *cidMap; - Guchar *fdSelect; - Guchar *charStringsIdxPtr, *fdArrayIdx, *idxPtr0, *idxPtr1, *ptr; - char buf[256]; - char eBuf[256]; - int nGlyphs, nCIDs, nFDs; - int fdSelectFmt, nRanges, gid0, gid1, fd; - int key; - double x; - GBool isFP; - int i, j, n; - - out = outA; - - // read top dict (first font only) - readTopDict(&dict); - - // read the FDArray dictionaries and Private dictionaries - if (dict.fdArrayOffset == 0) { - nFDs = 1; - privateDicts = (Type1CPrivateDict *) - gmalloc(nFDs * sizeof(Type1CPrivateDict)); - privateDicts[0].dictData = new GString(); - privateDicts[0].subrsOffset = 0; - privateDicts[0].defaultWidthX = 0; - privateDicts[0].defaultWidthXFP = gFalse; - privateDicts[0].nominalWidthX = 0; - privateDicts[0].nominalWidthXFP = gFalse; - } else { - fdArrayIdx = (Guchar *)file + dict.fdArrayOffset; - nFDs = getIndexLen(fdArrayIdx); - privateDicts = (Type1CPrivateDict *) - gmalloc(nFDs * sizeof(Type1CPrivateDict)); - idxPtr1 = getIndexValPtr(fdArrayIdx, 0); - for (i = 0; i < nFDs; ++i) { - privateDicts[i].dictData = NULL; - idxPtr0 = idxPtr1; - idxPtr1 = getIndexValPtr(fdArrayIdx, i + 1); - ptr = idxPtr0; - j = 0; - while (ptr < idxPtr1) { - if (*ptr <= 27 || *ptr == 31) { - key = *ptr++; - if (key == 0x0c) { - key = (key << 8) | *ptr++; - } - if (key == 0x0012) { - readPrivateDict(&privateDicts[i], (int)op[1], (int)op[0]); - } - j = 0; - } else { - x = getNum(&ptr, &isFP); - if (j < 48) { - op[j] = x; - fp[j++] = isFP; - } - } - } - if (!privateDicts[i].dictData) { - privateDicts[i].dictData = new GString(); - privateDicts[i].subrsOffset = 0; - privateDicts[i].defaultWidthX = 0; - privateDicts[i].defaultWidthXFP = gFalse; - privateDicts[i].nominalWidthX = 0; - privateDicts[i].nominalWidthXFP = gFalse; - } - } - } - - // get the glyph count - charStringsIdxPtr = (Guchar *)file + dict.charStrings; - nGlyphs = getIndexLen(charStringsIdxPtr); - - // read the FDSelect table - fdSelect = (Guchar *)gmalloc(nGlyphs); - if (dict.fdSelectOffset == 0) { - for (i = 0; i < nGlyphs; ++i) { - fdSelect[i] = 0; - } - } else { - ptr = (Guchar *)file + dict.fdSelectOffset; - fdSelectFmt = *ptr++; - if (fdSelectFmt == 0) { - memcpy(fdSelect, ptr, nGlyphs); - } else if (fdSelectFmt == 3) { - nRanges = getWord(ptr, 2); - ptr += 2; - gid0 = getWord(ptr, 2); - ptr += 2; - for (i = 1; i <= nRanges; ++i) { - fd = *ptr++; - gid1 = getWord(ptr, 2); - ptr += 2; - for (j = gid0; j < gid1; ++j) { - fdSelect[j] = fd; - } - gid0 = gid1; - } - } else { - error(-1, "Unknown FDSelect table format in CID font"); - for (i = 0; i < nGlyphs; ++i) { - fdSelect[i] = 0; - } - } - } - - // read the charset, compute the CID-to-GID mapping - charset = readCharset(dict.charset, nGlyphs); - nCIDs = 0; - for (i = 0; i < nGlyphs; ++i) { - if (charset[i] >= nCIDs) { - nCIDs = charset[i] + 1; - } - } - cidMap = (int *)gmalloc(nCIDs * sizeof(int)); - for (i = 0; i < nCIDs; ++i) { - cidMap[i] = -1; - } - for (i = 0; i < nGlyphs; ++i) { - cidMap[charset[i]] = i; - } - - // write the descendant Type 1 fonts - for (i = 0; i < nCIDs; i += 256) { - - //~ this assumes that all CIDs in this block have the same FD -- - //~ to handle multiple FDs correctly, need to somehow divide the - //~ font up by FD - fd = 0; - for (j = 0; j < 256 && i+j < nCIDs; ++j) { - if (cidMap[i+j] >= 0) { - fd = fdSelect[cidMap[i+j]]; - break; - } - } - - // font dictionary (unencrypted section) - fprintf(out, "16 dict begin\n"); - fprintf(out, "/FontName /%s_%02x def\n", psName, i >> 8); - fprintf(out, "/FontType 1 def\n"); - fprintf(out, "/FontMatrix [%g %g %g %g %g %g] def\n", - dict.fontMatrix[0], dict.fontMatrix[1], dict.fontMatrix[2], - dict.fontMatrix[3], dict.fontMatrix[4], dict.fontMatrix[5]); - fprintf(out, "/FontBBox [%g %g %g %g] def\n", - dict.fontBBox[0], dict.fontBBox[1], - dict.fontBBox[2], dict.fontBBox[3]); - fprintf(out, "/PaintType %d def\n", dict.paintType); - if (dict.paintType != 0) { - fprintf(out, "/StrokeWidth %g def\n", dict.strokeWidth); - } - fprintf(out, "/Encoding 256 array\n"); - for (j = 0; j < 256 && i+j < nCIDs; ++j) { - fprintf(out, "dup %d /c%02x put\n", j, j); - } - fprintf(out, "readonly def\n"); - fprintf(out, "currentdict end\n"); - - // start the binary section - fprintf(out, "currentfile eexec\n"); - r1 = 55665; - line = 0; - - // start the private dictionary - eexecWrite("\x83\xca\x73\xd5"); - eexecWrite("dup /Private 32 dict dup begin\n"); - eexecWrite("/RD {string currentfile exch readstring pop} executeonly def\n"); - eexecWrite("/ND {noaccess def} executeonly def\n"); - eexecWrite("/NP {noaccess put} executeonly def\n"); - eexecWrite("/MinFeature {16 16} ND\n"); - eexecWrite(privateDicts[fd].dictData->getCString()); - defaultWidthX = privateDicts[fd].defaultWidthX; - defaultWidthXFP = privateDicts[fd].defaultWidthXFP; - nominalWidthX = privateDicts[fd].nominalWidthX; - nominalWidthXFP = privateDicts[fd].nominalWidthXFP; - - // start the CharStrings - sprintf(eBuf, "2 index /CharStrings 256 dict dup begin\n"); - eexecWrite(eBuf); - - // write the .notdef CharString - idxPtr0 = getIndexValPtr(charStringsIdxPtr, 0); - idxPtr1 = getIndexValPtr(charStringsIdxPtr, 1); - n = idxPtr1 - idxPtr0; - eexecCvtGlyph(".notdef", idxPtr0, n); - - // write the CharStrings - for (j = 0; j < 256 && i+j < nCIDs; ++j) { - if (cidMap[i+j] >= 0) { - idxPtr0 = getIndexValPtr(charStringsIdxPtr, cidMap[i+j]); - idxPtr1 = getIndexValPtr(charStringsIdxPtr, cidMap[i+j]+1); - n = idxPtr1 - idxPtr0; - sprintf(buf, "c%02x", j); - eexecCvtGlyph(buf, idxPtr0, n); - } - } - eexecWrite("end\n"); - eexecWrite("end\n"); - eexecWrite("readonly put\n"); - eexecWrite("noaccess put\n"); - eexecWrite("dup /FontName get exch definefont pop\n"); - eexecWrite("mark currentfile closefile\n"); - - // trailer - if (line > 0) { - fputc('\n', out); - } - for (j = 0; j < 8; ++j) { - fprintf(out, "0000000000000000000000000000000000000000000000000000000000000000\n"); - } - fprintf(out, "cleartomark\n"); - } - - // write the Type 0 parent font - fprintf(out, "16 dict begin\n"); - fprintf(out, "/FontName /%s def\n", psName); - fprintf(out, "/FontType 0 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FMapType 2 def\n"); - fprintf(out, "/Encoding [\n"); - for (i = 0; i < nCIDs; i += 256) { - fprintf(out, "%d\n", i >> 8); - } - fprintf(out, "] def\n"); - fprintf(out, "/FDepVector [\n"); - for (i = 0; i < nCIDs; i += 256) { - fprintf(out, "/%s_%02x findfont\n", psName, i >> 8); - } - fprintf(out, "] def\n"); - fprintf(out, "FontName currentdict end definefont pop\n"); - - // clean up - for (i = 0; i < nFDs; ++i) { - delete privateDicts[i].dictData; - } - gfree(privateDicts); - gfree(cidMap); - gfree(charset); - gfree(fdSelect); -} - -void Type1CFontFile::readTopDict(Type1CTopDict *dict) { - Guchar *idxPtr0, *idxPtr1, *ptr; - double x; - GBool isFP; - int key; - int i; - - idxPtr0 = getIndexValPtr(topDictIdxPtr, 0); - idxPtr1 = getIndexValPtr(topDictIdxPtr, 1); - dict->version = 0; - dict->notice = 0; - dict->copyright = 0; - dict->fullName = 0; - dict->familyName = 0; - dict->weight = 0; - dict->isFixedPitch = 0; - dict->italicAngle = 0; - dict->underlinePosition = -100; - dict->underlineThickness = 50; - dict->paintType = 0; - dict->charstringType = 2; - dict->fontMatrix[0] = 0.001; - dict->fontMatrix[1] = 0; - dict->fontMatrix[2] = 0; - dict->fontMatrix[3] = 0.001; - dict->fontMatrix[4] = 0; - dict->fontMatrix[5] = 0; - dict->uniqueID = 0; - dict->fontBBox[0] = 0; - dict->fontBBox[1] = 0; - dict->fontBBox[2] = 0; - dict->fontBBox[3] = 0; - dict->strokeWidth = 0; - dict->charset = 0; - dict->encoding = 0; - dict->charStrings = 0; - dict->privateSize = 0; - dict->privateOffset = 0; - dict->registry = 0; - dict->ordering = 0; - dict->supplement = 0; - dict->fdArrayOffset = 0; - dict->fdSelectOffset = 0; - i = 0; - ptr = idxPtr0; - while (ptr < idxPtr1) { - if (*ptr <= 27 || *ptr == 31) { - key = *ptr++; - if (key == 0x0c) { - key = (key << 8) | *ptr++; - } - switch (key) { - case 0x0000: dict->version = (int)op[0]; break; - case 0x0001: dict->notice = (int)op[0]; break; - case 0x0c00: dict->copyright = (int)op[0]; break; - case 0x0002: dict->fullName = (int)op[0]; break; - case 0x0003: dict->familyName = (int)op[0]; break; - case 0x0004: dict->weight = (int)op[0]; break; - case 0x0c01: dict->isFixedPitch = (int)op[0]; break; - case 0x0c02: dict->italicAngle = op[0]; break; - case 0x0c03: dict->underlinePosition = op[0]; break; - case 0x0c04: dict->underlineThickness = op[0]; break; - case 0x0c05: dict->paintType = (int)op[0]; break; - case 0x0c06: dict->charstringType = (int)op[0]; break; - case 0x0c07: dict->fontMatrix[0] = op[0]; - dict->fontMatrix[1] = op[1]; - dict->fontMatrix[2] = op[2]; - dict->fontMatrix[3] = op[3]; - dict->fontMatrix[4] = op[4]; - dict->fontMatrix[5] = op[5]; break; - case 0x000d: dict->uniqueID = (int)op[0]; break; - case 0x0005: dict->fontBBox[0] = op[0]; - dict->fontBBox[1] = op[1]; - dict->fontBBox[2] = op[2]; - dict->fontBBox[3] = op[3]; break; - case 0x0c08: dict->strokeWidth = op[0]; break; - case 0x000f: dict->charset = (int)op[0]; break; - case 0x0010: dict->encoding = (int)op[0]; break; - case 0x0011: dict->charStrings = (int)op[0]; break; - case 0x0012: dict->privateSize = (int)op[0]; - dict->privateOffset = (int)op[1]; break; - case 0x0c1e: dict->registry = (int)op[0]; - dict->ordering = (int)op[1]; - dict->supplement = (int)op[2]; break; - case 0x0c24: dict->fdArrayOffset = (int)op[0]; break; - case 0x0c25: dict->fdSelectOffset = (int)op[0]; break; - } - i = 0; - } else { - x = getNum(&ptr, &isFP); - if (i < 48) { - op[i] = x; - fp[i++] = isFP; - } - } - } -} - -void Type1CFontFile::readPrivateDict(Type1CPrivateDict *privateDict, - int offset, int size) { - Guchar *idxPtr0, *idxPtr1, *ptr; - char eBuf[256]; - int key; - double x; - GBool isFP; - int i; - - privateDict->dictData = new GString(); - privateDict->subrsOffset = 0; - privateDict->defaultWidthX = 0; - privateDict->defaultWidthXFP = gFalse; - privateDict->nominalWidthX = 0; - privateDict->nominalWidthXFP = gFalse; - idxPtr0 = (Guchar *)file + offset; - idxPtr1 = idxPtr0 + size; - ptr = idxPtr0; - i = 0; - while (ptr < idxPtr1) { - if (*ptr <= 27 || *ptr == 31) { - key = *ptr++; - if (key == 0x0c) { - key = (key << 8) | *ptr++; - } - switch (key) { - case 0x0006: - getDeltaInt(eBuf, "BlueValues", op, i); - privateDict->dictData->append(eBuf); - break; - case 0x0007: - getDeltaInt(eBuf, "OtherBlues", op, i); - privateDict->dictData->append(eBuf); - break; - case 0x0008: - getDeltaInt(eBuf, "FamilyBlues", op, i); - privateDict->dictData->append(eBuf); - break; - case 0x0009: - getDeltaInt(eBuf, "FamilyOtherBlues", op, i); - privateDict->dictData->append(eBuf); - break; - case 0x0c09: - sprintf(eBuf, "/BlueScale %g def\n", op[0]); - privateDict->dictData->append(eBuf); - break; - case 0x0c0a: - sprintf(eBuf, "/BlueShift %d def\n", (int)op[0]); - privateDict->dictData->append(eBuf); - break; - case 0x0c0b: - sprintf(eBuf, "/BlueFuzz %d def\n", (int)op[0]); - privateDict->dictData->append(eBuf); - break; - case 0x000a: - sprintf(eBuf, "/StdHW [%g] def\n", op[0]); - privateDict->dictData->append(eBuf); - break; - case 0x000b: - sprintf(eBuf, "/StdVW [%g] def\n", op[0]); - privateDict->dictData->append(eBuf); - break; - case 0x0c0c: - getDeltaReal(eBuf, "StemSnapH", op, i); - privateDict->dictData->append(eBuf); - break; - case 0x0c0d: - getDeltaReal(eBuf, "StemSnapV", op, i); - privateDict->dictData->append(eBuf); - break; - case 0x0c0e: - sprintf(eBuf, "/ForceBold %s def\n", op[0] ? "true" : "false"); - privateDict->dictData->append(eBuf); - break; - case 0x0c0f: - sprintf(eBuf, "/ForceBoldThreshold %g def\n", op[0]); - privateDict->dictData->append(eBuf); - break; - case 0x0c11: - sprintf(eBuf, "/LanguageGroup %d def\n", (int)op[0]); - privateDict->dictData->append(eBuf); - break; - case 0x0c12: - sprintf(eBuf, "/ExpansionFactor %g def\n", op[0]); - privateDict->dictData->append(eBuf); - break; - case 0x0c13: - error(-1, "Got Type 1C InitialRandomSeed"); - break; - case 0x0013: - privateDict->subrsOffset = (int)op[0]; - break; - case 0x0014: - privateDict->defaultWidthX = op[0]; - privateDict->defaultWidthXFP = fp[0]; - break; - case 0x0015: - privateDict->nominalWidthX = op[0]; - privateDict->nominalWidthXFP = fp[0]; - break; - default: - error(-1, "Unknown Type 1C private dict entry %04x", key); - break; - } - i = 0; - } else { - x = getNum(&ptr, &isFP); - if (i < 48) { - op[i] = x; - fp[i++] = isFP; - } - } - } -} - -Gushort *Type1CFontFile::readCharset(int charset, int nGlyphs) { - Gushort *glyphNames; - Guchar *ptr; - int charsetFormat, c; - int nLeft, i, j; - - if (charset == 0) { - glyphNames = type1CISOAdobeCharset; - } else if (charset == 1) { - glyphNames = type1CExpertCharset; - } else if (charset == 2) { - glyphNames = type1CExpertSubsetCharset; - } else { - glyphNames = (Gushort *)gmalloc(nGlyphs * sizeof(Gushort)); - glyphNames[0] = 0; - ptr = (Guchar *)file + charset; - charsetFormat = *ptr++; - if (charsetFormat == 0) { - for (i = 1; i < nGlyphs; ++i) { - glyphNames[i] = getWord(ptr, 2); - ptr += 2; - } - } else if (charsetFormat == 1) { - i = 1; - while (i < nGlyphs) { - c = getWord(ptr, 2); - ptr += 2; - nLeft = *ptr++; - for (j = 0; j <= nLeft && i < nGlyphs; ++j) { - glyphNames[i++] = c++; - } - } - } else if (charsetFormat == 2) { - i = 1; - while (i < nGlyphs) { - c = getWord(ptr, 2); - ptr += 2; - nLeft = getWord(ptr, 2); - ptr += 2; - for (j = 0; j <= nLeft && i < nGlyphs; ++j) { - glyphNames[i++] = c++; - } - } - } - } - return glyphNames; -} - -void Type1CFontFile::eexecWrite(char *s) { - Guchar *p; - Guchar x; - - for (p = (Guchar *)s; *p; ++p) { - x = *p ^ (r1 >> 8); - r1 = (x + r1) * 52845 + 22719; - fputc(hexChars[x >> 4], out); - fputc(hexChars[x & 0x0f], out); - line += 2; - if (line == 64) { - fputc('\n', out); - line = 0; - } - } -} - -void Type1CFontFile::eexecCvtGlyph(char *glyphName, Guchar *s, int n) { - char eBuf[256]; - - cvtGlyph(s, n); - sprintf(eBuf, "/%s %d RD ", glyphName, charBuf->getLength()); - eexecWrite(eBuf); - eexecWriteCharstring((Guchar *)charBuf->getCString(), charBuf->getLength()); - eexecWrite(" ND\n"); - delete charBuf; -} - -void Type1CFontFile::cvtGlyph(Guchar *s, int n) { - int nHints; - int x; - GBool first = gTrue; - double d, dx, dy; - GBool dFP; - Gushort r2; - Guchar byte; - int i, k; - - charBuf = new GString(); - charBuf->append((char)73); - charBuf->append((char)58); - charBuf->append((char)147); - charBuf->append((char)134); - - i = 0; - nOps = 0; - nHints = 0; - while (i < n) { - if (s[i] == 12) { - switch (s[i+1]) { - case 0: // dotsection (should be Type 1 only?) - // ignored - break; - case 34: // hflex - if (nOps != 7) { - error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps); - } - eexecDumpNum(op[0], fp[0]); - eexecDumpNum(0, gFalse); - eexecDumpNum(op[1], fp[1]); - eexecDumpNum(op[2], fp[2]); - eexecDumpNum(op[3], fp[3]); - eexecDumpNum(0, gFalse); - eexecDumpOp1(8); - eexecDumpNum(op[4], fp[4]); - eexecDumpNum(0, gFalse); - eexecDumpNum(op[5], fp[5]); - eexecDumpNum(-op[2], fp[2]); - eexecDumpNum(op[6], fp[6]); - eexecDumpNum(0, gFalse); - eexecDumpOp1(8); - break; - case 35: // flex - if (nOps != 13) { - error(-1, "Wrong number of args (%d) to Type 2 flex", nOps); - } - eexecDumpNum(op[0], fp[0]); - eexecDumpNum(op[1], fp[1]); - eexecDumpNum(op[2], fp[2]); - eexecDumpNum(op[3], fp[3]); - eexecDumpNum(op[4], fp[4]); - eexecDumpNum(op[5], fp[5]); - eexecDumpOp1(8); - eexecDumpNum(op[6], fp[6]); - eexecDumpNum(op[7], fp[7]); - eexecDumpNum(op[8], fp[8]); - eexecDumpNum(op[9], fp[9]); - eexecDumpNum(op[10], fp[10]); - eexecDumpNum(op[11], fp[11]); - eexecDumpOp1(8); - break; - case 36: // hflex1 - if (nOps != 9) { - error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps); - } - eexecDumpNum(op[0], fp[0]); - eexecDumpNum(op[1], fp[1]); - eexecDumpNum(op[2], fp[2]); - eexecDumpNum(op[3], fp[3]); - eexecDumpNum(op[4], fp[4]); - eexecDumpNum(0, gFalse); - eexecDumpOp1(8); - eexecDumpNum(op[5], fp[5]); - eexecDumpNum(0, gFalse); - eexecDumpNum(op[6], fp[6]); - eexecDumpNum(op[7], fp[7]); - eexecDumpNum(op[8], fp[8]); - eexecDumpNum(-(op[1] + op[3] + op[7]), fp[1] | fp[3] | fp[7]); - eexecDumpOp1(8); - break; - case 37: // flex1 - if (nOps != 11) { - error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps); - } - eexecDumpNum(op[0], fp[0]); - eexecDumpNum(op[1], fp[1]); - eexecDumpNum(op[2], fp[2]); - eexecDumpNum(op[3], fp[3]); - eexecDumpNum(op[4], fp[4]); - eexecDumpNum(op[5], fp[5]); - eexecDumpOp1(8); - eexecDumpNum(op[6], fp[6]); - eexecDumpNum(op[7], fp[7]); - eexecDumpNum(op[8], fp[8]); - eexecDumpNum(op[9], fp[9]); - dx = op[0] + op[2] + op[4] + op[6] + op[8]; - dy = op[1] + op[3] + op[5] + op[7] + op[9]; - if (fabs(dx) > fabs(dy)) { - eexecDumpNum(op[10], fp[10]); - eexecDumpNum(-dy, fp[1] | fp[3] | fp[5] | fp[7] | fp[9]); - } else { - eexecDumpNum(-dx, fp[0] | fp[2] | fp[4] | fp[6] | fp[8]); - eexecDumpNum(op[10], fp[10]); - } - eexecDumpOp1(8); - break; - case 3: // and - case 4: // or - case 5: // not - case 8: // store - case 9: // abs - case 10: // add - case 11: // sub - case 12: // div - case 13: // load - case 14: // neg - case 15: // eq - case 18: // drop - case 20: // put - case 21: // get - case 22: // ifelse - case 23: // random - case 24: // mul - case 26: // sqrt - case 27: // dup - case 28: // exch - case 29: // index - case 30: // roll - error(-1, "Unimplemented Type 2 charstring op: 12.%d", s[i+1]); - break; - default: - error(-1, "Illegal Type 2 charstring op: 12.%d", s[i+1]); - break; - } - i += 2; - nOps = 0; - } else if (s[i] == 19) { // hintmask - // ignored - if (first) { - cvtGlyphWidth(nOps == 1); - first = gFalse; - } - if (nOps > 0) { - if (nOps & 1) { - error(-1, "Wrong number of args (%d) to Type 2 hintmask/vstemhm", - nOps); - } - nHints += nOps / 2; - } - i += 1 + ((nHints + 7) >> 3); - nOps = 0; - } else if (s[i] == 20) { // cntrmask - // ignored - if (first) { - cvtGlyphWidth(nOps == 1); - first = gFalse; - } - if (nOps > 0) { - if (nOps & 1) { - error(-1, "Wrong number of args (%d) to Type 2 cntrmask/vstemhm", - nOps); - } - nHints += nOps / 2; - } - i += 1 + ((nHints + 7) >> 3); - nOps = 0; - } else if (s[i] == 28) { - x = (s[i+1] << 8) + s[i+2]; - if (x & 0x8000) { - x |= -1 << 15; - } - if (nOps < 48) { - fp[nOps] = gFalse; - op[nOps++] = x; - } - i += 3; - } else if (s[i] <= 31) { - switch (s[i]) { - case 4: // vmoveto - if (first) { - cvtGlyphWidth(nOps == 2); - first = gFalse; - } - if (nOps != 1) { - error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps); - } - eexecDumpNum(op[0], fp[0]); - eexecDumpOp1(4); - break; - case 5: // rlineto - if (nOps < 2 || nOps % 2 != 0) { - error(-1, "Wrong number of args (%d) to Type 2 rlineto", nOps); - } - for (k = 0; k < nOps; k += 2) { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpOp1(5); - } - break; - case 6: // hlineto - if (nOps < 1) { - error(-1, "Wrong number of args (%d) to Type 2 hlineto", nOps); - } - for (k = 0; k < nOps; ++k) { - eexecDumpNum(op[k], fp[k]); - eexecDumpOp1((k & 1) ? 7 : 6); - } - break; - case 7: // vlineto - if (nOps < 1) { - error(-1, "Wrong number of args (%d) to Type 2 vlineto", nOps); - } - for (k = 0; k < nOps; ++k) { - eexecDumpNum(op[k], fp[k]); - eexecDumpOp1((k & 1) ? 6 : 7); - } - break; - case 8: // rrcurveto - if (nOps < 6 || nOps % 6 != 0) { - error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps); - } - for (k = 0; k < nOps; k += 6) { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpNum(op[k+4], fp[k+4]); - eexecDumpNum(op[k+5], fp[k+5]); - eexecDumpOp1(8); - } - break; - case 14: // endchar / seac - if (first) { - cvtGlyphWidth(nOps == 1 || nOps == 5); - first = gFalse; - } - if (nOps == 4) { - eexecDumpNum(0, 0); - eexecDumpNum(op[0], fp[0]); - eexecDumpNum(op[1], fp[1]); - eexecDumpNum(op[2], fp[2]); - eexecDumpNum(op[3], fp[3]); - eexecDumpOp2(6); - } else if (nOps == 0) { - eexecDumpOp1(14); - } else { - error(-1, "Wrong number of args (%d) to Type 2 endchar", nOps); - } - break; - case 21: // rmoveto - if (first) { - cvtGlyphWidth(nOps == 3); - first = gFalse; - } - if (nOps != 2) { - error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps); - } - eexecDumpNum(op[0], fp[0]); - eexecDumpNum(op[1], fp[1]); - eexecDumpOp1(21); - break; - case 22: // hmoveto - if (first) { - cvtGlyphWidth(nOps == 2); - first = gFalse; - } - if (nOps != 1) { - error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps); - } - eexecDumpNum(op[0], fp[0]); - eexecDumpOp1(22); - break; - case 24: // rcurveline - if (nOps < 8 || (nOps - 2) % 6 != 0) { - error(-1, "Wrong number of args (%d) to Type 2 rcurveline", nOps); - } - for (k = 0; k < nOps - 2; k += 6) { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpNum(op[k+4], fp[k+4]); - eexecDumpNum(op[k+5], fp[k+5]); - eexecDumpOp1(8); - } - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k]); - eexecDumpOp1(5); - break; - case 25: // rlinecurve - if (nOps < 8 || (nOps - 6) % 2 != 0) { - error(-1, "Wrong number of args (%d) to Type 2 rlinecurve", nOps); - } - for (k = 0; k < nOps - 6; k += 2) { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k]); - eexecDumpOp1(5); - } - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpNum(op[k+4], fp[k+4]); - eexecDumpNum(op[k+5], fp[k+5]); - eexecDumpOp1(8); - break; - case 26: // vvcurveto - if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { - error(-1, "Wrong number of args (%d) to Type 2 vvcurveto", nOps); - } - if (nOps % 2 == 1) { - eexecDumpNum(op[0], fp[0]); - eexecDumpNum(op[1], fp[1]); - eexecDumpNum(op[2], fp[2]); - eexecDumpNum(op[3], fp[3]); - eexecDumpNum(0, gFalse); - eexecDumpNum(op[4], fp[4]); - eexecDumpOp1(8); - k = 5; - } else { - k = 0; - } - for (; k < nOps; k += 4) { - eexecDumpNum(0, gFalse); - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(0, gFalse); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpOp1(8); - } - break; - case 27: // hhcurveto - if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { - error(-1, "Wrong number of args (%d) to Type 2 hhcurveto", nOps); - } - if (nOps % 2 == 1) { - eexecDumpNum(op[1], fp[1]); - eexecDumpNum(op[0], fp[0]); - eexecDumpNum(op[2], fp[2]); - eexecDumpNum(op[3], fp[3]); - eexecDumpNum(op[4], fp[4]); - eexecDumpNum(0, gFalse); - eexecDumpOp1(8); - k = 5; - } else { - k = 0; - } - for (; k < nOps; k += 4) { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(0, gFalse); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpNum(0, gFalse); - eexecDumpOp1(8); - } - break; - case 30: // vhcurveto - if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { - error(-1, "Wrong number of args (%d) to Type 2 vhcurveto", nOps); - } - for (k = 0; k < nOps && k != nOps-5; k += 4) { - if (k % 8 == 0) { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpOp1(30); - } else { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpOp1(31); - } - } - if (k == nOps-5) { - if (k % 8 == 0) { - eexecDumpNum(0, gFalse); - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpNum(op[k+4], fp[k+4]); - } else { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(0, gFalse); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+4], fp[k+4]); - eexecDumpNum(op[k+3], fp[k+3]); - } - eexecDumpOp1(8); - } - break; - case 31: // hvcurveto - if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { - error(-1, "Wrong number of args (%d) to Type 2 hvcurveto", nOps); - } - for (k = 0; k < nOps && k != nOps-5; k += 4) { - if (k % 8 == 0) { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpOp1(31); - } else { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpOp1(30); - } - } - if (k == nOps-5) { - if (k % 8 == 0) { - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(0, gFalse); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+4], fp[k+4]); - eexecDumpNum(op[k+3], fp[k+3]); - } else { - eexecDumpNum(0, gFalse); - eexecDumpNum(op[k], fp[k]); - eexecDumpNum(op[k+1], fp[k+1]); - eexecDumpNum(op[k+2], fp[k+2]); - eexecDumpNum(op[k+3], fp[k+3]); - eexecDumpNum(op[k+4], fp[k+4]); - } - eexecDumpOp1(8); - } - break; - case 1: // hstem - if (first) { - cvtGlyphWidth(nOps & 1); - first = gFalse; - } - if (nOps & 1) { - error(-1, "Wrong number of args (%d) to Type 2 hstem", nOps); - } - d = 0; - dFP = gFalse; - for (k = 0; k < nOps; k += 2) { - if (op[k+1] < 0) { - d += op[k] + op[k+1]; - dFP |= fp[k] | fp[k+1]; - eexecDumpNum(d, dFP); - eexecDumpNum(-op[k+1], fp[k+1]); - } else { - d += op[k]; - dFP |= fp[k]; - eexecDumpNum(d, dFP); - eexecDumpNum(op[k+1], fp[k+1]); - d += op[k+1]; - dFP |= fp[k+1]; - } - eexecDumpOp1(1); - } - nHints += nOps / 2; - break; - case 3: // vstem - if (first) { - cvtGlyphWidth(nOps & 1); - first = gFalse; - } - if (nOps & 1) { - error(-1, "Wrong number of args (%d) to Type 2 vstem", nOps); - } - d = 0; - dFP = gFalse; - for (k = 0; k < nOps; k += 2) { - if (op[k+1] < 0) { - d += op[k] + op[k+1]; - dFP |= fp[k] | fp[k+1]; - eexecDumpNum(d, dFP); - eexecDumpNum(-op[k+1], fp[k+1]); - } else { - d += op[k]; - dFP |= fp[k]; - eexecDumpNum(d, dFP); - eexecDumpNum(op[k+1], fp[k+1]); - d += op[k+1]; - dFP |= fp[k+1]; - } - eexecDumpOp1(3); - } - nHints += nOps / 2; - break; - case 18: // hstemhm - // ignored - if (first) { - cvtGlyphWidth(nOps & 1); - first = gFalse; - } - if (nOps & 1) { - error(-1, "Wrong number of args (%d) to Type 2 hstemhm", nOps); - } - nHints += nOps / 2; - break; - case 23: // vstemhm - // ignored - if (first) { - cvtGlyphWidth(nOps & 1); - first = gFalse; - } - if (nOps & 1) { - error(-1, "Wrong number of args (%d) to Type 2 vstemhm", nOps); - } - nHints += nOps / 2; - break; - case 10: // callsubr - case 11: // return - case 16: // blend - case 29: // callgsubr - error(-1, "Unimplemented Type 2 charstring op: %d", s[i]); - break; - default: - error(-1, "Illegal Type 2 charstring op: %d", s[i]); - break; - } - ++i; - nOps = 0; - } else if (s[i] <= 246) { - if (nOps < 48) { - fp[nOps] = gFalse; - op[nOps++] = (int)s[i] - 139; - } - ++i; - } else if (s[i] <= 250) { - if (nOps < 48) { - fp[nOps] = gFalse; - op[nOps++] = (((int)s[i] - 247) << 8) + (int)s[i+1] + 108; - } - i += 2; - } else if (s[i] <= 254) { - if (nOps < 48) { - fp[nOps] = gFalse; - op[nOps++] = -(((int)s[i] - 251) << 8) - (int)s[i+1] - 108; - } - i += 2; - } else { - x = (s[i+1] << 24) | (s[i+2] << 16) | (s[i+3] << 8) | s[i+4]; - if (x & 0x80000000) - x |= -1 << 31; - if (nOps < 48) { - fp[nOps] = gTrue; - op[nOps++] = (double)x / 65536.0; - } - i += 5; - } - } - - // charstring encryption - r2 = 4330; - for (i = 0; i < charBuf->getLength(); ++i) { - byte = charBuf->getChar(i) ^ (r2 >> 8); - charBuf->setChar(i, byte); - r2 = (byte + r2) * 52845 + 22719; - } -} - -void Type1CFontFile::cvtGlyphWidth(GBool useOp) { - double w; - GBool wFP; - int i; - - if (useOp) { - w = nominalWidthX + op[0]; - wFP = nominalWidthXFP | fp[0]; - for (i = 1; i < nOps; ++i) { - op[i-1] = op[i]; - fp[i-1] = fp[i]; - } - --nOps; - } else { - w = defaultWidthX; - wFP = defaultWidthXFP; - } - eexecDumpNum(0, gFalse); - eexecDumpNum(w, wFP); - eexecDumpOp1(13); -} - -void Type1CFontFile::eexecDumpNum(double x, GBool fpA) { - Guchar buf[12]; - int y, n; - - n = 0; - if (fpA) { - if (x >= -32768 && x < 32768) { - y = (int)(x * 256.0); - buf[0] = 255; - buf[1] = (Guchar)(y >> 24); - buf[2] = (Guchar)(y >> 16); - buf[3] = (Guchar)(y >> 8); - buf[4] = (Guchar)y; - buf[5] = 255; - buf[6] = 0; - buf[7] = 0; - buf[8] = 1; - buf[9] = 0; - buf[10] = 12; - buf[11] = 12; - n = 12; - } else { - error(-1, "Type 2 fixed point constant out of range"); - } - } else { - y = (int)x; - if (y >= -107 && y <= 107) { - buf[0] = (Guchar)(y + 139); - n = 1; - } else if (y > 107 && y <= 1131) { - y -= 108; - buf[0] = (Guchar)((y >> 8) + 247); - buf[1] = (Guchar)(y & 0xff); - n = 2; - } else if (y < -107 && y >= -1131) { - y = -y - 108; - buf[0] = (Guchar)((y >> 8) + 251); - buf[1] = (Guchar)(y & 0xff); - n = 2; - } else { - buf[0] = 255; - buf[1] = (Guchar)(y >> 24); - buf[2] = (Guchar)(y >> 16); - buf[3] = (Guchar)(y >> 8); - buf[4] = (Guchar)y; - n = 5; - } - } - charBuf->append((char *)buf, n); -} - -void Type1CFontFile::eexecDumpOp1(int opA) { - charBuf->append((char)opA); -} - -void Type1CFontFile::eexecDumpOp2(int opA) { - charBuf->append((char)12); - charBuf->append((char)opA); -} - -void Type1CFontFile::eexecWriteCharstring(Guchar *s, int n) { - Guchar x; - int i; - - // eexec encryption - for (i = 0; i < n; ++i) { - x = s[i] ^ (r1 >> 8); - r1 = (x + r1) * 52845 + 22719; - fputc(hexChars[x >> 4], out); - fputc(hexChars[x & 0x0f], out); - line += 2; - if (line == 64) { - fputc('\n', out); - line = 0; - } - } -} - -void Type1CFontFile::getDeltaInt(char *buf, char *key, double *opA, - int n) { - int x, i; - - sprintf(buf, "/%s [", key); - buf += strlen(buf); - x = 0; - for (i = 0; i < n; ++i) { - x += (int)opA[i]; - sprintf(buf, "%s%d", i > 0 ? " " : "", x); - buf += strlen(buf); - } - sprintf(buf, "] def\n"); -} - -void Type1CFontFile::getDeltaReal(char *buf, char *key, double *opA, - int n) { - double x; - int i; - - sprintf(buf, "/%s [", key); - buf += strlen(buf); - x = 0; - for (i = 0; i < n; ++i) { - x += opA[i]; - sprintf(buf, "%s%g", i > 0 ? " " : "", x); - buf += strlen(buf); - } - sprintf(buf, "] def\n"); -} - -int Type1CFontFile::getIndexLen(Guchar *indexPtr) { - return (int)getWord(indexPtr, 2); -} - -Guchar *Type1CFontFile::getIndexValPtr(Guchar *indexPtr, int i) { - int n, offSize; - Guchar *idxStartPtr; - - n = (int)getWord(indexPtr, 2); - offSize = indexPtr[2]; - idxStartPtr = indexPtr + 3 + (n + 1) * offSize - 1; - return idxStartPtr + getWord(indexPtr + 3 + i * offSize, offSize); -} - -Guchar *Type1CFontFile::getIndexEnd(Guchar *indexPtr) { - int n, offSize; - Guchar *idxStartPtr; - - n = (int)getWord(indexPtr, 2); - offSize = indexPtr[2]; - idxStartPtr = indexPtr + 3 + (n + 1) * offSize - 1; - return idxStartPtr + getWord(indexPtr + 3 + n * offSize, offSize); -} - -Guint Type1CFontFile::getWord(Guchar *ptr, int size) { - Guint x; - int i; - - x = 0; - for (i = 0; i < size; ++i) { - x = (x << 8) + *ptr++; - } - return x; -} - -double Type1CFontFile::getNum(Guchar **ptr, GBool *isFP) { - static char nybChars[16] = "0123456789.ee -"; - int b0, b, nyb0, nyb1; - double x; - char buf[65]; - int i; - - x = 0; - *isFP = gFalse; - b0 = (*ptr)[0]; - if (b0 < 28) { - x = 0; - } else if (b0 == 28) { - x = ((*ptr)[1] << 8) + (*ptr)[2]; - *ptr += 3; - } else if (b0 == 29) { - x = ((*ptr)[1] << 24) + ((*ptr)[2] << 16) + ((*ptr)[3] << 8) + (*ptr)[4]; - *ptr += 5; - } else if (b0 == 30) { - *ptr += 1; - i = 0; - do { - b = *(*ptr)++; - nyb0 = b >> 4; - nyb1 = b & 0x0f; - if (nyb0 == 0xf) { - break; - } - buf[i++] = nybChars[nyb0]; - if (i == 64) { - break; - } - if (nyb0 == 0xc) { - buf[i++] = '-'; - } - if (i == 64) { - break; - } - if (nyb1 == 0xf) { - break; - } - buf[i++] = nybChars[nyb1]; - if (i == 64) { - break; - } - if (nyb1 == 0xc) { - buf[i++] = '-'; - } - } while (i < 64); - buf[i] = '\0'; - x = atof(buf); - *isFP = gTrue; - } else if (b0 == 31) { - x = 0; - } else if (b0 < 247) { - x = b0 - 139; - *ptr += 1; - } else if (b0 < 251) { - x = ((b0 - 247) << 8) + (*ptr)[1] + 108; - *ptr += 2; - } else { - x = -((b0 - 251) << 8) - (*ptr)[1] - 108; - *ptr += 2; - } - return x; -} - -char *Type1CFontFile::getString(int sid, char *buf) { - Guchar *idxPtr0, *idxPtr1; - int n; - - if (sid < 391) { - strcpy(buf, type1CStdStrings[sid]); - } else { - sid -= 391; - idxPtr0 = getIndexValPtr(stringIdxPtr, sid); - idxPtr1 = getIndexValPtr(stringIdxPtr, sid + 1); - if ((n = idxPtr1 - idxPtr0) > 255) { - n = 255; - } - strncpy(buf, (char *)idxPtr0, n); - buf[n] = '\0'; - } - return buf; -} - -//------------------------------------------------------------------------ -// TrueTypeFontFile -//------------------------------------------------------------------------ - -// -// Terminology -// ----------- -// -// character code = number used as an element of a text string -// -// character name = glyph name = name for a particular glyph within a -// font -// -// glyph index = position (within some internal table in the font) -// where the instructions to draw a particular glyph are -// stored -// -// Type 1 fonts -// ------------ -// -// Type 1 fonts contain: -// -// Encoding: array of glyph names, maps char codes to glyph names -// -// Encoding[charCode] = charName -// -// CharStrings: dictionary of instructions, keyed by character names, -// maps character name to glyph data -// -// CharStrings[charName] = glyphData -// -// TrueType fonts -// -------------- -// -// TrueType fonts contain: -// -// 'cmap' table: mapping from character code to glyph index; there may -// be multiple cmaps in a TrueType font -// -// cmap[charCode] = glyphIdx -// -// 'post' table: mapping from glyph index to glyph name -// -// post[glyphIdx] = glyphName -// -// Type 42 fonts -// ------------- -// -// Type 42 fonts contain: -// -// Encoding: array of glyph names, maps char codes to glyph names -// -// Encoding[charCode] = charName -// -// CharStrings: dictionary of glyph indexes, keyed by character names, -// maps character name to glyph index -// -// CharStrings[charName] = glyphIdx -// - -struct TTFontTableHdr { - char tag[4]; - Guint checksum; - Guint offset; - Guint length; -}; - -struct T42Table { - char *tag; // 4-byte tag - GBool required; // required by the TrueType spec? -}; - -// TrueType tables to be embedded in Type 42 fonts. -// NB: the table names must be in alphabetical order here. -#define nT42Tables 11 -static T42Table t42Tables[nT42Tables] = { - { "cvt ", gTrue }, - { "fpgm", gTrue }, - { "glyf", gTrue }, - { "head", gTrue }, - { "hhea", gTrue }, - { "hmtx", gTrue }, - { "loca", gTrue }, - { "maxp", gTrue }, - { "prep", gTrue }, - { "vhea", gFalse }, - { "vmtx", gFalse } -}; -#define t42HeadTable 3 -#define t42LocaTable 6 -#define t42GlyfTable 2 - -// Glyph names in some arbitrary standard that Apple uses for their -// TrueType fonts. -static char *macGlyphNames[258] = { - ".notdef", - "null", - "CR", - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quotesingle", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "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", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "grave", - "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", - "braceleft", - "bar", - "braceright", - "asciitilde", - "Adieresis", - "Aring", - "Ccedilla", - "Eacute", - "Ntilde", - "Odieresis", - "Udieresis", - "aacute", - "agrave", - "acircumflex", - "adieresis", - "atilde", - "aring", - "ccedilla", - "eacute", - "egrave", - "ecircumflex", - "edieresis", - "iacute", - "igrave", - "icircumflex", - "idieresis", - "ntilde", - "oacute", - "ograve", - "ocircumflex", - "odieresis", - "otilde", - "uacute", - "ugrave", - "ucircumflex", - "udieresis", - "dagger", - "degree", - "cent", - "sterling", - "section", - "bullet", - "paragraph", - "germandbls", - "registered", - "copyright", - "trademark", - "acute", - "dieresis", - "notequal", - "AE", - "Oslash", - "infinity", - "plusminus", - "lessequal", - "greaterequal", - "yen", - "mu1", - "partialdiff", - "summation", - "product", - "pi", - "integral", - "ordfeminine", - "ordmasculine", - "Ohm", - "ae", - "oslash", - "questiondown", - "exclamdown", - "logicalnot", - "radical", - "florin", - "approxequal", - "increment", - "guillemotleft", - "guillemotright", - "ellipsis", - "nbspace", - "Agrave", - "Atilde", - "Otilde", - "OE", - "oe", - "endash", - "emdash", - "quotedblleft", - "quotedblright", - "quoteleft", - "quoteright", - "divide", - "lozenge", - "ydieresis", - "Ydieresis", - "fraction", - "currency", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - "daggerdbl", - "periodcentered", - "quotesinglbase", - "quotedblbase", - "perthousand", - "Acircumflex", - "Ecircumflex", - "Aacute", - "Edieresis", - "Egrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Igrave", - "Oacute", - "Ocircumflex", - "applelogo", - "Ograve", - "Uacute", - "Ucircumflex", - "Ugrave", - "dotlessi", - "circumflex", - "tilde", - "overscore", - "breve", - "dotaccent", - "ring", - "cedilla", - "hungarumlaut", - "ogonek", - "caron", - "Lslash", - "lslash", - "Scaron", - "scaron", - "Zcaron", - "zcaron", - "brokenbar", - "Eth", - "eth", - "Yacute", - "yacute", - "Thorn", - "thorn", - "minus", - "multiply", - "onesuperior", - "twosuperior", - "threesuperior", - "onehalf", - "onequarter", - "threequarters", - "franc", - "Gbreve", - "gbreve", - "Idot", - "Scedilla", - "scedilla", - "Cacute", - "cacute", - "Ccaron", - "ccaron", - "dmacron" -}; - -enum T42FontIndexMode { - t42FontModeUnicode, - t42FontModeCharCode, - t42FontModeCharCodeOffset, - t42FontModeMacRoman -}; - -TrueTypeFontFile::TrueTypeFontFile(char *fileA, int lenA) { - int pos, i; - - file = fileA; - len = lenA; - - encoding = NULL; - - // read table directory - nTables = getUShort(4); - tableHdrs = (TTFontTableHdr *)gmalloc(nTables * sizeof(TTFontTableHdr)); - pos = 12; - for (i = 0; i < nTables; ++i) { - tableHdrs[i].tag[0] = getByte(pos+0); - tableHdrs[i].tag[1] = getByte(pos+1); - tableHdrs[i].tag[2] = getByte(pos+2); - tableHdrs[i].tag[3] = getByte(pos+3); - tableHdrs[i].checksum = getULong(pos+4); - tableHdrs[i].offset = getULong(pos+8); - tableHdrs[i].length = getULong(pos+12); - pos += 16; - } - - // check for tables that are required by both the TrueType spec - // and the Type 42 spec - if (seekTable("head") < 0 || - seekTable("hhea") < 0 || - seekTable("loca") < 0 || - seekTable("maxp") < 0 || - seekTable("glyf") < 0 || - seekTable("hmtx") < 0) { - error(-1, "TrueType font file is missing a required table"); - return; - } - - // read the 'head' table - pos = seekTable("head"); - bbox[0] = getShort(pos + 36); - bbox[1] = getShort(pos + 38); - bbox[2] = getShort(pos + 40); - bbox[3] = getShort(pos + 42); - locaFmt = getShort(pos + 50); - - // read the 'maxp' table - pos = seekTable("maxp"); - nGlyphs = getUShort(pos + 4); -} - -TrueTypeFontFile::~TrueTypeFontFile() { - int i; - - if (encoding) { - for (i = 0; i < 256; ++i) { - gfree(encoding[i]); - } - gfree(encoding); - } - gfree(tableHdrs); -} - -char *TrueTypeFontFile::getName() { - return NULL; -} - -char **TrueTypeFontFile::getEncoding() { - int cmap[256]; - int nCmaps, cmapPlatform, cmapEncoding, cmapFmt; - int cmapLen, cmapOffset, cmapFirst; - int segCnt, segStart, segEnd, segDelta, segOffset; - int pos, i, j, k; - Guint fmt; - GString *s; - int stringIdx, stringPos, n; - - if (encoding) { - return encoding; - } - - //----- construct the (char code) -> (glyph idx) mapping - - // map everything to the missing glyph - for (i = 0; i < 256; ++i) { - cmap[i] = 0; - } - - // look for the 'cmap' table - if ((pos = seekTable("cmap")) >= 0) { - nCmaps = getUShort(pos+2); - - // if the font has a Windows-symbol cmap, use it; - // otherwise, use the first cmap in the table - for (i = 0; i < nCmaps; ++i) { - cmapPlatform = getUShort(pos + 4 + 8*i); - cmapEncoding = getUShort(pos + 4 + 8*i + 2); - if (cmapPlatform == 3 && cmapEncoding == 0) { - break; - } - } - if (i >= nCmaps) { - i = 0; - cmapPlatform = getUShort(pos + 4); - cmapEncoding = getUShort(pos + 4 + 2); - } - pos += getULong(pos + 4 + 8*i + 4); - - // read the cmap - cmapFmt = getUShort(pos); - switch (cmapFmt) { - case 0: // byte encoding table (Apple standard) - cmapLen = getUShort(pos + 2); - for (i = 0; i < cmapLen && i < 256; ++i) { - cmap[i] = getByte(pos + 6 + i); - } - break; - case 4: // segment mapping to delta values (Microsoft standard) - if (cmapPlatform == 3 && cmapEncoding == 0) { - // Windows-symbol uses char codes 0xf000 - 0xf0ff - cmapOffset = 0xf000; - } else { - cmapOffset = 0; - } - segCnt = getUShort(pos + 6) / 2; - for (i = 0; i < segCnt; ++i) { - segEnd = getUShort(pos + 14 + 2*i); - segStart = getUShort(pos + 16 + 2*segCnt + 2*i); - segDelta = getUShort(pos + 16 + 4*segCnt + 2*i); - segOffset = getUShort(pos + 16 + 6*segCnt + 2*i); - if (segStart - cmapOffset <= 0xff && - segEnd - cmapOffset >= 0) { - for (j = (segStart - cmapOffset >= 0) ? segStart : cmapOffset; - j <= segEnd && j - cmapOffset <= 0xff; - ++j) { - if (segOffset == 0) { - k = (j + segDelta) & 0xffff; - } else { - k = getUShort(pos + 16 + 6*segCnt + 2*i + - segOffset + 2 * (j - segStart)); - if (k != 0) { - k = (k + segDelta) & 0xffff; - } - } - cmap[j - cmapOffset] = k; - } - } - } - break; - case 6: // trimmed table mapping - cmapFirst = getUShort(pos + 6); - cmapLen = getUShort(pos + 8); - for (i = cmapFirst; i < 256 && i < cmapFirst + cmapLen; ++i) { - cmap[i] = getUShort(pos + 10 + 2*i); - } - break; - default: - error(-1, "Unimplemented cmap format (%d) in TrueType font file", - cmapFmt); - break; - } - } - - //----- construct the (glyph idx) -> (glyph name) mapping - //----- and compute the (char code) -> (glyph name) mapping - - encoding = (char **)gmalloc(256 * sizeof(char *)); - for (i = 0; i < 256; ++i) { - encoding[i] = NULL; - } - - if ((pos = seekTable("post")) >= 0) { - fmt = getULong(pos); - - // Apple font - if (fmt == 0x00010000) { - for (i = 0; i < 256; ++i) { - j = (cmap[i] < 258) ? cmap[i] : 0; - encoding[i] = copyString(macGlyphNames[j]); - } - - // Microsoft font - } else if (fmt == 0x00020000) { - stringIdx = 0; - stringPos = pos + 34 + 2*nGlyphs; - for (i = 0; i < 256; ++i) { - if (cmap[i] < nGlyphs) { - j = getUShort(pos + 34 + 2 * cmap[i]); - if (j < 258) { - encoding[i] = copyString(macGlyphNames[j]); - } else { - j -= 258; - if (j != stringIdx) { - for (stringIdx = 0, stringPos = pos + 34 + 2*nGlyphs; - stringIdx < j; - ++stringIdx, stringPos += 1 + getByte(stringPos)) ; - } - n = getByte(stringPos); - s = new GString(file + stringPos + 1, n); - encoding[i] = copyString(s->getCString()); - delete s; - ++stringIdx; - stringPos += 1 + n; - } - } else { - encoding[i] = copyString(macGlyphNames[0]); - } - } - - // Apple subset - } else if (fmt == 0x000280000) { - for (i = 0; i < 256; ++i) { - if (cmap[i] < nGlyphs) { - j = i + getChar(pos + 32 + cmap[i]); - } else { - j = 0; - } - encoding[i] = copyString(macGlyphNames[j]); - } - - // Ugh, just assume the Apple glyph set - } else { - for (i = 0; i < 256; ++i) { - j = (cmap[i] < 258) ? cmap[i] : 0; - encoding[i] = copyString(macGlyphNames[j]); - } - } - - // no "post" table: assume the Apple glyph set - } else { - for (i = 0; i < 256; ++i) { - j = (cmap[i] < 258) ? cmap[i] : 0; - encoding[i] = copyString(macGlyphNames[j]); - } - } - - return encoding; -} - -void TrueTypeFontFile::convertToType42(char *name, char **encodingA, - CharCodeToUnicode *toUnicode, - GBool pdfFontHasEncoding, FILE *out) { - // write the header - fprintf(out, "%%!PS-TrueTypeFont-%g\n", getFixed(0)); - - // begin the font dictionary - fprintf(out, "10 dict begin\n"); - fprintf(out, "/FontName /%s def\n", name); - fprintf(out, "/FontType 42 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FontBBox [%d %d %d %d] def\n", - bbox[0], bbox[1], bbox[2], bbox[3]); - fprintf(out, "/PaintType 0 def\n"); - - // write the guts of the dictionary - cvtEncoding(encodingA, out); - cvtCharStrings(encodingA, toUnicode, pdfFontHasEncoding, out); - cvtSfnts(out, NULL); - - // end the dictionary and define the font - fprintf(out, "FontName currentdict end definefont pop\n"); -} - -void TrueTypeFontFile::convertToCIDType2(char *name, Gushort *cidMap, - int nCIDs, FILE *out) { - Gushort cid; - int i, j, k; - - // write the header - fprintf(out, "%%!PS-TrueTypeFont-%g\n", getFixed(0)); - - // begin the font dictionary - fprintf(out, "20 dict begin\n"); - fprintf(out, "/CIDFontName /%s def\n", name); - fprintf(out, "/CIDFontType 2 def\n"); - fprintf(out, "/FontType 42 def\n"); - fprintf(out, "/CIDSystemInfo 3 dict dup begin\n"); - fprintf(out, " /Registry (Adobe) def\n"); - fprintf(out, " /Ordering (Identity) def\n"); - fprintf(out, " /Supplement 0 def\n"); - fprintf(out, " end def\n"); - fprintf(out, "/GDBytes 2 def\n"); - if (cidMap) { - fprintf(out, "/CIDCount %d def\n", nCIDs); - if (nCIDs > 32767) { - fprintf(out, "/CIDMap ["); - for (i = 0; i < nCIDs; i += 32768 - 16) { - fprintf(out, "<\n"); - for (j = 0; j < 32768 - 16 && i+j < nCIDs; j += 16) { - fprintf(out, " "); - for (k = 0; k < 16 && i+j+k < nCIDs; ++k) { - cid = cidMap[i+j+k]; - fprintf(out, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff); - } - fprintf(out, "\n"); - } - fprintf(out, " >"); - } - fprintf(out, "\n"); - fprintf(out, "] def\n"); - } else { - fprintf(out, "/CIDMap <\n"); - for (i = 0; i < nCIDs; i += 16) { - fprintf(out, " "); - for (j = 0; j < 16 && i+j < nCIDs; ++j) { - cid = cidMap[i+j]; - fprintf(out, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff); - } - fprintf(out, "\n"); - } - fprintf(out, "> def\n"); - } - } else { - // direct mapping - just fill the string(s) with s[i]=i - fprintf(out, "/CIDCount %d def\n", nGlyphs); - if (nGlyphs > 32767) { - fprintf(out, "/CIDMap [\n"); - for (i = 0; i < nGlyphs; i += 32767) { - j = nGlyphs - i < 32767 ? nGlyphs - i : 32767; - fprintf(out, " %d string 0 1 %d {\n", 2 * j, j - 1); - fprintf(out, " 2 copy dup 2 mul exch %d add -8 bitshift put\n", i); - fprintf(out, " 1 index exch dup 2 mul 1 add exch %d add" - " 255 and put\n", i); - fprintf(out, " } for\n"); - } - fprintf(out, "] def\n"); - } else { - fprintf(out, "/CIDMap %d string\n", 2 * nGlyphs); - fprintf(out, " 0 1 %d {\n", nGlyphs - 1); - fprintf(out, " 2 copy dup 2 mul exch -8 bitshift put\n"); - fprintf(out, " 1 index exch dup 2 mul 1 add exch 255 and put\n"); - fprintf(out, " } for\n"); - fprintf(out, "def\n"); - } - } - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FontBBox [%d %d %d %d] def\n", - bbox[0], bbox[1], bbox[2], bbox[3]); - fprintf(out, "/PaintType 0 def\n"); - fprintf(out, "/Encoding [] readonly def\n"); - fprintf(out, "/CharStrings 1 dict dup begin\n"); - fprintf(out, " /.notdef 0 def\n"); - fprintf(out, " end readonly def\n"); - - // write the guts of the dictionary - cvtSfnts(out, NULL); - - // end the dictionary and define the font - fprintf(out, "CIDFontName currentdict end /CIDFont defineresource pop\n"); -} - -void TrueTypeFontFile::convertToType0(char *name, Gushort *cidMap, - int nCIDs, FILE *out) { - GString *sfntsName; - int n, i, j; - - // write the Type 42 sfnts array - sfntsName = (new GString(name))->append("_sfnts"); - cvtSfnts(out, sfntsName); - delete sfntsName; - - // write the descendant Type 42 fonts - n = cidMap ? nCIDs : nGlyphs; - for (i = 0; i < n; i += 256) { - fprintf(out, "10 dict begin\n"); - fprintf(out, "/FontName /%s_%02x def\n", name, i >> 8); - fprintf(out, "/FontType 42 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FontBBox [%d %d %d %d] def\n", - bbox[0], bbox[1], bbox[2], bbox[3]); - fprintf(out, "/PaintType 0 def\n"); - fprintf(out, "/sfnts %s_sfnts def\n", name); - fprintf(out, "/Encoding 256 array\n"); - for (j = 0; j < 256 && i+j < n; ++j) { - fprintf(out, "dup %d /c%02x put\n", j, j); - } - fprintf(out, "readonly def\n"); - fprintf(out, "/CharStrings 257 dict dup begin\n"); - fprintf(out, "/.notdef 0 def\n"); - for (j = 0; j < 256 && i+j < n; ++j) { - fprintf(out, "/c%02x %d def\n", j, cidMap ? cidMap[i+j] : i+j); - } - fprintf(out, "end readonly def\n"); - fprintf(out, "FontName currentdict end definefont pop\n"); - } - - // write the Type 0 parent font - fprintf(out, "16 dict begin\n"); - fprintf(out, "/FontName /%s def\n", name); - fprintf(out, "/FontType 0 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FMapType 2 def\n"); - fprintf(out, "/Encoding [\n"); - for (i = 0; i < n; i += 256) { - fprintf(out, "%d\n", i >> 8); - } - fprintf(out, "] def\n"); - fprintf(out, "/FDepVector [\n"); - for (i = 0; i < n; i += 256) { - fprintf(out, "/%s_%02x findfont\n", name, i >> 8); - } - fprintf(out, "] def\n"); - fprintf(out, "FontName currentdict end definefont pop\n"); -} - -int TrueTypeFontFile::getByte(int pos) { - if (pos < 0 || pos >= len) { - return 0; - } - return file[pos] & 0xff; -} - -int TrueTypeFontFile::getChar(int pos) { - int x; - - if (pos < 0 || pos >= len) { - return 0; - } - x = file[pos] & 0xff; - if (x & 0x80) - x |= 0xffffff00; - return x; -} - -int TrueTypeFontFile::getUShort(int pos) { - int x; - - if (pos < 0 || pos+1 >= len) { - return 0; - } - x = file[pos] & 0xff; - x = (x << 8) + (file[pos+1] & 0xff); - return x; -} - -int TrueTypeFontFile::getShort(int pos) { - int x; - - if (pos < 0 || pos+1 >= len) { - return 0; - } - x = file[pos] & 0xff; - x = (x << 8) + (file[pos+1] & 0xff); - if (x & 0x8000) - x |= 0xffff0000; - return x; -} - -Guint TrueTypeFontFile::getULong(int pos) { - int x; - - if (pos < 0 || pos+3 >= len) { - return 0; - } - x = file[pos] & 0xff; - x = (x << 8) + (file[pos+1] & 0xff); - x = (x << 8) + (file[pos+2] & 0xff); - x = (x << 8) + (file[pos+3] & 0xff); - return x; -} - -double TrueTypeFontFile::getFixed(int pos) { - int x, y; - - x = getShort(pos); - y = getUShort(pos+2); - return (double)x + (double)y / 65536; -} - -int TrueTypeFontFile::seekTable(char *tag) { - int i; - - for (i = 0; i < nTables; ++i) { - if (!strncmp(tableHdrs[i].tag, tag, 4)) { - return tableHdrs[i].offset; - } - } - return -1; -} - -int TrueTypeFontFile::seekTableIdx(char *tag) { - int i; - - for (i = 0; i < nTables; ++i) { - if (!strncmp(tableHdrs[i].tag, tag, 4)) { - return i; - } - } - return -1; -} - -void TrueTypeFontFile::cvtEncoding(char **encodingA, FILE *out) { - char *name; - int i; - - fprintf(out, "/Encoding 256 array\n"); - for (i = 0; i < 256; ++i) { - if (!(name = encodingA[i])) { - name = ".notdef"; - } - fprintf(out, "dup %d /%s put\n", i, name); - } - fprintf(out, "readonly def\n"); -} - -void TrueTypeFontFile::cvtCharStrings(char **encodingA, - CharCodeToUnicode *toUnicode, - GBool pdfFontHasEncoding, FILE *out) { - int unicodeCmap, macRomanCmap, msSymbolCmap; - int nCmaps, cmapPlatform, cmapEncoding, cmapFmt, cmapOffset; - T42FontIndexMode mode; - char *name; - Unicode u; - int pos, i, j, k; - - // always define '.notdef' - fprintf(out, "/CharStrings 256 dict dup begin\n"); - fprintf(out, "/.notdef 0 def\n"); - - // if there's no 'cmap' table, punt - if ((pos = seekTable("cmap")) < 0) { - goto err; - } - - // To match up with the Adobe-defined behaviour, we choose a cmap - // like this: - // 1. If the PDF font has an encoding: - // 1a. If the TrueType font has a Microsoft Unicode cmap, use it, - // and use the Unicode indexes, not the char codes. - // 1b. If the TrueType font has a Macintosh Roman cmap, use it, - // and reverse map the char names through MacRomanEncoding to - // get char codes. - // 2. If the PDF font does not have an encoding: - // 2a. If the TrueType font has a Macintosh Roman cmap, use it, - // and use char codes directly. - // 2b. If the TrueType font has a Microsoft Symbol cmap, use it, - // and use (0xf000 + char code). - // 3. If none of these rules apply, use the first cmap and hope for - // the best (this shouldn't happen). - nCmaps = getUShort(pos+2); - unicodeCmap = macRomanCmap = msSymbolCmap = -1; - cmapOffset = 0; - for (i = 0; i < nCmaps; ++i) { - cmapPlatform = getUShort(pos + 4 + 8*i); - cmapEncoding = getUShort(pos + 4 + 8*i + 2); - if (cmapPlatform == 3 && cmapEncoding == 1) { - unicodeCmap = i; - } else if (cmapPlatform == 1 && cmapEncoding == 0) { - macRomanCmap = i; - } else if (cmapPlatform == 3 && cmapEncoding == 0) { - msSymbolCmap = i; - } - } - i = 0; - mode = t42FontModeCharCode; - if (pdfFontHasEncoding) { - if (unicodeCmap >= 0) { - i = unicodeCmap; - mode = t42FontModeUnicode; - } else if (macRomanCmap >= 0) { - i = macRomanCmap; - mode = t42FontModeMacRoman; - } - } else { - if (macRomanCmap >= 0) { - i = macRomanCmap; - mode = t42FontModeCharCode; - } else if (msSymbolCmap >= 0) { - i = msSymbolCmap; - mode = t42FontModeCharCodeOffset; - cmapOffset = 0xf000; - } - } - cmapPlatform = getUShort(pos + 4 + 8*i); - cmapEncoding = getUShort(pos + 4 + 8*i + 2); - pos += getULong(pos + 4 + 8*i + 4); - cmapFmt = getUShort(pos); - if (cmapFmt != 0 && cmapFmt != 4 && cmapFmt != 6) { - error(-1, "Unimplemented cmap format (%d) in TrueType font file", - cmapFmt); - goto err; - } - - // map char name to glyph index: - // 1. use encoding to map name to char code - // 2. use cmap to map char code to glyph index - j = 0; // make gcc happy - for (i = 0; i < 256; ++i) { - name = encodingA[i]; - if (name && strcmp(name, ".notdef")) { - switch (mode) { - case t42FontModeUnicode: - toUnicode->mapToUnicode((CharCode)i, &u, 1); - j = (int)u; - break; - case t42FontModeCharCode: - j = i; - break; - case t42FontModeCharCodeOffset: - j = cmapOffset + i; - break; - case t42FontModeMacRoman: - j = globalParams->getMacRomanCharCode(name); - break; - } - // note: Distiller (maybe Adobe's PS interpreter in general) - // doesn't like TrueType fonts that have CharStrings entries - // which point to nonexistent glyphs, hence the (k < nGlyphs) - // test - if ((k = getCmapEntry(cmapFmt, pos, j)) > 0 && - k < nGlyphs) { - fprintf(out, "/%s %d def\n", name, k); - } - } - } - - err: - fprintf(out, "end readonly def\n"); -} - -int TrueTypeFontFile::getCmapEntry(int cmapFmt, int pos, int code) { - int cmapLen, cmapFirst; - int segCnt, segEnd, segStart, segDelta, segOffset; - int a, b, m, i; - - switch (cmapFmt) { - case 0: // byte encoding table (Apple standard) - cmapLen = getUShort(pos + 2); - if (code >= cmapLen) { - return 0; - } - return getByte(pos + 6 + code); - - case 4: // segment mapping to delta values (Microsoft standard) - segCnt = getUShort(pos + 6) / 2; - a = -1; - b = segCnt - 1; - segEnd = getUShort(pos + 14 + 2*b); - if (code > segEnd) { - // malformed font -- the TrueType spec requires the last segEnd - // to be 0xffff - return 0; - } - // invariant: seg[a].end < code <= seg[b].end - while (b - a > 1) { - m = (a + b) / 2; - segEnd = getUShort(pos + 14 + 2*m); - if (segEnd < code) { - a = m; - } else { - b = m; - } - } - segStart = getUShort(pos + 16 + 2*segCnt + 2*b); - segDelta = getUShort(pos + 16 + 4*segCnt + 2*b); - segOffset = getUShort(pos + 16 + 6*segCnt + 2*b); - if (segOffset == 0) { - i = (code + segDelta) & 0xffff; - } else { - i = getUShort(pos + 16 + 6*segCnt + 2*b + - segOffset + 2 * (code - segStart)); - if (i != 0) { - i = (i + segDelta) & 0xffff; - } - } - return i; - - case 6: // trimmed table mapping - cmapFirst = getUShort(pos + 6); - cmapLen = getUShort(pos + 8); - if (code < cmapFirst || code >= cmapFirst + cmapLen) { - return 0; - } - return getUShort(pos + 10 + 2*(code - cmapFirst)); - - default: - // shouldn't happen - this is checked earlier - break; - } - return 0; -} - -void TrueTypeFontFile::cvtSfnts(FILE *out, GString *name) { - TTFontTableHdr newTableHdrs[nT42Tables]; - char tableDir[12 + nT42Tables*16]; - char headTable[54]; - int *origLocaTable; - char *locaTable; - int nNewTables; - Guint checksum; - int pos, glyfPos, length, glyphLength, pad; - int i, j, k; - - // construct the 'head' table, zero out the font checksum - memcpy(headTable, file + seekTable("head"), 54); - headTable[8] = headTable[9] = headTable[10] = headTable[11] = (char)0; - - // read the original 'loca' table and construct the new one - // (pad each glyph out to a multiple of 4 bytes) - origLocaTable = (int *)gmalloc((nGlyphs + 1) * sizeof(int)); - pos = seekTable("loca"); - for (i = 0; i <= nGlyphs; ++i) { - if (locaFmt) { - origLocaTable[i] = getULong(pos + 4*i); - } else { - origLocaTable[i] = 2 * getUShort(pos + 2*i); - } - } - locaTable = (char *)gmalloc((nGlyphs + 1) * (locaFmt ? 4 : 2)); - if (locaFmt) { - locaTable[0] = locaTable[1] = locaTable[2] = locaTable[3] = 0; - } else { - locaTable[0] = locaTable[1] = 0; - } - pos = 0; - for (i = 1; i <= nGlyphs; ++i) { - length = origLocaTable[i] - origLocaTable[i-1]; - if (length & 3) { - length += 4 - (length & 3); - } - pos += length; - if (locaFmt) { - locaTable[4*i ] = (char)(pos >> 24); - locaTable[4*i+1] = (char)(pos >> 16); - locaTable[4*i+2] = (char)(pos >> 8); - locaTable[4*i+3] = (char) pos; - } else { - locaTable[2*i ] = (char)(pos >> 9); - locaTable[2*i+1] = (char)(pos >> 1); - } - } - - // count the number of tables - nNewTables = 0; - for (i = 0; i < nT42Tables; ++i) { - if (t42Tables[i].required || - seekTable(t42Tables[i].tag) >= 0) { - ++nNewTables; - } - } - - // construct the new table headers, including table checksums - // (pad each table out to a multiple of 4 bytes) - pos = 12 + nNewTables*16; - k = 0; - for (i = 0; i < nT42Tables; ++i) { - length = -1; - checksum = 0; // make gcc happy - if (i == t42HeadTable) { - length = 54; - checksum = computeTableChecksum(headTable, 54); - } else if (i == t42LocaTable) { - length = (nGlyphs + 1) * (locaFmt ? 4 : 2); - checksum = computeTableChecksum(locaTable, length); - } else if (i == t42GlyfTable) { - length = 0; - checksum = 0; - glyfPos = seekTable("glyf"); - for (j = 0; j < nGlyphs; ++j) { - glyphLength = origLocaTable[j+1] - origLocaTable[j]; - pad = (glyphLength & 3) ? 4 - (glyphLength & 3) : 0; - length += glyphLength + pad; - checksum += computeTableChecksum(file + glyfPos + origLocaTable[j], - glyphLength); - } - } else { - if ((j = seekTableIdx(t42Tables[i].tag)) >= 0) { - length = tableHdrs[j].length; - checksum = computeTableChecksum(file + tableHdrs[j].offset, length); - } else if (t42Tables[i].required) { - error(-1, "Embedded TrueType font is missing a required table ('%s')", - t42Tables[i].tag); - length = 0; - checksum = 0; - } - } - if (length >= 0) { - strncpy(newTableHdrs[k].tag, t42Tables[i].tag, 4); - newTableHdrs[k].checksum = checksum; - newTableHdrs[k].offset = pos; - newTableHdrs[k].length = length; - pad = (length & 3) ? 4 - (length & 3) : 0; - pos += length + pad; - ++k; - } - } - - // construct the table directory - tableDir[0] = 0x00; // sfnt version - tableDir[1] = 0x01; - tableDir[2] = 0x00; - tableDir[3] = 0x00; - tableDir[4] = 0; // numTables - tableDir[5] = nNewTables; - tableDir[6] = 0; // searchRange - tableDir[7] = (char)128; - tableDir[8] = 0; // entrySelector - tableDir[9] = 3; - tableDir[10] = 0; // rangeShift - tableDir[11] = (char)(16 * nNewTables - 128); - pos = 12; - for (i = 0; i < nNewTables; ++i) { - tableDir[pos ] = newTableHdrs[i].tag[0]; - tableDir[pos+ 1] = newTableHdrs[i].tag[1]; - tableDir[pos+ 2] = newTableHdrs[i].tag[2]; - tableDir[pos+ 3] = newTableHdrs[i].tag[3]; - tableDir[pos+ 4] = (char)(newTableHdrs[i].checksum >> 24); - tableDir[pos+ 5] = (char)(newTableHdrs[i].checksum >> 16); - tableDir[pos+ 6] = (char)(newTableHdrs[i].checksum >> 8); - tableDir[pos+ 7] = (char) newTableHdrs[i].checksum; - tableDir[pos+ 8] = (char)(newTableHdrs[i].offset >> 24); - tableDir[pos+ 9] = (char)(newTableHdrs[i].offset >> 16); - tableDir[pos+10] = (char)(newTableHdrs[i].offset >> 8); - tableDir[pos+11] = (char) newTableHdrs[i].offset; - tableDir[pos+12] = (char)(newTableHdrs[i].length >> 24); - tableDir[pos+13] = (char)(newTableHdrs[i].length >> 16); - tableDir[pos+14] = (char)(newTableHdrs[i].length >> 8); - tableDir[pos+15] = (char) newTableHdrs[i].length; - pos += 16; - } - - // compute the font checksum and store it in the head table - checksum = computeTableChecksum(tableDir, 12 + nNewTables*16); - for (i = 0; i < nNewTables; ++i) { - checksum += newTableHdrs[i].checksum; - } - checksum = 0xb1b0afba - checksum; // because the TrueType spec says so - headTable[ 8] = (char)(checksum >> 24); - headTable[ 9] = (char)(checksum >> 16); - headTable[10] = (char)(checksum >> 8); - headTable[11] = (char) checksum; - - // start the sfnts array - if (name) { - fprintf(out, "/%s [\n", name->getCString()); - } else { - fprintf(out, "/sfnts [\n"); - } - - // write the table directory - dumpString(tableDir, 12 + nNewTables*16, out); - - // write the tables - for (i = 0; i < nNewTables; ++i) { - if (i == t42HeadTable) { - dumpString(headTable, 54, out); - } else if (i == t42LocaTable) { - length = (nGlyphs + 1) * (locaFmt ? 4 : 2); - dumpString(locaTable, length, out); - } else if (i == t42GlyfTable) { - glyfPos = seekTable("glyf"); - for (j = 0; j < nGlyphs; ++j) { - length = origLocaTable[j+1] - origLocaTable[j]; - if (length > 0) { - dumpString(file + glyfPos + origLocaTable[j], length, out); - } - } - } else { - // length == 0 means the table is missing and the error was - // already reported during the construction of the table - // headers - if ((length = newTableHdrs[i].length) > 0) { - dumpString(file + seekTable(t42Tables[i].tag), length, out); - } - } - } - - // end the sfnts array - fprintf(out, "] def\n"); - - gfree(origLocaTable); - gfree(locaTable); -} - -void TrueTypeFontFile::dumpString(char *s, int length, FILE *out) { - int pad, i, j; - - fprintf(out, "<"); - for (i = 0; i < length; i += 32) { - for (j = 0; j < 32 && i+j < length; ++j) { - fprintf(out, "%02X", s[i+j] & 0xff); - } - if (i % (65536 - 32) == 65536 - 64) { - fprintf(out, ">\n<"); - } else if (i+32 < length) { - fprintf(out, "\n"); - } - } - if (length & 3) { - pad = 4 - (length & 3); - for (i = 0; i < pad; ++i) { - fprintf(out, "00"); - } - } - // add an extra zero byte because the Adobe Type 42 spec says so - fprintf(out, "00>\n"); -} - -Guint TrueTypeFontFile::computeTableChecksum(char *data, int length) { - Guint checksum, word; - int i; - - checksum = 0; - for (i = 0; i+3 < length; i += 4) { - word = ((data[i ] & 0xff) << 24) + - ((data[i+1] & 0xff) << 16) + - ((data[i+2] & 0xff) << 8) + - (data[i+3] & 0xff); - checksum += word; - } - if (length & 3) { - word = 0; - i = length & ~3; - switch (length & 3) { - case 3: - word |= (data[i+2] & 0xff) << 8; - case 2: - word |= (data[i+1] & 0xff) << 16; - case 1: - word |= (data[i ] & 0xff) << 24; - break; - } - checksum += word; - } - return checksum; -} - -void TrueTypeFontFile::writeTTF(FILE *out) { - static char cmapTab[20] = { - 0, 0, // table version number - 0, 1, // number of encoding tables - 0, 1, // platform ID - 0, 0, // encoding ID - 0, 0, 0, 12, // offset of subtable - 0, 0, // subtable format - 0, 1, // subtable length - 0, 1, // subtable version - 0, // map char 0 -> glyph 0 - 0 // pad to multiple of four bytes - }; - static char nameTab[8] = { - 0, 0, // format - 0, 0, // number of name records - 0, 6, // offset to start of string storage - 0, 0 // pad to multiple of four bytes - }; - static char postTab[32] = { - 0, 1, 0, 0, // format - 0, 0, 0, 0, // italic angle - 0, 0, // underline position - 0, 0, // underline thickness - 0, 0, 0, 0, // fixed pitch - 0, 0, 0, 0, // min Type 42 memory - 0, 0, 0, 0, // max Type 42 memory - 0, 0, 0, 0, // min Type 1 memory - 0, 0, 0, 0 // max Type 1 memory - }; - GBool haveCmap, haveName, havePost; - GBool dirCmap, dirName, dirPost; - int nNewTables, nAllTables, pad; - char *tableDir; - Guint t, pos; - int i, j; - - // check for missing tables - haveCmap = seekTable("cmap") >= 0; - haveName = seekTable("name") >= 0; - havePost = seekTable("post") >= 0; - nNewTables = (haveCmap ? 0 : 1) + (haveName ? 0 : 1) + (havePost ? 0 : 1); - if (!nNewTables) { - // none are missing - write the TTF file as is - fwrite(file, 1, len, out); - return; - } - - // construct the new table directory - nAllTables = nTables + nNewTables; - tableDir = (char *)gmalloc(12 + nAllTables * 16); - memcpy(tableDir, file, 12 + nTables * 16); - tableDir[4] = (char)((nAllTables >> 8) & 0xff); - tableDir[5] = (char)(nAllTables & 0xff); - for (i = -1, t = (Guint)nAllTables; t; ++i, t >>= 1) ; - t = 1 << (4 + i); - tableDir[6] = (char)((t >> 8) & 0xff); - tableDir[7] = (char)(t & 0xff); - tableDir[8] = (char)((i >> 8) & 0xff); - tableDir[9] = (char)(i & 0xff); - t = nAllTables * 16 - t; - tableDir[10] = (char)((t >> 8) & 0xff); - tableDir[11] = (char)(t & 0xff); - dirCmap = haveCmap; - dirName = haveName; - dirPost = havePost; - j = 0; - pad = (len & 3) ? 4 - (len & 3) : 0; - pos = len + pad + 16 * nNewTables; - for (i = 0; i < nTables; ++i) { - if (!dirCmap && strncmp(tableHdrs[i].tag, "cmap", 4) > 0) { - tableDir[12 + 16*j ] = 'c'; - tableDir[12 + 16*j + 1] = 'm'; - tableDir[12 + 16*j + 2] = 'a'; - tableDir[12 + 16*j + 3] = 'p'; - tableDir[12 + 16*j + 4] = (char)0; //~ should compute the checksum - tableDir[12 + 16*j + 5] = (char)0; - tableDir[12 + 16*j + 6] = (char)0; - tableDir[12 + 16*j + 7] = (char)0; - tableDir[12 + 16*j + 8] = (char)((pos >> 24) & 0xff); - tableDir[12 + 16*j + 9] = (char)((pos >> 16) & 0xff); - tableDir[12 + 16*j + 10] = (char)((pos >> 8) & 0xff); - tableDir[12 + 16*j + 11] = (char)( pos & 0xff); - tableDir[12 + 16*j + 12] = (char)((sizeof(cmapTab) >> 24) & 0xff); - tableDir[12 + 16*j + 13] = (char)((sizeof(cmapTab) >> 16) & 0xff); - tableDir[12 + 16*j + 14] = (char)((sizeof(cmapTab) >> 8) & 0xff); - tableDir[12 + 16*j + 15] = (char)( sizeof(cmapTab) & 0xff); - pos += sizeof(cmapTab); - ++j; - dirCmap = gTrue; - } - if (!dirName && strncmp(tableHdrs[i].tag, "name", 4) > 0) { - tableDir[12 + 16*j ] = 'n'; - tableDir[12 + 16*j + 1] = 'a'; - tableDir[12 + 16*j + 2] = 'm'; - tableDir[12 + 16*j + 3] = 'e'; - tableDir[12 + 16*j + 4] = (char)0; //~ should compute the checksum - tableDir[12 + 16*j + 5] = (char)0; - tableDir[12 + 16*j + 6] = (char)0; - tableDir[12 + 16*j + 7] = (char)0; - tableDir[12 + 16*j + 8] = (char)((pos >> 24) & 0xff); - tableDir[12 + 16*j + 9] = (char)((pos >> 16) & 0xff); - tableDir[12 + 16*j + 10] = (char)((pos >> 8) & 0xff); - tableDir[12 + 16*j + 11] = (char)( pos & 0xff); - tableDir[12 + 16*j + 12] = (char)((sizeof(nameTab) >> 24) & 0xff); - tableDir[12 + 16*j + 13] = (char)((sizeof(nameTab) >> 16) & 0xff); - tableDir[12 + 16*j + 14] = (char)((sizeof(nameTab) >> 8) & 0xff); - tableDir[12 + 16*j + 15] = (char)( sizeof(nameTab) & 0xff); - pos += sizeof(nameTab); - ++j; - dirName = gTrue; - } - if (!dirName && strncmp(tableHdrs[i].tag, "post", 4) > 0) { - tableDir[12 + 16*j ] = 'p'; - tableDir[12 + 16*j + 1] = 'o'; - tableDir[12 + 16*j + 2] = 's'; - tableDir[12 + 16*j + 3] = 't'; - tableDir[12 + 16*j + 4] = (char)0; //~ should compute the checksum - tableDir[12 + 16*j + 5] = (char)0; - tableDir[12 + 16*j + 6] = (char)0; - tableDir[12 + 16*j + 7] = (char)0; - tableDir[12 + 16*j + 8] = (char)((pos >> 24) & 0xff); - tableDir[12 + 16*j + 9] = (char)((pos >> 16) & 0xff); - tableDir[12 + 16*j + 10] = (char)((pos >> 8) & 0xff); - tableDir[12 + 16*j + 11] = (char)( pos & 0xff); - tableDir[12 + 16*j + 12] = (char)((sizeof(postTab) >> 24) & 0xff); - tableDir[12 + 16*j + 13] = (char)((sizeof(postTab) >> 16) & 0xff); - tableDir[12 + 16*j + 14] = (char)((sizeof(postTab) >> 8) & 0xff); - tableDir[12 + 16*j + 15] = (char)( sizeof(postTab) & 0xff); - pos += sizeof(postTab); - ++j; - dirPost = gTrue; - } - memcpy(&tableDir[12 + 16*j], file + 12 + 16*i, 16); - t = tableHdrs[i].offset + nNewTables * 16; - tableDir[12 + 16*j + 8] = (char)((t >> 24) & 0xff); - tableDir[12 + 16*j + 9] = (char)((t >> 16) & 0xff); - tableDir[12 + 16*j + 10] = (char)((t >> 8) & 0xff); - tableDir[12 + 16*j + 11] = (char)( t & 0xff); - ++j; - } - if (!dirCmap) { - tableDir[12 + 16*j ] = 'c'; - tableDir[12 + 16*j + 1] = 'm'; - tableDir[12 + 16*j + 2] = 'a'; - tableDir[12 + 16*j + 3] = 'p'; - tableDir[12 + 16*j + 4] = (char)0; //~ should compute the checksum - tableDir[12 + 16*j + 5] = (char)0; - tableDir[12 + 16*j + 6] = (char)0; - tableDir[12 + 16*j + 7] = (char)0; - tableDir[12 + 16*j + 8] = (char)((pos >> 24) & 0xff); - tableDir[12 + 16*j + 9] = (char)((pos >> 16) & 0xff); - tableDir[12 + 16*j + 10] = (char)((pos >> 8) & 0xff); - tableDir[12 + 16*j + 11] = (char)( pos & 0xff); - tableDir[12 + 16*j + 12] = (char)((sizeof(cmapTab) >> 24) & 0xff); - tableDir[12 + 16*j + 13] = (char)((sizeof(cmapTab) >> 16) & 0xff); - tableDir[12 + 16*j + 14] = (char)((sizeof(cmapTab) >> 8) & 0xff); - tableDir[12 + 16*j + 15] = (char)( sizeof(cmapTab) & 0xff); - pos += sizeof(cmapTab); - ++j; - dirCmap = gTrue; - } - if (!dirName) { - tableDir[12 + 16*j ] = 'n'; - tableDir[12 + 16*j + 1] = 'a'; - tableDir[12 + 16*j + 2] = 'm'; - tableDir[12 + 16*j + 3] = 'e'; - tableDir[12 + 16*j + 4] = (char)0; //~ should compute the checksum - tableDir[12 + 16*j + 5] = (char)0; - tableDir[12 + 16*j + 6] = (char)0; - tableDir[12 + 16*j + 7] = (char)0; - tableDir[12 + 16*j + 8] = (char)((pos >> 24) & 0xff); - tableDir[12 + 16*j + 9] = (char)((pos >> 16) & 0xff); - tableDir[12 + 16*j + 10] = (char)((pos >> 8) & 0xff); - tableDir[12 + 16*j + 11] = (char)( pos & 0xff); - tableDir[12 + 16*j + 12] = (char)((sizeof(nameTab) >> 24) & 0xff); - tableDir[12 + 16*j + 13] = (char)((sizeof(nameTab) >> 16) & 0xff); - tableDir[12 + 16*j + 14] = (char)((sizeof(nameTab) >> 8) & 0xff); - tableDir[12 + 16*j + 15] = (char)( sizeof(nameTab) & 0xff); - pos += sizeof(nameTab); - ++j; - dirName = gTrue; - } - if (!dirPost) { - tableDir[12 + 16*j ] = 'p'; - tableDir[12 + 16*j + 1] = 'o'; - tableDir[12 + 16*j + 2] = 's'; - tableDir[12 + 16*j + 3] = 't'; - tableDir[12 + 16*j + 4] = (char)0; //~ should compute the checksum - tableDir[12 + 16*j + 5] = (char)0; - tableDir[12 + 16*j + 6] = (char)0; - tableDir[12 + 16*j + 7] = (char)0; - tableDir[12 + 16*j + 8] = (char)((pos >> 24) & 0xff); - tableDir[12 + 16*j + 9] = (char)((pos >> 16) & 0xff); - tableDir[12 + 16*j + 10] = (char)((pos >> 8) & 0xff); - tableDir[12 + 16*j + 11] = (char)( pos & 0xff); - tableDir[12 + 16*j + 12] = (char)((sizeof(postTab) >> 24) & 0xff); - tableDir[12 + 16*j + 13] = (char)((sizeof(postTab) >> 16) & 0xff); - tableDir[12 + 16*j + 14] = (char)((sizeof(postTab) >> 8) & 0xff); - tableDir[12 + 16*j + 15] = (char)( sizeof(postTab) & 0xff); - pos += sizeof(postTab); - ++j; - dirPost = gTrue; - } - - // write the table directory - fwrite(tableDir, 1, 12 + 16 * nAllTables, out); - - // write the original tables - fwrite(file + 12 + 16*nTables, 1, len - (12 + 16*nTables), out); - - // write the new tables - for (i = 0; i < pad; ++i) { - fputc((char)0, out); - } - if (!haveCmap) { - fwrite(cmapTab, 1, sizeof(cmapTab), out); - } - if (!haveName) { - fwrite(nameTab, 1, sizeof(nameTab), out); - } - if (!havePost) { - fwrite(postTab, 1, sizeof(postTab), out); - } - - gfree(tableDir); -} diff --git a/pdf2swf/xpdf/FontFile.h b/pdf2swf/xpdf/FontFile.h deleted file mode 100644 index d5de25c..0000000 --- a/pdf2swf/xpdf/FontFile.h +++ /dev/null @@ -1,215 +0,0 @@ -//======================================================================== -// -// FontFile.h -// -// Copyright 1999-2002 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef FONTFILE_H -#define FONTFILE_H - -#ifdef __GNUC__ -#pragma interface -#endif - -#include -#include "gtypes.h" -#include "GString.h" -#include "CharTypes.h" - -class CharCodeToUnicode; - -//------------------------------------------------------------------------ -// FontFile -//------------------------------------------------------------------------ - -class FontFile { -public: - - FontFile(); - virtual ~FontFile(); - - // Returns the font name, as specified internally by the font file. - // Returns NULL if no name is available. - virtual char *getName() = 0; - - // Returns the custom font encoding, or NULL if the encoding is not - // available. - virtual char **getEncoding() = 0; -}; - -//------------------------------------------------------------------------ -// Type1FontFile -//------------------------------------------------------------------------ - -class Type1FontFile: public FontFile { -public: - - Type1FontFile(char *file, int len); - virtual ~Type1FontFile(); - virtual char *getName() { return name; } - virtual char **getEncoding() { return encoding; } - -private: - - char *name; - char **encoding; -}; - -//------------------------------------------------------------------------ -// Type1CFontFile -//------------------------------------------------------------------------ - -struct Type1CTopDict; -struct Type1CPrivateDict; - -class Type1CFontFile: public FontFile { -public: - - Type1CFontFile(char *fileA, int lenA); - virtual ~Type1CFontFile(); - - virtual char *getName(); - virtual char **getEncoding(); - - // Convert to a Type 1 font, suitable for embedding in a PostScript - // file. The name will be used as the PostScript font name. - void convertToType1(FILE *outA); - - // Convert to a Type 0 CIDFont, suitable for embedding in a - // PostScript file. The name will be used as the PostScript font - // name. - void convertToCIDType0(char *psName, FILE *outA); - - // Convert to a Type 0 (but non-CID) composite font, suitable for - // embedding in a PostScript file. The name will be used as the - // PostScript font name. - void convertToType0(char *psName, FILE *outA); - -private: - - void readNameAndEncoding(); - void readTopDict(Type1CTopDict *dict); - void readPrivateDict(Type1CPrivateDict *privateDict, - int offset, int size); - Gushort *readCharset(int charset, int nGlyphs); - void eexecWrite(char *s); - void eexecCvtGlyph(char *glyphName, Guchar *s, int n); - void cvtGlyph(Guchar *s, int n); - void cvtGlyphWidth(GBool useOp); - void eexecDumpNum(double x, GBool fpA); - void eexecDumpOp1(int opA); - void eexecDumpOp2(int opA); - void eexecWriteCharstring(Guchar *s, int n); - void getDeltaInt(char *buf, char *key, double *opA, int n); - void getDeltaReal(char *buf, char *key, double *opA, int n); - int getIndexLen(Guchar *indexPtr); - Guchar *getIndexValPtr(Guchar *indexPtr, int i); - Guchar *getIndexEnd(Guchar *indexPtr); - Guint getWord(Guchar *ptr, int size); - double getNum(Guchar **ptr, GBool *fp); - char *getString(int sid, char *buf); - - char *file; - int len; - - GString *name; - char **encoding; - - int topOffSize; - Guchar *topDictIdxPtr; - Guchar *stringIdxPtr; - Guchar *gsubrIdxPtr; - - FILE *out; - double op[48]; // operands - GBool fp[48]; // true if operand is fixed point - int nOps; // number of operands - double defaultWidthX; // default glyph width - double nominalWidthX; // nominal glyph width - GBool defaultWidthXFP; // true if defaultWidthX is fixed point - GBool nominalWidthXFP; // true if nominalWidthX is fixed point - Gushort r1; // eexec encryption key - GString *charBuf; // charstring output buffer - int line; // number of eexec chars on current line -}; - -//------------------------------------------------------------------------ -// TrueTypeFontFile -//------------------------------------------------------------------------ - -struct TTFontTableHdr; - -class TrueTypeFontFile: public FontFile { -public: - - TrueTypeFontFile(char *fileA, int lenA); - ~TrueTypeFontFile(); - - // This always returns NULL, since it's probably better to trust the - // font name in the PDF file rather than the one in the TrueType - // font file. - virtual char *getName(); - - virtual char **getEncoding(); - - // Convert to a Type 42 font, suitable for embedding in a PostScript - // file. The name will be used as the PostScript font name (so we - // don't need to depend on the 'name' table in the font). The - // encoding is needed because the PDF Font object can modify the - // encoding. - void convertToType42(char *name, char **encodingA, - CharCodeToUnicode *toUnicode, - GBool pdfFontHasEncoding, FILE *out); - - // Convert to a Type 2 CIDFont, suitable for embedding in a - // PostScript file. The name will be used as the PostScript font - // name (so we don't need to depend on the 'name' table in the - // font). - void convertToCIDType2(char *name, Gushort *cidMap, - int nCIDs, FILE *out); - - // Convert to a Type 0 (but non-CID) composite font, suitable for - // embedding in a PostScript file. The name will be used as the - // PostScript font name (so we don't need to depend on the 'name' - // table in the font). - void convertToType0(char *name, Gushort *cidMap, - int nCIDs, FILE *out); - - // Write a TTF file, filling in any missing tables that are required - // by the TrueType spec. If the font already has all the required - // tables, it will be written unmodified. - void writeTTF(FILE *out); - -private: - - char *file; - int len; - - char **encoding; - - TTFontTableHdr *tableHdrs; - int nTables; - int bbox[4]; - int locaFmt; - int nGlyphs; - - int getByte(int pos); - int getChar(int pos); - int getUShort(int pos); - int getShort(int pos); - Guint getULong(int pos); - double getFixed(int pos); - int seekTable(char *tag); - int seekTableIdx(char *tag); - void cvtEncoding(char **encodingA, FILE *out); - void cvtCharStrings(char **encodingA, CharCodeToUnicode *toUnicode, - GBool pdfFontHasEncoding, FILE *out); - int getCmapEntry(int cmapFmt, int pos, int code); - void cvtSfnts(FILE *out, GString *name); - void dumpString(char *s, int length, FILE *out); - Guint computeTableChecksum(char *data, int length); -}; - -#endif -- 1.7.10.4