Index: fofi/FoFiTrueType.cc =================================================================== RCS file: /cvs/poppler/poppler/fofi/FoFiTrueType.cc,v retrieving revision 1.6 diff -u -r1.6 FoFiTrueType.cc --- fofi/FoFiTrueType.cc 25 Apr 2007 19:59:10 -0000 1.6 +++ fofi/FoFiTrueType.cc 28 Jun 2007 05:21:25 -0000 @@ -115,6 +115,8 @@ #define nameTag 0x6e616d65 #define os2Tag 0x4f532f32 #define postTag 0x706f7374 +#define vrt2Tag 0x76727432 +#define vertTag 0x76657274 static int cmpTrueTypeLocaOffset(const void *p1, const void *p2) { TrueTypeLoca *loca1 = (TrueTypeLoca *)p1; @@ -282,6 +284,8 @@ nameToGID = NULL; parsedOk = gFalse; faceIndex = faceIndexA; + gsubFeatureTable = 0; + gsubLookupList = 0; parse(); } @@ -2038,3 +2042,304 @@ } return -1; } + +Guint FoFiTrueType::charToTag(const char *tagName) +{ + int n = strlen(tagName); + Guint tag = 0; + int i; + + if (n > 4) n = 4; + for (i = 0;i < n;i++) { + tag <<= 8; + tag |= tagName[i] & 0xff; + } + for (;i < 4;i++) { + tag <<= 8; + tag |= ' '; + } + return tag; +} + +/* + setup GSUB table data + Only supporting vertical text substitution. +*/ +int FoFiTrueType::setupGSUB(const char *tagName) +{ + Guint gsubTable; + unsigned int i; + Guint scriptList, featureList; + Guint scriptCount; + Guint tag; + Guint scriptTable = 0; + Guint langSys; + Guint featureCount; + Guint featureIndex; + Guint ftable = 0; + Guint llist; + Guint scriptTag; + int x; + Guint pos; + + if (tagName == 0) { + gsubFeatureTable = 0; + return 0; + } + scriptTag = charToTag(tagName); + /* read GSUB Header */ + if ((x = seekTable("GSUB")) < 0) { + return 0; /* GSUB table not found */ + } + gsubTable = tables[x].offset; + pos = gsubTable+4; + scriptList = getU16BE(pos,&parsedOk); + pos += 2; + featureList = getU16BE(pos,&parsedOk); + pos += 2; + llist = getU16BE(pos,&parsedOk); + + gsubLookupList = llist+gsubTable; /* change to offset from top of file */ + /* read script list table */ + pos = gsubTable+scriptList; + scriptCount = getU16BE(pos,&parsedOk); + pos += 2; + /* find script */ + for (i = 0;i < scriptCount;i++) { + tag = getU32BE(pos,&parsedOk); + pos += 4; + scriptTable = getU16BE(pos,&parsedOk); + pos += 2; + if (tag == scriptTag) { + /* found */ + break; + } + } + if (i >= scriptCount) { + /* not found */ + return 0; + } + + /* read script table */ + /* use default language system */ + pos = gsubTable+scriptList+scriptTable; + langSys = getU16BE(pos,&parsedOk);/* default language system */ + + /* read LangSys table */ + if (langSys == 0) { + /* no ldefault LangSys */ + return 0; + } + + pos = gsubTable+scriptList+scriptTable+langSys+2; + featureIndex = getU16BE(pos,&parsedOk); /* ReqFeatureIndex */ + pos += 2; + + if (featureIndex != 0xffff) { + Guint tpos; + /* read feature record */ + tpos = gsubTable+featureList; + featureCount = getU16BE(tpos,&parsedOk); + tpos = gsubTable+featureList+2+featureIndex*(4+2); + tag = getU32BE(tpos,&parsedOk); + tpos += 4; + if (tag == vrt2Tag) { + /* vrt2 is preferred, overwrite vert */ + ftable = getU16BE(tpos,&parsedOk); + /* convert to offset from file top */ + gsubFeatureTable = ftable+gsubTable+featureList; + return 0; + } else if (tag == vertTag) { + ftable = getU16BE(tpos,&parsedOk); + } + } + featureCount = getU16BE(pos,&parsedOk); + pos += 2; + /* find 'vrt2' or 'vert' feature */ + for (i = 0;i < featureCount;i++) { + Guint oldPos; + + featureIndex = getU16BE(pos,&parsedOk); + pos += 2; + oldPos = pos; /* save position */ + /* read feature record */ + pos = gsubTable+featureList+2+featureIndex*(4+2); + tag = getU32BE(pos,&parsedOk); + pos += 4; + if (tag == vrt2Tag) { + /* vrt2 is preferred, overwrite vert */ + ftable = getU16BE(pos,&parsedOk); + break; + } else if (ftable == 0 && tag == vertTag) { + ftable = getU16BE(pos,&parsedOk); + } + pos = oldPos; /* restore old position */ + } + if (ftable == 0) { + /* vert nor vrt2 are not found */ + return 0; + } + /* convert to offset from file top */ + gsubFeatureTable = ftable+gsubTable+featureList; + return 0; +} + +Guint FoFiTrueType::doMapToVertGID(Guint orgGID) +{ + Guint lookupCount; + Guint lookupListIndex; + Guint i; + Guint gid = 0; + Guint pos; + + pos = gsubFeatureTable+2; + lookupCount = getU16BE(pos,&parsedOk); + pos += 2; + for (i = 0;i < lookupCount;i++) { + lookupListIndex = getU16BE(pos,&parsedOk); + pos += 2; + if ((gid = scanLookupList(lookupListIndex,orgGID)) != 0) { + break; + } + } + return gid; +} + +Guint FoFiTrueType::mapToVertGID(Guint orgGID) +{ + Guint mapped; + + if (gsubFeatureTable == 0) return orgGID; + if ((mapped = doMapToVertGID(orgGID)) != 0) { + return mapped; + } + return orgGID; +} + +Guint FoFiTrueType::scanLookupList(Guint listIndex, Guint orgGID) +{ + Guint lookupTable; + Guint subTableCount; + Guint subTable; + Guint i; + Guint gid = 0; + Guint pos; + + if (gsubLookupList == 0) return 0; /* no lookup list */ + pos = gsubLookupList+2+listIndex*2; + lookupTable = getU16BE(pos,&parsedOk); + /* read lookup table */ + pos = gsubLookupList+lookupTable+4; + subTableCount = getU16BE(pos,&parsedOk); + pos += 2;; + for (i = 0;i < subTableCount;i++) { + subTable = getU16BE(pos,&parsedOk); + pos += 2; + if ((gid = scanLookupSubTable(gsubLookupList+lookupTable+subTable,orgGID)) + != 0) break; + } + return gid; +} + +Guint FoFiTrueType::scanLookupSubTable(Guint subTable, Guint orgGID) +{ + Guint format; + Guint coverage; + int delta; + int glyphCount; + Guint substitute; + Guint gid = 0; + int coverageIndex; + int pos; + + pos = subTable; + format = getU16BE(pos,&parsedOk); + pos += 2; + coverage = getU16BE(pos,&parsedOk); + pos += 2; + if ((coverageIndex = + checkGIDInCoverage(subTable+coverage,orgGID)) >= 0) { + switch (format) { + case 1: + /* format 1 */ + delta = getS16BE(pos,&parsedOk); + pos += 2; + gid = orgGID+delta; + break; + case 2: + /* format 2 */ + glyphCount = getS16BE(pos,&parsedOk); + pos += 2; + if (glyphCount > coverageIndex) { + pos += coverageIndex*2; + substitute = getU16BE(pos,&parsedOk); + gid = substitute; + } + break; + default: + /* unknown format */ + break; + } + } + return gid; +} + +int FoFiTrueType::checkGIDInCoverage(Guint coverage, Guint orgGID) +{ + int index = -1; + Guint format; + Guint count; + Guint i; + Guint pos; + + pos = coverage; + format = getU16BE(pos,&parsedOk); + pos += 2; + switch (format) { + case 1: + count = getU16BE(pos,&parsedOk); + pos += 2; + for (i = 0;i < count;i++) { + Guint gid; + + gid = getU16BE(pos,&parsedOk); + pos += 2; + if (gid == orgGID) { + /* found */ + index = i; + break; + } else if (gid > orgGID) { + /* not found */ + break; + } + } + break; + case 2: + count = getU16BE(pos,&parsedOk); + pos += 2; + for (i = 0;i < count;i++) { + Guint startGID, endGID; + Guint startIndex; + + startGID = getU16BE(pos,&parsedOk); + pos += 2; + endGID = getU16BE(pos,&parsedOk); + pos += 2; + startIndex = getU16BE(pos,&parsedOk); + pos += 2; + if (startGID <= orgGID && orgGID <= endGID) { + /* found */ + index = startIndex+orgGID-startGID; + break; + } else if (orgGID <= endGID) { + /* not found */ + break; + } + } + break; + default: + break; + } + return index; +} + Index: fofi/FoFiTrueType.h =================================================================== RCS file: /cvs/poppler/poppler/fofi/FoFiTrueType.h,v retrieving revision 1.4 diff -u -r1.4 FoFiTrueType.h --- fofi/FoFiTrueType.h 25 Apr 2007 19:59:10 -0000 1.4 +++ fofi/FoFiTrueType.h 28 Jun 2007 05:21:25 -0000 @@ -56,6 +56,10 @@ // Return the GID corresponding to according to the th cmap. Gushort mapCodeToGID(int i, int c); + // map gid to vertical glyph gid if exist. + // if not exist return original gid + Guint mapToVertGID(Guint orgGID); + // Returns the GID corresponding to according to the post // table. Returns 0 if there is no mapping for or if the // font does not have a post table. @@ -135,6 +139,7 @@ void writeTTF(FoFiOutputFunc outputFunc, void *outputStream, char *name = NULL, Gushort *codeToGID = NULL); + int setupGSUB(const char *tagName); private: FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA, int faceIndexA); @@ -155,6 +160,11 @@ void parse(); void readPostTable(); int seekTable(char *tag); + Guint charToTag(const char *tagName); + Guint doMapToVertGID(Guint orgGID); + Guint scanLookupList(Guint listIndex, Guint orgGID); + Guint scanLookupSubTable(Guint subTable, Guint orgGID); + int checkGIDInCoverage(Guint coverage, Guint orgGID); TrueTypeTable *tables; int nTables; @@ -168,6 +178,8 @@ GBool parsedOk; int faceIndex; + Guint gsubFeatureTable; + Guint gsubLookupList; }; #endif Index: poppler/CairoFontEngine.cc =================================================================== RCS file: /cvs/poppler/poppler/poppler/CairoFontEngine.cc,v retrieving revision 1.23 diff -u -r1.23 CairoFontEngine.cc --- poppler/CairoFontEngine.cc 29 May 2006 18:44:17 -0000 1.23 +++ poppler/CairoFontEngine.cc 28 Jun 2007 05:21:25 -0000 @@ -135,46 +135,19 @@ case fontCIDType2: codeToGID = NULL; n = 0; - if (dfp) { - // create a CID-to-GID mapping, via Unicode - if ((ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) { - if ((ff = FoFiTrueType::load(fileName->getCString()))) { - // look for a Unicode cmap - for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) { - if ((ff->getCmapPlatform(cmap) == 3 && - ff->getCmapEncoding(cmap) == 1) || - ff->getCmapPlatform(cmap) == 0) { - break; - } - } - if (cmap < ff->getNumCmaps()) { - // map CID -> Unicode -> GID - n = ctu->getLength(); - codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); - for (code = 0; code < n; ++code) { - if (ctu->mapToUnicode(code, uBuf, 8) > 0) { - codeToGID[code] = ff->mapCodeToGID(cmap, uBuf[0]); - } else { - codeToGID[code] = 0; - } - } - } - delete ff; - } - ctu->decRefCnt(); - } else { - error(-1, "Couldn't find a mapping to Unicode for font '%s'", - gfxFont->getName() ? gfxFont->getName()->getCString() - : "(unnamed)"); - goto err2; - } - } else { - if (((GfxCIDFont *)gfxFont)->getCIDToGID()) { - n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); + if (((GfxCIDFont *)gfxFont)->getCIDToGID()) { + n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); + if (n) { codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), - n * sizeof(Gushort)); + n * sizeof(Gushort)); } + } else { + ff = FoFiTrueType::load(fileName->getCString()); + if (! ff) + goto err2; + codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n); + delete ff; } codeToGIDLen = n; /* Fall through */ Index: poppler/CharCodeToUnicode.cc =================================================================== RCS file: /cvs/poppler/poppler/poppler/CharCodeToUnicode.cc,v retrieving revision 1.6 diff -u -r1.6 CharCodeToUnicode.cc --- poppler/CharCodeToUnicode.cc 25 Apr 2007 19:59:10 -0000 1.6 +++ poppler/CharCodeToUnicode.cc 28 Jun 2007 05:21:25 -0000 @@ -197,6 +197,22 @@ return ctu; } +CharCodeToUnicode *CharCodeToUnicode::parseCMapFromFile(GooString *fileName, + int nBits) { + CharCodeToUnicode *ctu; + FILE *f; + + ctu = new CharCodeToUnicode(NULL); + if ((f = globalParams->findToUnicodeFile(fileName))) { + ctu->parseCMap1(&getCharFromFile, f, nBits); + fclose(f); + } else { + error(-1, "Couldn't find ToUnicode CMap file for '%s'", + fileName->getCString()); + } + return ctu; +} + void CharCodeToUnicode::mergeCMap(GooString *buf, int nBits) { char *p; Index: poppler/CharCodeToUnicode.h =================================================================== RCS file: /cvs/poppler/poppler/poppler/CharCodeToUnicode.h,v retrieving revision 1.4 diff -u -r1.4 CharCodeToUnicode.h --- poppler/CharCodeToUnicode.h 11 Jun 2007 21:14:22 -0000 1.4 +++ poppler/CharCodeToUnicode.h 28 Jun 2007 05:21:25 -0000 @@ -48,6 +48,7 @@ // Parse a ToUnicode CMap for an 8- or 16-bit font. static CharCodeToUnicode *parseCMap(GooString *buf, int nBits); + static CharCodeToUnicode *parseCMapFromFile(GooString *fileName, int nBits); // Parse a ToUnicode CMap for an 8- or 16-bit font, merging it into // . Index: poppler/GfxFont.cc =================================================================== RCS file: /cvs/poppler/poppler/poppler/GfxFont.cc,v retrieving revision 1.12 diff -u -r1.12 GfxFont.cc --- poppler/GfxFont.cc 25 May 2007 18:43:04 -0000 1.12 +++ poppler/GfxFont.cc 28 Jun 2007 05:21:26 -0000 @@ -1557,16 +1557,101 @@ return cMap ? cMap->getCollection() : (GooString *)NULL; } +Gushort GfxCIDFont::mapCodeToGID(FoFiTrueType *ff, int cmapi, + Unicode unicode, GBool wmode) { + Gushort gid = ff->mapCodeToGID(cmapi,unicode); + if (wmode) { + Gushort vgid = ff->mapToVertGID(gid); + if (vgid != 0) gid = vgid; + } + return gid; +} + Gushort *GfxCIDFont::getCodeToGIDMap(FoFiTrueType *ff, int *mapsizep) { - Gushort *map; - int cmapPlatform, cmapEncoding; - int unicodeCmap, macRomanCmap, msSymbolCmap, cmap; - GBool useMacRoman, useUnicode; - char *charName; + /* space characters */ + static unsigned long spaces[] = { + 0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007, + 0x2008,0x2009,0x200A,0x00A0,0x200B,0x2060,0x3000,0xFEFF, + 0 + }; + static char *adobe_cns1_cmaps[] = { + "UniCNS-UCS2-V", + "UniCNS-UCS2-H", + 0 + }; + static char *adobe_gb1_cmaps[] = { + "UniGB-UCS2-V", + "UniGB-UCS2-H", + 0 + }; + static char *adobe_japan1_cmaps[] = { + "UniJIS-UCS2-V", + "UniJIS-UCS2-H", + 0 + }; + static char *adobe_japan2_cmaps[] = { + "UniHojo-UCS2-V", + "UniHojo-UCS2-H", + 0 + }; + static char *adobe_korea1_cmaps[] = { + "UniKS-UCS2-V", + "UniKS-UCS2-H", + 0 + }; + static struct CMapListEntry { + char *collection; + char *scriptTag; + char *toUnicodeMap; + char **CMaps; + } CMapList[] = { + { + "Adobe-CNS1", + "kana", + "Adobe-CNS1-UCS2", + adobe_cns1_cmaps, + }, + { + "Adobe-GB1", + "kana", + "Adobe-GB1-UCS2", + adobe_gb1_cmaps, + }, + { + "Adobe-Japan1", + "kana", + "Adobe-Japan1-UCS2", + adobe_japan1_cmaps, + }, + { + "Adobe-Japan2", + "kana", + "Adobe-Japan2-UCS2", + adobe_japan2_cmaps, + }, + { + "Adobe-Korea1", + "kana", + "Adobe-Korea1-UCS2", + adobe_korea1_cmaps, + }, + 0 + }; + Unicode *humap = 0; + Unicode *vumap = 0; + Gushort *codeToGID = 0; + unsigned long n; + int i; + unsigned long code; + Unicode uBuf[8]; + int wmode; + char **cmapName; + CMap *cMap; + int nUsed; Unicode u; - int code, i; - int mapsize; - int cidlen; + CMapListEntry *lp; + int cmap; + int cmapPlatform, cmapEncoding; *mapsizep = 0; if (!ctu) return NULL; @@ -1582,27 +1667,122 @@ 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)); + wmode = getWMode(); + for (lp = CMapList;lp->collection != 0;lp++) { + if (strcmp(lp->collection,getCollection()->getCString()) == 0) { + break; } - map[cidlen] = ff->mapCodeToGID(cmap, u); - cidlen++; } + n = ctu->getLength(); + humap = new Unicode[n]; + if (lp->collection != 0) { + CharCodeToUnicode *tctu; + GooString tname(lp->toUnicodeMap); + + if ((tctu = CharCodeToUnicode::parseCMapFromFile(&tname,16)) != 0) { + CharCode cid; + for (cid = 0;cid < n ;cid++) { + int len; + Unicode ucodes[4]; + + len = tctu->mapToUnicode(cid,ucodes,4); + if (len == 1) { + humap[cid] = ucodes[0]; + } else { + /* if not single character, ignore it */ + humap[cid] = 0; + } + } + delete tctu; + } + vumap = new Unicode[n]; + memset(vumap,0,sizeof(Unicode)*n); + for (cmapName = lp->CMaps;*cmapName != 0;cmapName++) { + GooString cname(*cmapName); + + if ((cMap = globalParams->getCMap(getCollection(),&cname)) + != 0) { + for (u = 0;u <= 65535;u++) { + CID cid; + char code[2]; + + code[0] = (u >> 8) & 0xff; + code[1] = u & 0xff; + cid = cMap->getCID(code,2,&nUsed); + if (cid != 0) { + if (cMap->getWMode()) { + if (cid < n && vumap[cid] == 0) { + vumap[cid] = u; + } + } else { + if (cid < n && humap[cid] == 0) { + humap[cid] = u; + } + } + } + } + cMap->decRefCnt(); + } + } + ff->setupGSUB(lp->scriptTag); + } else { + error(-1,"Unknown character collection %s\n", + getCollection()->getCString()); + if ((ctu = getToUnicode()) != 0) { + CharCode cid; + for (cid = 0;cid <= n ;cid++) { + int len; + Unicode ucode; - *mapsizep = cidlen; - return map; + len = ctu->mapToUnicode(cid,&ucode,1); + humap[cid] = ucode; + } + ctu->decRefCnt(); + } + } + // map CID -> Unicode -> GID + codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); + for (code = 0; code < n; ++code) { + Unicode unicode; + unsigned long gid; + + unicode = 0; + gid = 0; + if (vumap != 0) unicode = vumap[code]; + if (unicode != 0) { + gid = mapCodeToGID(ff,cmap,unicode,gTrue); + if (gid == 0 && humap != 0) { + if (humap != 0) unicode = humap[code]; + if (unicode != 0) gid = mapCodeToGID(ff,cmap,unicode,gTrue); + } + } + if (gid == 0) { + if (humap != 0) unicode = humap[code]; + if (unicode != 0) gid = mapCodeToGID(ff,cmap,unicode,wmode); + } + if (gid == 0) { + /* special handling space characters */ + unsigned long *p; + + if (humap != 0) unicode = humap[code]; + if (unicode != 0) { + /* check if code is space character , so map code to 0x0020 */ + for (p = spaces;*p != 0;p++) { + if (*p == unicode) { + unicode = 0x20; + gid = mapCodeToGID(ff,cmap,unicode,wmode); + break; + } + } + } + } + codeToGID[code] = gid; + } + *mapsizep = n; + if (humap != 0) delete[] humap; + if (vumap != 0) delete[] vumap; +end_0: + return codeToGID; } double GfxCIDFont::getWidth (char* s, int len) { Index: poppler/GfxFont.h =================================================================== RCS file: /cvs/poppler/poppler/poppler/GfxFont.h,v retrieving revision 1.7 diff -u -r1.7 GfxFont.h --- poppler/GfxFont.h 25 May 2007 18:43:05 -0000 1.7 +++ poppler/GfxFont.h 28 Jun 2007 05:21:26 -0000 @@ -333,6 +333,8 @@ double getWidth(char* s, int len); private: + Gushort mapCodeToGID(FoFiTrueType *ff, int cmapi, + Unicode unicode, GBool wmode); CMap *cMap; // char code --> CID CharCodeToUnicode *ctu; // CID --> Unicode Index: poppler/SplashOutputDev.cc =================================================================== RCS file: /cvs/poppler/poppler/poppler/SplashOutputDev.cc,v retrieving revision 1.14 diff -u -r1.14 SplashOutputDev.cc --- poppler/SplashOutputDev.cc 28 Apr 2007 23:25:59 -0000 1.14 +++ poppler/SplashOutputDev.cc 28 Jun 2007 05:21:26 -0000 @@ -1107,49 +1107,22 @@ case fontCIDType2OT: codeToGID = NULL; n = 0; - if (dfp) { - // create a CID-to-GID mapping, via Unicode - if ((ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) { - if (fileName) - ff = FoFiTrueType::load(fileName->getCString()); - else - ff = FoFiTrueType::make(tmpBuf, tmpBufLen); - if (ff) { - // look for a Unicode cmap - for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) { - if ((ff->getCmapPlatform(cmap) == 3 && - ff->getCmapEncoding(cmap) == 1) || - ff->getCmapPlatform(cmap) == 0) { - break; - } - } - if (cmap < ff->getNumCmaps()) { - // map CID -> Unicode -> GID - n = ctu->getLength(); - codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); - for (code = 0; code < n; ++code) { - if (ctu->mapToUnicode(code, uBuf, 8) > 0) { - codeToGID[code] = ff->mapCodeToGID(cmap, uBuf[0]); - } else { - codeToGID[code] = 0; - } - } - } - delete ff; - } - ctu->decRefCnt(); - } else { - error(-1, "Couldn't find a mapping to Unicode for font '%s'", - gfxFont->getName() ? gfxFont->getName()->getCString() - : "(unnamed)"); - } - } else { - if (((GfxCIDFont *)gfxFont)->getCIDToGID()) { - n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); + if (((GfxCIDFont *)gfxFont)->getCIDToGID()) { + n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); + if (n) { codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), - n * sizeof(Gushort)); + n * sizeof(Gushort)); } + } else { + if (fileName) + ff = FoFiTrueType::load(fileName->getCString()); + else + ff = FoFiTrueType::make(tmpBuf, tmpBufLen); + if (! ff) + goto err2; + codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n); + delete ff; } if (!(fontFile = fontEngine->loadTrueTypeFont( id,