mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-07-29 18:37:20 +02:00
Use the CFF program directly for CID fonts wrapped in OpenType FontFile3
When a CIDFontType0 descendant has its program in a FontFile3 stream with /Subtype /OpenType, the OTF wrapper sometimes lacks a usable cmap and the CID→GID mapping only exists inside the embedded CFF itself. In that case the OpenType-table path produces wrong glyphs, so route the font through CFFFont and let it consume the inner CFF directly. The file has been found in https://issues.chromium.org/issues/471404119.
This commit is contained in:
parent
3450e95179
commit
91f2facce3
@ -4664,9 +4664,22 @@ class PartialEvaluator {
|
||||
throw new FormatError("invalid font name");
|
||||
}
|
||||
|
||||
let fontFile, subtype, length1, length2, length3;
|
||||
let fontFile, fontFileN, subtype, length1, length2, length3;
|
||||
try {
|
||||
fontFile = descriptor.get("FontFile", "FontFile2", "FontFile3");
|
||||
fontFile = descriptor.get("FontFile");
|
||||
if (fontFile) {
|
||||
fontFileN = 1;
|
||||
} else {
|
||||
fontFile = descriptor.get("FontFile2");
|
||||
if (fontFile) {
|
||||
fontFileN = 2;
|
||||
} else {
|
||||
fontFile = descriptor.get("FontFile3");
|
||||
if (fontFile) {
|
||||
fontFileN = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fontFile) {
|
||||
if (!(fontFile instanceof BaseStream)) {
|
||||
@ -4776,6 +4789,7 @@ class PartialEvaluator {
|
||||
name: fontName.name,
|
||||
subtype,
|
||||
file: fontFile,
|
||||
fontFileN,
|
||||
length1,
|
||||
length2,
|
||||
length3,
|
||||
|
||||
@ -2670,10 +2670,23 @@ class Font {
|
||||
}
|
||||
|
||||
const isTrueType = !tables["CFF "];
|
||||
let parsedCff = null;
|
||||
if (!isTrueType) {
|
||||
try {
|
||||
parsedCff = new CFFParser(
|
||||
new Stream(tables["CFF "].data),
|
||||
properties,
|
||||
SEAC_ANALYSIS_ENABLED
|
||||
).parse();
|
||||
} catch {
|
||||
warn("Failed to parse font " + properties.loadedName);
|
||||
}
|
||||
|
||||
// OpenType font (skip composite fonts with non-default glyph mapping).
|
||||
if (
|
||||
(header.version === "OTTO" && !properties.composite) ||
|
||||
(header.version === "OTTO" &&
|
||||
(!properties.composite ||
|
||||
(properties.fontFileN === 3 && parsedCff?.isCIDFont))) ||
|
||||
!tables.head ||
|
||||
!tables.hhea ||
|
||||
!tables.maxp ||
|
||||
@ -2713,19 +2726,11 @@ class Font {
|
||||
}
|
||||
|
||||
let numGlyphsFromCFF;
|
||||
if (!isTrueType) {
|
||||
if (parsedCff) {
|
||||
try {
|
||||
// Trying to repair CFF file
|
||||
const parser = new CFFParser(
|
||||
new Stream(tables["CFF "].data),
|
||||
properties,
|
||||
SEAC_ANALYSIS_ENABLED
|
||||
);
|
||||
const cff = parser.parse();
|
||||
cff.duplicateFirstGlyph();
|
||||
const compiler = new CFFCompiler(cff);
|
||||
tables["CFF "].data = compiler.compile();
|
||||
numGlyphsFromCFF = cff.charStringCount;
|
||||
parsedCff.duplicateFirstGlyph();
|
||||
tables["CFF "].data = new CFFCompiler(parsedCff).compile();
|
||||
numGlyphsFromCFF = parsedCff.charStringCount;
|
||||
} catch {
|
||||
warn("Failed to compile font " + properties.loadedName);
|
||||
}
|
||||
|
||||
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -921,3 +921,4 @@
|
||||
!operator_list_cycle.pdf
|
||||
!knockout_groups_test.pdf
|
||||
!issue18032.pdf
|
||||
!Embedded_font.pdf
|
||||
|
||||
BIN
test/pdfs/Embedded_font.pdf
Normal file
BIN
test/pdfs/Embedded_font.pdf
Normal file
Binary file not shown.
@ -14260,5 +14260,12 @@
|
||||
"rounds": 1,
|
||||
"type": "eq",
|
||||
"about": "Non-isolated knockout group with a nested non-isolated subgroup over existing text."
|
||||
},
|
||||
{
|
||||
"id": "Embedded_font.pdf",
|
||||
"file": "pdfs/Embedded_font.pdf",
|
||||
"md5": "b68dd5a3e6833d1af94e295fe1d60285",
|
||||
"rounds": 1,
|
||||
"type": "eq"
|
||||
}
|
||||
]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user