Repository navigation
fix(docx): set what follows a panel where the page does, and name the rest - #873
Merged
Merged
Conversation
… rest
Word sets a panel's content below its whole top border and its margin, and
ends the row its margin and its whole bottom border past the content; the page
strokes each border on the panel's edge. Half a border, and as much of its
inner half as the padding falls short of it, reaches past the panel's box. The
export took each border whole out of the space round the panel: a padded card
with a gap below it stood what followed half a border high, unnamed.
- The reach comes out of the space round the panel, then the panel's padding
(the cell margin), then, above, the room over its first line; what none of
them takes is named, on the panel for its top border and on the block below
for its bottom one ("space above").
- A panel holds the page's height less its padding as its row's height, which
Word and LibreOffice read as the content's; a shape container holds its
outline's height less both borders and its margins, its borders inside it.
- What a panel's content leaves below itself - a line held to an icon, a
card's border ending it - comes out of the room the page leaves under that
content, then its padding below; a card's border ending a row's cell reaches
past the row only by what the row's room under that cell does not hold.
- The paragraph Word keeps between two tables is named where the space between
them does not take it, together with a border reaching the same block; a
container's top edge above a table counts as that space.
- A margin below zero under a panel pulls what follows up and is no border; a
panel the layout moves to a new page leaves the tail above on its page; a
tail left over the last block of a section is named.
Fidelity baselines (Word, LibreOffice on Windows) rewritten: twelve documents
stand nearer the page in Word, eight further where the whole border taken out
of the space had made up for other errors.
…here its writer knows the room
- A pull out of the block above - a negative bottom margin, a panel's as a
paragraph's - comes out of the space below it before any tail, the space
above a table included; what that space and the next block's own top edge do
not give stands the next block lower and is named ("space above").
- A cell no longer carries the border of the card ending it into the flow; the
cell's writer decides. A row takes it, with the cell's hanging line, out of
the room under that cell, then the card's padding; a panel takes it out of
the card's padding, then its own; a table's composed cell and a column of
side-by-side layers take it out of the card's padding and name the rest, up
to that much where a cell beside it may hold it.
- A container leaves no room under its content: what its content leaves below
itself comes out of its padding directly.
- A panel the layout moves to a new page holds the space above it there, as a
table does.
Fidelity baselines (Word, LibreOffice on Windows) rewritten:
invoice-subscription stands nearer the page than with the previous commit.
…el border reach Measured by CI's LibreOffice on Linux on this branch: 24 of the 62 documents change, 11 standing nearer the page in median and 9 further, the same documents and directions as LibreOffice on Windows.
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
Word sets a panel's content below its whole top border and its margin, and ends the row its
margin and its whole bottom border past the content; the page strokes each border on the
panel's edge, taking no room. With the cell margin written as
padding − border/2, a panelreaches past the page's box by
border/2 + max(0, border/2 − padding)on each edge — measuredin Word 16 and LibreOffice on Windows alike on a 2pt border: 2pt with no padding, 1pt with 1, 2
or 4pt of it. The export took each border whole out of the space round the panel, so a padded
card with a gap below it stood what followed half a border high, unnamed, and only a row's panel
named the rest.
What changed
All in
DocxSemanticBackend:outsideTheRowstates the measured reach.writePanelPiecetakes it out of the spaceround the panel first (the border stands where the page strokes it), then out of the panel's
padding (
takeOffTheCellMargin— the border drawn that much inside the panel's edge, thecontent where the page sets it), then, above, out of the room over the first line
(
takeTheTopBorderInside). What none of them takes is named: on the panel's node kind for itstop border, on the block below for its bottom one.
nameTheTailNotTaken, subjectspace above, onenote with the total): a panel's bottom border reach, a line hanging below the block above, the
0.1pt paragraph Word keeps between two tables, and a pull — a negative bottom margin, a
panel's as a paragraph's — that neither the space below it nor the next block's own top edge
gives back (Word sets no block over another). The bottom reach the space below does not take
comes out of that panel's padding first (
borderBelowCell).carriedBorder):its writer decides. A row takes it, with the cell's hanging line, out of the room under that
cell, then the card's padding; a panel takes it out of the card's padding, then its own; a
table's composed cell or a column of side-by-side layers — whose content the layout does not
measure against its row — takes it out of the card's padding and names the rest on the cell's
content, up to that much where a cell beside it may hold it.
holdThePanelsHeight: Word and LibreOffice read a panel's written row height as itscontent's, with its margins and both borders round it (measured: held a point above its
content, an outlined card stood a point taller). A panel holds the page's height less its
padding, as a uniformly ruled card already was, and less what the room over its first line gave
its top border, which used to come off it a second time; a shape container, its layers centred
in it, holds its outline's height less both borders and its margins (it was held one border
less only), and nothing of its borders reaches past it.
under it. A container's top edge above a table counts as room for the table's tail. A panel the
layout moves to a new page leaves the tail above on its page and holds the space above it there,
as a table does. A tail or pull left over a block that takes nothing out of a top edge of its
own — a list item — is named at the next block or at the section's end.
Docs: the recipe's "What a panel keeps and loses" (borders, height, what hangs below, the
measured nesting) and its pull paragraph, the capability matrix's rectangle row,
render-docx/ README.md, the field ledger (DocxNodeFieldLedgerTest: panels'stroke/bordersandparagraphs' and panels'
margin/paddingname what is reported), and four unreleased v2.5.0CHANGELOG entries that described the old border model (row paint, CobaltRota's chips,
MerchantInvoice, the badge entry).
Verification
./mvnw -B -ntp clean verifyon this branch with fix(docx): write a page zone's picture in its line, and stand each part on its own baseline #872 merged → BUILD SUCCESS: render-docx1307 run, 0 failures, 1 skipped, qa 1820, core 818.
DocxPanelTailTest(40): borders above and below with and without padding and space, thespace before the padding, held heights, shape containers, hangs, cards ending a panel, a row's
cell, a table's cell (alone and beside another) and a column of layers, pulls before a
paragraph, a spacer, a table and a list, a pull against a card's top border, a panel moved to a
new page, touching tables and cards named once with the total. Exact values updated in
DocxContainerSpacingTest,DocxPanelHeightTest,DocxRowPaintTest.space round them), cards outlined at 0.5 and 2pt stacked and at 0.5pt in a row's columns, and
chips in table cells, converted by Word 16 and LibreOffice on Windows: every line stands where
the page sets it, or as much lower as the report names — within 0.15pt in Word and 0.05pt in
LibreOffice.
between two tables;
ObsidianInvoice's totals row, 0.72pt = a 0.62pt border + that 0.1pt). Wordbaseline (
word-windows*.tsv, viascripts/docx-visual/word-fidelity.ps1 -Update): 12documents nearer the page (
letter-engineering_resumemedian 1.27 → 0.13pt,cv-engineering_resume0.58 → 0.24,proposal-modern0.48 → 0.19,cv-minimal_underlined0.71 → 0.44), 8 further (
cv-panel0.34 → 0.83,invoice-subscription0.23 → 0.61,cv-modern_professional0.09 → 0.32,cv-classic_serif0.17 → 0.31, four by under 0.2pt).LibreOffice on Windows likewise, 13 nearer and 9 further. LibreOffice on Linux
(
libreoffice-linux*.tsv, from CI'sdocx-fidelityartifact): 24 documents change, 11 nearerin median (
letter-engineering_resume1.40 → 0.19pt,invoice-obsidian1.38 → 0.27pt with 15lines over 2pt where there were 25), 9 further — the same documents as on Windows.
Notes for review
Where traced, the documents that move further from the page do so because the whole border taken
out of the space had been making up for errors elsewhere, now exposed: a heading's baseline left
up to half a point from where Word seats it in an exact line (
cv-modern_professional's summaryheading stands where the layout sets it, 82.57 against 82.55pt, its baseline 0.36pt lower), a
spacer of no height written as a 0.1pt paragraph (one per card in
cv-panel), rounding to thetwip inside a card, a 0.37pt step between a table's header and its first row
(
invoice-subscription), and the space above a block moved to a new page written at the page'stop (
proposal-editorial).cv-charcoal_gold,cv-nordic_cleanandinvoice-workspacemove byunder 0.06pt in median, not traced. Each traced cause is a defect of its own, outside this change.
Lane: shared-engine (DOCX backend) —
render-docxonly, no public API.Merge order: follows #872, merged into this branch; the two touch disjoint parts of the
backend (page zones there, panels here), and no corpus document has a page zone.