Skip to content

fix(docx): name in the report what a container written as its contents leaves of its layout - #859

Merged
DemchaAV merged 2 commits into
2.5-devfrom
fix/docx-report-flow-container-losses
Oct 6, 2026
Merged

DemchaAV merged 2 commits into
2.5-devfrom
fix/docx-report-flow-container-losses

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Why

A container the DOCX export writes as its contents left part of its own layout out of the Word file and said nothing, while DocxExportReport promises to name every loss:

  • a canvas's caption set at its middle came out at its top, with everything under it risen to meet it;
  • a band bled to the page's edges stopped at its box;
  • a column fixed narrower than its band ran its text the band's width;
  • a line drawn in the flow and kept with the next block could end a page without it.

DocxNodeFieldLedgerTest listed each of these as a gap.

What changed

  • inThePagedFlow() says where the page keeps a block with the next and bleeds a section's paint toward its edges: in the flow it lays out page by page, the body and the panels in it. Everything else is a box the page places:
    • an overlay (overlayDepth);
    • a row's or a table's composed cell, or a layer stack's column (slotDepth, raised in writeCellNodes and writeLayerColumns).
  • canvasLosses names what a canvas written as its contents leaves out. Its drawings stand where it places them; what it writes is written one block after another inside its margin and padding.
    • Places: named unless it stacks what it writes from its corner, each block at the foot of the one before.
    • Height: named where the canvas stands in a flow (overlayDepth - oneLayerDepth == 1, a stack of one layer being no overlay), has a placement to measure by, and something follows it there other than a page break (followedInFlow).
      • followedInFlow is kept by writeChildren, by writeContainerBody for a box's last child, and by the loop over the roots.
      • A timeline's marker is a canvas alone in its row's cell, and gets no note.
    • Width: named where a block it writes holds a paragraph or a list and the canvas is narrower than the column.
  • A painted section's bleed is named in the paged flow, on every page and every side.
  • A layer stack's column names a fixed width narrower than its band (writeLayerColumns).
  • A line drawn in the paged flow and kept with the next block names the keep, unless the next block is a page break. A drawing writes no paragraph to keep, and is anchored in a paragraph near it, so a page can end between it and the next block, whatever that block is.
  • The ledger:
    • 6 node fields move from a gap to REPORTED: a canvas's width and placements, a section's bleed, a line's keep, and a section's and a container's fixed width.
    • A canvas's clipPolicy moves to INERT: the page clips no canvas, and CanvasLayerDefinition emits no clip. INERT's Javadoc now covers a field the page does not apply.
    • A canvas's height stays a gap: as its row's tallest cell, or ending a band or a layer stack's column, it is not yet named.
    • 15 node-field gaps remain, each named.
  • The recipe (the sections and containers row, and a new "A canvas → its contents" fallback), the capability matrix (the layer stack row) and the CHANGELOG say what each note names.

Verification

  • ./mvnw -B -ntp install -pl :graph-compose-render-docx → BUILD SUCCESS: 1030 tests, 0 failures, 1 skipped (the property-gated fidelity probe).
  • DocxFlowContainerReportTest is new, 16 tests. A note on a container is checked whole; a phrase added to a drawn line's note is checked by how the note ends.
    • Canvas notes:
      • a canvas names its places, room and width;
      • one that only draws names its room;
      • one in a stack of one layer names its places and room.
    • Canvases that get no note:
      • one writing a spacer at its corner as tall as it;
      • one stacking what it writes from its corner;
      • one nothing follows;
      • one before a page break;
      • one composed in a table cell;
      • a timeline's markers.
    • Bleed:
      • a bled panel names its bleed, and the body XML equals the unbled one's;
      • one running onto a second page names it too;
      • a bled panel in a layer, and an unpainted bled section, get no note.
    • Keep:
      • a kept line names the keep before a table, before a paragraph and in a panel;
      • in a row's cell, or before a page break, it does not.
    • A column fixed narrower than its band names its width.
  • The tests fail without the code they cover. Removed in turn or together, each of these made its tests fail:
    • the one-layer adjustment;
    • the followed check;
    • the page-break exceptions;
    • the slot depth;
    • the placement check;
    • the stacking check.
  • The DOCX bytes do not change. The 62 corpus documents exported deterministically are byte-identical to the export before the change: DocxFidelityCorpusTest -Dgraphcompose.docxFidelity=export, SHA-256 per file, 0 of 62 differ.
  • Documentation and qa DOCX tests:
    • -pl :graph-compose-core -Dtest='com.demcha.documentation.**' → 166 tests, 0 failures;
    • qa documentation guards plus DocxPageZoneTest, DocxTransparentWrapperTest, TimelineRailAcrossBackendsTest and RtlAcrossBackendsTest → 52 tests, 0 failures.
  • The full reactor gate was not run; no public API, POM or workflow file changed.

Lane: render-docx backend (report only, no change to what is written) plus tests and docs.

…s leaves of its layout

A canvas's places, the room it holds where something follows it and the
width its text wraps at, a bled panel's bleed where the page bleeds it, a
layer stack column's fixed width, and the keep of a line drawn in the body
before a block that writes a table first were left out of the Word file in
silence. Each container's note now names them. A canvas's clip policy is
recorded as having nothing to carry: the page clips no canvas. Nothing
written changes.
… out page by page

A drawn line's drawing is anchored in a paragraph near it, so its keep with
the next block is lost before a paragraph as much as before a table, and
in a panel as much as in the body; the page keeps blocks together, and
bleeds a section's paint, in the flow it lays out page by page, and in no
row's or table's cell, layer or layer stack's column. Both are named there
now, on every page and side. A canvas names its room only where it has a
placement and something other than a page break follows it, and its places
only where it does not stack what it writes from its corner; its room as
its row's tallest cell stays a gap.
@DemchaAV
DemchaAV merged commit af36cdc into 2.5-dev Oct 6, 2026
13 checks passed
@DemchaAV
DemchaAV deleted the fix/docx-report-flow-container-losses branch October 6, 2026 09:29
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