fix(docx): align table cells where the page aligns them - #735
Merged
Merged
Conversation
The export read neither half of a cell's textAnchor. Every column a template right-aligns or centres came out flush left, and since Word's default is the top of the cell while the engine's is the vertical middle, a single line beside a taller neighbour sat at the top of its row. The anchor, cascaded as the layout cascades it, is now w:vAlign on every cell and w:jc on a text cell's paragraph, with the engine's default when none is stated: middle left, or middle right for a right-to-left cell, and DEFAULT at the bottom left as the renderer draws it. A composed cell takes the vertical half only, as the engine places it. The committed word-export-companion.docx gains w:vAlign="center" on its 30 cells and nothing else.
The layout flattens a break inside a cell's line to a space before it looks for the first strong character; the export read the raw line. A cell reading "123\nשלום" under TextDirection.AUTO was drawn right to left on the page and written left to right in Word, and its default alignment followed. The export now reads the lines the same way. Adds coverage for a row's anchor beating its column's, an anchor on every row a spanning cell covers, a right-to-left cell anchored at DEFAULT, and the auto direction above. Splits the recipe's Tables sentence in two.
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
A table cell's
textAnchorsays where the page places its content in the cell's box, and the DOCX export read neither half of it.CENTER, 18CENTER_RIGHT, 20TOP_LEFTand others. Every amount, quantity and total column the page right-aligns or centres came out flush left in Word.TableCellLayoutStyle.DEFAULT→Anchor.centerLeft()). A single line beside a taller neighbour sat at the top of its row.What changed
resolveCellAnchorresolves the anchor through the same cascade the layout merges: table default, column, row, cell. With none stated it uses the engine's default:CENTER_LEFT;CENTER_RIGHTfor a right-to-left cell, asTableLayoutSupport.answerDirectiongives it.applyVerticalAnchorwritesw:vAlignon every cell:CENTER_*→center;BOTTOM_*→bottom;TOP_*→ not written, since it is Word's default;DEFAULT→bottom. The engine mapsDocumentTableTextAnchor.DEFAULTtoAnchor.defaultAnchor(), andPdfTableRowFragmentRenderHandler.resolveTextLinesand the composed-cell placement both put its vertical half at the bottom.w:jcfrom the horizontal half, through the existingtoAlignment.toAlignmentswaps left and right for aw:bidiparagraph, because Word reads them as the flow's start and end. The left (the start) is not written.NodeDefinitionSupportplaces a composed child vertically by the anchor and never across, since the child is laid out at the cell's full inner width. The paragraph keeps its own alignment.AUTOcell's direction is read from the text as the layout reads it.TableLayoutSupportflattens a break inside a line to a space before it looks for the first strong character, and the export read the raw line. A cell reading"123\nשלום"was drawn right to left and written left to right, and its default alignment followed.word-export-companion.docxgainsw:vAlign="center"on its 30 cells. Itsdocument.xmldiffers by those lines and nothing else, and the package holds the same parts.Verification
In an editor. A probe with three columns, rendered by the engine and converted with LibreOffice:
CENTER_RIGHTAmount column;BOTTOM_RIGHTcell and a two-line right-aligned cell;CENTER_LEFTcell.The quantity and the amount sit centred beside the three-line cell, and "Bot" sits bottom-right, as on the page. The right-to-left default starts on the right, and the authored left lands on the left. The engine draws Hebrew in Helvetica as
?, but its placement is the same.Tests.
./mvnw -B -ntp test -pl :graph-compose-render-docx→ 354 run, 0 failures.New
DocxCellAnchorTest(9):vAlign center, nojc;vAlign/jc;jc, an authored left writesjc right, andDEFAULTsits bottom left;AUTOcell whose line opens on digits then Hebrew is right to left;vAlign bottomforBOTTOM_RIGHT, and its paragraph stays left.Each of these was sabotaged and fails its test:
vAlign(3 tests);jc(3 tests);DEFAULTto top;vAlignon the span's first row only;Gate. Full reactor gate (
clean verifyover core, render-pdf/docx/pptx, templates, testing, qa, coverage) → BUILD SUCCESS (qa 1788 green). Examples after install: 93 green, withword-export-companion.docxregenerated byWordExportExample(itsdocument.xmlgains the 30vAlignlines and nothing else).Not in this change: the engine sizes a multi-line cell's row with
lineSpacingbetween the lines, but the PDF draws them stacked without it. The DOCX follows the PDF. The mismatch is inside the engine and is left as a separate fix.Lane: shared-engine (render-docx). No public API change.