#endif
#include <stdlib.h>
+#include <string.h>
#include "gtypes.h"
#include "gmem.h"
#include "GString.h"
//------------------------------------------------------------------------
+#define ttcfTag 0x74746366
+
+//------------------------------------------------------------------------
+
struct TrueTypeTable {
Guint tag;
Guint checksum;
#define cmapTag 0x636d6170
#define glyfTag 0x676c7966
+#define headTag 0x68656164
#define locaTag 0x6c6f6361
#define nameTag 0x6e616d65
#define postTag 0x706f7374
{ "vhea", gFalse },
{ "vmtx", gFalse }
};
-#define t42HeadTable 3
-#define t42LocaTable 6
-#define t42GlyfTable 2
+#define t42HeadTable 3
+#define t42LocaTable 6
+#define t42GlyfTable 2
+#define t42VheaTable 9
+#define t42VmtxTable 10
//------------------------------------------------------------------------
FoFiTrueType::~FoFiTrueType() {
gfree(tables);
gfree(cmaps);
- delete nameToGID;
+ if (nameToGID) {
+ delete nameToGID;
+ }
}
int FoFiTrueType::getNumCmaps() {
// write the guts of the dictionary
cvtEncoding(encoding, outputFunc, outputStream);
cvtCharStrings(encoding, codeToGID, outputFunc, outputStream);
- cvtSfnts(outputFunc, outputStream, NULL);
+ cvtSfnts(outputFunc, outputStream, NULL, gFalse);
// end the dictionary and define the font
(*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40);
void FoFiTrueType::convertToCIDType2(char *psName,
Gushort *cidMap, int nCIDs,
+ GBool needVerticalMetrics,
FoFiOutputFunc outputFunc,
void *outputStream) {
char buf[512];
(*outputFunc)(outputStream, " end readonly def\n", 19);
// write the guts of the dictionary
- cvtSfnts(outputFunc, outputStream, NULL);
+ cvtSfnts(outputFunc, outputStream, NULL, needVerticalMetrics);
// end the dictionary and define the font
(*outputFunc)(outputStream,
}
void FoFiTrueType::convertToType0(char *psName, Gushort *cidMap, int nCIDs,
+ GBool needVerticalMetrics,
FoFiOutputFunc outputFunc,
void *outputStream) {
char buf[512];
// write the Type 42 sfnts array
sfntsName = (new GString(psName))->append("_sfnts");
- cvtSfnts(outputFunc, outputStream, sfntsName);
+ cvtSfnts(outputFunc, outputStream, sfntsName, needVerticalMetrics);
delete sfntsName;
// write the descendant Type 42 fonts
}
void FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
- void *outputStream) {
- static char cmapTab[20] = {
+ void *outputStream, char *name,
+ Gushort *codeToGID) {
+ // this substitute cmap table maps char codes 0000-ffff directly to
+ // glyphs 0000-ffff
+ static char cmapTab[36] = {
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
+ 0, 4, // subtable format
+ 0, 24, // subtable length
+ 0, 0, // subtable version
+ 0, 2, // segment count * 2
+ 0, 2, // 2 * 2 ^ floor(log2(segCount))
+ 0, 0, // floor(log2(segCount))
+ 0, 0, // 2*segCount - 2*2^floor(log2(segCount))
+ (char)0xff, (char)0xff, // endCount[0]
+ 0, 0, // reserved
+ 0, 0, // startCount[0]
+ 0, 0, // idDelta[0]
+ 0, 0 // pad to a mulitple of four bytes
};
static char nameTab[8] = {
0, 0, // format
int nZeroLengthTables;
TrueTypeLoca *locaTable;
TrueTypeTable *newTables;
- int nNewTables, cmapIdx, cmapLen, glyfLen;
+ char *newNameTab, *newCmapTab;
+ int nNewTables, cmapIdx, cmapLen, glyfLen, newNameLen, newCmapLen, next;
+ Guint locaChecksum, glyfChecksum, fileChecksum;
char *tableDir;
- char locaBuf[4];
+ char locaBuf[4], checksumBuf[4];
GBool ok;
Guint t;
int pos, i, j, k, n;
missingPost = seekTable("post") < 0;
// read the loca table, check to see if it's sorted
- locaTable = (TrueTypeLoca *)gmalloc((nGlyphs + 1) * sizeof(TrueTypeLoca));
+ locaTable = (TrueTypeLoca *)gmallocn(nGlyphs + 1, sizeof(TrueTypeLoca));
unsortedLoca = gFalse;
i = seekTable("loca");
pos = tables[i].offset;
// if nothing is broken, just write the TTF file as is
if (!missingCmap && !missingName && !missingPost && !unsortedLoca &&
- !badCmapLen && nZeroLengthTables == 0) {
+ !badCmapLen && nZeroLengthTables == 0 && !name && !codeToGID) {
(*outputFunc)(outputStream, (char *)file, len);
goto done1;
}
glyfLen = pos;
}
+ // compute checksums for the loca and glyf tables
+ locaChecksum = glyfChecksum = 0;
+ if (unsortedLoca) {
+ if (locaFmt) {
+ for (j = 0; j <= nGlyphs; ++j) {
+ locaChecksum += locaTable[j].newOffset;
+ }
+ } else {
+ for (j = 0; j <= nGlyphs; j += 2) {
+ locaChecksum += locaTable[j].newOffset << 16;
+ if (j + 1 <= nGlyphs) {
+ locaChecksum += locaTable[j+1].newOffset;
+ }
+ }
+ }
+ pos = tables[seekTable("glyf")].offset;
+ for (j = 0; j < nGlyphs; ++j) {
+ n = locaTable[j].len;
+ if (n > 0) {
+ k = locaTable[j].origOffset;
+ if (checkRegion(pos + k, n)) {
+ glyfChecksum += computeTableChecksum(file + pos + k, n);
+ }
+ }
+ }
+ }
+
+ // construct the new name table
+ if (name) {
+ n = strlen(name);
+ newNameLen = (6 + 4*12 + 2 * (3*n + 7) + 3) & ~3;
+ newNameTab = (char *)gmalloc(newNameLen);
+ memset(newNameTab, 0, newNameLen);
+ newNameTab[0] = 0; // format selector
+ newNameTab[1] = 0;
+ newNameTab[2] = 0; // number of name records
+ newNameTab[3] = 4;
+ newNameTab[4] = 0; // offset to start of string storage
+ newNameTab[5] = 6 + 4*12;
+ next = 0;
+ for (i = 0; i < 4; ++i) {
+ newNameTab[6 + i*12 + 0] = 0; // platform ID = Microsoft
+ newNameTab[6 + i*12 + 1] = 3;
+ newNameTab[6 + i*12 + 2] = 0; // encoding ID = Unicode
+ newNameTab[6 + i*12 + 3] = 1;
+ newNameTab[6 + i*12 + 4] = 0x04; // language ID = American English
+ newNameTab[6 + i*12 + 5] = 0x09;
+ newNameTab[6 + i*12 + 6] = 0; // name ID
+ newNameTab[6 + i*12 + 7] = i + 1;
+ newNameTab[6 + i*12 + 8] = i+1 == 2 ? 0 : ((2*n) >> 8); // string length
+ newNameTab[6 + i*12 + 9] = i+1 == 2 ? 14 : ((2*n) & 0xff);
+ newNameTab[6 + i*12 + 10] = next >> 8; // string offset
+ newNameTab[6 + i*12 + 11] = next & 0xff;
+ if (i+1 == 2) {
+ memcpy(newNameTab + 6 + 4*12 + next, "\0R\0e\0g\0u\0l\0a\0r", 14);
+ next += 14;
+ } else {
+ for (j = 0; j < n; ++j) {
+ newNameTab[6 + 4*12 + next + 2*j] = 0;
+ newNameTab[6 + 4*12 + next + 2*j + 1] = name[j];
+ }
+ next += 2*n;
+ }
+ }
+ } else {
+ newNameLen = 0;
+ newNameTab = NULL;
+ }
+
+ // construct the new cmap table
+ if (codeToGID) {
+ newCmapLen = 44 + 256 * 2;
+ newCmapTab = (char *)gmalloc(newCmapLen);
+ newCmapTab[0] = 0; // table version number = 0
+ newCmapTab[1] = 0;
+ newCmapTab[2] = 0; // number of encoding tables = 1
+ newCmapTab[3] = 1;
+ newCmapTab[4] = 0; // platform ID = Microsoft
+ newCmapTab[5] = 3;
+ newCmapTab[6] = 0; // encoding ID = Unicode
+ newCmapTab[7] = 1;
+ newCmapTab[8] = 0; // offset of subtable
+ newCmapTab[9] = 0;
+ newCmapTab[10] = 0;
+ newCmapTab[11] = 12;
+ newCmapTab[12] = 0; // subtable format = 4
+ newCmapTab[13] = 4;
+ newCmapTab[14] = 0x02; // subtable length
+ newCmapTab[15] = 0x20;
+ newCmapTab[16] = 0; // subtable version = 0
+ newCmapTab[17] = 0;
+ newCmapTab[18] = 0; // segment count * 2
+ newCmapTab[19] = 4;
+ newCmapTab[20] = 0; // 2 * 2 ^ floor(log2(segCount))
+ newCmapTab[21] = 4;
+ newCmapTab[22] = 0; // floor(log2(segCount))
+ newCmapTab[23] = 1;
+ newCmapTab[24] = 0; // 2*segCount - 2*2^floor(log2(segCount))
+ newCmapTab[25] = 0;
+ newCmapTab[26] = 0x00; // endCount[0]
+ newCmapTab[27] = (char)0xff;
+ newCmapTab[28] = (char)0xff; // endCount[1]
+ newCmapTab[29] = (char)0xff;
+ newCmapTab[30] = 0; // reserved
+ newCmapTab[31] = 0;
+ newCmapTab[32] = 0x00; // startCount[0]
+ newCmapTab[33] = 0x00;
+ newCmapTab[34] = (char)0xff; // startCount[1]
+ newCmapTab[35] = (char)0xff;
+ newCmapTab[36] = 0; // idDelta[0]
+ newCmapTab[37] = 0;
+ newCmapTab[38] = 0; // idDelta[1]
+ newCmapTab[39] = 1;
+ newCmapTab[40] = 0; // idRangeOffset[0]
+ newCmapTab[41] = 4;
+ newCmapTab[42] = 0; // idRangeOffset[1]
+ newCmapTab[43] = 0;
+ for (i = 0; i < 256; ++i) {
+ newCmapTab[44 + 2*i] = codeToGID[i] >> 8;
+ newCmapTab[44 + 2*i + 1] = codeToGID[i] & 0xff;
+ }
+ } else {
+ newCmapLen = 0;
+ newCmapTab = NULL;
+ }
+
// construct the new table directory:
// - keep all original tables with non-zero length
// - fix the cmap table's length, if necessary
// - add missing tables
// - sort the table by tag
// - compute new table positions, including 4-byte alignment
+ // - (re)compute table checksums
nNewTables = nTables - nZeroLengthTables +
(missingCmap ? 1 : 0) + (missingName ? 1 : 0) +
(missingPost ? 1 : 0);
- newTables = (TrueTypeTable *)gmalloc(nNewTables * sizeof(TrueTypeTable));
+ newTables = (TrueTypeTable *)gmallocn(nNewTables, sizeof(TrueTypeTable));
j = 0;
for (i = 0; i < nTables; ++i) {
if (tables[i].len > 0) {
newTables[j] = tables[i];
newTables[j].origOffset = tables[i].offset;
- if (newTables[j].tag == cmapTag && badCmapLen) {
+ if (checkRegion(tables[i].offset, newTables[i].len)) {
+ newTables[j].checksum =
+ computeTableChecksum(file + tables[i].offset, tables[i].len);
+ if (tables[i].tag == headTag) {
+ // don't include the file checksum
+ newTables[j].checksum -= getU32BE(tables[i].offset + 8, &ok);
+ }
+ }
+ if (newTables[j].tag == cmapTag && codeToGID) {
+ newTables[j].len = newCmapLen;
+ newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
+ newCmapLen);
+ } else if (newTables[j].tag == cmapTag && badCmapLen) {
newTables[j].len = cmapLen;
} else if (newTables[j].tag == locaTag && unsortedLoca) {
newTables[j].len = (nGlyphs + 1) * (locaFmt ? 4 : 2);
+ newTables[j].checksum = locaChecksum;
} else if (newTables[j].tag == glyfTag && unsortedLoca) {
newTables[j].len = glyfLen;
+ newTables[j].checksum = glyfChecksum;
+ } else if (newTables[j].tag == nameTag && name) {
+ newTables[j].len = newNameLen;
+ newTables[j].checksum = computeTableChecksum((Guchar *)newNameTab,
+ newNameLen);
}
++j;
}
}
if (missingCmap) {
newTables[j].tag = cmapTag;
- newTables[j].checksum = 0; //~ should compute the checksum
- newTables[j].len = sizeof(cmapTab);
+ if (codeToGID) {
+ newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
+ newCmapLen);
+ newTables[j].len = newCmapLen;
+ } else {
+ newTables[j].checksum = computeTableChecksum((Guchar *)cmapTab,
+ sizeof(cmapTab));
+ newTables[j].len = sizeof(cmapTab);
+ }
++j;
}
if (missingName) {
newTables[j].tag = nameTag;
- newTables[j].checksum = 0; //~ should compute the checksum
- newTables[j].len = sizeof(nameTab);
+ if (name) {
+ newTables[j].checksum = computeTableChecksum((Guchar *)newNameTab,
+ newNameLen);
+ newTables[j].len = newNameLen;
+ } else {
+ newTables[j].checksum = computeTableChecksum((Guchar *)nameTab,
+ sizeof(nameTab));
+ newTables[j].len = sizeof(nameTab);
+ }
++j;
}
if (missingPost) {
newTables[j].tag = postTag;
- newTables[j].checksum = 0; //~ should compute the checksum
+ newTables[j].checksum = computeTableChecksum((Guchar *)postTab,
+ sizeof(postTab));
newTables[j].len = sizeof(postTab);
++j;
}
}
(*outputFunc)(outputStream, tableDir, 12 + nNewTables * 16);
+ // compute the file checksum
+ fileChecksum = computeTableChecksum((Guchar *)tableDir,
+ 12 + nNewTables * 16);
+ for (i = 0; i < nNewTables; ++i) {
+ fileChecksum += newTables[i].checksum;
+ }
+ fileChecksum = 0xb1b0afba - fileChecksum;
+
// write the tables
for (i = 0; i < nNewTables; ++i) {
- if (newTables[i].tag == cmapTag && missingCmap) {
+ if (newTables[i].tag == headTag) {
+ if (checkRegion(newTables[i].origOffset, newTables[i].len)) {
+ (*outputFunc)(outputStream, (char *)file + newTables[i].origOffset, 8);
+ checksumBuf[0] = fileChecksum >> 24;
+ checksumBuf[1] = fileChecksum >> 16;
+ checksumBuf[2] = fileChecksum >> 8;
+ checksumBuf[3] = fileChecksum;
+ (*outputFunc)(outputStream, checksumBuf, 4);
+ (*outputFunc)(outputStream,
+ (char *)file + newTables[i].origOffset + 12,
+ newTables[i].len - 12);
+ } else {
+ for (j = 0; j < newTables[i].len; ++j) {
+ (*outputFunc)(outputStream, "\0", 1);
+ }
+ }
+ } else if (newTables[i].tag == cmapTag && codeToGID) {
+ (*outputFunc)(outputStream, newCmapTab, newTables[i].len);
+ } else if (newTables[i].tag == cmapTag && missingCmap) {
(*outputFunc)(outputStream, cmapTab, newTables[i].len);
+ } else if (newTables[i].tag == nameTag && name) {
+ (*outputFunc)(outputStream, newNameTab, newTables[i].len);
} else if (newTables[i].tag == nameTag && missingName) {
(*outputFunc)(outputStream, nameTab, newTables[i].len);
} else if (newTables[i].tag == postTag && missingPost) {
}
}
+ gfree(newCmapTab);
+ gfree(newNameTab);
gfree(tableDir);
gfree(newTables);
done1:
}
void FoFiTrueType::cvtSfnts(FoFiOutputFunc outputFunc,
- void *outputStream, GString *name) {
+ void *outputStream, GString *name,
+ GBool needVerticalMetrics) {
Guchar headData[54];
TrueTypeLoca *locaTable;
Guchar *locaData;
Guint checksum;
int nNewTables;
int length, pos, glyfPos, i, j, k;
+ Guchar vheaTab[36] = {
+ 0, 1, 0, 0, // table version number
+ 0, 0, // ascent
+ 0, 0, // descent
+ 0, 0, // reserved
+ 0, 0, // max advance height
+ 0, 0, // min top side bearing
+ 0, 0, // min bottom side bearing
+ 0, 0, // y max extent
+ 0, 0, // caret slope rise
+ 0, 1, // caret slope run
+ 0, 0, // caret offset
+ 0, 0, // reserved
+ 0, 0, // reserved
+ 0, 0, // reserved
+ 0, 0, // reserved
+ 0, 0, // metric data format
+ 0, 1 // number of advance heights in vmtx table
+ };
+ Guchar *vmtxTab;
+ GBool needVhea, needVmtx;
+ int advance;
// construct the 'head' table, zero out the font checksum
i = seekTable("head");
// table, cmpTrueTypeLocaPos uses offset as its primary sort key,
// and idx as its secondary key (ensuring that adjacent entries with
// the same pos value remain in the same order)
- locaTable = (TrueTypeLoca *)gmalloc((nGlyphs + 1) * sizeof(TrueTypeLoca));
+ locaTable = (TrueTypeLoca *)gmallocn(nGlyphs + 1, sizeof(TrueTypeLoca));
i = seekTable("loca");
pos = tables[i].offset;
ok = gTrue;
}
// construct the new 'loca' table
- locaData = (Guchar *)gmalloc((nGlyphs + 1) * (locaFmt ? 4 : 2));
+ locaData = (Guchar *)gmallocn(nGlyphs + 1, (locaFmt ? 4 : 2));
for (i = 0; i <= nGlyphs; ++i) {
pos = locaTable[i].newOffset;
if (locaFmt) {
++nNewTables;
}
}
+ vmtxTab = NULL; // make gcc happy
+ advance = 0; // make gcc happy
+ if (needVerticalMetrics) {
+ needVhea = seekTable("vhea") < 0;
+ needVmtx = seekTable("vmtx") < 0;
+ if (needVhea || needVmtx) {
+ i = seekTable("head");
+ advance = getU16BE(tables[i].offset + 18, &ok); // units per em
+ if (needVhea) {
+ ++nNewTables;
+ }
+ if (needVmtx) {
+ ++nNewTables;
+ }
+ }
+ }
// construct the new table headers, including table checksums
// (pad each table out to a multiple of 4 bytes)
if (checkRegion(tables[j].offset, length)) {
checksum = computeTableChecksum(file + tables[j].offset, length);
}
+ } else if (needVerticalMetrics && i == t42VheaTable) {
+ vheaTab[10] = advance / 256; // max advance height
+ vheaTab[11] = advance % 256;
+ length = sizeof(vheaTab);
+ checksum = computeTableChecksum(vheaTab, length);
+ } else if (needVerticalMetrics && i == t42VmtxTable) {
+ length = 4 + (nGlyphs - 1) * 4;
+ vmtxTab = (Guchar *)gmalloc(length);
+ vmtxTab[0] = advance / 256;
+ vmtxTab[1] = advance % 256;
+ for (j = 2; j < length; j += 2) {
+ vmtxTab[j] = 0;
+ vmtxTab[j+1] = 0;
+ }
+ checksum = computeTableChecksum(vmtxTab, length);
} else if (t42Tables[i].required) {
//~ error(-1, "Embedded TrueType font is missing a required table ('%s')",
//~ t42Tables[i].tag);
checkRegion(tables[j].offset, tables[j].len)) {
dumpString(file + tables[j].offset, tables[j].len,
outputFunc, outputStream);
+ } else if (needVerticalMetrics && i == t42VheaTable) {
+ dumpString(vheaTab, length, outputFunc, outputStream);
+ } else if (needVerticalMetrics && i == t42VmtxTable) {
+ dumpString(vmtxTab, length, outputFunc, outputStream);
+ gfree(vmtxTab);
}
}
}
}
void FoFiTrueType::parse() {
+ Guint topTag;
int pos, i, j;
parsedOk = gTrue;
+ // look for a collection (TTC)
+ topTag = getU32BE(0, &parsedOk);
+ if (!parsedOk) {
+ return;
+ }
+ if (topTag == ttcfTag) {
+ pos = getU32BE(12, &parsedOk);
+ if (!parsedOk) {
+ return;
+ }
+ } else {
+ pos = 0;
+ }
+
// read the table directory
- nTables = getU16BE(4, &parsedOk);
+ nTables = getU16BE(pos + 4, &parsedOk);
if (!parsedOk) {
return;
}
- tables = (TrueTypeTable *)gmalloc(nTables * sizeof(TrueTypeTable));
- pos = 12;
+ tables = (TrueTypeTable *)gmallocn(nTables, sizeof(TrueTypeTable));
+ pos += 12;
for (i = 0; i < nTables; ++i) {
tables[i].tag = getU32BE(pos, &parsedOk);
tables[i].checksum = getU32BE(pos + 4, &parsedOk);
if (!parsedOk) {
return;
}
- cmaps = (TrueTypeCmap *)gmalloc(nCmaps * sizeof(TrueTypeCmap));
+ cmaps = (TrueTypeCmap *)gmallocn(nCmaps, sizeof(TrueTypeCmap));
for (j = 0; j < nCmaps; ++j) {
cmaps[j].platform = getU16BE(pos, &parsedOk);
cmaps[j].encoding = getU16BE(pos + 2, &parsedOk);
return;
}
- // read the post table
- readPostTable();
+ // make sure the loca table is sane (correct length and entries are
+ // in bounds)
+ i = seekTable("loca");
+ if (tables[i].len < (nGlyphs + 1) * (locaFmt ? 4 : 2)) {
+ parsedOk = gFalse;
+ return;
+ }
+ for (j = 0; j <= nGlyphs; ++j) {
+ if (locaFmt) {
+ pos = (int)getU32BE(tables[i].offset + j*4, &parsedOk);
+ } else {
+ pos = getU16BE(tables[i].offset + j*2, &parsedOk);
+ }
+ if (pos < 0 || pos > len) {
+ parsedOk = gFalse;
+ }
+ }
if (!parsedOk) {
return;
}
+
+ // read the post table
+ readPostTable();
}
void FoFiTrueType::readPostTable() {
GString *name;
int tablePos, postFmt, stringIdx, stringPos;
+ GBool ok;
int i, j, n, m;
+ ok = gTrue;
if ((i = seekTable("post")) < 0) {
return;
}
tablePos = tables[i].offset;
- postFmt = getU32BE(tablePos, &parsedOk);
- if (!parsedOk) {
- return;
+ postFmt = getU32BE(tablePos, &ok);
+ if (!ok) {
+ goto err;
}
if (postFmt == 0x00010000) {
nameToGID = new GHash(gTrue);
}
} else if (postFmt == 0x00020000) {
nameToGID = new GHash(gTrue);
- n = getU16BE(tablePos + 32, &parsedOk);
- if (!parsedOk) {
- return;
+ n = getU16BE(tablePos + 32, &ok);
+ if (!ok) {
+ goto err;
}
if (n > nGlyphs) {
n = nGlyphs;
stringIdx = 0;
stringPos = tablePos + 34 + 2*n;
for (i = 0; i < n; ++i) {
- j = getU16BE(tablePos + 34 + 2*i, &parsedOk);
+ j = getU16BE(tablePos + 34 + 2*i, &ok);
if (j < 258) {
nameToGID->removeInt(macGlyphNames[j]);
nameToGID->add(new GString(macGlyphNames[j]), i);
if (j != stringIdx) {
for (stringIdx = 0, stringPos = tablePos + 34 + 2*n;
stringIdx < j;
- ++stringIdx, stringPos += 1 + getU8(stringPos, &parsedOk)) ;
- if (!parsedOk) {
- return;
+ ++stringIdx, stringPos += 1 + getU8(stringPos, &ok)) ;
+ if (!ok) {
+ goto err;
}
}
- m = getU8(stringPos, &parsedOk);
- if (!parsedOk || !checkRegion(stringPos + 1, m)) {
- parsedOk = gFalse;
- return;
+ m = getU8(stringPos, &ok);
+ if (!ok || !checkRegion(stringPos + 1, m)) {
+ goto err;
}
name = new GString((char *)&file[stringPos + 1], m);
nameToGID->removeInt(name);
} else if (postFmt == 0x00028000) {
nameToGID = new GHash(gTrue);
for (i = 0; i < nGlyphs; ++i) {
- j = getU8(tablePos + 32 + i, &parsedOk);
- if (!parsedOk) {
- return;
+ j = getU8(tablePos + 32 + i, &ok);
+ if (!ok) {
+ goto err;
}
if (j < 258) {
nameToGID->removeInt(macGlyphNames[j]);
}
}
}
+
+ return;
+
+ err:
+ if (nameToGID) {
+ delete nameToGID;
+ nameToGID = NULL;
+ }
}
int FoFiTrueType::seekTable(char *tag) {