mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
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
4 changed files with 56 additions and 0 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue