--- xpdf-3.00.orig/fofi/FoFiTrueType.cc 2004-01-22 02:26:44.000000000 +0100 +++ xpdf-3.00.orig/fofi/FoFiTrueType.cc 2004-05-05 21:53:26.774706688 +0200 @@ -233,10 +233,10 @@ // FoFiTrueType //------------------------------------------------------------------------ -FoFiTrueType *FoFiTrueType::make(char *fileA, int lenA) { +FoFiTrueType *FoFiTrueType::make(char *fileA, int lenA, int faceIndexA) { FoFiTrueType *ff; - ff = new FoFiTrueType(fileA, lenA, gFalse); + ff = new FoFiTrueType(fileA, lenA, gFalse, faceIndexA); if (!ff->parsedOk) { delete ff; return NULL; @@ -244,7 +244,7 @@ return ff; } -FoFiTrueType *FoFiTrueType::load(char *fileName) { +FoFiTrueType *FoFiTrueType::load(char *fileName, int faceIndexA) { FoFiTrueType *ff; char *fileA; int lenA; @@ -252,7 +252,7 @@ if (!(fileA = FoFiBase::readFile(fileName, &lenA))) { return NULL; } - ff = new FoFiTrueType(fileA, lenA, gTrue); + ff = new FoFiTrueType(fileA, lenA, gTrue, faceIndexA); if (!ff->parsedOk) { delete ff; return NULL; @@ -260,7 +260,7 @@ return ff; } -FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA): +FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceIndexA): FoFiBase(fileA, lenA, freeFileDataA) { tables = NULL; @@ -269,6 +269,7 @@ nCmaps = 0; nameToGID = NULL; parsedOk = gFalse; + faceIndex = faceIndexA; parse(); } @@ -1262,18 +1263,47 @@ return checksum; } +#define toTag(a,b,c,d) (((unsigned int)(a)<<24) | ((unsigned int)(b)<<16) | ((unsigned int)(c)<<8) | (d)) + void FoFiTrueType::parse() { int pos, i, j; + unsigned int head; parsedOk = gTrue; + pos = 0; // read the table directory - nTables = getU16BE(4, &parsedOk); + head = getU32BE(pos, &parsedOk); + if (! parsedOk) + return; + if (head == toTag('t','t','c','f')) { + /* TTC font */ + unsigned int tableDir; + int dircount; + + dircount = getU32BE(8, &parsedOk); + if (!parsedOk) + return; + if (! dircount) { + parsedOk = gFalse; + return; + } + + if (faceIndex >= dircount) + faceIndex = 0; + pos = getU32BE(12 + faceIndex * 4, &parsedOk); + if (! parsedOk) + return; + } + + pos += 4; + nTables = getU16BE(pos, &parsedOk); if (!parsedOk) { return; } + + pos += 8; tables = (TrueTypeTable *)gmalloc(nTables * sizeof(TrueTypeTable)); - pos = 12; for (i = 0; i < nTables; ++i) { tables[i].tag = getU32BE(pos, &parsedOk); tables[i].checksum = getU32BE(pos + 4, &parsedOk); --- xpdf-3.00.orig/fofi/FoFiTrueType.h 2004-01-22 02:26:44.000000000 +0100 +++ xpdf-3.00.orig/fofi/FoFiTrueType.h 2004-05-05 21:53:26.774706688 +0200 @@ -30,10 +30,10 @@ public: // Create a FoFiTrueType object from a memory buffer. - static FoFiTrueType *make(char *fileA, int lenA); + static FoFiTrueType *make(char *fileA, int lenA, int faceIndexA=0); // Create a FoFiTrueType object from a file on disk. - static FoFiTrueType *load(char *fileName); + static FoFiTrueType *load(char *fileName, int faceIndexA=0); virtual ~FoFiTrueType(); @@ -100,7 +100,7 @@ private: - FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA); + FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceIndexA=0); void cvtEncoding(char **encoding, FoFiOutputFunc outputFunc, void *outputStream); @@ -128,6 +128,7 @@ GHash *nameToGID; GBool parsedOk; + int faceIndex; }; #endif --- xpdf-3.00.orig/splash/SplashFTFontEngine.cc 2004-01-22 02:26:44.000000000 +0100 +++ xpdf-3.00.orig/splash/SplashFTFontEngine.cc 2004-05-05 21:53:26.774706688 +0200 @@ -100,13 +100,14 @@ char *fileName, GBool deleteFile, Gushort *codeToGID, - int codeToGIDLen) { + int codeToGIDLen, + int faceIndex) { FoFiTrueType *ff; GString *tmpFileName; FILE *tmpFile; SplashFontFile *ret; - if (!(ff = FoFiTrueType::load(fileName))) { + if (!(ff = FoFiTrueType::load(fileName, faceIndex))) { return NULL; } tmpFileName = NULL; --- xpdf-3.00.orig/splash/SplashFTFontEngine.h 2004-01-22 02:26:44.000000000 +0100 +++ xpdf-3.00.orig/splash/SplashFTFontEngine.h 2004-05-05 21:53:26.775706481 +0200 @@ -41,7 +41,8 @@ GBool deleteFile); SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, char *fileName, GBool deleteFile, - Gushort *codeToGID, int codeToGIDLen); + Gushort *codeToGID, int codeToGIDLen, + int faceIndex=0); private: --- xpdf-3.00.orig/splash/SplashFontEngine.cc 2004-01-22 02:26:44.000000000 +0100 +++ xpdf-3.00.orig/splash/SplashFontEngine.cc 2004-05-05 21:53:26.775706481 +0200 @@ -188,14 +188,15 @@ char *fileName, GBool deleteFile, Gushort *codeToGID, - int codeToGIDLen) { + int codeToGIDLen, + int faceIndex) { SplashFontFile *fontFile; fontFile = NULL; #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H if (!fontFile && ftEngine) { fontFile = ftEngine->loadTrueTypeFont(idA, fileName, deleteFile, - codeToGID, codeToGIDLen); + codeToGID, codeToGIDLen, faceIndex); } #endif --- xpdf-3.00.orig/splash/SplashFontEngine.h 2004-01-22 02:26:44.000000000 +0100 +++ xpdf-3.00.orig/splash/SplashFontEngine.h 2004-05-05 21:53:26.775706481 +0200 @@ -58,7 +58,8 @@ GBool deleteFile); SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, char *fileName, GBool deleteFile, - Gushort *codeToGID, int codeToGIDLen); + Gushort *codeToGID, int codeToGIDLen, + int faceIndex=0); // Get a font - this does a cache lookup first, and if not found, // creates a new SplashFont object and adds it to the cache. The --- xpdf-3.00.orig/xpdf/CharCodeToUnicode.h 2004-01-22 02:26:45.000000000 +0100 +++ xpdf-3.00.orig/xpdf/CharCodeToUnicode.h 2004-05-05 21:53:26.776706274 +0200 @@ -67,6 +67,8 @@ // Map a CharCode to Unicode. int mapToUnicode(CharCode c, Unicode *u, int size); + CharCode getMapLen() { return mapLen; } + private: void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits); --- xpdf-3.00.orig/xpdf/GfxFont.cc 2004-01-22 02:26:45.000000000 +0100 +++ xpdf-3.00.orig/xpdf/GfxFont.cc 2004-05-05 21:53:26.776706274 +0200 @@ -323,7 +323,7 @@ void GfxFont::findExtFontFile() { static char *type1Exts[] = { ".pfa", ".pfb", ".ps", "", NULL }; - static char *ttExts[] = { ".ttf", NULL }; + static char *ttExts[] = { ".ttf", ".ttc", NULL }; if (name) { if (type == fontType1) { @@ -1442,6 +1442,53 @@ return cMap ? cMap->getCollection() : (GString *)NULL; } +Gushort *GfxCIDFont::getCodeToGIDMap(FoFiTrueType *ff, int *mapsizep) { + Gushort *map; + int cmapPlatform, cmapEncoding; + int unicodeCmap, macRomanCmap, msSymbolCmap, cmap; + GBool useMacRoman, useUnicode; + char *charName; + Unicode u; + int code, i; + int mapsize; + int cidlen; + + *mapsizep = 0; + + /* we use only unicode cmap */ + cmap = -1; + for (i = 0; i < ff->getNumCmaps(); ++i) { + cmapPlatform = ff->getCmapPlatform(i); + cmapEncoding = ff->getCmapEncoding(i); + if ((cmapPlatform == 3 && cmapEncoding == 1) || cmapPlatform == 0) + cmap = i; + } + if (cmap < 0) + return NULL; + + cidlen = 0; + mapsize = 64; + map = (Gushort *)gmalloc(mapsize * sizeof(Gushort)); + + while (cidlen < ctu->getMapLen()) { + int n; + if ((n = ctu->mapToUnicode((CharCode)cidlen, &u, 1)) == 0) { + cidlen++; + continue; + } + if (cidlen >= mapsize) { + while (cidlen >= mapsize) + mapsize *= 2; + map = (Gushort *)grealloc(map, mapsize * sizeof(Gushort)); + } + map[cidlen] = ff->mapCodeToGID(cmap, u); + cidlen++; + } + + *mapsizep = cidlen; + return map; +} + //------------------------------------------------------------------------ // GfxFontDict //------------------------------------------------------------------------ --- xpdf-3.00.orig/xpdf/GfxFont.h 2004-01-22 02:26:45.000000000 +0100 +++ xpdf-3.00.orig/xpdf/GfxFont.h 2004-05-05 21:53:26.777706068 +0200 @@ -276,6 +276,8 @@ Gushort *getCIDToGID() { return cidToGID; } int getCIDToGIDLen() { return cidToGIDLen; } + Gushort *getCodeToGIDMap(FoFiTrueType *ff, int *length); + private: CMap *cMap; // char code --> CID --- xpdf-3.00.orig/xpdf/GlobalParams.cc 2004-01-22 02:26:45.000000000 +0100 +++ xpdf-3.00.orig/xpdf/GlobalParams.cc 2004-05-05 21:55:38.853417275 +0200 @@ -15,6 +15,7 @@ #include #include #include +#include #if HAVE_PAPER_H #include #endif @@ -593,6 +594,7 @@ DisplayFontParamKind kind, GString *fileName, int line) { DisplayFontParam *param, *old; + struct stat statbuf; if (tokens->getLength() < 2) { goto err1; @@ -605,12 +607,24 @@ goto err2; } param->t1.fileName = ((GString *)tokens->get(2))->copy(); + if (stat((param->t1.fileName->getCString)(), &statbuf)) { + delete param; // silently ignore non-existing files + return; + } break; case displayFontTT: - if (tokens->getLength() != 3) { + if (tokens->getLength() < 3) { goto err2; } param->tt.fileName = ((GString *)tokens->get(2))->copy(); + if (stat((param->tt.fileName->getCString)(), &statbuf)) { + delete param; // silently ignore non-existing files + return; + } + if (tokens->getLength() > 3) + param->tt.faceIndex = atoi(((GString *)tokens->get(3))->getCString()); + else + param->tt.faceIndex = 0; break; } --- xpdf-3.00.orig/xpdf/GlobalParams.h 2004-01-22 02:26:45.000000000 +0100 +++ xpdf-3.00.orig/xpdf/GlobalParams.h 2004-05-05 21:53:26.778705861 +0200 @@ -60,6 +60,7 @@ } t1; struct { GString *fileName; + int faceIndex; } tt; }; --- xpdf-3.00.orig/xpdf/SplashOutputDev.cc 2004-01-22 02:26:45.000000000 +0100 +++ xpdf-3.00.orig/xpdf/SplashOutputDev.cc 2004-05-05 21:53:26.778705861 +0200 @@ -501,6 +501,7 @@ SplashCoord mat[4]; char *name; int c, substIdx, n, code; + int faceIndex = 0; needFontUpdate = gFalse; font = NULL; @@ -590,6 +591,7 @@ case displayFontTT: fileName = dfp->tt.fileName; fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType; + faceIndex = dfp->tt.faceIndex; break; } } @@ -651,14 +653,23 @@ break; case fontCIDType2: n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); - codeToGID = (Gushort *)gmalloc(n * sizeof(Gushort)); - memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), - n * sizeof(Gushort)); + if (n) { + codeToGID = (Gushort *)gmalloc(n * sizeof(Gushort)); + memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), + n * sizeof(Gushort)); + } else { + if (!(ff = FoFiTrueType::load(fileName->getCString()))) { + fprintf(stderr, "failture loading cid2 %s\n", fileName->getCString()); + goto err2; + } + codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n); + delete ff; + } if (!(fontFile = fontEngine->loadTrueTypeFont( id, fileName->getCString(), fileName == tmpFileName, - codeToGID, n))) { + codeToGID, n, faceIndex))) { error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)");