Implement TrueType character map "format 2" (fixes #14117)
If a PDF included an embedded TrueType font whose preferred character map (cmap) was in "format 2", the code would select that character map and then refuse to read it because of an unsupported format, thus causing the characters not to be rendered. This commit implements support for format 2 as described at the link below. https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html
This commit is contained in:
parent
3945965605
commit
586295fad6
@ -1497,6 +1497,55 @@ class Font {
|
||||
});
|
||||
}
|
||||
hasShortCmap = true;
|
||||
} else if (format === 2) {
|
||||
const subHeaderKeys = [];
|
||||
let maxSubHeaderKey = 0;
|
||||
// Read subHeaderKeys. If subHeaderKeys[i] === 0, then i is a
|
||||
// single-byte character. Otherwise, i is the first byte of a
|
||||
// multi-byte character, and the value is 8*index into
|
||||
// subHeaders.
|
||||
for (let i = 0; i < 256; i++) {
|
||||
const subHeaderKey = file.getUint16() >> 3;
|
||||
subHeaderKeys.push(subHeaderKey);
|
||||
maxSubHeaderKey = Math.max(subHeaderKey, maxSubHeaderKey);
|
||||
}
|
||||
// Read subHeaders. The number of entries is determined
|
||||
// dynamically based on the subHeaderKeys found above.
|
||||
const subHeaders = [];
|
||||
for (let i = 0; i <= maxSubHeaderKey; i++) {
|
||||
subHeaders.push({
|
||||
firstCode: file.getUint16(),
|
||||
entryCount: file.getUint16(),
|
||||
idDelta: signedInt16(file.getByte(), file.getByte()),
|
||||
idRangePos: file.pos + file.getUint16(),
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < 256; i++) {
|
||||
if (subHeaderKeys[i] === 0) {
|
||||
// i is a single-byte code.
|
||||
file.pos = subHeaders[0].idRangePos + 2 * i;
|
||||
glyphId = file.getUint16();
|
||||
mappings.push({
|
||||
charCode: i,
|
||||
glyphId,
|
||||
});
|
||||
} else {
|
||||
// i is the first byte of a two-byte code.
|
||||
const s = subHeaders[subHeaderKeys[i]];
|
||||
for (j = 0; j < s.entryCount; j++) {
|
||||
const charCode = (i << 8) + j + s.firstCode;
|
||||
file.pos = s.idRangePos + 2 * j;
|
||||
glyphId = file.getUint16();
|
||||
if (glyphId !== 0) {
|
||||
glyphId = (glyphId + s.idDelta) % 65536;
|
||||
}
|
||||
mappings.push({
|
||||
charCode,
|
||||
glyphId,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (format === 4) {
|
||||
// re-creating the table in format 4 since the encoding
|
||||
// might be changed
|
||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -288,6 +288,7 @@
|
||||
!PDFJS-7562-reduced.pdf
|
||||
!issue11768_reduced.pdf
|
||||
!issue5039.pdf
|
||||
!issue14117.pdf
|
||||
!issue5070.pdf
|
||||
!issue5238.pdf
|
||||
!issue5244.pdf
|
||||
|
BIN
test/pdfs/issue14117.pdf
Normal file
BIN
test/pdfs/issue14117.pdf
Normal file
Binary file not shown.
@ -5589,6 +5589,12 @@
|
||||
"type": "eq",
|
||||
"annotations": true
|
||||
},
|
||||
{ "id": "issue14117",
|
||||
"file": "pdfs/issue14117.pdf",
|
||||
"md5": "9b1c33ad2f59f4e723c258e863149abf",
|
||||
"rounds": 1,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "annotation-text-widget-annotations",
|
||||
"file": "pdfs/annotation-text-widget.pdf",
|
||||
"md5": "b7b8923a12998fca8603fae53f73f19b",
|
||||
|
Loading…
Reference in New Issue
Block a user