Skip to content

fix(docx): hold a row a drawing makes tall, and raise a title pulled above its row inside its line - #792

Merged
DemchaAV merged 3 commits into
2.5-devfrom
fix/docx-workspace-bill-to
Sep 30, 2026
Merged

DemchaAV merged 3 commits into
2.5-devfrom
fix/docx-workspace-bill-to

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Sep 30, 2026 •

Copy link
Copy Markdown
Owner

Why

WorkspaceInvoice stood well off its page in Word, for two reasons.

  • The bill-to heading row. The heading is a row: a 20pt badge, drawn where the page puts it and so holding nothing in its cell, beside an 8pt label. Word made the row as tall as the label, and the address under it stood 10pt high.
  • The masthead title. The title is pulled 4pt above its row by its cell's negative top padding. A Word paragraph starts no higher than its cell, so the title and the whole page under it stood 4pt low. The row opens the page, so there is no space above it to lift into; standsAboveItsCell / raiseRows need one.

SubscriptionInvoice, MerchantInvoice and PlatformInvoice have rows a drawing makes tall too.

What changed

  • writeRow: aDrawingMakesTheRow. Outside a painted panel too, a row is now held at least as tall as the page makes it (holdRowAtLeast, as inside a panel) when its tallest child — margins included, as the row is sized by them — is one whose cell Word holds nothing in (holdsNothing).
    • A drawing no taller than its neighbours' text is left to Word, such as a timeline's rail beside its entry. Holding every row regressed CV entries whose page height exceeds Word's text.
    • The row's own placed height excludes its margins, which are written around the table (LayoutCompiler places a row at naturalMeasure.height()).
  • writeContainerBody: riseIntoItsLine. A container in a cell with a negative top edge, and a one-line first paragraph, writes that paragraph as much shorter as it is pulled up. Its text is seated from where the Word line starts, using the stacked-line entry DocxStackedLines.Line.
    • The line gives up no more than the room above its letters (DocxInk, INK_MARGIN), as Word draws an exact line's text only inside the line. Past that, the rest stays as before.
    • A line whose letters cannot be read, such as one holding a picture, is left as it was.
    • The rise is what the paragraph's space above falls short of zero: the edges carried down to it, the space the block above owes, less a border standing below that block. The paragraph's own top edge is written apart, as before, so it is not counted in the rise. A section after other blocks in its cell rises as the page puts it, the space owed above it written first.
    • A paragraph written again, such as a header on every page class, rises by the same amount.
  • Docs. CHANGELOG.md and the Rows row of docs/recipes/docx-export.md are updated.

Verification

  • 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 gives BUILD SUCCESS (1791 + 127 tests). After install, examples are 93 green, and the knowledge checks and extract-api --check pass.
  • DocxRowHeightTest (new, 10 tests):
    • A badge row is held at 19–20pt, with or without margins on the row, and with the badge set down its cell by its margin.
    • A rail no taller than its text, and a row of text, hold nothing.
    • A title pulled up 4pt is written 4pt shorter, with no space above and seated within a half point.
    • The same title with its own 2pt margin keeps that margin as 2pt of space and still gives up 4pt.
    • A section after a label owing 6pt below it writes 2pt of space, and its line stays whole.
    • "RÉSUMÉ" pulled up 10pt gives up less than 4pt, the room above its accents, and still some.
    • A pulled line holding a picture is left as it was.
    • Each of these fails its own test when switched off: the hold, the rise, the row-margin fix, the children's margins, the letter cap, the owed space, and leaving the paragraph's own edge out of the rise.
  • Template corpus (62 documents), converted to PDF by Word:
    • Across all 62: median drift 0.56 → 0.52pt, and lines more than 2pt off 858 → 705.
    • WorkspaceInvoice: 4.8 → 0.4pt, lines off 78 → 6, one page.
    • SubscriptionInvoice: 8.8 → 0.5pt.
    • MerchantInvoice: 3.0 → 1.9pt.
    • PlatformInvoice: lines off 30 → 21.
    • In LibreOffice, the median falls from 0.55 to 0.52pt.
  • Known and left for its own change: PaymentsInvoice's bill-to block now stands level (constant +11pt), and its median rises from 3.7 to 10.3pt. Its collapsed heading row had been hiding a gap between the masthead and the parties that runs about 16pt long in Word.

Lane: shared-engine (render-docx). No public API change.

…above its row inside its line

A row whose tallest child is drawn where the page puts it holds nothing of it in Word and was only as tall as its text; it is now held at least as tall as the page makes it. A one-line paragraph a container pulls above its cell with a negative top edge is written that much shorter, its text seated where the page sets it, no further than the room above its letters.
…ain when written again

The rise is what the edges carried down, the space owed by the block above, less a border below it, and the paragraph's own top edge fall short of zero; a paragraph written again rises by the same amount.
@DemchaAV
DemchaAV merged commit ec7a2eb into 2.5-dev Sep 30, 2026
12 checks passed
@DemchaAV
DemchaAV deleted the fix/docx-workspace-bill-to branch September 30, 2026 16:25
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