Support CMap-data with only strings, when parsing TrueType composite fonts (bug 920426)
In the referenced bug, the embedded fonts contain custom CMap-data that only include strings. Note how for embedded composite TrueType fonts we're using the CMap-data when building the glyph mapping, and currently we end up with a completely empty map because the code expects only CID *numbers*. Furthermore, just fixing the glyph mapping alone isn't sufficient to fully address the bug, since we also need to consider this "special" kind of CMap-data when looking up glyph widths.
This commit is contained in:
parent
db7c91e7b1
commit
d3ca28bc34
@ -401,6 +401,21 @@ function buildToFontChar(encoding, glyphsUnicodeMap, differences) {
|
|||||||
return toFontChar;
|
return toFontChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertCidString(charCode, cid, shouldThrow = false) {
|
||||||
|
switch (cid.length) {
|
||||||
|
case 1:
|
||||||
|
return cid.charCodeAt(0);
|
||||||
|
case 2:
|
||||||
|
return (cid.charCodeAt(0) << 8) | cid.charCodeAt(1);
|
||||||
|
}
|
||||||
|
const msg = `Unsupported CID string (charCode ${charCode}): "${cid}".`;
|
||||||
|
if (shouldThrow) {
|
||||||
|
throw new FormatError(msg);
|
||||||
|
}
|
||||||
|
warn(msg);
|
||||||
|
return cid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebuilds the char code to glyph ID map by moving all char codes to the
|
* Rebuilds the char code to glyph ID map by moving all char codes to the
|
||||||
* private use area. This is done to avoid issues with various problematic
|
* private use area. This is done to avoid issues with various problematic
|
||||||
@ -929,7 +944,7 @@ class Font {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cidEncoding = properties.cidEncoding;
|
this.cidEncoding = properties.cidEncoding || "";
|
||||||
this.vertical = !!properties.vertical;
|
this.vertical = !!properties.vertical;
|
||||||
if (this.vertical) {
|
if (this.vertical) {
|
||||||
this.vmetrics = properties.vmetrics;
|
this.vmetrics = properties.vmetrics;
|
||||||
@ -2612,6 +2627,9 @@ class Font {
|
|||||||
const isCidToGidMapEmpty = cidToGidMap.length === 0;
|
const isCidToGidMapEmpty = cidToGidMap.length === 0;
|
||||||
|
|
||||||
properties.cMap.forEach(function (charCode, cid) {
|
properties.cMap.forEach(function (charCode, cid) {
|
||||||
|
if (typeof cid === "string") {
|
||||||
|
cid = convertCidString(charCode, cid, /* shouldThrow = */ true);
|
||||||
|
}
|
||||||
if (cid > 0xffff) {
|
if (cid > 0xffff) {
|
||||||
throw new FormatError("Max size of CID is 65,535");
|
throw new FormatError("Max size of CID is 65,535");
|
||||||
}
|
}
|
||||||
@ -3057,6 +3075,10 @@ class Font {
|
|||||||
let charcode = 0;
|
let charcode = 0;
|
||||||
if (this.composite && this.cMap.contains(glyphUnicode)) {
|
if (this.composite && this.cMap.contains(glyphUnicode)) {
|
||||||
charcode = this.cMap.lookup(glyphUnicode);
|
charcode = this.cMap.lookup(glyphUnicode);
|
||||||
|
|
||||||
|
if (typeof charcode === "string") {
|
||||||
|
charcode = convertCidString(glyphUnicode, charcode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ... via toUnicode map
|
// ... via toUnicode map
|
||||||
if (!charcode && this.toUnicode) {
|
if (!charcode && this.toUnicode) {
|
||||||
@ -3085,6 +3107,10 @@ class Font {
|
|||||||
let widthCode = charcode;
|
let widthCode = charcode;
|
||||||
if (this.cMap && this.cMap.contains(charcode)) {
|
if (this.cMap && this.cMap.contains(charcode)) {
|
||||||
widthCode = this.cMap.lookup(charcode);
|
widthCode = this.cMap.lookup(charcode);
|
||||||
|
|
||||||
|
if (typeof widthCode === "string") {
|
||||||
|
widthCode = convertCidString(charcode, widthCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
width = this.widths[widthCode];
|
width = this.widths[widthCode];
|
||||||
width = isNum(width) ? width : this.defaultWidth;
|
width = isNum(width) ? width : this.defaultWidth;
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -238,6 +238,7 @@
|
|||||||
!bug900822.pdf
|
!bug900822.pdf
|
||||||
!bug1392647.pdf
|
!bug1392647.pdf
|
||||||
!issue918.pdf
|
!issue918.pdf
|
||||||
|
!bug920426.pdf
|
||||||
!issue1905.pdf
|
!issue1905.pdf
|
||||||
!issue2833.pdf
|
!issue2833.pdf
|
||||||
!issue2931.pdf
|
!issue2931.pdf
|
||||||
|
BIN
test/pdfs/bug920426.pdf
Normal file
BIN
test/pdfs/bug920426.pdf
Normal file
Binary file not shown.
@ -154,6 +154,12 @@
|
|||||||
"link": false,
|
"link": false,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "bug920426",
|
||||||
|
"file": "pdfs/bug920426.pdf",
|
||||||
|
"md5": "2fd118b44513afb22509c3584388cc29",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "issue13343",
|
{ "id": "issue13343",
|
||||||
"file": "pdfs/issue13343.pdf",
|
"file": "pdfs/issue13343.pdf",
|
||||||
"md5": "f8bf1888839e15254555092c504e1900",
|
"md5": "f8bf1888839e15254555092c504e1900",
|
||||||
|
Loading…
Reference in New Issue
Block a user