Handle sub/super-scripts in rich text

- it aims to fix #14317;
 - change the fontSize and the verticalAlign properties according to the position of the text.
This commit is contained in:
Calixte Denizet 2021-11-27 15:49:57 +01:00
parent e439f4d620
commit cfdaa57353

View File

@ -107,13 +107,14 @@ const StyleMapping = new Map([
["margin-top", value => measureToString(getMeasurement(value))],
["text-indent", value => measureToString(getMeasurement(value))],
["font-family", value => value],
["vertical-align", value => measureToString(getMeasurement(value))],
]);
const spacesRegExp = /\s+/g;
const crlfRegExp = /[\r\n]+/g;
const crlfForRichTextRegExp = /\r\n?/g;
function mapStyle(styleStr, node) {
function mapStyle(styleStr, node, richText) {
const style = Object.create(null);
if (!styleStr) {
return style;
@ -158,6 +159,29 @@ function mapStyle(styleStr, node) {
);
}
if (
richText &&
style.verticalAlign &&
style.verticalAlign !== "0px" &&
style.fontSize
) {
// A non-zero verticalAlign means that we've a sub/super-script and
// consequently the font size must be decreased.
// https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf#G11.2097514
// And the two following factors to position the scripts have been
// found here:
// https://en.wikipedia.org/wiki/Subscript_and_superscript#Desktop_publishing
const SUB_SUPER_SCRIPT_FACTOR = 0.583;
const VERTICAL_FACTOR = 0.333;
const fontSize = getMeasurement(style.fontSize);
style.fontSize = measureToString(fontSize * SUB_SUPER_SCRIPT_FACTOR);
style.verticalAlign = measureToString(
Math.sign(getMeasurement(style.verticalAlign)) *
fontSize *
VERTICAL_FACTOR
);
}
fixTextIndent(style);
return style;
}
@ -333,7 +357,7 @@ class XhtmlObject extends XmlObject {
name: this[$nodeName],
attributes: {
href: this.href,
style: mapStyle(this.style, this),
style: mapStyle(this.style, this, this[$richText]),
},
children,
value,