summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/fofi
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/fofi')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc34
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h15
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc41
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc403
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h13
6 files changed, 482 insertions, 27 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
index 07cc3fcd52f..e1951b08b9f 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
@@ -171,6 +171,7 @@ Guint FoFiBase::getUVarBE(int pos, int size, GBool *ok) {
GBool FoFiBase::checkRegion(int pos, int size) {
return pos >= 0 &&
- pos + size >= pos &&
+ size >= 0 &&
+ size <= INT_MAX - pos &&
pos + size <= len;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
index 3709a1f2809..0f5b5bc7230 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
@@ -320,6 +320,7 @@ FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA,
nCmaps = 0;
nameToGID = NULL;
isDfont = isDfontA;
+ isTTC = gFalse;
parsedOk = gFalse;
parse(fontNum, allowHeadlessCFF);
@@ -985,7 +986,8 @@ void FoFiTrueType::convertToType0(char *psName, int *cidMap, int nCIDs,
GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
void *outputStream, char *name,
- int *codeToGID) {
+ int *codeToGID, Guchar *replacementCmapTable,
+ int replacementCmapTableLen) {
// this substitute cmap table maps char code ffff to glyph 0,
// with tables for MacRoman and MS Unicode
static char cmapTab[44] = {
@@ -1188,7 +1190,7 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
if (!missingCmap && !missingName && !missingPost && !missingOS2 &&
!unsortedLoca && !emptyCmap && !badCmapLen && !abbrevHMTX &&
nZeroLengthTables == 0 && nBogusTables == 0 &&
- !name && !codeToGID && !isDfont) {
+ !name && !codeToGID && !replacementCmapTable && !isDfont && !isTTC) {
(*outputFunc)(outputStream, (char *)file, len);
gfree(locaTable);
return gFalse;
@@ -1306,7 +1308,7 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
}
// construct the new cmap table
- if (codeToGID) {
+ if (codeToGID && !replacementCmapTable) {
newCmapLen = 44 + 256 * 2;
newCmapTab = (char *)gmalloc(newCmapLen);
newCmapTab[0] = 0; // table version number = 0
@@ -1435,8 +1437,15 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
// don't include the file checksum
newTables[j].checksum -= getU32BE(tables[i].offset + 8, &ok);
}
+ } else {
+ // we'll write four zero bytes for this table
+ newTables[j].len = 4;
}
- if (newTables[j].tag == cmapTag && codeToGID) {
+ if (newTables[j].tag == cmapTag && replacementCmapTable) {
+ newTables[j].len = replacementCmapTableLen;
+ newTables[j].checksum = computeTableChecksum(replacementCmapTable,
+ replacementCmapTableLen);
+ } else if (newTables[j].tag == cmapTag && codeToGID) {
newTables[j].len = newCmapLen;
newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
newCmapLen);
@@ -1470,7 +1479,11 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
}
if (missingCmap) {
newTables[j].tag = cmapTag;
- if (codeToGID) {
+ if (replacementCmapTable) {
+ newTables[j].checksum = computeTableChecksum(replacementCmapTable,
+ replacementCmapTableLen);
+ newTables[j].len = replacementCmapTableLen;
+ } else if (codeToGID) {
newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
newCmapLen);
newTables[j].len = newCmapLen;
@@ -1588,6 +1601,9 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
(*outputFunc)(outputStream, "\0", 1);
}
}
+ } else if (newTables[i].tag == cmapTag && replacementCmapTable) {
+ (*outputFunc)(outputStream, (char *)replacementCmapTable,
+ newTables[i].len);
} else if (newTables[i].tag == cmapTag && codeToGID) {
(*outputFunc)(outputStream, newCmapTab, newTables[i].len);
} else if (newTables[i].tag == cmapTag && missingCmap) {
@@ -1816,7 +1832,8 @@ void FoFiTrueType::cvtSfnts(FoFiOutputFunc outputFunc,
} else {
locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok);
}
- if (locaTable[i].origOffset > glyfTableLen) {
+ if (locaTable[i].origOffset < 0 ||
+ locaTable[i].origOffset > glyfTableLen) {
locaTable[i].origOffset = glyfTableLen;
}
}
@@ -2172,7 +2189,9 @@ void FoFiTrueType::parse(int fontNum, GBool allowHeadlessCFF) {
tables[j].checksum = getU32BE(offset + pos + 4, &parsedOk);
tables[j].offset = offset + (int)getU32BE(offset + pos + 8, &parsedOk);
tables[j].len = (int)getU32BE(offset + pos + 12, &parsedOk);
- if (tables[j].offset + tables[j].len >= tables[j].offset &&
+ if (tables[j].offset >= 0 &&
+ tables[j].len >= 0 &&
+ tables[j].offset + tables[j].len >= tables[j].offset &&
tables[j].offset + tables[j].len <= len) {
// ignore any bogus entries in the table directory
++j;
@@ -2274,6 +2293,7 @@ void FoFiTrueType::parse(int fontNum, GBool allowHeadlessCFF) {
void FoFiTrueType::parseTTC(int fontNum, int *pos) {
int nFonts;
+ isTTC = gTrue;
nFonts = getU32BE(8, &parsedOk);
if (!parsedOk) {
return;
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
index a0f759b2a6f..619e1bd6676 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
@@ -95,6 +95,9 @@ public:
// for OpenType CFF fonts.)
void getFontMatrix(double *mat);
+ // Return the number of glyphs in the font.
+ int getNumGlyphs() { return nGlyphs; }
+
// Returns true if this looks like a CJK font that uses bytecode
// instructions to assemble glyphs.
GBool checkForTrickyCJK();
@@ -154,10 +157,15 @@ public:
// various other errors. If <name> is non-NULL, the font is renamed
// to <name>. If <codeToGID> is non-NULL, the font is re-encoded,
// using a Windows Unicode cmap. If <name> is NULL and the font is
- // complete and correct, it will be written unmodified. (Not useful
- // for OpenType CFF fonts.) Returns true if the font was modified.
+ // complete and correct, it will be written unmodified. If
+ // <replacementCmapTable> is non-NULL it will be used as the cmap
+ // table in the written font (overriding any existing cmap table
+ // and/or the codeToGID arg). (Not useful for OpenType CFF fonts.)
+ // Returns true if the font was modified.
GBool writeTTF(FoFiOutputFunc outputFunc, void *outputStream,
- char *name = NULL, int *codeToGID = NULL);
+ char *name = NULL, int *codeToGID = NULL,
+ Guchar *replacementCmapTable = NULL,
+ int replacementCmapTableLen = 0);
// Returns a pointer to the CFF font embedded in this OpenType font.
// If successful, sets *<start> and *<length>, and returns true.
@@ -200,6 +208,7 @@ private:
GBool openTypeCFF;
GBool headlessCFF;
GBool isDfont;
+ GBool isTTC;
GBool parsedOk;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
index 4f5972a7bbb..0d067b5c5a9 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
@@ -99,7 +99,7 @@ void FoFiType1::writeEncoded(const char **newEncoding,
// copy everything up to the encoding
for (line = (char *)file;
- line && strncmp(line, "/Encoding", 9);
+ line && line + 9 <= (char *)file + len && strncmp(line, "/Encoding", 9);
line = getNextLine(line)) ;
if (!line) {
// no encoding - just copy the whole font file
@@ -122,7 +122,8 @@ void FoFiType1::writeEncoded(const char **newEncoding,
// find the end of the encoding data
//~ this ought to parse PostScript tokens
- if (!strncmp(line, "/Encoding StandardEncoding def", 30)) {
+ if (line + 30 <= (char *)file + len &&
+ !strncmp(line, "/Encoding StandardEncoding def", 30)) {
line = getNextLine(line);
} else {
// skip "/Encoding" + one whitespace char,
@@ -144,16 +145,18 @@ void FoFiType1::writeEncoded(const char **newEncoding,
// check for a second one here
if (line) {
for (line2 = line, i = 0;
- i < 20 && line2 && strncmp(line2, "/Encoding", 9);
+ i < 20 && line2 && line2 + 9 <= (char *)file + len &&
+ strncmp(line2, "/Encoding", 9);
line2 = getNextLine(line2), ++i) ;
if (i < 20 && line2) {
(*outputFunc)(outputStream, line, (int)(line2 - line));
- if (!strncmp(line2, "/Encoding StandardEncoding def", 30)) {
+ if (line2 + 30 <= (char *)file + len &&
+ !strncmp(line2, "/Encoding StandardEncoding def", 30)) {
line = getNextLine(line2);
} else {
- // skip "/Encoding" + one whitespace char,
+ // skip "/Encoding",
// then look for 'def' preceded by PostScript whitespace
- p = line2 + 10;
+ p = line2 + 9;
line = NULL;
for (; p < (char *)file + len; ++p) {
if ((*p == ' ' || *p == '\t' || *p == '\x0a' ||
@@ -203,9 +206,14 @@ void FoFiType1::parse() {
++i) {
// get font name
- if (!name && !strncmp(line, "/FontName", 9)) {
- strncpy(buf, line, 255);
- buf[255] = '\0';
+ if (!name && line + 9 <= (char *)file + len &&
+ !strncmp(line, "/FontName", 9)) {
+ n = 255;
+ if (line + n > (char *)file + len) {
+ n = (int)(((char *)file + len) - line);
+ }
+ strncpy(buf, line, n);
+ buf[n] = '\0';
if ((p = strchr(buf+9, '/')) &&
(p = strtok(p+1, " \t\n\r"))) {
name = copyString(p);
@@ -213,10 +221,10 @@ void FoFiType1::parse() {
line = getNextLine(line);
// get encoding
- } else if (!encoding &&
+ } else if (!encoding && line + 30 <= (char *)file + len &&
!strncmp(line, "/Encoding StandardEncoding def", 30)) {
encoding = (char **)fofiType1StandardEncoding;
- } else if (!encoding &&
+ } else if (!encoding && line + 19 <= (char *)file + len &&
!strncmp(line, "/Encoding 256 array", 19)) {
encoding = (char **)gmallocn(256, sizeof(char *));
for (j = 0; j < 256; ++j) {
@@ -284,9 +292,14 @@ void FoFiType1::parse() {
}
//~ check for getinterval/putinterval junk
- } else if (!gotMatrix && !strncmp(line, "/FontMatrix", 11)) {
- strncpy(buf, line + 11, 255);
- buf[255] = '\0';
+ } else if (!gotMatrix && line + 11 <= (char *)file + len &&
+ !strncmp(line, "/FontMatrix", 11)) {
+ n = 255;
+ if (line + 11 + n > (char *)file + len) {
+ n = (int)(((char *)file + len) - (line + 11));
+ }
+ strncpy(buf, line + 11, n);
+ buf[n] = '\0';
if ((p = strchr(buf, '['))) {
++p;
if ((p2 = strchr(p, ']'))) {
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) {
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
index ae869687898..eb75dce330d 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
@@ -18,6 +18,7 @@
#include "gtypes.h"
#include "FoFiBase.h"
+class GHash;
class GString;
//------------------------------------------------------------------------
@@ -169,6 +170,10 @@ public:
int getNumGlyphs() { return nGlyphs; }
GString *getGlyphName(int gid);
+ // Returns a hash mapping glyph names to GIDs. This is only useful
+ // with 8-bit fonts.
+ GHash *getNameToGIDMap();
+
// Return the mapping from CIDs to GIDs, and return the number of
// CIDs in *<nCIDs>. This is only useful for CID fonts.
int *getCIDToGIDMap(int *nCIDs);
@@ -208,6 +213,13 @@ public:
void convertToType0(char *psName, int *codeMap, int nCodes,
FoFiOutputFunc outputFunc, void *outputStream);
+ // Write an OpenType file, encapsulating the CFF font. <widths>
+ // provides the glyph widths (in design units) for <nWidths> glyphs.
+ // The cmap table must be supplied by the caller.
+ void convertToOpenType(FoFiOutputFunc outputFunc, void *outputStream,
+ int nWidths, Gushort *widths,
+ Guchar *cmapTable, int cmapTableLen);
+
private:
FoFiType1C(char *fileA, int lenA, GBool freeFileDataA);
@@ -224,6 +236,7 @@ private:
void eexecWrite(Type1CEexecBuf *eb, const char *s);
void eexecWriteCharstring(Type1CEexecBuf *eb, Guchar *s, int n);
void writePSString(char *s, FoFiOutputFunc outputFunc, void *outputStream);
+ Guint computeOpenTypeTableChecksum(Guchar *data, int length);
GBool parse();
void readTopDict();
void readFD(int offset, int length, Type1CPrivateDict *pDict);