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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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",

View File

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