diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2022-04-24 03:42:26 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2022-04-24 03:42:26 +0000 |
commit | d743821ec3b71e00af5dc5541d4e7bf5b003c55e (patch) | |
tree | 8145068541ec45af3c223f5a35891d02e4adf273 /Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc | |
parent | d0ce904282bf50ad444cf1ff7df7edd12a3b5a70 (diff) |
xpdf 4.04
git-svn-id: svn://tug.org/texlive/trunk@63119 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc')
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc | 206 |
1 files changed, 159 insertions, 47 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc index f224ff75b5f..30e8bd1c79c 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc @@ -198,6 +198,27 @@ GfxFont *GfxFont::makeFont(XRef *xref, const char *tagA, return font; } +GfxFont *GfxFont::makeDefaultFont(XRef *xref) { + Object type, subtype, baseFont; + type.initName("Font"); + subtype.initName("Type1"); + baseFont.initName("Helvetica"); + Object fontDict; + fontDict.initDict(xref); + fontDict.dictAdd(copyString("Type"), &type); + fontDict.dictAdd(copyString("Subtype"), &subtype); + fontDict.dictAdd(copyString("BaseFont"), &baseFont); + + Ref r; + r.gen = 100000; + r.num = GfxFontDict::hashFontObject(&fontDict); + + GfxFont *font = makeFont(xref, "undef", r, fontDict.getDict()); + fontDict.free(); + + return font; +} + GfxFont::GfxFont(const char *tagA, Ref idA, GString *nameA, GfxFontType typeA, Ref embFontIDA) { ok = gFalse; @@ -1701,9 +1722,59 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA, obj2.free(); obj1.free(); + // encoding (i.e., CMap) + if (fontDict->lookup("Encoding", &obj1)->isNull()) { + error(errSyntaxError, -1, "Missing Encoding entry in Type 0 font"); + goto err2; + } + if (!(cMap = CMap::parse(NULL, collection, &obj1))) { + goto err2; + } + + // check for fonts that use the Identity-H encoding (cmap), and the + // Adobe-Identity character collection + identityEnc = obj1.isName("Identity-H") && + !collection->cmp("Adobe-Identity"); + + obj1.free(); + + // CIDToGIDMap + // (the PDF 1.7 spec only allows these for TrueType fonts, but + // Acrobat apparently also allows them for OpenType CFF fonts -- and + // the PDF 2.0 spec has removed the prohibition) + hasIdentityCIDToGID = gFalse; + desFontDict->lookup("CIDToGIDMap", &obj1); + if (obj1.isStream()) { + cidToGIDLen = 0; + i = 64; + cidToGID = (int *)gmallocn(i, sizeof(int)); + obj1.streamReset(); + while ((c1 = obj1.streamGetChar()) != EOF && + (c2 = obj1.streamGetChar()) != EOF) { + if (cidToGIDLen == i) { + i *= 2; + cidToGID = (int *)greallocn(cidToGID, i, sizeof(int)); + } + cidToGID[cidToGIDLen++] = (c1 << 8) + c2; + } + obj1.streamClose(); + identityEnc = gFalse; + } else if (obj1.isName("Identity")) { + hasIdentityCIDToGID = gTrue; + } else if (!obj1.isNull()) { + error(errSyntaxError, -1, "Invalid CIDToGIDMap entry in CID font"); + } + obj1.free(); + // look for a ToUnicode CMap hasKnownCollection = gFalse; - if (!(ctu = readToUnicodeCMap(fontDict, 16, NULL))) { + if (globalParams->getUseTrueTypeUnicodeMapping()) { + readTrueTypeUnicodeMapping(xref); + } + if (!ctu) { + ctu = readToUnicodeCMap(fontDict, 16, NULL); + } + if (!ctu) { ctuUsesCharCode = gFalse; // use an identity mapping for the "Adobe-Identity" and @@ -1748,55 +1819,11 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA, } } - // encoding (i.e., CMap) - if (fontDict->lookup("Encoding", &obj1)->isNull()) { - error(errSyntaxError, -1, "Missing Encoding entry in Type 0 font"); - goto err2; - } - if (!(cMap = CMap::parse(NULL, collection, &obj1))) { - goto err2; - } - - // check for fonts that use the Identity-H encoding (cmap), and the - // Adobe-Identity character collection - identityEnc = obj1.isName("Identity-H") && - !collection->cmp("Adobe-Identity"); - - obj1.free(); - - // CIDToGIDMap - // (the PDF 1.7 spec only allows these for TrueType fonts, but - // Acrobat apparently also allows them for OpenType CFF fonts -- and - // the PDF 2.0 spec has removed the prohibition) - hasIdentityCIDToGID = gFalse; - desFontDict->lookup("CIDToGIDMap", &obj1); - if (obj1.isStream()) { - cidToGIDLen = 0; - i = 64; - cidToGID = (int *)gmallocn(i, sizeof(int)); - obj1.streamReset(); - while ((c1 = obj1.streamGetChar()) != EOF && - (c2 = obj1.streamGetChar()) != EOF) { - if (cidToGIDLen == i) { - i *= 2; - cidToGID = (int *)greallocn(cidToGID, i, sizeof(int)); - } - cidToGID[cidToGIDLen++] = (c1 << 8) + c2; - } - obj1.streamClose(); - identityEnc = gFalse; - } else if (obj1.isName("Identity")) { - hasIdentityCIDToGID = gTrue; - } else if (!obj1.isNull()) { - error(errSyntaxError, -1, "Invalid CIDToGIDMap entry in CID font"); - } - obj1.free(); - //----- character metrics ----- // default char width - if (desFontDict->lookup("DW", &obj1)->isInt()) { - widths.defWidth = obj1.getInt() * 0.001; + if (desFontDict->lookup("DW", &obj1)->isNum()) { + widths.defWidth = obj1.getNum() * 0.001; } obj1.free(); @@ -1968,6 +1995,91 @@ GfxCIDFont::~GfxCIDFont() { } } +// Construct a code-to-Unicode mapping, based on the TrueType Unicode +// cmap (if present). Constructs ctu if succesful; leaves ctu = null +// otherwise. Always leaves ctu = null for non-TrueType fonts. +void GfxCIDFont::readTrueTypeUnicodeMapping(XRef *xref) { + char *buf; + FoFiTrueType *ff; + Unicode *gidToUnicode, *codeToUnicode; + Unicode u; + int bufLen, cmapPlatform, cmapEncoding, unicodeCmap; + int nGlyphs, nMappings, gid, i; + + // must be an embedded TrueType font, with an unknown char collection + if ((type != fontCIDType2 && type == fontCIDType2OT) || + embFontID.num < 0 || + hasKnownCollection) { + goto err0; + } + + // read the embedded font and construct a FoFiTrueType + if (!(buf = readEmbFontFile(xref, &bufLen))) { + goto err0; + } + if (!(ff = FoFiTrueType::make(buf, bufLen, 0))) { + goto err1; + } + + // find the TrueType Unicode cmap + unicodeCmap = -1; + for (i = 0; i < ff->getNumCmaps(); ++i) { + cmapPlatform = ff->getCmapPlatform(i); + cmapEncoding = ff->getCmapEncoding(i); + if ((cmapPlatform == 3 && cmapEncoding == 1) || + (cmapPlatform == 0 && cmapEncoding <= 4)) { + unicodeCmap = i; + break; + } + } + if (unicodeCmap < 0) { + goto err2; + } + + // construct reverse GID-to-Unicode map + nGlyphs = ff->getNumGlyphs(); + gidToUnicode = (Unicode *)gmallocn(nGlyphs, sizeof(Unicode)); + memset(gidToUnicode, 0, nGlyphs * sizeof(Unicode)); + nMappings = 0; + for (u = 1; u <= 0xffff; ++u) { + gid = ff->mapCodeToGID(unicodeCmap, (int)u); + if (gid > 0 && gid < nGlyphs) { + gidToUnicode[gid] = u; + ++nMappings; + } + } + // bail out if the Unicode cmap was completely empty + if (nMappings == 0) { + goto err3; + } + + // construct code-to-Unicode map + codeToUnicode = (Unicode *)gmallocn(65536, sizeof(Unicode)); + memset(codeToUnicode, 0, 65536 * sizeof(Unicode)); + for (i = 0; i <= 0xffff; ++i) { + // we've already checked for an identity encoding, so CID = i + if (cidToGID && i < cidToGIDLen) { + gid = cidToGID[i]; + } else { + gid = i; + } + if (gid < nGlyphs && gidToUnicode[gid] > 0) { + codeToUnicode[i] = gidToUnicode[gid]; + } + } + ctu = CharCodeToUnicode::make16BitToUnicode(codeToUnicode); + + gfree(codeToUnicode); + err3: + gfree(gidToUnicode); + err2: + delete ff; + err1: + gfree(buf); + err0: + return; +} + int GfxCIDFont::getNextChar(char *s, int len, CharCode *code, Unicode *u, int uSize, int *uLen, double *dx, double *dy, double *ox, double *oy) { |