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.
This commit is contained in:
Calixte Denizet 2021-06-23 11:10:20 +02:00
parent 9441245320
commit e82446fa5a
9 changed files with 70 additions and 34 deletions

View File

@ -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 };

View File

@ -22,7 +22,8 @@ import {
$toStyle, $toStyle,
XFAObject, XFAObject,
} from "./xfa_object.js"; } 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 { TextMeasure } from "./text.js";
import { warn } from "../../shared/util.js"; import { warn } from "../../shared/util.js";
@ -472,20 +473,25 @@ function isPrintOnly(node) {
); );
} }
function getFonts(family, fontFinder) { function setFontFamily(xfaFont, fontFinder, style) {
if (family.startsWith("'") || family.startsWith('"')) { const name = stripQuotes(xfaFont.typeface);
family = family.slice(1, family.length - 1); const typeface = fontFinder.find(name);
}
const pdfFont = fontFinder.find(family); style.fontFamily = `"${name}"`;
if (pdfFont) { if (typeface) {
const { fontFamily } = pdfFont.regular.cssFontInfo; const { fontFamily } = typeface.regular.cssFontInfo;
if (fontFamily !== family) { if (fontFamily !== name) {
return `"${family}","${fontFamily}"`; 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 { export {
@ -493,12 +499,12 @@ export {
createWrapper, createWrapper,
fixDimensions, fixDimensions,
fixTextIndent, fixTextIndent,
getFonts,
isPrintOnly, isPrintOnly,
layoutClass, layoutClass,
layoutText, layoutText,
measureToString, measureToString,
setAccess, setAccess,
setFontFamily,
setMinMaxDimensions, setMinMaxDimensions,
toStyle, toStyle,
}; };

View File

@ -70,12 +70,12 @@ import {
createWrapper, createWrapper,
fixDimensions, fixDimensions,
fixTextIndent, fixTextIndent,
getFonts,
isPrintOnly, isPrintOnly,
layoutClass, layoutClass,
layoutText, layoutText,
measureToString, measureToString,
setAccess, setAccess,
setFontFamily,
setMinMaxDimensions, setMinMaxDimensions,
toStyle, toStyle,
} from "./html_utils.js"; } from "./html_utils.js";
@ -2695,7 +2695,7 @@ class Font extends XFAObject {
style.fontSize = fontSize; style.fontSize = fontSize;
} }
style.fontFamily = getFonts(this.typeface, this[$globalData].fontFinder); setFontFamily(this, this[$globalData].fontFinder, style);
if (this.underline !== 0) { if (this.underline !== 0) {
style.textDecoration = "underline"; style.textDecoration = "underline";

View File

@ -13,6 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
import { selectFont } from "./fonts.js";
const WIDTH_FACTOR = 1.2; const WIDTH_FACTOR = 1.2;
const HEIGHT_FACTOR = 1.2; const HEIGHT_FACTOR = 1.2;
@ -30,18 +32,7 @@ class FontInfo {
return; return;
} }
this.pdfFont = null; this.pdfFont = selectFont(xfaFont, typeface);
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;
}
if (!this.pdfFont) { if (!this.pdfFont) {
[this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder); [this.pdfFont, this.xfaFont] = this.defaultFont(fontFinder);

View File

@ -24,6 +24,13 @@ const dimConverters = {
}; };
const measurementPattern = /([+-]?[0-9]+\.?[0-9]*)(.*)/; 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 }) { function getInteger({ data, defaultValue, validate }) {
if (!data) { if (!data) {
return defaultValue; return defaultValue;
@ -206,4 +213,5 @@ export {
getRelevant, getRelevant,
getStringOption, getStringOption,
HTMLResult, HTMLResult,
stripQuotes,
}; };

View File

@ -28,7 +28,7 @@ import {
XmlObject, XmlObject,
} from "./xfa_object.js"; } from "./xfa_object.js";
import { $buildXFAObject, NamespaceIds } from "./namespaces.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"; import { getMeasurement, HTMLResult } from "./utils.js";
const XHTML_NS_ID = NamespaceIds.xhtml.id; const XHTML_NS_ID = NamespaceIds.xhtml.id;
@ -92,7 +92,7 @@ const StyleMapping = new Map([
["margin-right", value => measureToString(getMeasurement(value))], ["margin-right", value => measureToString(getMeasurement(value))],
["margin-top", value => measureToString(getMeasurement(value))], ["margin-top", value => measureToString(getMeasurement(value))],
["text-indent", 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; 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); fixTextIndent(style);
return style; return style;
} }

View File

@ -0,0 +1 @@
https://bugzilla.mozilla.org/attachment.cgi?id=9228400

View File

@ -930,6 +930,14 @@
"link": true, "link": true,
"type": "load" "type": "load"
}, },
{ "id": "xfa_bug1717681",
"file": "pdfs/xfa_bug1717681.pdf",
"md5": "435b1eae7e017b1a932fe204d1ba8be5",
"link": true,
"rounds": 1,
"enableXfa": true,
"type": "eq"
},
{ "id": "xfa_bug1716380", { "id": "xfa_bug1716380",
"file": "pdfs/xfa_bug1716380.pdf", "file": "pdfs/xfa_bug1716380.pdf",
"md5": "1351f816f0509fe750ca61ef2bd40872", "md5": "1351f816f0509fe750ca61ef2bd40872",

View File

@ -24,6 +24,7 @@
left: 0; left: 0;
z-index: 200; z-index: 200;
transform-origin: 0 0; transform-origin: 0 0;
line-height: 1.2;
} }
.xfaLayer * { .xfaLayer * {
@ -55,10 +56,6 @@
margin-left: 3em; margin-left: 3em;
} }
.xfaLayer p {
margin-bottom: -1px;
}
.xfaFont { .xfaFont {
color: black; color: black;
font-weight: normal; font-weight: normal;