From 690b5d1941c268829da41ec862d17f5bc81f5d42 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Sat, 10 Jul 2021 16:18:45 +0200 Subject: [PATCH] XFA - Use fake MyriadPro as a fallback for missing fonts - aims to fix #13597. --- src/core/document.js | 21 +++++++++++++----- src/core/xfa/factory.js | 4 ++-- src/core/xfa/fonts.js | 23 ++++++++++++-------- src/core/xfa_fonts.js | 36 ++++++++++++++++++------------- test/pdfs/xfa_issue13597.pdf.link | 1 + test/test_manifest.json | 8 +++++++ 6 files changed, 62 insertions(+), 31 deletions(-) create mode 100644 test/pdfs/xfa_issue13597.pdf.link diff --git a/src/core/document.js b/src/core/document.js index 1e5e18069..9143e8903 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -993,7 +993,22 @@ class PDFDocument { promises.length = 0; pdfFonts.length = 0; + const reallyMissingFonts = new Set(); for (const missing of missingFonts) { + if (!getXfaFontWidths(`${missing}-Regular`)) { + // No substitution available: we'll fallback on Myriad. + reallyMissingFonts.add(missing); + } + } + + if (reallyMissingFonts.size) { + missingFonts.push("PdfJS-Fallback"); + } + + for (const missing of missingFonts) { + if (reallyMissingFonts.has(missing)) { + continue; + } for (const fontInfo of [ { name: "Regular", fontWeight: 400, italicAngle: 0 }, { name: "Bold", fontWeight: 700, italicAngle: 0 }, @@ -1002,10 +1017,6 @@ class PDFDocument { ]) { const name = `${missing}-${fontInfo.name}`; const widths = getXfaFontWidths(name); - if (!widths) { - continue; - } - const dict = new Dict(null); dict.set("BaseFont", Name.get(name)); dict.set("Type", Name.get("Font")); @@ -1040,7 +1051,7 @@ class PDFDocument { } await Promise.all(promises); - this.xfaFactory.appendFonts(pdfFonts); + this.xfaFactory.appendFonts(pdfFonts, reallyMissingFonts); } async serializeXfaData(annotationStorage) { diff --git a/src/core/xfa/factory.js b/src/core/xfa/factory.js index d0e680fa7..fb4568aeb 100644 --- a/src/core/xfa/factory.js +++ b/src/core/xfa/factory.js @@ -83,8 +83,8 @@ class XFAFactory { return null; } - appendFonts(fonts) { - this.form[$globalData].fontFinder.add(fonts); + appendFonts(fonts, reallyMissingFonts) { + this.form[$globalData].fontFinder.add(fonts, reallyMissingFonts); } getPages() { diff --git a/src/core/xfa/fonts.js b/src/core/xfa/fonts.js index b51313d85..839febf80 100644 --- a/src/core/xfa/fonts.js +++ b/src/core/xfa/fonts.js @@ -24,7 +24,7 @@ class FontFinder { this.add(pdfFonts); } - add(pdfFonts) { + add(pdfFonts, reallyMissingFonts = null) { for (const pdfFont of pdfFonts) { this.addPdfFont(pdfFont); } @@ -33,6 +33,14 @@ class FontFinder { pdfFont.regular = pdfFont.italic || pdfFont.bold || pdfFont.bolditalic; } } + + if (!reallyMissingFonts || reallyMissingFonts.size === 0) { + return; + } + const myriad = this.fonts.get("PdfJS-Fallback-PdfJS-XFA"); + for (const missing of reallyMissingFonts) { + this.fonts.set(missing, myriad); + } } addPdfFont(pdfFont) { @@ -47,13 +55,10 @@ class FontFinder { } } let property = ""; - if (cssFontInfo.italicAngle !== "0") { - if (parseFloat(cssFontInfo.fontWeight) >= 700) { - property = "bolditalic"; - } else { - property = "italic"; - } - } else if (parseFloat(cssFontInfo.fontWeight) >= 700) { + const fontWeight = parseFloat(cssFontInfo.fontWeight); + if (parseFloat(cssFontInfo.italicAngle) !== 0) { + property = fontWeight >= 700 ? "bolditalic" : "italic"; + } else if (fontWeight >= 700) { property = "bold"; } @@ -91,7 +96,7 @@ class FontFinder { return font; } - const pattern = /,|-| |bolditalic|bold|italic|regular|it/gi; + const pattern = /,|-|_| |bolditalic|bold|italic|regular|it/gi; let name = fontName.replace(pattern, ""); font = this.fonts.get(name); if (font) { diff --git a/src/core/xfa_fonts.js b/src/core/xfa_fonts.js index f6646bc21..9b52b62ce 100644 --- a/src/core/xfa_fonts.js +++ b/src/core/xfa_fonts.js @@ -63,30 +63,36 @@ import { getLookupTableFactory } from "./core_utils.js"; import { normalizeFontName } from "./fonts_utils.js"; const getXFAFontMap = getLookupTableFactory(function (t) { - t["MyriadPro-Regular"] = { + t["MyriadPro-Regular"] = t["PdfJS-Fallback-Regular"] = { name: "LiberationSans-Regular", factors: MyriadProRegularFactors, baseWidths: LiberationSansRegularWidths, lineHeight: MyriadProRegularLineHeight, }; - t["MyriadPro-Bold"] = { + t["MyriadPro-Bold"] = t["PdfJS-Fallback-Bold"] = { name: "LiberationSans-Bold", factors: MyriadProBoldFactors, baseWidths: LiberationSansBoldWidths, lineHeight: MyriadProBoldLineHeight, }; - t["MyriadPro-It"] = { - name: "LiberationSans-Italic", - factors: MyriadProItalicFactors, - baseWidths: LiberationSansItalicWidths, - lineHeight: MyriadProItalicLineHeight, - }; - t["MyriadPro-BoldIt"] = { - name: "LiberationSans-BoldItalic", - factors: MyriadProBoldItalicFactors, - baseWidths: LiberationSansBoldItalicWidths, - lineHeight: MyriadProBoldItalicLineHeight, - }; + t["MyriadPro-It"] = + t["MyriadPro-Italic"] = + t["PdfJS-Fallback-Italic"] = + { + name: "LiberationSans-Italic", + factors: MyriadProItalicFactors, + baseWidths: LiberationSansItalicWidths, + lineHeight: MyriadProItalicLineHeight, + }; + t["MyriadPro-BoldIt"] = + t["MyriadPro-BoldItalic"] = + t["PdfJS-Fallback-BoldItalic"] = + { + name: "LiberationSans-BoldItalic", + factors: MyriadProBoldItalicFactors, + baseWidths: LiberationSansBoldItalicWidths, + lineHeight: MyriadProBoldItalicLineHeight, + }; t.ArialMT = t.Arial = t["Arial-Regular"] = @@ -154,7 +160,7 @@ const getXFAFontMap = getLookupTableFactory(function (t) { baseWidths: LiberationSansBoldItalicWidths, lineHeight: SegoeuiBoldItalicLineHeight, }; - t["Helvetica-Regular"] = { + t["Helvetica-Regular"] = t.Helvetica = { name: "LiberationSans-Regular", factors: HelveticaRegularFactors, baseWidths: LiberationSansRegularWidths, diff --git a/test/pdfs/xfa_issue13597.pdf.link b/test/pdfs/xfa_issue13597.pdf.link new file mode 100644 index 000000000..cb57b6e3f --- /dev/null +++ b/test/pdfs/xfa_issue13597.pdf.link @@ -0,0 +1 @@ +https://web.archive.org/web/20210710141547/https://help.adobe.com/en_US/livecycle/11.0/SampleForms/941/Form.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index cd6af1c60..397db806a 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -1184,6 +1184,14 @@ "enableXfa": true, "type": "eq" }, + { "id": "xfa_issue13597", + "file": "pdfs/xfa_issue13597.pdf", + "md5": "1ed9338f7e797789c0b41182f51b9002", + "link": true, + "rounds": 1, + "enableXfa": true, + "type": "eq" + }, { "id": "xfa_issue13633", "file": "pdfs/xfa_issue13633.pdf", "md5": "e5b0d09285ca6a140eba08d740be0ea0",