diff --git a/src/core/xfa/xhtml.js b/src/core/xfa/xhtml.js index 510747db4..273cc93bc 100644 --- a/src/core/xfa/xhtml.js +++ b/src/core/xfa/xhtml.js @@ -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,