Repository navigation
fix(docx): write a painted box holding text in the body as a panel - #971
Merged
Merged
Conversation
A shape container shaped as a rectangle or a rounded rectangle, filled or outlined, holding text and placed in the body, was drawn at its size with its layers written in the flow: its text took the flow's width and ran past the outline, the block under it stood over the outline, and the outline kept its height when text was added in an editor. It is now written as a panel, as it already was composed in a table cell: one cell its outline's size, its fill and border on the cell, its padding round it, the row kept on one page. Its layers stand where the layout places them in the outline; one the page sets at the outline's top is set at the cell's top and takes the top border out of the space above its first line. The row is held at least the outline's height, so it grows with its text; a clip that cuts what the layers paint past the outline's foot holds it at exactly that height less one border, which Word and LibreOffice cut the content at. The report names the square corners, the clip written as an exact height, and layers running past the foot unclipped. The rows of the fidelity corpus's three body shape containers are rewritten in the Word and Windows LibreOffice baselines.
A block of a fixed width set at a body panel's left was left at the cell's whole width, as a block the page lays out in the whole room is: the page wraps it at its own width, and the inline path held it there. It is held to its width again. The first layer's height a panel's layer notes compare against is the one its cell sets it at: the top for a layer taller than the outline. Tests pin the outline's top and foot read inside a padded shape, and a fixed-width block at the left.
The rows of narrow_container, clipped_container and rounded_card in the Linux LibreOffice baseline are taken from the first CI run of this change (artifact docx-fidelity-40398446747), which matches LibreOffice 24.2's docker build to the hundredth; every other row is as it was. The narrow and clipped boxes move nearer the page. Of rounded_card, the two lines under the card stand 0.6pt high there: LibreOffice 24.2 counts a cell's borders inside the least height its row is held at, as it counts the row's margins, where Word adds them, and the card's content is shorter than its outline. Word sets them within 0.1pt. The DOCX recipe names the difference.
Only a section, a container or a list set at a body panel's left, of no fixed width, stands where it is written: the page lays it out in the whole room. A shape, a canvas or a table there has a width of its own and is held to it, as the inline path held it: a pill at a card's left centred its label in the card. The clip's note says Word cuts what the panel's cell holds, which is what an exact row cuts. The DOCX recipe and the CHANGELOG name the badge and the line pair as kept, and LibreOffice 24.2's narrow box as 1pt short. Tests read twips through DocxTwips.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
In the body, the DOCX export drew a shape container's outline as a shape of its size, where the page draws it, and wrote its layers in the flow. The layers took the flow's width, not the outline's, and the outline did not grow with them. Measured in Word 16 and LibreOffice 24.2 on the three body shape containers of the fidelity corpus (#970):
A shape container composed in a table cell is already written as a panel (
writtenAsAPanel): a table of one cell carrying its fill and outline, which holds its text and grows with it. One holding text in the body is written the same way now, but for a badge centring a few letters, drawn as one shape holding them, and a pill holding a title and its dates, written as one line, as before.What changed
DocxSemanticBackendwrittenAsAPaneltakes, besides a shape composed in a cell, a painted rectangle or rounded rectangle holding text (holdsWrappedText: a paragraph or a list) that the layout places in the body: outside any table cell, inside no layer stack, shape container or canvas, on one page, and given room in the flow (placedInTheBody); not one written as a band beside a drawing. A frame holding only a picture or drawing, and every other shape, is written as before. Its panel goes through the samewritePanel/writePanelPiece:panelWidth), and its row the outline's height (holdTheShapesRow), the shape's padding written round it as a margin, as the page sets it; the row may not split, as the layout moves a shape whole;slotInItsPanelreads the placement for a placed shape, any layer). A section, a container or a list set at the outline's left, unmoved, of no fixed width, is not held (standsAsItsLayer): the page lays it out in the whole room and reports the box of its longest line, and held to that box Word broke the card's line a word early, the cell's right border taking the rest. One given a fixed width is held to it, as the page lays it out in that width, and so is any other block — a shape, a canvas, a table — which has a width of its own;setFromItsTop) — set from its top, or taller than the outline — is set at the cell's top and takes the border out of the space above its first line; without it the card's heading stood 1pt low in both editors. One with nothing above its first line to take it is named;reportClipCut, which now remembers where it named the clip,clipsCutting) and their boxes run past the outline's foot (pastItsFoot), the row is held at exactly the outline's height less the heavier border, which Word and LibreOffice add to an exact row: both cut a cell's content at an exact row's foot, as the page cuts it at the outline. Measured on the clipped box: held exactly at 58pt it stood 59pt in both, at 60pt 61pt. The clip's note is replaced (report.replace) by one that says the clip is written as an exact height, cuts square where the outline is rounded, and hides text an edit adds there. Layers whose boxes run past the foot with no clip to cut them grow the row, and the report says how far.corner radius), as for any panel (roundsItsCorners, shared with the clip note); a turned box is named as written upright. Thespace abovenote on the paragraph under the clipped box, measured against lines the page cut and the export wrote whole, is gone.DocxClipInk.TOLERANCEis package-private, so the row reads the same half point the clip measurement does.Tests
DocxBodyShapePanelTest(new, 17).DocxCarriedWithoutReportTest(two cases),DocxClipReportTestandDocxDrawingsTestused a painted box holding text as their example of a drawn outline; they now use a shape that stays drawn — a tile holding a dot, an ellipse — so each keeps pinning what it pinned.DocxNodeFieldLedgerTest(outline,layers,clipPolicy,padding) andDocxValueFieldLedgerTest(CLIP_BOUNDS,CLIP_PATH) describe the body panel.synthetic-narrow_container,synthetic-clipped_containerandsynthetic-rounded_cardinword-windows*.tsv,libreoffice-windows*.tsvandlibreoffice-linux*.tsvare taken from the runs below — the card's Word rows come out as they were; its lines stand 0.5pt further left in LibreOffice 26.8 and 0.5pt further right in LibreOffice 24.2, and the two lines under it 0.6pt higher in 24.2 — and every other row is as it was.Docs: the DOCX recipe's shape-container entry and the two passages that refer to it, the capability matrix's clip row, the CHANGELOG, the
SyntheticDocxCorpusJavadoc.Measured
Lines found of the page's, then the drift of the found lines (pt; negative is high), before → after:
synthetic-narrow_containersynthetic-clipped_containersynthetic-rounded_cardRead off the editors' PDFs:
right end).lengthen-a-paragraph).narrow_containerandrounded_cardpass.clipped_containerfails, as it should: its row is exact, so added text is hidden, as the page hides it.Tests
DocxBodyShapePanelTest(new, 17): the panel's size, row and keep; the layer held in across from its placement, and inside a padded box; a block at the outline's left not held to its box, one of a fixed width and a shape held to theirs; a later layer's note read against the cell's top; a padded shape read from its outline, at its top and its foot; the top border taken from the space above; the exact row of a clip that cuts, its note, and the same for a square box; a clip that cuts above the foot left at least with its old note; the at-least row and the note of layers past the foot unclipped; the turned box's note; a band kept a band; and the boxes that stay as they were — an ellipse, an unpainted box, a tile, a picture's frame, a box in a layer stack, in a painted section's cell, in a row's cell, and one its margins give no room.DocxBodyShapePanelTest,DocxComposedCellTest,DocxClipReportTest), every one caught, the source byte-identical afterwards: the body check, the overlays round the shape, room in the flow, text only, the band guard, the exact row and its one border, the overflow note, the vertical alignment of a layer taller than the outline and the later layers' note read against it, the square box's clip note, the clip note replaced not added, the clip remembered, the top border, a block at the left not held, and one of a fixed width and a shape held, the outline's top and foot read inside the padding, the placed slot, the outline's width and height, the row kept on one page, and both note wordings.2.5-dev, the three shape-container documents changed; report notes 1499 → 1498, every note removed or added on those three.scripts/docx-visual/word-fidelity.ps1→ the corpus test inwordmode passes on all 70 documents againstword-windows.tsv, its three rows rewritten (-Update, then those three documents' rows alone taken in).invoice-obsidianandproposal-indigofail as they do on2.5-dev(test(qa): hold the ways a page breaks inside a panel in the DOCX fidelity corpus #965), each exported byte for byte as2.5-devdoes.synthetic-rounded_cardalone, as measured beforehand in LibreOffice 24.2's docker build: the two lines under the card −0.02 → −0.62pt, past the gate's half point, and none of the other two documents' lines further from the page. The three documents' rows are taken from that run's artifact (docx-fidelity-40398446747) in a commit of their own, every other row as it was; they match the docker build's to the hundredth. Ofrounded_card, the two lines under the card stand 0.6pt higher and its four lines 0.5pt further right than before, the four within the half point the gate allows.clean verifyof the reactor as CI runs it → BUILD SUCCESS (core 823, render-pdf 339, render-docx 2310, testing 5, render-pptx 142, templates 127, qa 1846); the four knowledge checks and core javadoc (0 warnings) pass; examples 93.Named, not fixed
Lane: DOCX backend (
render-docx). No public API change.