Handle errors gracefully, in PartialEvaluator.translateFont, when fetching the font file (issue 9462)

The *third* page of the referenced PDF document currently fails to render completely, since one of its font files fail to load.
Since that error isn't handled, a large part of the text is thus missing which looks quite bad. By "replacing" the font data with an *empty* stream, we'll thus be able to fallback to rendering the text with a standard font (instead of using `ErrorFont`). While there's obviously no guarantee that things will look perfect, actually rendering the text at all should be an improvement in general.

Also, print a warning in `PartialEvaluator.loadFont` when the `PartialEvaluator.translateFont` method rejects, since that'd have helped debug/fix the issue faster.
This commit is contained in:
Jonas Jenwald 2021-02-06 17:48:26 +01:00
parent 8ccd9eac3d
commit e6fe8a7d53

View File

@ -47,6 +47,7 @@ import {
Ref, Ref,
RefSet, RefSet,
} from "./primitives.js"; } from "./primitives.js";
import { DecodeStream, NullStream } from "./stream.js";
import { import {
ErrorFont, ErrorFont,
Font, Font,
@ -85,7 +86,6 @@ import {
} from "./image_utils.js"; } from "./image_utils.js";
import { bidi } from "./bidi.js"; import { bidi } from "./bidi.js";
import { ColorSpace } from "./colorspace.js"; import { ColorSpace } from "./colorspace.js";
import { DecodeStream } from "./stream.js";
import { getGlyphsUnicode } from "./glyphlist.js"; import { getGlyphsUnicode } from "./glyphlist.js";
import { getMetrics } from "./metrics.js"; import { getMetrics } from "./metrics.js";
import { MurmurHash3_64 } from "./murmurhash3.js"; import { MurmurHash3_64 } from "./murmurhash3.js";
@ -1066,7 +1066,7 @@ class PartialEvaluator {
try { try {
preEvaluatedFont = this.preEvaluateFont(font); preEvaluatedFont = this.preEvaluateFont(font);
} catch (reason) { } catch (reason) {
warn(`loadFont - ignoring preEvaluateFont errors: "${reason}".`); warn(`loadFont - preEvaluateFont failed: "${reason}".`);
return errorFont(); return errorFont();
} }
const { descriptor, hash } = preEvaluatedFont; const { descriptor, hash } = preEvaluatedFont;
@ -1156,6 +1156,7 @@ class PartialEvaluator {
this.handler.send("UnsupportedFeature", { this.handler.send("UnsupportedFeature", {
featureId: UNSUPPORTED_FEATURES.errorFontTranslate, featureId: UNSUPPORTED_FEATURES.errorFontTranslate,
}); });
warn(`loadFont - translateFont failed: "${reason}".`);
try { try {
// error, but it's still nice to have font type reported // error, but it's still nice to have font type reported
@ -3459,7 +3460,16 @@ class PartialEvaluator {
throw new FormatError("invalid font name"); throw new FormatError("invalid font name");
} }
var fontFile = descriptor.get("FontFile", "FontFile2", "FontFile3"); let fontFile;
try {
fontFile = descriptor.get("FontFile", "FontFile2", "FontFile3");
} catch (ex) {
if (!this.options.ignoreErrors) {
throw ex;
}
warn(`translateFont - fetching "${fontName.name}" font file: "${ex}".`);
fontFile = new NullStream();
}
if (fontFile) { if (fontFile) {
if (fontFile.dict) { if (fontFile.dict) {
var subtype = fontFile.dict.get("Subtype"); var subtype = fontFile.dict.get("Subtype");