diff options
author | Albert Astals Cid <aacid@kde.org> | 2006-02-02 22:50:01 +0000 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2006-02-02 22:50:01 +0000 |
commit | 1ddeed60d07c3a7e011f3f594fa9299379d0b000 (patch) | |
tree | 7e344cb8130bb7146205d05859783f05119e84b5 | |
parent | 34df4cfa5cd8788ccf2ea698cbedd05b209041f5 (diff) |
don't use files to pass fonts to freetype
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | fofi/FoFiTrueType.cc | 43 | ||||
-rw-r--r-- | fofi/FoFiTrueType.h | 7 | ||||
-rw-r--r-- | fofi/FoFiType1C.h | 2 | ||||
-rw-r--r-- | goo/gfile.cc | 8 | ||||
-rw-r--r-- | poppler/GfxFont.cc | 49 | ||||
-rw-r--r-- | poppler/GfxFont.h | 2 | ||||
-rw-r--r-- | poppler/GlobalParams.cc | 1 | ||||
-rw-r--r-- | poppler/GlobalParams.h | 1 | ||||
-rw-r--r-- | poppler/SplashOutputDev.cc | 94 | ||||
-rw-r--r-- | splash/SplashFTFontEngine.cc | 44 | ||||
-rw-r--r-- | splash/SplashFTFontEngine.h | 16 | ||||
-rw-r--r-- | splash/SplashFTFontFile.cc | 47 | ||||
-rw-r--r-- | splash/SplashFTFontFile.h | 18 | ||||
-rw-r--r-- | splash/SplashFontEngine.cc | 46 | ||||
-rw-r--r-- | splash/SplashFontEngine.h | 16 | ||||
-rw-r--r-- | splash/SplashFontFile.cc | 70 | ||||
-rw-r--r-- | splash/SplashFontFile.h | 25 | ||||
-rw-r--r-- | splash/SplashT1FontEngine.cc | 29 | ||||
-rw-r--r-- | splash/SplashT1FontFile.cc | 30 | ||||
-rw-r--r-- | splash/SplashT1FontFile.h | 4 |
21 files changed, 396 insertions, 182 deletions
@@ -1,3 +1,29 @@ +2006-01-18 Albert Astals Cid <aacid@kde.org> + + * fofi/FoFiTrueType.cc + * fofi/FoFiTrueType.h + * fofi/FoFiType1C.h + * goo/gfile.cc + * poppler/GfxFont.cc + * poppler/GfxFont.h + * poppler/GlobalParams.cc + * poppler/GlobalParams.h + * poppler/SplashOutputDev.cc + * splash/SplashFTFontEngine.cc + * splash/SplashFTFontEngine.h + * splash/SplashFTFontFile.cc + * splash/SplashFTFontFile.h + * splash/SplashFontEngine.cc + * splash/SplashFontEngine.h + * splash/SplashFontFile.cc + * splash/SplashFontFile.h + * splash/SplashT1FontEngine.cc + * splash/SplashT1FontFile.cc + * splash/SplashT1FontFile.h: Merge patch to not use external file + when passing the font to Freetype, original patch by Takashi Iwai + adapted by me to kpdf rediffed by Stefan Schweizer against poppler + cvs + 2006-01-31 Jeff Muizelaar <jeff@infidigm.net> * poppler/GlobalParams.cc (GlobalParams::getDisplayFont): diff --git a/fofi/FoFiTrueType.cc b/fofi/FoFiTrueType.cc index 1c5f60de..ff355d2b 100644 --- a/fofi/FoFiTrueType.cc +++ b/fofi/FoFiTrueType.cc @@ -241,10 +241,10 @@ static char *macGlyphNames[258] = { // 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; @@ -252,7 +252,7 @@ FoFiTrueType *FoFiTrueType::make(char *fileA, int lenA) { return ff; } -FoFiTrueType *FoFiTrueType::load(char *fileName) { +FoFiTrueType *FoFiTrueType::load(char *fileName, int faceIndexA) { FoFiTrueType *ff; char *fileA; int lenA; @@ -260,7 +260,7 @@ FoFiTrueType *FoFiTrueType::load(char *fileName) { 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; @@ -268,7 +268,7 @@ FoFiTrueType *FoFiTrueType::load(char *fileName) { 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; @@ -277,6 +277,7 @@ FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA): nCmaps = 0; nameToGID = NULL; parsedOk = gFalse; + faceIndex = faceIndexA; parse(); } @@ -1535,9 +1536,12 @@ Guint FoFiTrueType::computeTableChecksum(Guchar *data, int length) { return checksum; } +#define toTag(a,b,c,d) (((unsigned int)(a)<<24) | ((unsigned int)(b)<<16) | ((unsigned int)(c)<<8) | (d)) + void FoFiTrueType::parse() { Guint topTag; int pos, i, j; + unsigned int head; parsedOk = gTrue; @@ -1556,12 +1560,37 @@ void FoFiTrueType::parse() { } // read the table directory - nTables = getU16BE(pos + 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 *)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); diff --git a/fofi/FoFiTrueType.h b/fofi/FoFiTrueType.h index 42f6b298..c81e3b7a 100644 --- a/fofi/FoFiTrueType.h +++ b/fofi/FoFiTrueType.h @@ -29,11 +29,12 @@ class FoFiTrueType: public FoFiBase { 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); + FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceIndexA=0); virtual ~FoFiTrueType(); // Return the number of cmaps defined by this font. @@ -104,7 +105,6 @@ public: private: - FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA); void cvtEncoding(char **encoding, FoFiOutputFunc outputFunc, void *outputStream); @@ -133,6 +133,7 @@ private: GooHash *nameToGID; GBool parsedOk; + int faceIndex; }; #endif diff --git a/fofi/FoFiType1C.h b/fofi/FoFiType1C.h index 36c0aa90..ce4decdc 100644 --- a/fofi/FoFiType1C.h +++ b/fofi/FoFiType1C.h @@ -138,6 +138,7 @@ public: // Create a FoFiType1C object from a file on disk. static FoFiType1C *load(char *fileName); + FoFiType1C(char *fileA, int lenA, GBool freeFileDataA); virtual ~FoFiType1C(); // Return the font name. @@ -173,7 +174,6 @@ public: private: - FoFiType1C(char *fileA, int lenA, GBool freeFileDataA); void eexecCvtGlyph(Type1CEexecBuf *eb, char *glyphName, int offset, int nBytes, Type1CIndex *subrIdx, diff --git a/goo/gfile.cc b/goo/gfile.cc index 8b75bbde..b08b313c 100644 --- a/goo/gfile.cc +++ b/goo/gfile.cc @@ -489,6 +489,14 @@ GBool openTempFile(GooString **name, FILE **f, char *mode, char *ext) { } (*name)->append("/XXXXXX")->append(ext); fd = mkstemps((*name)->getCString(), strlen(ext)); +#elif defined(HAVE_MKSTEMP) + if ((s = getenv("TMPDIR"))) { + *name = new GooString(s); + } else { + *name = new GooString("/tmp"); + } + (*name)->append("/XXXXXX")->append(ext); + fd = mkstemp((*name)->getCString()); #else if (!(s = tmpnam(NULL))) { return gFalse; diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc index 39f00301..962c140b 100644 --- a/poppler/GfxFont.cc +++ b/poppler/GfxFont.cc @@ -361,7 +361,7 @@ CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits, 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) { @@ -1522,6 +1522,53 @@ GooString *GfxCIDFont::getCollection() { return cMap ? cMap->getCollection() : (GooString *)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->getLength()) { + 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 //------------------------------------------------------------------------ diff --git a/poppler/GfxFont.h b/poppler/GfxFont.h index 5e6eb09f..15d1b9ae 100644 --- a/poppler/GfxFont.h +++ b/poppler/GfxFont.h @@ -310,6 +310,8 @@ public: Gushort *getCIDToGID() { return cidToGID; } int getCIDToGIDLen() { return cidToGIDLen; } + Gushort *getCodeToGIDMap(FoFiTrueType *ff, int *length); + private: CMap *cMap; // char code --> CID diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc index df4c04ca..45f2b6d7 100644 --- a/poppler/GlobalParams.cc +++ b/poppler/GlobalParams.cc @@ -1278,6 +1278,7 @@ DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) { { dfp = new DisplayFontParam(fontName->copy(), displayFontTT); dfp->tt.fileName = new GooString((char*)s); + FcPatternGetInteger(m, FC_INDEX, 0, &(dfp->tt.faceIndex)); } else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4)) { diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h index 9418df7a..8c30dffc 100644 --- a/poppler/GlobalParams.h +++ b/poppler/GlobalParams.h @@ -55,6 +55,7 @@ struct DisplayFontParamT1 { struct DisplayFontParamTT { GooString *fileName; + int faceIndex; }; class DisplayFontParam { diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc index 171d72aa..5dcb614d 100644 --- a/poppler/SplashOutputDev.cc +++ b/poppler/SplashOutputDev.cc @@ -941,10 +941,13 @@ void SplashOutputDev::updateFont(GfxState *state) { GfxFontType fontType; SplashOutFontFileID *id; SplashFontFile *fontFile; + SplashFontSrc *fontsrc; FoFiTrueType *ff; Ref embRef; Object refObj, strObj; - GooString *tmpFileName, *fileName, *substName; + GooString *fileName, *substName; + char *tmpBuf; + int tmpBufLen; FILE *tmpFile; Gushort *codeToGID; DisplayFontParam *dfp; @@ -954,10 +957,12 @@ void SplashOutputDev::updateFont(GfxState *state) { char *name; Unicode uBuf[8]; int c, substIdx, n, code, cmap; + int faceIndex = 0; needFontUpdate = gFalse; font = NULL; - tmpFileName = NULL; + fileName = NULL; + tmpBuf = NULL; substIdx = -1; dfp = NULL; @@ -978,22 +983,9 @@ void SplashOutputDev::updateFont(GfxState *state) { // if there is an embedded font, write it to disk if (gfxFont->getEmbeddedFontID(&embRef)) { - if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) { - error(-1, "Couldn't create temporary font file"); + tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen); + if (! tmpBuf) goto err2; - } - refObj.initRef(embRef.num, embRef.gen); - refObj.fetch(xref, &strObj); - refObj.free(); - strObj.streamReset(); - while ((c = strObj.streamGetChar()) != EOF) { - fputc(c, tmpFile); - } - strObj.streamClose(); - strObj.free(); - fclose(tmpFile); - fileName = tmpFileName; - // if there is an external font file, use it } else if (!(fileName = gfxFont->getExtFontFile())) { @@ -1016,18 +1008,23 @@ void SplashOutputDev::updateFont(GfxState *state) { case displayFontTT: fileName = dfp->tt.fileName; fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType; + faceIndex = dfp->tt.faceIndex; break; } } + fontsrc = new SplashFontSrc; + if (fileName) + fontsrc->setFile(fileName, gFalse); + else + fontsrc->setBuf(tmpBuf, tmpBufLen, gFalse); + // load the font file switch (fontType) { case fontType1: - if (!(fontFile = fontEngine->loadType1Font( - id, - fileName->getCString(), - fileName == tmpFileName, - ((Gfx8BitFont *)gfxFont)->getEncoding()))) { + fontFile = fontEngine->loadType1Font(id, fontsrc, + ((Gfx8BitFont *)gfxFont)->getEncoding()); + if (! fontFile) { error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); @@ -1035,11 +1032,9 @@ void SplashOutputDev::updateFont(GfxState *state) { } break; case fontType1C: - if (!(fontFile = fontEngine->loadType1CFont( - id, - fileName->getCString(), - fileName == tmpFileName, - ((Gfx8BitFont *)gfxFont)->getEncoding()))) { + fontFile = fontEngine->loadType1CFont(id, fontsrc, + ((Gfx8BitFont *)gfxFont)->getEncoding()); + if (! fontFile) { error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); @@ -1047,7 +1042,8 @@ void SplashOutputDev::updateFont(GfxState *state) { } break; case fontTrueType: - if ((ff = FoFiTrueType::load(fileName->getCString()))) { + if ((ff = FoFiTrueType::load(fileName->getCString())) || + (ff = new FoFiTrueType(tmpBuf, tmpBufLen, gFalse))) { codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff); n = 256; delete ff; @@ -1057,8 +1053,7 @@ void SplashOutputDev::updateFont(GfxState *state) { } if (!(fontFile = fontEngine->loadTrueTypeFont( id, - fileName->getCString(), - fileName == tmpFileName, + fontsrc, codeToGID, n))) { error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() @@ -1068,10 +1063,8 @@ void SplashOutputDev::updateFont(GfxState *state) { break; case fontCIDType0: case fontCIDType0C: - if (!(fontFile = fontEngine->loadCIDFont( - id, - fileName->getCString(), - fileName == tmpFileName))) { + fontFile = fontEngine->loadCIDFont(id, fontsrc); + if (! fontFile) { error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); @@ -1084,7 +1077,8 @@ void SplashOutputDev::updateFont(GfxState *state) { if (dfp) { // create a CID-to-GID mapping, via Unicode if ((ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) { - if ((ff = FoFiTrueType::load(fileName->getCString()))) { + if ((ff = FoFiTrueType::load(fileName->getCString())) || + (ff = new FoFiTrueType(tmpBuf, tmpBufLen, gFalse))) { // look for a Unicode cmap for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) { if ((ff->getCmapPlatform(cmap) == 3 && @@ -1116,16 +1110,28 @@ void SplashOutputDev::updateFont(GfxState *state) { } else { if (((GfxCIDFont *)gfxFont)->getCIDToGID()) { n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); - codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); - memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), - n * sizeof(Gushort)); + if (n) { + codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); + memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), + n * sizeof(Gushort)); + } else { + if (fileName) + ff = FoFiTrueType::load(fileName->getCString()); + else + ff = new FoFiTrueType(tmpBuf, tmpBufLen, gFalse); + if (! ff) + goto err2; + codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n); + delete ff; + } } } if (!(fontFile = fontEngine->loadTrueTypeFont( id, - fileName->getCString(), - fileName == tmpFileName, - codeToGID, n))) { + fontsrc, + codeToGID, + n, + faceIndex))) { error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); @@ -1153,17 +1159,11 @@ void SplashOutputDev::updateFont(GfxState *state) { } font = fontEngine->getFont(fontFile, mat); - if (tmpFileName) { - delete tmpFileName; - } return; err2: delete id; err1: - if (tmpFileName) { - delete tmpFileName; - } return; } diff --git a/splash/SplashFTFontEngine.cc b/splash/SplashFTFontEngine.cc index b3c9c96e..b4121bf2 100644 --- a/splash/SplashFTFontEngine.cc +++ b/splash/SplashFTFontEngine.cc @@ -64,22 +64,19 @@ SplashFTFontEngine::~SplashFTFontEngine() { } SplashFontFile *SplashFTFontEngine::loadType1Font(SplashFontFileID *idA, - char *fileName, - GBool deleteFile, + SplashFontSrc *src, char **enc) { - return SplashFTFontFile::loadType1Font(this, idA, fileName, deleteFile, enc); + return SplashFTFontFile::loadType1Font(this, idA, src, enc); } SplashFontFile *SplashFTFontEngine::loadType1CFont(SplashFontFileID *idA, - char *fileName, - GBool deleteFile, + SplashFontSrc *src, char **enc) { - return SplashFTFontFile::loadType1Font(this, idA, fileName, deleteFile, enc); + return SplashFTFontFile::loadType1Font(this, idA, src, enc); } SplashFontFile *SplashFTFontEngine::loadCIDFont(SplashFontFileID *idA, - char *fileName, - GBool deleteFile) { + SplashFontSrc *src) { FoFiType1C *ff; Gushort *cidToGIDMap; int nCIDs; @@ -89,15 +86,21 @@ SplashFontFile *SplashFTFontEngine::loadCIDFont(SplashFontFileID *idA, if (useCIDs) { cidToGIDMap = NULL; nCIDs = 0; - } else if ((ff = FoFiType1C::load(fileName))) { + } else { + if (src->isFile) { + ff = FoFiType1C::load(src->fileName->getCString()); + } else { + ff = new FoFiType1C(src->buf, src->bufLen, gFalse); + } + if (ff) { cidToGIDMap = ff->getCIDToGIDMap(&nCIDs); delete ff; } else { cidToGIDMap = NULL; nCIDs = 0; } - ret = SplashFTFontFile::loadCIDFont(this, idA, fileName, deleteFile, - cidToGIDMap, nCIDs); + } + ret = SplashFTFontFile::loadCIDFont(this, idA, src, cidToGIDMap, nCIDs); if (!ret) { gfree(cidToGIDMap); } @@ -105,16 +108,17 @@ SplashFontFile *SplashFTFontEngine::loadCIDFont(SplashFontFileID *idA, } SplashFontFile *SplashFTFontEngine::loadTrueTypeFont(SplashFontFileID *idA, - char *fileName, - GBool deleteFile, + SplashFontSrc *src, Gushort *codeToGID, - int codeToGIDLen) { + int codeToGIDLen, + int faceIndex) { +#if 0 FoFiTrueType *ff; GooString *tmpFileName; FILE *tmpFile; SplashFontFile *ret; - if (!(ff = FoFiTrueType::load(fileName))) { + if (!(ff = FoFiTrueType::load(fileName, faceIndex))) { return NULL; } tmpFileName = NULL; @@ -127,7 +131,8 @@ SplashFontFile *SplashFTFontEngine::loadTrueTypeFont(SplashFontFileID *idA, fclose(tmpFile); ret = SplashFTFontFile::loadTrueTypeFont(this, idA, tmpFileName->getCString(), - gTrue, codeToGID, codeToGIDLen); + gTrue, codeToGID, codeToGIDLen, + faceIndex); if (ret) { if (deleteFile) { unlink(fileName); @@ -137,6 +142,13 @@ SplashFontFile *SplashFTFontEngine::loadTrueTypeFont(SplashFontFileID *idA, } delete tmpFileName; return ret; +#else + SplashFontFile *ret; + ret = SplashFTFontFile::loadTrueTypeFont(this, idA, src, + codeToGID, codeToGIDLen, + faceIndex); + return ret; +#endif } #endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H diff --git a/splash/SplashFTFontEngine.h b/splash/SplashFTFontEngine.h index c397abbd..e6600f58 100644 --- a/splash/SplashFTFontEngine.h +++ b/splash/SplashFTFontEngine.h @@ -19,6 +19,7 @@ class SplashFontFile; class SplashFontFileID; +class SplashFontSrc; //------------------------------------------------------------------------ // SplashFTFontEngine @@ -32,15 +33,12 @@ public: ~SplashFTFontEngine(); // Load fonts. - SplashFontFile *loadType1Font(SplashFontFileID *idA, char *fileName, - GBool deleteFile, char **enc); - SplashFontFile *loadType1CFont(SplashFontFileID *idA, char *fileName, - GBool deleteFile, char **enc); - SplashFontFile *loadCIDFont(SplashFontFileID *idA, char *fileName, - GBool deleteFile); - SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, char *fileName, - GBool deleteFile, - Gushort *codeToGID, int codeToGIDLen); + SplashFontFile *loadType1Font(SplashFontFileID *idA, SplashFontSrc *src, char **enc); + SplashFontFile *loadType1CFont(SplashFontFileID *idA, SplashFontSrc *src, char **enc); + SplashFontFile *loadCIDFont(SplashFontFileID *idA, SplashFontSrc *src); + SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, SplashFontSrc *src, + Gushort *codeToGID, int codeToGIDLen, + int faceIndex=0); private: diff --git a/splash/SplashFTFontFile.cc b/splash/SplashFTFontFile.cc index ecea373c..76927660 100644 --- a/splash/SplashFTFontFile.cc +++ b/splash/SplashFTFontFile.cc @@ -13,6 +13,7 @@ #endif #include "goo/gmem.h" +#include "goo/GooString.h" #include "SplashFTFontEngine.h" #include "SplashFTFont.h" #include "SplashFTFontFile.h" @@ -23,16 +24,19 @@ SplashFontFile *SplashFTFontFile::loadType1Font(SplashFTFontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, - GBool deleteFileA, + SplashFontSrc *src, char **encA) { FT_Face faceA; Gushort *codeToGIDA; char *name; int i; - if (FT_New_Face(engineA->lib, fileNameA, 0, &faceA)) { - return NULL; + if (src->isFile) { + if (FT_New_Face(engineA->lib, src->fileName->getCString(), 0, &faceA)) + return NULL; + } else { + if (FT_New_Memory_Face(engineA->lib, (const FT_Byte *)src->buf, src->bufLen, 0, &faceA)) + return NULL; } codeToGIDA = (Gushort *)gmallocn(256, sizeof(int)); for (i = 0; i < 256; ++i) { @@ -42,48 +46,55 @@ SplashFontFile *SplashFTFontFile::loadType1Font(SplashFTFontEngine *engineA, } } - return new SplashFTFontFile(engineA, idA, fileNameA, deleteFileA, + return new SplashFTFontFile(engineA, idA, src, faceA, codeToGIDA, 256); } SplashFontFile *SplashFTFontFile::loadCIDFont(SplashFTFontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, - GBool deleteFileA, + SplashFontSrc *src, Gushort *codeToGIDA, int codeToGIDLenA) { FT_Face faceA; - if (FT_New_Face(engineA->lib, fileNameA, 0, &faceA)) { - return NULL; + if (src->isFile) { + if (FT_New_Face(engineA->lib, src->fileName->getCString(), 0, &faceA)) + return NULL; + } else { + if (FT_New_Memory_Face(engineA->lib, (const FT_Byte *)src->buf, src->bufLen, 0, &faceA)) + return NULL; } - return new SplashFTFontFile(engineA, idA, fileNameA, deleteFileA, + return new SplashFTFontFile(engineA, idA, src, faceA, codeToGIDA, codeToGIDLenA); } SplashFontFile *SplashFTFontFile::loadTrueTypeFont(SplashFTFontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, - GBool deleteFileA, + SplashFontSrc *src, Gushort *codeToGIDA, - int codeToGIDLenA) { + int codeToGIDLenA, + int faceIndexA) { FT_Face faceA; - if (FT_New_Face(engineA->lib, fileNameA, 0, &faceA)) { - return NULL; + if (src->isFile) { + if (FT_New_Face(engineA->lib, src->fileName->getCString(), faceIndexA, &faceA)) + return NULL; + } else { + if (FT_New_Memory_Face(engineA->lib, (const FT_Byte *)src->buf, src->bufLen, faceIndexA, &faceA)) + return NULL; } - return new SplashFTFontFile(engineA, idA, fileNameA, deleteFileA, + return new SplashFTFontFile(engineA, idA, src, faceA, codeToGIDA, codeToGIDLenA); } SplashFTFontFile::SplashFTFontFile(SplashFTFontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, GBool deleteFileA, + SplashFontSrc *srcA, FT_Face faceA, Gushort *codeToGIDA, int codeToGIDLenA): - SplashFontFile(idA, fileNameA, deleteFileA) + SplashFontFile(idA, srcA) { engine = engineA; face = faceA; diff --git a/splash/SplashFTFontFile.h b/splash/SplashFTFontFile.h index b2fc6ceb..b1d0f41b 100644 --- a/splash/SplashFTFontFile.h +++ b/splash/SplashFTFontFile.h @@ -28,18 +28,18 @@ class SplashFTFontFile: public SplashFontFile { public: static SplashFontFile *loadType1Font(SplashFTFontEngine *engineA, - SplashFontFileID *idA, char *fileNameA, - GBool deleteFileA, char **encA); + SplashFontFileID *idA, + SplashFontSrc *src, char **encA); static SplashFontFile *loadCIDFont(SplashFTFontEngine *engineA, - SplashFontFileID *idA, char *fileNameA, - GBool deleteFileA, - Gushort *codeToCIDA, int codeToGIDLenA); + SplashFontFileID *idA, + SplashFontSrc *src, + Gushort *codeToCIDA, int codeToGIDLenA); static SplashFontFile *loadTrueTypeFont(SplashFTFontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, - GBool deleteFileA, + SplashFontSrc *src, Gushort *codeToGIDA, - int codeToGIDLenA); + int codeToGIDLenA, + int faceIndexA=0); virtual ~SplashFTFontFile(); @@ -51,7 +51,7 @@ private: SplashFTFontFile(SplashFTFontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, GBool deleteFileA, + SplashFontSrc *srcA, FT_Face faceA, Gushort *codeToGIDA, int codeToGIDLenA); diff --git a/splash/SplashFontEngine.cc b/splash/SplashFontEngine.cc index 53e4469f..4e629776 100644 --- a/splash/SplashFontEngine.cc +++ b/splash/SplashFontEngine.cc @@ -105,19 +105,19 @@ SplashFontFile *SplashFontEngine::getFontFile(SplashFontFileID *id) { } SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA, - char *fileName, - GBool deleteFile, char **enc) { + SplashFontSrc *src, + char **enc) { SplashFontFile *fontFile; fontFile = NULL; #if HAVE_T1LIB_H if (!fontFile && t1Engine) { - fontFile = t1Engine->loadType1Font(idA, fileName, deleteFile, enc); + fontFile = t1Engine->loadType1Font(idA, src, enc); } #endif #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H if (!fontFile && ftEngine) { - fontFile = ftEngine->loadType1Font(idA, fileName, deleteFile, enc); + fontFile = ftEngine->loadType1Font(idA, src, enc); } #endif @@ -126,29 +126,26 @@ SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA, // semantics, this will remove the last link; otherwise it will // return an error, leaving the file to be deleted later (if // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } + src->unref(); #endif return fontFile; } SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA, - char *fileName, - GBool deleteFile, + SplashFontSrc *src, char **enc) { SplashFontFile *fontFile; fontFile = NULL; #if HAVE_T1LIB_H if (!fontFile && t1Engine) { - fontFile = t1Engine->loadType1CFont(idA, fileName, deleteFile, enc); + fontFile = t1Engine->loadType1CFont(idA, src, enc); } #endif #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H if (!fontFile && ftEngine) { - fontFile = ftEngine->loadType1CFont(idA, fileName, deleteFile, enc); + fontFile = ftEngine->loadType1CFont(idA, src, enc); } #endif @@ -157,23 +154,20 @@ SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA, // semantics, this will remove the last link; otherwise it will // return an error, leaving the file to be deleted later (if // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } + src->unref(); #endif return fontFile; } SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA, - char *fileName, - GBool deleteFile) { + SplashFontSrc *src) { SplashFontFile *fontFile; fontFile = NULL; #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H if (!fontFile && ftEngine) { - fontFile = ftEngine->loadCIDFont(idA, fileName, deleteFile); + fontFile = ftEngine->loadCIDFont(idA, src); } #endif @@ -182,26 +176,24 @@ SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA, // semantics, this will remove the last link; otherwise it will // return an error, leaving the file to be deleted later (if // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } + src->unref(); #endif return fontFile; } SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA, - char *fileName, - GBool deleteFile, + SplashFontSrc *src, 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); + fontFile = ftEngine->loadTrueTypeFont(idA, src, + codeToGID, codeToGIDLen, faceIndex); } #endif @@ -214,9 +206,7 @@ SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA, // semantics, this will remove the last link; otherwise it will // return an error, leaving the file to be deleted later (if // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } + src->unref(); #endif return fontFile; diff --git a/splash/SplashFontEngine.h b/splash/SplashFontEngine.h index 8a71d48e..23c49acd 100644 --- a/splash/SplashFontEngine.h +++ b/splash/SplashFontEngine.h @@ -19,6 +19,7 @@ class SplashDTFontEngine; class SplashFontFile; class SplashFontFileID; class SplashFont; +class SplashFontSrc; //------------------------------------------------------------------------ @@ -48,15 +49,12 @@ public: SplashFontFile *getFontFile(SplashFontFileID *id); // Load fonts - these create new SplashFontFile objects. - SplashFontFile *loadType1Font(SplashFontFileID *idA, char *fileName, - GBool deleteFile, char **enc); - SplashFontFile *loadType1CFont(SplashFontFileID *idA, char *fileName, - GBool deleteFile, char **enc); - SplashFontFile *loadCIDFont(SplashFontFileID *idA, char *fileName, - GBool deleteFile); - SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, char *fileName, - GBool deleteFile, - Gushort *codeToGID, int codeToGIDLen); + SplashFontFile *loadType1Font(SplashFontFileID *idA, SplashFontSrc *src, char **enc); + SplashFontFile *loadType1CFont(SplashFontFileID *idA, SplashFontSrc *src, char **enc); + SplashFontFile *loadCIDFont(SplashFontFileID *idA, SplashFontSrc *src); + SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, SplashFontSrc *src, + 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 diff --git a/splash/SplashFontFile.cc b/splash/SplashFontFile.cc index e1ed5275..b92dd1b2 100644 --- a/splash/SplashFontFile.cc +++ b/splash/SplashFontFile.cc @@ -12,6 +12,7 @@ #include <stdio.h> #include <unistd.h> +#include "goo/gmem.h" #include "goo/GooString.h" #include "SplashFontFile.h" #include "SplashFontFileID.h" @@ -26,19 +27,15 @@ extern "C" int unlink(char *filename); // SplashFontFile //------------------------------------------------------------------------ -SplashFontFile::SplashFontFile(SplashFontFileID *idA, char *fileNameA, - GBool deleteFileA) { +SplashFontFile::SplashFontFile(SplashFontFileID *idA, SplashFontSrc *srcA) { id = idA; - fileName = new GooString(fileNameA); - deleteFile = deleteFileA; + src = srcA; + src->ref(); refCnt = 0; } SplashFontFile::~SplashFontFile() { - if (deleteFile) { - unlink(fileName->getCString()); - } - delete fileName; + src->unref(); delete id; } @@ -51,3 +48,60 @@ void SplashFontFile::decRefCnt() { delete this; } } + +// + +SplashFontSrc::SplashFontSrc() { + isFile = gFalse; + deleteSrc = gFalse; + fileName = NULL; + buf = NULL; + refcnt = 1; +} + +SplashFontSrc::~SplashFontSrc() { + if (deleteSrc) { + if (isFile) { + if (fileName) + unlink(fileName->getCString()); + } else { + if (buf) + gfree(buf); + } + } + + if (isFile && fileName) + delete fileName; +} + +void SplashFontSrc::ref() { + refcnt++; +} + +void SplashFontSrc::unref() { + if (! --refcnt) + delete this; +} + +void SplashFontSrc::setFile(GooString *file, GBool del) +{ + isFile = gTrue; + fileName = file->copy(); + deleteSrc = del; +} + +void SplashFontSrc::setFile(const char *file, GBool del) +{ + isFile = gTrue; + fileName = new GooString(file); + deleteSrc = del; +} + +void SplashFontSrc::setBuf(char *bufA, int bufLenA, GBool del) +{ + isFile = gFalse; + buf = bufA; + bufLen = bufLenA; + deleteSrc = del; +} + diff --git a/splash/SplashFontFile.h b/splash/SplashFontFile.h index 67fed487..e434b9b2 100644 --- a/splash/SplashFontFile.h +++ b/splash/SplashFontFile.h @@ -23,6 +23,25 @@ class SplashFontFileID; // SplashFontFile //------------------------------------------------------------------------ +struct SplashFontSrc { + SplashFontSrc(); + ~SplashFontSrc(); + + void setFile(GooString *file, GBool del); + void setFile(const char *file, GBool del); + void setBuf(char *bufA, int buflenA, GBool del); + + void ref(); + void unref(); + + GBool isFile; + GooString *fileName; + char *buf; + int bufLen; + GBool deleteSrc; + int refcnt; +}; + class SplashFontFile { public: @@ -44,12 +63,10 @@ public: protected: - SplashFontFile(SplashFontFileID *idA, char *fileNameA, - GBool deleteFileA); + SplashFontFile(SplashFontFileID *idA, SplashFontSrc *srcA); SplashFontFileID *id; - GooString *fileName; - GBool deleteFile; + SplashFontSrc *src; int refCnt; friend class SplashFontEngine; diff --git a/splash/SplashT1FontEngine.cc b/splash/SplashT1FontEngine.cc index 393f756a..d180a5a8 100644 --- a/splash/SplashT1FontEngine.cc +++ b/splash/SplashT1FontEngine.cc @@ -82,22 +82,26 @@ SplashT1FontEngine::~SplashT1FontEngine() { } SplashFontFile *SplashT1FontEngine::loadType1Font(SplashFontFileID *idA, - char *fileName, - GBool deleteFile, + SplashFontSrc *src, char **enc) { - return SplashT1FontFile::loadType1Font(this, idA, fileName, deleteFile, enc); + return SplashT1FontFile::loadType1Font(this, idA, src, enc); } SplashFontFile *SplashT1FontEngine::loadType1CFont(SplashFontFileID *idA, - char *fileName, - GBool deleteFile, + SplashFontSrc *src, char **enc) { FoFiType1C *ff; GooString *tmpFileName; FILE *tmpFile; SplashFontFile *ret; - if (!(ff = FoFiType1C::load(fileName))) { + SplashFontSrc *newsrc; + + if (src->isFile) + ff = FoFiType1C::load(src->fileName); + else + ff = new FoFiType1C(src->buf, src->bufLen, gFalse); + if (! ff) return NULL; } tmpFileName = NULL; @@ -108,16 +112,11 @@ SplashFontFile *SplashT1FontEngine::loadType1CFont(SplashFontFileID *idA, ff->convertToType1(NULL, gTrue, &fileWrite, tmpFile); delete ff; fclose(tmpFile); - ret = SplashT1FontFile::loadType1Font(this, idA, tmpFileName->getCString(), - gTrue, enc); - if (ret) { - if (deleteFile) { - unlink(fileName); - } - } else { - unlink(tmpFileName->getCString()); - } + newsrc = new SplashFontSrc; + newsrc->setFile(tmpFileName, gTrue); delete tmpFileName; + ret = SplashT1FontFile::loadType1Font(this, idA, newsrc, enc); + newsrc->unref(); return ret; } diff --git a/splash/SplashT1FontFile.cc b/splash/SplashT1FontFile.cc index b64ede05..c5e9f5fe 100644 --- a/splash/SplashT1FontFile.cc +++ b/splash/SplashT1FontFile.cc @@ -25,8 +25,7 @@ SplashFontFile *SplashT1FontFile::loadType1Font(SplashT1FontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, - GBool deleteFileA, + SplashFontSrc *src, char **encA) { int t1libIDA; char **encTmp; @@ -34,9 +33,27 @@ SplashFontFile *SplashT1FontFile::loadType1Font(SplashT1FontEngine *engineA, int encStrSize; char *encPtr; int i; + GString *fileNameA; + SplashFontSrc *newsrc = NULL; + SplashFontFile *ff; + if (! src->isFile) { + GString *tmpFileName; + FILE *tmpFile; + if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) + return NULL; + fwrite(src->buf, 1, src->bufLen, tmpFile); + fclose(tmpFile); + newsrc = new SplashFontSrc; + newsrc->setFile(tmpFileName, gTrue); + src = newsrc; + delete tmpFileName; + } + fileNameA = src->fileName; // load the font file if ((t1libIDA = T1_AddFont(fileNameA)) < 0) { + if (newsrc) + delete newsrc; return NULL; } T1_LoadFont(t1libIDA); @@ -63,15 +80,18 @@ SplashFontFile *SplashT1FontFile::loadType1Font(SplashT1FontEngine *engineA, encTmp[256] = "custom"; T1_ReencodeFont(t1libIDA, encTmp); - return new SplashT1FontFile(engineA, idA, fileNameA, deleteFileA, + ff = new SplashT1FontFile(engineA, idA, src, t1libIDA, encTmp, encStrTmp); + if (newsrc) + newsrc->unref(); + return ff; } SplashT1FontFile::SplashT1FontFile(SplashT1FontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, GBool deleteFileA, + SplashFontSrc *srcA, int t1libIDA, char **encA, char *encStrA): - SplashFontFile(idA, fileNameA, deleteFileA) + SplashFontFile(idA, srcA) { engine = engineA; t1libID = t1libIDA; diff --git a/splash/SplashT1FontFile.h b/splash/SplashT1FontFile.h index fbed44c8..2ab72167 100644 --- a/splash/SplashT1FontFile.h +++ b/splash/SplashT1FontFile.h @@ -26,7 +26,7 @@ public: static SplashFontFile *loadType1Font(SplashT1FontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, GBool deleteFileA, + SplashFontSrc *src, char **encA); virtual ~SplashT1FontFile(); @@ -39,7 +39,7 @@ private: SplashT1FontFile(SplashT1FontEngine *engineA, SplashFontFileID *idA, - char *fileNameA, GBool deleteFileA, + SplashFontSrc *src, int t1libIDA, char **encA, char *encStrA); SplashT1FontEngine *engine; |