From e82446fa5a0ecbe3803224562e37c76f2e273792 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Wed, 23 Jun 2021 11:10:20 +0200 Subject: [PATCH] XFA - Get line height from the font - when the CSS line-height property is set to 'normal' then the value depends of the user agent. So use a line height based on the font itself and if for any reasons this value is not available use 1.2 as default. - it's a partial fix for https://bugzilla.mozilla.org/show_bug.cgi?id=1717681. --- src/core/xfa/fonts.js | 15 ++++++++++++++- src/core/xfa/html_utils.js | 32 ++++++++++++++++++------------- src/core/xfa/template.js | 4 ++-- src/core/xfa/text.js | 15 +++------------ src/core/xfa/utils.js | 8 ++++++++ src/core/xfa/xhtml.js | 16 ++++++++++++++-- test/pdfs/xfa_bug1717681.pdf.link | 1 + test/test_manifest.json | 8 ++++++++ web/xfa_layer_builder.css | 5 +---- 9 files changed, 70 insertions(+), 34 deletions(-) create mode 100644 test/pdfs/xfa_bug1717681.pdf.link diff --git a/src/core/xfa/fonts.js b/src/core/xfa/fonts.js index 0bd68cc75ecc8..479e6b2cc33de 100644 --- a/src/core/xfa/fonts.js +++ b/src/core/xfa/fonts.js @@ -154,4 +154,17 @@ class FontFinder { } } -export { FontFinder }; +function selectFont(xfaFont, typeface) { + if (xfaFont.posture === "italic") { + if (xfaFont.weight === "bold") { + return typeface.bolditalic; + } + return typeface.italic; + } else if (xfaFont.weight === "bold") { + return typeface.bold; + } + + return typeface.regular; +} + +export { FontFinder, selectFont }; diff --git a/src/core/xfa/html_utils.js b/src/core/xfa/html_utils.js index 9648e3ccdef4b..d7cbd365c999c 100644 --- a/src/core/xfa/html_utils.js +++ b/src/core/xfa/html_utils.js @@ -22,7 +22,8 @@ import { $toStyle, XFAObject, } from "./xfa_object.js"; -import { getMeasurement } from "./utils.js"; +import { getMeasurement, stripQuotes } from "./utils.js"; +import { selectFont } from "./fonts.js"; import { TextMeasure } from "./text.js"; import { warn } from "../../shared/util.js"; @@ -472,20 +473,25 @@ function isPrintOnly(node) { ); } -function getFonts(family, fontFinder) { - if (family.startsWith("'") || family.startsWith('"')) { - family = family.slice(1, family.length - 1); - } +function setFontFamily(xfaFont, fontFinder, style) { + const name = stripQuotes(xfaFont.typeface); + const typeface = fontFinder.find(name); - const pdfFont = fontFinder.find(family); - if (pdfFont) { - const { fontFamily } = pdfFont.regular.cssFontInfo; - if (fontFamily !== family) { - return `"${family}","${fontFamily}"`; + style.fontFamily = `"${name}"`; + if (typeface) { + const { fontFamily } = typeface.regular.cssFontInfo; + if (fontFamily !== name) { + style.fontFamily += `,"${fontFamily}"`; + } + if (style.lineHeight) { + // Already something so don't overwrite. + return; + } + const pdfFont = selectFont(xfaFont, typeface); + if (pdfFont && pdfFont.lineHeight > 0) { + style.lineHeight = pdfFont.lineHeight; } } - - return `"${family}"`; } export { @@ -493,12 +499,12 @@ export { createWrapper, fixDimensions, fixTextIndent, - getFonts, isPrintOnly, layoutClass, layoutText, measureToString, setAccess, + setFontFamily, setMinMaxDimensions, toStyle, }; diff --git a/src/core/xfa/template.js b/src/core/xfa/template.js index a81aa34610c43..237667e923f72 100644 --- a/src/core/xfa/template.js +++ b/src/core/xfa/template.js @@ -70,12 +70,12 @@ import { createWrapper, fixDimensions, fixTextIndent, - getFonts, isPrintOnly, layoutClass, layoutText, measureToString, setAccess, + setFontFamily, setMinMaxDimensions, toStyle, } from "./html_utils.js"; @@ -2695,7 +2695,7 @@ class Font extends XFAObject { style.fontSize = fontSize; } - style.fontFamily = getFonts(this.typeface, this[$globalData].fontFinder); + setFontFamily(this, this[$globalData].fontFinder, style); if (this.underline !== 0) { style.textDecoration = "underline"; diff --git a/src/core/xfa/text.js b/src/core/xfa/text.js index 2cf5dee73e9c5..064edcf8cdd24 100644 --- a/src/core/xfa/text.js +++ b/src/core/xfa/text.js @@ -13,6 +13,8 @@ * limitations under the License. */ +import { selectFont } from "./fonts.js"; + const WIDTH_FACTOR = 1.2; const HEIGHT_FACTOR = 1.2; @@ -30,18 +32,7 @@ class FontInfo { return; } - this.pdfFont = null; - if (xfaFont.posture === "italic") { - if (xfaFont.weight === "bold") { - this.pdfFont = typeface.bolditalic; - } else { - this.pdfFont = typeface.italic; - } - } else if (xfaFont.weigth === "bold") { - this.pdfFont = typeface.bold; - } else { - this.pdfFont = typeface.regular; - } + this.pdfFont = selectFont(xfaFont, typeface); if (!this.pdfFont) { [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder); diff --git a/src/core/xfa/utils.js b/src/core/xfa/utils.js index 28aa1eaa2016e..4a4ebc7427183 100644 --- a/src/core/xfa/utils.js +++ b/src/core/xfa/utils.js @@ -24,6 +24,13 @@ const dimConverters = { }; const measurementPattern = /([+-]?[0-9]+\.?[0-9]*)(.*)/; +function stripQuotes(str) { + if (str.startsWith("'") || str.startsWith('"')) { + return str.slice(1, str.length - 1); + } + return str; +} + function getInteger({ data, defaultValue, validate }) { if (!data) { return defaultValue; @@ -206,4 +213,5 @@ export { getRelevant, getStringOption, HTMLResult, + stripQuotes, }; diff --git a/src/core/xfa/xhtml.js b/src/core/xfa/xhtml.js index ce24d68e9fd0b..3f6fbde87744e 100644 --- a/src/core/xfa/xhtml.js +++ b/src/core/xfa/xhtml.js @@ -28,7 +28,7 @@ import { XmlObject, } from "./xfa_object.js"; import { $buildXFAObject, NamespaceIds } from "./namespaces.js"; -import { fixTextIndent, getFonts, measureToString } from "./html_utils.js"; +import { fixTextIndent, measureToString, setFontFamily } from "./html_utils.js"; import { getMeasurement, HTMLResult } from "./utils.js"; const XHTML_NS_ID = NamespaceIds.xhtml.id; @@ -92,7 +92,7 @@ const StyleMapping = new Map([ ["margin-right", value => measureToString(getMeasurement(value))], ["margin-top", value => measureToString(getMeasurement(value))], ["text-indent", value => measureToString(getMeasurement(value))], - ["font-family", (value, fontFinder) => getFonts(value, fontFinder)], + ["font-family", value => value], ]); const spacesRegExp = /\s+/g; @@ -128,6 +128,18 @@ function mapStyle(styleStr, fontFinder) { } } + if (style.fontFamily) { + setFontFamily( + { + typeface: style.fontFamily, + weight: style.fontWeight || "normal", + posture: style.fontStyle || "normal", + }, + fontFinder, + style + ); + } + fixTextIndent(style); return style; } diff --git a/test/pdfs/xfa_bug1717681.pdf.link b/test/pdfs/xfa_bug1717681.pdf.link new file mode 100644 index 0000000000000..fd3ea1aaa2641 --- /dev/null +++ b/test/pdfs/xfa_bug1717681.pdf.link @@ -0,0 +1 @@ +https://bugzilla.mozilla.org/attachment.cgi?id=9228400 diff --git a/test/test_manifest.json b/test/test_manifest.json index 4c21606943bb6..0280174f75619 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -930,6 +930,14 @@ "link": true, "type": "load" }, + { "id": "xfa_bug1717681", + "file": "pdfs/xfa_bug1717681.pdf", + "md5": "435b1eae7e017b1a932fe204d1ba8be5", + "link": true, + "rounds": 1, + "enableXfa": true, + "type": "eq" + }, { "id": "xfa_bug1716380", "file": "pdfs/xfa_bug1716380.pdf", "md5": "1351f816f0509fe750ca61ef2bd40872", diff --git a/web/xfa_layer_builder.css b/web/xfa_layer_builder.css index 2cc7b3120dbc8..93d35c5fd6d5d 100644 --- a/web/xfa_layer_builder.css +++ b/web/xfa_layer_builder.css @@ -24,6 +24,7 @@ left: 0; z-index: 200; transform-origin: 0 0; + line-height: 1.2; } .xfaLayer * { @@ -55,10 +56,6 @@ margin-left: 3em; } -.xfaLayer p { - margin-bottom: -1px; -} - .xfaFont { color: black; font-weight: normal;