diff --git a/src/core/xfa/xhtml.js b/src/core/xfa/xhtml.js index 788e8c762ac26..edc8ff630d606 100644 --- a/src/core/xfa/xhtml.js +++ b/src/core/xfa/xhtml.js @@ -236,8 +236,7 @@ class XhtmlObject extends XmlObject { } } - [$pushGlyphs](measure, mustPop = true) { - const xfaFont = Object.create(null); + [$pushGlyphs](measure, mustPop = true, xfaFont = Object.create(null)) { const margin = { top: NaN, bottom: NaN, @@ -374,9 +373,7 @@ class B extends XhtmlObject { } [$pushGlyphs](measure) { - measure.pushFont({ weight: "bold" }); - super[$pushGlyphs](measure); - measure.popFont(); + super[$pushGlyphs](measure, /* mustPop = */ true, { weight: "bold" }); } } @@ -464,9 +461,7 @@ class I extends XhtmlObject { } [$pushGlyphs](measure) { - measure.pushFont({ posture: "italic" }); - super[$pushGlyphs](measure); - measure.popFont(); + super[$pushGlyphs](measure, /* mustPop = */ true, { posture: "italic" }); } } diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 65b515800a631..ff657d28d8431 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -1065,3 +1065,4 @@ !issue19954_reduced.pdf !issue1936_reduced.pdf !issue22462.pdf +!xfa_issue22023.pdf diff --git a/test/pdfs/xfa_issue22023.pdf b/test/pdfs/xfa_issue22023.pdf new file mode 100644 index 0000000000000..18cc3c5a1849b Binary files /dev/null and b/test/pdfs/xfa_issue22023.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index ee1be8a54d5c8..032134f59a34d 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -15343,5 +15343,14 @@ "rounds": 1, "type": "eq", "about": "Short loca offsets overflow after duplicating glyph 0." + }, + { + "id": "xfa_issue22023", + "file": "pdfs/xfa_issue22023.pdf", + "md5": "44b75da68e9ccc5c24dc4f9ea05399bf", + "rounds": 1, + "enableXfa": true, + "type": "eq", + "about": "XFA rich text with b and i elements." } ] diff --git a/test/unit/xfa_tohtml_spec.js b/test/unit/xfa_tohtml_spec.js index 046c272f1932e..6bd4c33c33d61 100644 --- a/test/unit/xfa_tohtml_spec.js +++ b/test/unit/xfa_tohtml_spec.js @@ -689,4 +689,91 @@ describe("XFAFactory", function () { const p = searchHtmlNode(pages, "name", "p"); expect(p.attributes.style.fontSize).toEqual("13.86px"); }); + + it("should measure b and i elements like the equivalent styles", async () => { + const draws = { + regular: "Hello World", + b: "Hello World", + boldSpan: `Hello World`, + i: "Hello World", + italicSpan: `Hello World`, + bi: "Hello World", + boldItalicSpan: `Hello World`, + bInSpan: `Hello
World`, + boldSpanInSpan: `Hello
World`, + bWithStyle: `Hello`, + spanWithStyle: `Hello`, + }; + const xml = ` + + + + + `; + const factory = new XFAFactory(new Map([["xdp:xdp", xml]])); + // Glyph widths differ per variant, so the selected font shows in the size. + const makeFont = (name, fontWeight, italicAngle, width) => ({ + name, + cssFontInfo: { fontFamily: "Helvetica", fontWeight, italicAngle }, + lineHeight: 1.2, + lineGap: 0.2, + defaultWidth: width, + encodeString: str => [str], + charsToGlyphs: str => Array.from(str, unicode => ({ unicode, width })), + }); + factory.setFonts([ + makeFont("Helvetica", 400, 0, 500), + makeFont("Helvetica-Bold", 700, 0, 600), + makeFont("Helvetica-Oblique", 400, -12, 550), + makeFont("Helvetica-BoldOblique", 700, -12, 650), + ]); + + expect(await factory.getNumPages()).toEqual(1); + + const pages = await factory.getPages(); + const container = searchHtmlNode(pages, "xfaName", "draws", true); + const sizes = new Map( + container.children.map(({ attributes, children }) => { + const { width, height } = attributes.style; + return [children[0].attributes.xfaName, [width, height]]; + }) + ); + + expect(sizes.size).toEqual(Object.keys(draws).length); + expect(sizes.get("b")).not.toEqual(sizes.get("regular")); + expect(sizes.get("i")).not.toEqual(sizes.get("regular")); + for (const [element, span] of [ + ["b", "boldSpan"], + ["i", "italicSpan"], + ["bi", "boldItalicSpan"], + ["bInSpan", "boldSpanInSpan"], + ["bWithStyle", "spanWithStyle"], + ]) { + expect(sizes.get(element)).withContext(element).toEqual(sizes.get(span)); + } + }); }); diff --git a/web/xfa_layer_builder.css b/web/xfa_layer_builder.css index 73560fec34900..0832edb946c12 100644 --- a/web/xfa_layer_builder.css +++ b/web/xfa_layer_builder.css @@ -113,6 +113,14 @@ color: blue; } +.xfaLayer b { + font-weight: bold; +} + +.xfaLayer i { + font-style: italic; +} + .xfaRich li { margin-left: 3em; }