Skip to content

fix(docx): start a body panel's text the whole padding in, its left border centred on its edge - #842

Merged
DemchaAV merged 2 commits into
2.5-devfrom
fix/docx-horizontal-offsets-8
Oct 4, 2026
Merged

DemchaAV merged 2 commits into
2.5-devfrom
fix/docx-horizontal-offsets-8

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Why

A panel — a filled or bordered container — is a one-cell table. Its cell's margins were the padding less half of each border, and the table half a border wider on each side, on the model that an editor keeps a cell's border inside the cell.

For a panel in the body, Word and LibreOffice on Windows measured otherwise. On ModernInvoice's header panel, behind a 4pt left accent:

  • Word drew the bar from 25.92 to 29.88, centred on the page's edge at 28, and set the text at 39.96 against the page's 42.00.
  • LibreOffice on Windows set it at 40.10.

Word 16 and LibreOffice on Windows (build bce0998) both start a body table's text at its indent and centre its left border on its edge, so half the border taken off the margin and the indent stood every line in the panel 2pt left of the page's. The same held for ModernProposal and ClassicInvoice (2pt), NordicClean and ModernReceipt (1.5pt), and EditorialProposal and NorthlineProposal (up to 0.55pt).

What changed

writePanelPiece, for a panel in the body (currentCell == null) only:

  • the indent (w:tblInd) is the padding in, where the text starts, no longer less half the left border;
  • the cell's left margin is the whole left padding;
  • the table is no wider on its left than the panel: its left border is centred on its edge.

A panel in a cell keeps its geometry, including #838's trim. So does the right side, which nothing has measured otherwise. Javadoc of writePanel and insideTheBorders, the recipe's panel section, the capability matrix's panel row and CHANGELOG are updated.

Verification

  • Word corpus. scripts/docx-visual/word-fidelity.ps1 -Update (Word 16.0.20430) → BUILD SUCCESS.
    • Lines past 2pt across: 12 → 4.
    • 49 lines nearer, every panel line above within 0.2pt (ModernInvoice, ModernProposal: −2.04 → 0.00).
    • 20 further: 19 ObsidianInvoice items (up to 0.36pt) and ModernReceipt's status chip (+7.60 → +9.16).
    • The down column is unchanged in every row; no line lost.
  • LibreOffice (Windows). 56 nearer, 13 further (ObsidianInvoice up to 0.30pt, the chip 1.50pt), nothing down.
  • LibreOffice (Linux) moves further. The CI's LibreOffice (build 420) reads a body table's indent as the table's edge, its text a margin further in. These panels' lines stood a padding right of the page's there already (ModernInvoice +12.05, NordicClean +8.60, ModernReceipt +14.60), and stand the border's width further (+16.10, +11.60, +17.60): 78 lines further, none nearer, past 2pt across still 301. The baseline is this PR's CI artifact. The two readings cannot both be met by one indent; Word is the reference, and Windows LibreOffice agrees with it. Whether writing an explicit compatibility mode makes that build read the indent as Word does is untested and its own change.
  • What moves further, and why.
    • ObsidianInvoice's items are a table inside a panel with a 0.625pt border all round. That table's text box was already narrower than the page's (left +0.34, right −0.27 in Word), and the panel's content now moves half that border right with everything else in it.
    • ModernReceipt's status chip moves with its panel's content. It stood 7.6pt right before, because the chip's padding is not in the file, which the export reports. That is its own fix.
  • Tests:
    • DocxContainerPaintTest.aBorderStraddlesThePanelsEdgeAsOnThePage: a 3pt accent and 14pt padding give a left margin of 280 twips (was 250), an indent of 280 (was 250), and a table as wide as the panel and the slack (was 1.5pt wider).
    • DocxPanelInsetTest.aPaddedPanelsTextIsHeldInByTheCellNotByAnIndent: the left margin is 14pt (was 12.5).
    • DocxContainerPaintTest.aNestedPanelIsPlacedByItsBordersOuterEdge: a panel in a cell keeps the padding less half its border as its left margin (applying the body's rule in a cell fails it, and fix(docx): keep a panel hung by its left border inside its cell, so Word does not widen the cell #838's test).
  • Sabotage. Each change fails a test:
    • the old indent;
    • the old margin;
    • the old width.
  • render-docx. 894 tests green.
  • Full reactor gate. ./mvnw -B -ntp clean verify -pl :graph-compose-core,:graph-compose-render-pdf,:graph-compose-render-docx,:graph-compose-render-pptx,:graph-compose-templates,:graph-compose-testing,:graph-compose-qa,:graph-compose-coverage -am → BUILD SUCCESS (qa 1820 tests).
  • Examples. CommittedAssetDriftTest → 3/3 green.

Notes

Lane: shared-engine (render-docx).

…order centred on its edge

Both Word and LibreOffice start a body table's text at its indent and
centre its left border on its edge, as the page centres the panel's. The
export took half the left border off the cell's margin and the indent and
made the table that much wider, for an editor that keeps the border inside
the cell: every line in ModernInvoice's header panel, behind a 4pt accent,
stood 2pt left of the page's in both. In the body, the left margin is now
the whole padding, the indent the text's place, and the table no wider on
its left.

Lines more than 2pt off across fall from 12 to 4 in Word; nothing moves
down.
…he Linux build that reads it otherwise

Word 16 and LibreOffice on Windows start a body table's text at its
indent; the LibreOffice build on the Linux CI reads the indent as the
table's edge, its text a margin further in, so these panels, a padding
right of the page's there already, stand the border's width further. The
Linux baseline is this branch's CI measure. A test pins that a panel in a
cell keeps the padding less half its border as its left margin.
@DemchaAV
DemchaAV merged commit f17f410 into 2.5-dev Oct 4, 2026
13 checks passed
@DemchaAV
DemchaAV deleted the fix/docx-horizontal-offsets-8 branch October 4, 2026 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant