Skip to content

Commit

Permalink
XFA - Fix text positions (bug 1718741)
Browse files Browse the repository at this point in the history
  - font line height is taken into account by acrobat when it isn't with masterpdfeditor: I extracted a font from a pdf, modified some ascent/descent properties thanks to ttx and the reinjected the font in the pdf: only Acrobat is taken it into account. So in this patch, line heights for some substituted fonts are added.
  - it seems that Acrobat is using a line height of 1.2 when the line height in the font is not enough (it's the only way I found to fix correctly bug 1718741).
   - don't use flex in wrapper container (which was causing an horizontal overflow in the above bug).
   - consequently, the above fixes introduced a lot of small regressions, so in order to see real improvements on reftests, I fixed the regressions in this patch:
     - replace margin by padding in some case where padding is a part of a container dimensions;
     - remove some flex display: some containers are wrongly sized when rendered;
     - set letter-spacing to 0.01px: it helps to be sure that text is not broken because of not enough width in Firefox.
  • Loading branch information
calixteman committed Jul 9, 2021
1 parent 0afc785 commit ec6ff0f
Show file tree
Hide file tree
Showing 15 changed files with 220 additions and 103 deletions.
8 changes: 8 additions & 0 deletions src/core/calibri_factors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
};
1 change: 1 addition & 0 deletions src/core/evaluator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion src/core/fonts.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
8 changes: 8 additions & 0 deletions src/core/helvetica_factors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
};
8 changes: 8 additions & 0 deletions src/core/myriadpro_factors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
};
8 changes: 8 additions & 0 deletions src/core/segoeui_factors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
};
54 changes: 48 additions & 6 deletions src/core/xfa/html_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,18 +396,18 @@ 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) {
Object.assign(style, newStyle);
} else {
warn(`(DEBUG) - XFA - style for ${name} not implemented yet`);
}
continue;
}

if (converters.hasOwnProperty(name)) {
converters[name](node, style);
}
}
return style;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
}
}
Expand All @@ -593,5 +634,6 @@ export {
setAccess,
setFontFamily,
setMinMaxDimensions,
setPara,
toStyle,
};
Loading

0 comments on commit ec6ff0f

Please sign in to comment.