diff --git a/src/core/calibri_factors.js b/src/core/calibri_factors.js index c4e15f628..6a7804a68 100644 --- a/src/core/calibri_factors.js +++ b/src/core/calibri_factors.js @@ -81,6 +81,7 @@ const CalibriBoldFactors = [ 0.95794, 0.95794, 0.82616, 0.86513, 0.85162, 0.85162, 0.85162, 0.85162, 0.91133, 0.85162, 0.79492, 0.79492, 0.79492, 0.79492, 0.91133, 0.79109, ]; +const CalibriBoldLineHeight = 1.2207; // Factors to rescale LiberationSans-BoldItalic.ttf to have the same // metrics as calibriz.ttf. @@ -152,6 +153,7 @@ const CalibriBoldItalicFactors = [ 0.84548, 0.84548, 0.91133, 0.84548, 0.79492, 0.79492, 0.79492, 0.79492, 0.91133, 0.74081, ]; +const CalibriBoldItalicLineHeight = 1.2207; // Factors to rescale LiberationSans-Italic.ttf to have the same // metrics as calibrii.ttf. @@ -221,6 +223,7 @@ const CalibriItalicFactors = [ 0.84153, 0.89453, 0.89453, 0.89453, 0.89453, 0.91133, 0.89453, 0.79004, 0.79004, 0.79004, 0.79004, 0.91133, 0.75026, ]; +const CalibriItalicLineHeight = 1.2207; // Factors to rescale LiberationSans-Regular.ttf to have the same // metrics as calibri.ttf. @@ -291,10 +294,15 @@ const CalibriRegularFactors = [ 0.83969, 0.90527, 0.90527, 0.90527, 0.90527, 0.91133, 0.90527, 0.79004, 0.79004, 0.79004, 0.79004, 0.91133, 0.78848, ]; +const CalibriRegularLineHeight = 1.2207; export { CalibriBoldFactors, CalibriBoldItalicFactors, + CalibriBoldItalicLineHeight, + CalibriBoldLineHeight, CalibriItalicFactors, + CalibriItalicLineHeight, CalibriRegularFactors, + CalibriRegularLineHeight, }; diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 0d4291258..614599423 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -3888,6 +3888,7 @@ class PartialEvaluator { const standardFontName = getXfaFontName(fontName.name); if (standardFontName) { cssFontInfo.fontFamily = `${cssFontInfo.fontFamily}-PdfJS-XFA`; + cssFontInfo.lineHeight = standardFontName.lineHeight || null; glyphScaleFactors = standardFontName.factors || null; fontFile = await this.fetchStandardFontData(standardFontName.name); isInternalFont = !!fontFile; diff --git a/src/core/fonts.js b/src/core/fonts.js index 1ab9cd398..66d812acc 100644 --- a/src/core/fonts.js +++ b/src/core/fonts.js @@ -2548,7 +2548,12 @@ class Font { this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm; this.descent = metricsOverride.descent / metricsOverride.unitsPerEm; this.lineGap = metricsOverride.lineGap / metricsOverride.unitsPerEm; - this.lineHeight = this.ascent - this.descent + this.lineGap; + + if (this.cssFontInfo && this.cssFontInfo.lineHeight) { + this.lineHeight = this.cssFontInfo.lineHeight; + } else { + this.lineHeight = this.ascent - this.descent + this.lineGap; + } // The 'post' table has glyphs names. if (tables.post) { diff --git a/src/core/helvetica_factors.js b/src/core/helvetica_factors.js index 8f65e4475..2bd4c42e4 100644 --- a/src/core/helvetica_factors.js +++ b/src/core/helvetica_factors.js @@ -94,6 +94,7 @@ const HelveticaBoldFactors = [ 1.00022, 1.00022, 0.99973, 0.9993, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1, 1, 1, 1, 0.99973, 0.99902, ]; +const HelveticaBoldLineHeight = 1.2; // Factors to rescale LiberationSans-BoldItalic.ttf to have the same // metrics as NimbusSans-BoldItalic.otf. @@ -176,6 +177,7 @@ const HelveticaBoldItalicFactors = [ 0.99973, 1.00065, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 0.99973, 1, 1, 1, 1, 0.99973, 1.00061, ]; +const HelveticaBoldItalicLineHeight = 1.35; // Factors to rescale LiberationSans-Italic.ttf to have the same // metrics as NimbusSans-Italic.otf. @@ -256,6 +258,7 @@ const HelveticaItalicFactors = [ 0.99973, 0.99973, 1, 0.99977, 0.99977, 0.99977, 0.99977, 0.99977, 1, 1.0005, 1, 1, 1, 1, 0.99973, 1, 1, 1, 1, 1, 0.99973, 0.99918, ]; +const HelveticaItalicLineHeight = 1.35; // Factors to rescale LiberationSans-Regular.ttf to have the same // metrics as NimbusSans-Regular.otf. @@ -336,10 +339,15 @@ const HelveticaRegularFactors = [ 0.99977, 0.99977, 0.99977, 1, 1.00055, 1, 1, 1, 1, 0.99973, 1, 1, 1, 1, 1, 0.99973, 1.00019, ]; +const HelveticaRegularLineHeight = 1.2; export { HelveticaBoldFactors, HelveticaBoldItalicFactors, + HelveticaBoldItalicLineHeight, + HelveticaBoldLineHeight, HelveticaItalicFactors, + HelveticaItalicLineHeight, HelveticaRegularFactors, + HelveticaRegularLineHeight, }; diff --git a/src/core/myriadpro_factors.js b/src/core/myriadpro_factors.js index db7170e7b..da06cd4c7 100644 --- a/src/core/myriadpro_factors.js +++ b/src/core/myriadpro_factors.js @@ -77,6 +77,7 @@ const MyriadProBoldFactors = [ 0.97579, 0.97579, 0.97579, 0.9332, 1.05993, 0.94039, 0.94039, 0.94039, 0.94039, 0.99793, 0.94039, 0.938, 0.938, 0.938, 0.938, 0.99793, 0.95776, ]; +const MyriadProBoldLineHeight = 1.2; // Factors to rescale LiberationSans-BoldItalic.ttf to have the same // metrics as MyriadPro-BoldIt.otf. @@ -143,6 +144,7 @@ const MyriadProBoldItalicFactors = [ 0.89544, 1.0051, 0.89364, 0.89364, 0.89364, 0.89364, 0.97276, 0.89364, 0.9, 0.9, 0.9, 0.9, 0.97276, 0.86842, ]; +const MyriadProBoldItalicLineHeight = 1.2; // Factors to rescale LiberationSans-Italic.ttf to have the same // metrics as MyriadPro-It.otf. @@ -208,6 +210,7 @@ const MyriadProItalicFactors = [ 0.979, 0.979, 0.979, 0.979, 0.882, 0.93559, 0.882, 0.882, 0.882, 0.882, 0.88465, 0.882, 0.83, 0.83, 0.83, 0.83, 0.88465, 0.84596, ]; +const MyriadProItalicLineHeight = 1.2; // Factors to rescale LiberationSans-Regular.ttf to have the same // metrics as MyriadPro-Regular.otf. @@ -273,10 +276,15 @@ const MyriadProRegularFactors = [ 1.01915, 0.926, 0.96705, 0.942, 0.942, 0.942, 0.942, 0.92241, 0.942, 0.856, 0.856, 0.856, 0.856, 0.92241, 0.92761, ]; +const MyriadProRegularLineHeight = 1.2; export { MyriadProBoldFactors, MyriadProBoldItalicFactors, + MyriadProBoldItalicLineHeight, + MyriadProBoldLineHeight, MyriadProItalicFactors, + MyriadProItalicLineHeight, MyriadProRegularFactors, + MyriadProRegularLineHeight, }; diff --git a/src/core/segoeui_factors.js b/src/core/segoeui_factors.js index f4fd61c69..278d92bd7 100644 --- a/src/core/segoeui_factors.js +++ b/src/core/segoeui_factors.js @@ -81,6 +81,7 @@ const SegoeuiBoldFactors = [ 1.02511, 0.99298, 1.07237, 0.96752, 0.96752, 0.96752, 0.96752, 1.03424, 0.96752, 0.95801, 0.95801, 0.95801, 0.95801, 1.03424, 1.0106, ]; +const SegoeuiBoldLineHeight = 1.33008; // Factors to rescale LiberationSans-BoldItalic.ttf to have the same // metrics as segoeuiz.ttf. @@ -151,6 +152,7 @@ const SegoeuiBoldItalicFactors = [ 0.96752, 0.96752, 1.036, 0.96752, 0.97168, 0.97168, 0.97168, 0.97168, 1.036, 0.95134, ]; +const SegoeuiBoldItalicLineHeight = 1.33008; // Factors to rescale LiberationSans-Italic.ttf to have the same // metrics as segoeuii.ttf. @@ -221,6 +223,7 @@ const SegoeuiItalicFactors = [ 0.96777, 0.96777, 0.96777, 0.96927, 0.96777, 0.9043, 0.9043, 0.9043, 0.9043, 0.96927, 0.95364, ]; +const SegoeuiItalicLineHeight = 1.33008; // Factors to rescale LiberationSans-Regular.ttf to have the same // metrics as segoeui.ttf. @@ -291,10 +294,15 @@ const SegoeuiRegularFactors = [ 1.00068, 0.91797, 0.99346, 0.96777, 0.96777, 0.96777, 0.96777, 0.96927, 0.96777, 0.9043, 0.9043, 0.9043, 0.9043, 0.96927, 1.00221, ]; +const SegoeuiRegularLineHeight = 1.33008; export { SegoeuiBoldFactors, SegoeuiBoldItalicFactors, + SegoeuiBoldItalicLineHeight, + SegoeuiBoldLineHeight, SegoeuiItalicFactors, + SegoeuiItalicLineHeight, SegoeuiRegularFactors, + SegoeuiRegularLineHeight, }; diff --git a/src/core/xfa/html_utils.js b/src/core/xfa/html_utils.js index cd1f3b9df..d7fa3ce0b 100644 --- a/src/core/xfa/html_utils.js +++ b/src/core/xfa/html_utils.js @@ -396,6 +396,11 @@ function toStyle(node, ...names) { if (value === null) { continue; } + if (converters.hasOwnProperty(name)) { + converters[name](node, style); + continue; + } + if (value instanceof XFAObject) { const newStyle = value[$toStyle](); if (newStyle) { @@ -403,11 +408,6 @@ function toStyle(node, ...names) { } else { warn(`(DEBUG) - XFA - style for ${name} not implemented yet`); } - continue; - } - - if (converters.hasOwnProperty(name)) { - converters[name](node, style); } } return style; @@ -560,6 +560,44 @@ function isPrintOnly(node) { ); } +function setPara(node, nodeStyle, value) { + if (value.attributes.class && value.attributes.class.includes("xfaRich")) { + if (nodeStyle) { + if (node.h === "") { + nodeStyle.height = "auto"; + } + if (node.w === "") { + nodeStyle.width = "auto"; + } + } + if (node.para) { + // By definition exData are external data so para + // has no effect on it. + const valueStyle = value.attributes.style; + valueStyle.display = "flex"; + valueStyle.flexDirection = "column"; + switch (node.para.vAlign) { + case "top": + valueStyle.justifyContent = "start"; + break; + case "bottom": + valueStyle.justifyContent = "end"; + break; + case "middle": + valueStyle.justifyContent = "center"; + break; + } + + const paraStyle = node.para[$toStyle](); + for (const [key, val] of Object.entries(paraStyle)) { + if (!(key in valueStyle)) { + valueStyle[key] = val; + } + } + } + } +} + function setFontFamily(xfaFont, fontFinder, style) { const name = stripQuotes(xfaFont.typeface); const typeface = fontFinder.find(name); @@ -574,9 +612,12 @@ function setFontFamily(xfaFont, fontFinder, style) { // Already something so don't overwrite. return; } + const pdfFont = selectFont(xfaFont, typeface); if (pdfFont && pdfFont.lineHeight > 0) { - style.lineHeight = pdfFont.lineHeight; + style.lineHeight = Math.max(1.2, pdfFont.lineHeight); + } else { + style.lineHeight = 1.2; } } } @@ -593,5 +634,6 @@ export { setAccess, setFontFamily, setMinMaxDimensions, + setPara, toStyle, }; diff --git a/src/core/xfa/template.js b/src/core/xfa/template.js index b65ec9f4a..6188fb509 100644 --- a/src/core/xfa/template.js +++ b/src/core/xfa/template.js @@ -81,6 +81,7 @@ import { setAccess, setFontFamily, setMinMaxDimensions, + setPara, toStyle, } from "./html_utils.js"; import { @@ -165,12 +166,20 @@ function setTabIndex(node) { function valueToHtml(value) { return HTMLResult.success({ - name: "span", + name: "div", attributes: { class: ["xfaRich"], style: Object.create(null), }, - value, + children: [ + { + name: "span", + attributes: { + style: Object.create(null), + }, + value, + }, + ], }); } @@ -256,6 +265,15 @@ function handleBreak(node) { return true; } +function handleOverflow(node, extraNode, space) { + const root = node[$getTemplateRoot](); + const saved = root[$extra].noLayoutFailure; + root[$extra].noLayoutFailure = true; + const res = extraNode[$toHTML](space); + node[$addHTML](res.html, res.bbox); + root[$extra].noLayoutFailure = saved; +} + class AppearanceFilter extends StringObject { constructor(attributes) { super(TEMPLATE_NS_ID, "appearanceFilter"); @@ -1004,7 +1022,7 @@ class Caption extends XFAObject { children.push(value); } - const style = toStyle(this, "font", "margin", "para", "visibility"); + const style = toStyle(this, "font", "margin", "visibility"); switch (this.placement) { case "left": case "right": @@ -1020,6 +1038,8 @@ class Caption extends XFAObject { break; } + setPara(this, null, value); + this.reserve = savedReserve; return HTMLResult.success({ @@ -1685,6 +1705,11 @@ class Draw extends XFAObject { setMinMaxDimensions(this, style); + if (style.margin) { + style.padding = style.margin; + delete style.margin; + } + const classNames = ["xfaDraw"]; if (this.font) { classNames.push("xfaFont"); @@ -1719,42 +1744,7 @@ class Draw extends XFAObject { } html.children.push(value); - if (value.attributes.class && value.attributes.class.includes("xfaRich")) { - if (this.h === "") { - style.height = "auto"; - } - if (this.w === "") { - style.width = "auto"; - } - if (this.para) { - // By definition exData are external data so para - // has no effect on it. - attributes.style.display = "flex"; - attributes.style.flexDirection = "column"; - switch (this.para.vAlign) { - case "top": - attributes.style.justifyContent = "start"; - break; - case "bottom": - attributes.style.justifyContent = "end"; - break; - case "middle": - attributes.style.justifyContent = "center"; - break; - } - - const paraStyle = this.para[$toStyle](); - if (!value.attributes.style) { - value.attributes.style = paraStyle; - } else { - for (const [key, val] of Object.entries(paraStyle)) { - if (!(key in value.attributes.style)) { - value.attributes.style[key] = val; - } - } - } - } - } + setPara(this, style, value); this.w = savedW; this.h = savedH; @@ -2543,20 +2533,21 @@ class Field extends XFAObject { width = w; height = h; - if (this.ui instanceof CheckButton) { + if (this.ui.checkButton) { switch (this.caption.placement) { case "left": case "right": case "inline": - width += this.ui.size; + width += this.ui.checkButton.size; break; case "top": case "bottom": - height += this.ui.size; + height += this.ui.checkButton.size; break; } } } + if (width && this.w === "") { this.w = Math.min( this.maxW <= 0 ? Infinity : this.maxW, @@ -2612,6 +2603,11 @@ class Field extends XFAObject { class: classNames, }; + if (style.margin) { + style.padding = style.margin; + delete style.margin; + } + setAccess(this, classNames); if (this.name) { @@ -2664,7 +2660,7 @@ class Field extends XFAObject { } else { const htmlValue = this.value[$toHTML]().html; if (htmlValue !== null) { - value = htmlValue.value; + value = htmlValue.children[0].value; } } if (this.ui.textEdit && this.value.text && this.value.text.maxChars) { @@ -2693,6 +2689,9 @@ class Field extends XFAObject { } if (this.ui.button) { + if (style.padding) { + delete style.padding; + } if (caption.name === "div") { caption.name = "span"; } @@ -2951,11 +2950,7 @@ class Font extends XFAObject { // TODO: overlinePeriod style.fontStyle = this.posture; - - const fontSize = measureToString(0.99 * this.size); - if (fontSize !== "10px") { - style.fontSize = fontSize; - } + style.fontSize = measureToString(0.99 * this.size); setFontFamily(this, this[$globalData].fontFinder, style); @@ -3554,8 +3549,14 @@ class Overflow extends XFAObject { const parent = this[$getParent](); const root = this[$getTemplateRoot](); const target = root[$searchNode](this.target, parent); + const leader = root[$searchNode](this.leader, parent); + const trailer = root[$searchNode](this.trailer, parent); this[$extra] = { target: (target && target[0]) || null, + leader: (leader && leader[0]) || null, + trailer: (trailer && trailer[0]) || null, + addLeader: false, + addTrailer: false, }; } return this[$extra]; @@ -3875,16 +3876,16 @@ class Para extends XFAObject { [$toStyle]() { const style = toStyle(this, "hAlign"); if (this.marginLeft !== "") { - style.marginLeft = measureToString(this.marginLeft); + style.paddingLeft = measureToString(this.marginLeft); } if (this.marginRight !== "") { - style.marginRight = measureToString(this.marginRight); + style.paddingight = measureToString(this.marginRight); } if (this.spaceAbove !== "") { - style.marginTop = measureToString(this.spaceAbove); + style.paddingTop = measureToString(this.spaceAbove); } if (this.spaceBelow !== "") { - style.marginBottom = measureToString(this.spaceBelow); + style.paddingBottom = measureToString(this.spaceBelow); } if (this.textIndent !== "") { style.textIndent = measureToString(this.textIndent); @@ -4699,6 +4700,14 @@ class Subform extends XFAObject { attributes.xfaName = this.name; } + if (this.overflow) { + const overflowExtra = this.overflow[$getExtra](); + if (overflowExtra.addLeader) { + overflowExtra.addLeader = false; + handleOverflow(this, overflowExtra.leader, availableSpace); + } + } + const maxRun = this.layout === "lr-tb" || this.layout === "rl-tb" ? MAX_ATTEMPTS_FOR_LRTB_LAYOUT @@ -4740,6 +4749,14 @@ class Subform extends XFAObject { return HTMLResult.FAILURE; } + if (this.overflow) { + const overflowExtra = this.overflow[$getExtra](); + if (overflowExtra.addTrailer) { + overflowExtra.addTrailer = false; + handleOverflow(this, overflowExtra.trailer, availableSpace); + } + } + let marginH = 0; let marginV = 0; if (this.margin) { @@ -5137,24 +5154,13 @@ class Template extends XFAObject { const node = this[$extra].overflowNode; this[$extra].overflowNode = null; + const overflowExtra = node[$getExtra](); + const target = overflowExtra.target; + overflowExtra.addLeader = overflowExtra.leader !== null; + overflowExtra.addTrailer = overflowExtra.trailer !== null; + flush(i); - if (node.leader) { - leader = this[$searchNode](node.leader, node[$getParent]()); - leader = leader ? leader[0] : null; - } - - if (node.trailer) { - trailer = this[$searchNode](node.trailer, node[$getParent]()); - trailer = trailer ? trailer[0] : null; - } - - let target = null; - if (node.target) { - target = this[$searchNode](node.target, node[$getParent]()); - target = target ? target[0] : target; - } - i = Infinity; if (target instanceof PageArea) { // We must stop the contentAreas filling and go to the next page. diff --git a/src/core/xfa/text.js b/src/core/xfa/text.js index faed18e22..1ae4de6ee 100644 --- a/src/core/xfa/text.js +++ b/src/core/xfa/text.js @@ -15,7 +15,7 @@ import { selectFont } from "./fonts.js"; -const WIDTH_FACTOR = 1.05; +const WIDTH_FACTOR = 1.01; class FontInfo { constructor(xfaFont, margin, lineHeight, fontFinder) { @@ -183,7 +183,7 @@ class TextMeasure { const pdfFont = lastFont.pdfFont; const lineHeight = lastFont.lineHeight || - Math.round(Math.max(1, pdfFont.lineHeight) * fontSize); + Math.ceil(Math.max(1.2, pdfFont.lineHeight) * fontSize); const scale = fontSize / 1000; for (const line of str.split(/[\u2029\n]/)) { diff --git a/src/core/xfa/xhtml.js b/src/core/xfa/xhtml.js index 0f933c692..84de661cb 100644 --- a/src/core/xfa/xhtml.js +++ b/src/core/xfa/xhtml.js @@ -84,7 +84,13 @@ const StyleMapping = new Map([ ], ["xfa-spacerun", ""], ["xfa-tab-stops", ""], - ["font-size", value => measureToString(getMeasurement(value))], + [ + "font-size", + (value, original) => { + value = original.fontSize = getMeasurement(value); + return measureToString(0.99 * value); + }, + ], ["letter-spacing", value => measureToString(getMeasurement(value))], ["line-height", value => measureToString(getMeasurement(value))], ["margin", value => measureToString(getMeasurement(value))], @@ -104,6 +110,7 @@ function mapStyle(styleStr, fontFinder) { if (!styleStr) { return style; } + const original = Object.create(null); for (const [key, value] of styleStr.split(";").map(s => s.split(":", 2))) { const mapping = StyleMapping.get(key); if (mapping === "") { @@ -114,7 +121,7 @@ function mapStyle(styleStr, fontFinder) { if (typeof mapping === "string") { newValue = mapping; } else { - newValue = mapping(value, fontFinder); + newValue = mapping(value, original); } } if (key.endsWith("scale")) { @@ -135,6 +142,7 @@ function mapStyle(styleStr, fontFinder) { typeface: style.fontFamily, weight: style.fontWeight || "normal", posture: style.fontStyle || "normal", + size: original.fontSize || 0, }, fontFinder, style diff --git a/src/core/xfa_fonts.js b/src/core/xfa_fonts.js index 143381ad8..f6646bc21 100644 --- a/src/core/xfa_fonts.js +++ b/src/core/xfa_fonts.js @@ -16,14 +16,22 @@ import { CalibriBoldFactors, CalibriBoldItalicFactors, + CalibriBoldItalicLineHeight, + CalibriBoldLineHeight, CalibriItalicFactors, + CalibriItalicLineHeight, CalibriRegularFactors, + CalibriRegularLineHeight, } from "./calibri_factors.js"; import { HelveticaBoldFactors, HelveticaBoldItalicFactors, + HelveticaBoldItalicLineHeight, + HelveticaBoldLineHeight, HelveticaItalicFactors, + HelveticaItalicLineHeight, HelveticaRegularFactors, + HelveticaRegularLineHeight, } from "./helvetica_factors.js"; import { LiberationSansBoldItalicWidths, @@ -34,14 +42,22 @@ import { import { MyriadProBoldFactors, MyriadProBoldItalicFactors, + MyriadProBoldItalicLineHeight, + MyriadProBoldLineHeight, MyriadProItalicFactors, + MyriadProItalicLineHeight, MyriadProRegularFactors, + MyriadProRegularLineHeight, } from "./myriadpro_factors.js"; import { SegoeuiBoldFactors, SegoeuiBoldItalicFactors, + SegoeuiBoldItalicLineHeight, + SegoeuiBoldLineHeight, SegoeuiItalicFactors, + SegoeuiItalicLineHeight, SegoeuiRegularFactors, + SegoeuiRegularLineHeight, } from "./segoeui_factors.js"; import { getLookupTableFactory } from "./core_utils.js"; import { normalizeFontName } from "./fonts_utils.js"; @@ -51,21 +67,25 @@ const getXFAFontMap = getLookupTableFactory(function (t) { name: "LiberationSans-Regular", factors: MyriadProRegularFactors, baseWidths: LiberationSansRegularWidths, + lineHeight: MyriadProRegularLineHeight, }; t["MyriadPro-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.ArialMT = t.Arial = @@ -90,61 +110,73 @@ const getXFAFontMap = getLookupTableFactory(function (t) { name: "LiberationSans-Regular", factors: CalibriRegularFactors, baseWidths: LiberationSansRegularWidths, + lineHeight: CalibriRegularLineHeight, }; t["Calibri-Bold"] = { name: "LiberationSans-Bold", factors: CalibriBoldFactors, baseWidths: LiberationSansBoldWidths, + lineHeight: CalibriBoldLineHeight, }; t["Calibri-Italic"] = { name: "LiberationSans-Italic", factors: CalibriItalicFactors, baseWidths: LiberationSansItalicWidths, + lineHeight: CalibriItalicLineHeight, }; t["Calibri-BoldItalic"] = { name: "LiberationSans-BoldItalic", factors: CalibriBoldItalicFactors, baseWidths: LiberationSansBoldItalicWidths, + lineHeight: CalibriBoldItalicLineHeight, }; t["Segoeui-Regular"] = { name: "LiberationSans-Regular", factors: SegoeuiRegularFactors, baseWidths: LiberationSansRegularWidths, + lineHeight: SegoeuiRegularLineHeight, }; t["Segoeui-Bold"] = { name: "LiberationSans-Bold", factors: SegoeuiBoldFactors, baseWidths: LiberationSansBoldWidths, + lineHeight: SegoeuiBoldLineHeight, }; t["Segoeui-Italic"] = { name: "LiberationSans-Italic", factors: SegoeuiItalicFactors, baseWidths: LiberationSansItalicWidths, + lineHeight: SegoeuiItalicLineHeight, }; t["Segoeui-BoldItalic"] = { name: "LiberationSans-BoldItalic", factors: SegoeuiBoldItalicFactors, baseWidths: LiberationSansBoldItalicWidths, + lineHeight: SegoeuiBoldItalicLineHeight, }; t["Helvetica-Regular"] = { name: "LiberationSans-Regular", factors: HelveticaRegularFactors, baseWidths: LiberationSansRegularWidths, + lineHeight: HelveticaRegularLineHeight, }; t["Helvetica-Bold"] = { name: "LiberationSans-Bold", factors: HelveticaBoldFactors, baseWidths: LiberationSansBoldWidths, + lineHeight: HelveticaBoldLineHeight, }; t["Helvetica-Italic"] = { name: "LiberationSans-Italic", factors: HelveticaItalicFactors, baseWidths: LiberationSansItalicWidths, + lineHeight: HelveticaItalicLineHeight, }; t["Helvetica-BoldItalic"] = { name: "LiberationSans-BoldItalic", factors: HelveticaBoldItalicFactors, baseWidths: LiberationSansBoldItalicWidths, + lineHeight: HelveticaBoldItalicLineHeight, }; }); diff --git a/test/pdfs/xfa_bug1718741.pdf.link b/test/pdfs/xfa_bug1718741.pdf.link new file mode 100644 index 000000000..56e3e94c7 --- /dev/null +++ b/test/pdfs/xfa_bug1718741.pdf.link @@ -0,0 +1 @@ +https://bugzilla.mozilla.org/attachment.cgi?id=9229375 diff --git a/test/test_manifest.json b/test/test_manifest.json index 76c8ea51f..cd6af1c60 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -960,6 +960,14 @@ "enableXfa": true, "type": "eq" }, + { "id": "xfa_bug1718741", + "file": "pdfs/xfa_bug1718741.pdf", + "md5": "1b80f8287cdbf9a67e4bff8be20b1bbd", + "link": true, + "rounds": 1, + "enableXfa": true, + "type": "eq" + }, { "id": "xfa_bug1718670_1", "file": "pdfs/xfa_bug1718670_1.pdf", "md5": "06745be56a89acd80e5bdeddabb7cb7b", diff --git a/test/unit/xfa_tohtml_spec.js b/test/unit/xfa_tohtml_spec.js index 3a6d5bd29..68cbbfcb9 100644 --- a/test/unit/xfa_tohtml_spec.js +++ b/test/unit/xfa_tohtml_spec.js @@ -126,7 +126,7 @@ describe("XFAFactory", function () { fontStyle: "normal", fontWeight: "normal", fontSize: "6.93px", - margin: "1px 4px 2px 3px", + padding: "1px 4px 2px 3px", verticalAlign: "2px", }); diff --git a/web/xfa_layer_builder.css b/web/xfa_layer_builder.css index 379f10ff2..eb697f689 100644 --- a/web/xfa_layer_builder.css +++ b/web/xfa_layer_builder.css @@ -41,7 +41,7 @@ font-style: inherit; font-weight: inherit; font-kerning: inherit; - letter-spacing: inherit; + letter-spacing: -0.01px; text-align: inherit; text-decoration: inherit; vertical-align: inherit; @@ -118,13 +118,9 @@ pointer-events: none; } -.xfaWrapper { - display: flex; - align-items: stretch; -} - .xfaWrapped { - flex: 1 1 auto; + width: 100%; + height: 100%; } .xfaTextfield, @@ -169,8 +165,8 @@ .xfaRich { white-space: pre-wrap; - width: auto; - height: auto; + width: 100%; + height: 100%; } .xfaImage { @@ -188,12 +184,6 @@ align-items: stretch; } -.xfaLr, -.xfaRl, -.xfaTb > div { - flex: 1 1 auto; -} - .xfaLr { display: flex; flex-direction: row; @@ -229,20 +219,12 @@ align-items: stretch; } -.xfaTable > div { - flex: 1 1 auto; -} - .xfaTable .xfaRow { display: flex; flex-direction: row; align-items: stretch; } -.xfaTable .xfaRow > div { - flex: 1 1 auto; -} - .xfaTable .xfaRlRow { display: flex; flex-direction: row-reverse;