diff options
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc')
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc | 403 |
1 files changed, 401 insertions, 2 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc index cdb767ae8bf..13c045f8b97 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc @@ -18,6 +18,7 @@ #include "gmem.h" #include "gmempp.h" #include "GString.h" +#include "GHash.h" #include "FoFiEncodings.h" #include "FoFiType1C.h" @@ -152,6 +153,23 @@ GString *FoFiType1C::getGlyphName(int gid) { return new GString(buf); } +GHash *FoFiType1C::getNameToGIDMap() { + GHash *map; + char name[256]; + GBool ok; + int gid; + + map = new GHash(gTrue); + for (gid = 0; gid < nGlyphs; ++gid) { + ok = gTrue; + getString(charset[gid], name, &ok); + if (ok) { + map->add(new GString(name), gid); + } + } + return map; +} + int *FoFiType1C::getCIDToGIDMap(int *nCIDs) { int *map; int n, i; @@ -2183,6 +2201,371 @@ void FoFiType1C::writePSString(char *s, FoFiOutputFunc outputFunc, (*outputFunc)(outputStream, buf, i); } +void FoFiType1C::convertToOpenType(FoFiOutputFunc outputFunc, + void *outputStream, + int nWidths, Gushort *widths, + Guchar *cmapTable, int cmapTableLen) { + // dummy OS/2 table (taken from FoFiTrueType::writeTTF) + static Guchar os2Tab[86] = { + 0, 1, // version + 0, 1, // xAvgCharWidth + 0x01, 0x90, // usWeightClass + 0, 5, // usWidthClass + 0, 0, // fsType + 0, 0, // ySubscriptXSize + 0, 0, // ySubscriptYSize + 0, 0, // ySubscriptXOffset + 0, 0, // ySubscriptYOffset + 0, 0, // ySuperscriptXSize + 0, 0, // ySuperscriptYSize + 0, 0, // ySuperscriptXOffset + 0, 0, // ySuperscriptYOffset + 0, 0, // yStrikeoutSize + 0, 0, // yStrikeoutPosition + 0, 0, // sFamilyClass + 0, 0, 0, 0, 0, // panose + 0, 0, 0, 0, 0, + 0, 0, 0, 0, // ulUnicodeRange1 + 0, 0, 0, 0, // ulUnicodeRange2 + 0, 0, 0, 0, // ulUnicodeRange3 + 0, 0, 0, 0, // ulUnicodeRange4 + 0, 0, 0, 0, // achVendID + 0, 0, // fsSelection + 0, 0, // usFirstCharIndex + 0, 0, // usLastCharIndex + 0, 0, // sTypoAscender + 0, 0, // sTypoDescender + 0, 0, // sTypoLineGap + 0x20, 0x00, // usWinAscent + 0x20, 0x00, // usWinDescent + 0, 0, 0, 1, // ulCodePageRange1 + 0, 0, 0, 0 // ulCodePageRange2 + }; + Guchar headTable[54], hheaTable[36], maxpTable[6]; + Guchar nameTable[26], postTable[32]; + Guchar *hmtxTable; + static const char *tableTag[9] = { + "CFF ", + "OS/2", + "cmap", + "head", + "hhea", + "hmtx", + "maxp", + "name", + "post" + }; + Guchar *tableData[9]; + int tableLength[9]; + Guchar header[12 + 9*16]; + double mat[6]; + Gushort maxWidth; + Guint checksum, fileChecksum; + int unitsPerEm, xMin, yMin, xMax, yMax, offset, i; + + //--- CFF_ table + tableData[0] = file; + tableLength[0] = len; + + //--- OS/2 table + tableData[1] = os2Tab; + tableLength[1] = 86; + + //--- cmap table + tableData[2] = cmapTable; + tableLength[2] = cmapTableLen; + + //--- head table + getFontMatrix(mat); + if (mat[0] == 0) { + unitsPerEm = 1000; + } else { + unitsPerEm = (int)(1 / mat[0] + 0.5); + } + xMin = (int)(topDict.fontBBox[0] + 0.5); + yMin = (int)(topDict.fontBBox[1] + 0.5); + xMax = (int)(topDict.fontBBox[2] + 0.5); + yMax = (int)(topDict.fontBBox[3] + 0.5); + headTable[ 0] = 0x00; // version + headTable[ 1] = 0x01; + headTable[ 2] = 0x00; + headTable[ 3] = 0x00; + headTable[ 4] = 0x00; // revision + headTable[ 5] = 0x00; + headTable[ 6] = 0x00; + headTable[ 7] = 0x00; + headTable[ 8] = 0x00; // checksumAdjustment + headTable[ 9] = 0x00; // (set later) + headTable[10] = 0x00; + headTable[11] = 0x00; + headTable[12] = 0x5f; // magicNumber + headTable[13] = 0x0f; + headTable[14] = 0x3c; + headTable[15] = 0xf5; + headTable[16] = 0x00; // flags + headTable[17] = 0x03; + headTable[18] = (Guchar)(unitsPerEm >> 8); // unitsPerEm + headTable[19] = (Guchar)unitsPerEm; + headTable[20] = 0x00; // created + headTable[21] = 0x00; + headTable[22] = 0x00; + headTable[23] = 0x00; + headTable[24] = 0x00; + headTable[25] = 0x00; + headTable[26] = 0x00; + headTable[27] = 0x00; + headTable[28] = 0x00; // modified + headTable[29] = 0x00; + headTable[30] = 0x00; + headTable[31] = 0x00; + headTable[32] = 0x00; + headTable[33] = 0x00; + headTable[34] = 0x00; + headTable[35] = 0x00; + headTable[36] = (Guchar)(xMin >> 8); // xMin + headTable[37] = (Guchar)xMin; + headTable[38] = (Guchar)(yMin >> 8); // yMin + headTable[39] = (Guchar)yMin; + headTable[40] = (Guchar)(xMax >> 8); // xMax + headTable[41] = (Guchar)xMax; + headTable[42] = (Guchar)(yMax >> 8); // yMax + headTable[43] = (Guchar)yMax; + headTable[44] = 0; // macStyle + headTable[45] = 0; + headTable[46] = 0; // lowestRecPPEM + headTable[47] = 3; + headTable[48] = 0; // fontDirectionHint + headTable[49] = 2; // (deprecated) + headTable[50] = 0; // indexToLocFormat + headTable[51] = 0; // (n/a to CFF fonts) + headTable[52] = 0; // glyphDataFormat + headTable[53] = 0; // (n/a to CFF fonts) + tableData[3] = headTable; + tableLength[3] = 54; + + //--- hhea table + maxWidth = widths[0]; + for (i = 1; i < nWidths; ++i) { + if (widths[i] > maxWidth) { + maxWidth = widths[i]; + } + } + hheaTable[ 0] = 0x00; // version + hheaTable[ 1] = 0x01; + hheaTable[ 2] = 0x00; + hheaTable[ 3] = 0x00; + hheaTable[ 4] = (Guchar)(yMax >> 8); // ascender + hheaTable[ 5] = (Guchar)yMax; + hheaTable[ 6] = (Guchar)(yMin >> 8); // descender + hheaTable[ 7] = (Guchar)yMin; + hheaTable[ 8] = 0; // lineGap + hheaTable[ 9] = 0; + hheaTable[10] = (Guchar)(maxWidth >> 8); // advanceWidthMax + hheaTable[11] = (Guchar)maxWidth; + hheaTable[12] = 0; // minLeftSideBearing + hheaTable[13] = 0; + hheaTable[14] = 0; // minRightSideBearing + hheaTable[15] = 0; + hheaTable[16] = (Guchar)(maxWidth >> 8); // xMaxExtent + hheaTable[17] = (Guchar)maxWidth; + hheaTable[18] = 0; // caretSlopeRise + hheaTable[19] = 1; + hheaTable[20] = 0; // caretSlopeRun + hheaTable[21] = 0; + hheaTable[22] = 0; // caretOffset + hheaTable[23] = 0; + hheaTable[24] = 0; // reserved + hheaTable[25] = 0; + hheaTable[26] = 0; // reserved + hheaTable[27] = 0; + hheaTable[28] = 0; // reserved + hheaTable[29] = 0; + hheaTable[30] = 0; // reserved + hheaTable[31] = 0; + hheaTable[32] = 0; // metricDataFormat + hheaTable[33] = 0; + hheaTable[34] = (Guchar)(nWidths >> 8); // numberOfHMetrics + hheaTable[35] = (Guchar)nWidths; + tableData[4] = hheaTable; + tableLength[4] = 36; + + //--- hmtx table + //~ this currently sets LSB to 0 for all glyphs + hmtxTable = (Guchar *)gmallocn(nWidths, 4); + for (i = 0; i < nWidths; ++i) { + hmtxTable[4*i ] = (Guchar)(widths[i] >> 8); + hmtxTable[4*i+1] = (Guchar)widths[i]; + hmtxTable[4*i+2] = 0; + hmtxTable[4*i+3] = 0; + } + tableData[5] = hmtxTable; + tableLength[5] = 4 * nWidths; + + //--- maxp table + maxpTable[0] = 0x00; // version = 0.5 + maxpTable[1] = 0x00; + maxpTable[2] = 0x50; + maxpTable[3] = 0x00; + maxpTable[4] = (Guchar)(nGlyphs >> 8); // numGlyphs + maxpTable[5] = (Guchar)nGlyphs; + tableData[6] = maxpTable; + tableLength[6] = 6; + + //--- name table + nameTable[ 0] = 0x00; // format + nameTable[ 1] = 0x00; + nameTable[ 2] = 0x00; // count + nameTable[ 3] = 0x01; + nameTable[ 4] = 0x00; // stringOffset + nameTable[ 5] = 0x12; + nameTable[ 6] = 0x00; // platformID + nameTable[ 7] = 0x00; + nameTable[ 8] = 0x00; // encodingID + nameTable[ 9] = 0x03; + nameTable[10] = 0x00; // languageID + nameTable[11] = 0x00; + nameTable[12] = 0x00; // nameID + nameTable[13] = 0x00; + nameTable[14] = 0x00; // length + nameTable[15] = 0x08; + nameTable[16] = 0x00; // offset + nameTable[17] = 0x00; + nameTable[18] = 0x00; // string data + nameTable[19] = (Guchar)'n'; + nameTable[20] = 0x00; + nameTable[21] = (Guchar)'o'; + nameTable[22] = 0x00; + nameTable[23] = (Guchar)'n'; + nameTable[24] = 0x00; + nameTable[25] = (Guchar)'e'; + tableData[7] = nameTable; + tableLength[7] = 26; + + //--- post table + postTable[ 0] = 0x00; // version = 3.0 + postTable[ 1] = 0x03; + postTable[ 2] = 0x00; + postTable[ 3] = 0x00; + postTable[ 4] = 0x00; // italicAngle + postTable[ 5] = 0x00; + postTable[ 6] = 0x00; + postTable[ 7] = 0x00; + postTable[ 8] = 0x00; // underlinePosition + postTable[ 9] = 0x00; + postTable[10] = 0x00; // underlineThickness + postTable[11] = 0x00; + postTable[12] = 0x00; // isFixedPitch + postTable[13] = 0x00; + postTable[14] = 0x00; + postTable[15] = 0x00; + postTable[16] = 0x00; // minMemType42 + postTable[17] = 0x00; + postTable[18] = 0x00; + postTable[19] = 0x00; + postTable[20] = 0x00; // maxMemType42 + postTable[21] = 0x00; + postTable[22] = 0x00; + postTable[23] = 0x00; + postTable[24] = 0x00; // minMemType1 + postTable[25] = 0x00; + postTable[26] = 0x00; + postTable[27] = 0x00; + postTable[28] = 0x00; // maxMemType1 + postTable[29] = 0x00; + postTable[30] = 0x00; + postTable[31] = 0x00; + tableData[8] = postTable; + tableLength[8] = 32; + + //--- header and table directory + header[ 0] = 'O'; // sfnt version + header[ 1] = 'T'; + header[ 2] = 'T'; + header[ 3] = 'O'; + header[ 4] = 0x00; // numTables + header[ 5] = 0x09; + header[ 6] = 0x00; // searchRange + header[ 7] = 0x80; + header[ 8] = 0x00; // entrySelector + header[ 9] = 0x03; + header[10] = 0x00; // rangeShift + header[11] = 0x10; + offset = 12 + 9*16; + fileChecksum = 0; + for (i = 0; i < 9; ++i) { + header[12 + i*16 + 0] = tableTag[i][0]; + header[12 + i*16 + 1] = tableTag[i][1]; + header[12 + i*16 + 2] = tableTag[i][2]; + header[12 + i*16 + 3] = tableTag[i][3]; + checksum = computeOpenTypeTableChecksum(tableData[i], tableLength[i]); + fileChecksum += checksum; + header[12 + i*16 + 4] = (Guchar)(checksum >> 24); + header[12 + i*16 + 5] = (Guchar)(checksum >> 16); + header[12 + i*16 + 6] = (Guchar)(checksum >> 8); + header[12 + i*16 + 7] = (Guchar)checksum; + header[12 + i*16 + 8] = (Guchar)(offset >> 24); + header[12 + i*16 + 9] = (Guchar)(offset >> 16); + header[12 + i*16 + 10] = (Guchar)(offset >> 8); + header[12 + i*16 + 11] = (Guchar)offset; + header[12 + i*16 + 12] = (Guchar)(tableLength[i] >> 24); + header[12 + i*16 + 13] = (Guchar)(tableLength[i] >> 16); + header[12 + i*16 + 14] = (Guchar)(tableLength[i] >> 8); + header[12 + i*16 + 15] = (Guchar)tableLength[i]; + offset += tableLength[i]; + if (tableLength[i] & 3) { + offset += 4 - (tableLength[i] & 3); + } + } + + //--- file checksum + fileChecksum += computeOpenTypeTableChecksum(header, 12 + 9*16); + fileChecksum = 0xb1b0afba - fileChecksum; + headTable[ 8] = (Guchar)(fileChecksum >> 24); + headTable[ 9] = (Guchar)(fileChecksum >> 16); + headTable[10] = (Guchar)(fileChecksum >> 8); + headTable[11] = (Guchar)fileChecksum; + + //--- write the OpenType font + (*outputFunc)(outputStream, (char *)header, 12 + 9*16); + for (i = 0; i < 9; ++i) { + (*outputFunc)(outputStream, (char *)tableData[i], tableLength[i]); + if (tableLength[i] & 3) { + (*outputFunc)(outputStream, "\0\0\0", 4 - (tableLength[i] & 3)); + } + } + + gfree(hmtxTable); +} + +Guint FoFiType1C::computeOpenTypeTableChecksum(Guchar *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; +} + GBool FoFiType1C::parse() { Type1CIndex fdIdx; Type1CIndexVal val; @@ -2577,7 +2960,14 @@ void FoFiType1C::readFDSelect() { parsedOk = gFalse; return; } - memcpy(fdSelect, file + pos, nGlyphs); + for (gid0 = 0; gid0 < nGlyphs; ++gid0) { + if (file[pos + gid0] >= nFDs) { + //~ error(-1, "Bad FDSelect table in CID font"); + parsedOk = gFalse; + return; + } + fdSelect[gid0] = file[pos + gid0]; + } } else if (fdSelectFmt == 3) { nRanges = getU16BE(pos, &parsedOk); pos += 2; @@ -2590,7 +2980,7 @@ void FoFiType1C::readFDSelect() { return; } pos += 2; - if (gid0 > gid1 || gid1 > nGlyphs) { + if (gid0 > gid1 || gid1 > nGlyphs || fd >= nFDs) { //~ error(-1, "Bad FDSelect table in CID font"); parsedOk = gFalse; return; @@ -2703,10 +3093,19 @@ GBool FoFiType1C::readCharset() { if (topDict.charsetOffset == 0) { charset = fofiType1CISOAdobeCharset; + if (nGlyphs > 229) { + nGlyphs = 229; + } } else if (topDict.charsetOffset == 1) { charset = fofiType1CExpertCharset; + if (nGlyphs > 166) { + nGlyphs = 166; + } } else if (topDict.charsetOffset == 2) { charset = fofiType1CExpertSubsetCharset; + if (nGlyphs > 87) { + nGlyphs = 87; + } } else { charset = (Gushort *)gmallocn(nGlyphs, sizeof(Gushort)); for (i = 0; i < nGlyphs; ++i) { |