summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2022-04-24 03:42:26 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2022-04-24 03:42:26 +0000
commitd743821ec3b71e00af5dc5541d4e7bf5b003c55e (patch)
tree8145068541ec45af3c223f5a35891d02e4adf273 /Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
parentd0ce904282bf50ad444cf1ff7df7edd12a3b5a70 (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.cc206
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) {