Repository navigation
fix(docx): keep a band of layers whole on the page the layout moves it to - #933
Merged
Merged
Conversation
…t to The layout moves a layer stack or a shape container to a new page whole, but only a stack of one layer was kept so in Word. Measured in Word and LibreOffice, a band of two layers the page moved to the next page stood with its first layer at the foot of the page above, and a shape container of three lines with two of them there. Every layer stack and shape container in the flow is now kept on its page as a block kept together is. Set on the new page whole, a band then lost the space above its first block, as Word drops it at the top of a page: its first paragraph, picture or spacer now holds that space in a line kept with it, as one in the flow does, also for a band in a stack of one layer and after a backdrop the band draws first.
DemchaAV
marked this pull request as draft
October 21, 2026 03:35
A band opening its page held the top edge of its first paragraph, picture or spacer until it wrote a body paragraph. A table of text cells writes none, so the caption under a table that opens the band was held as if it opened the page, an empty line above it in the middle of the page. A table written in the body now ends the band's opening as a paragraph does, and every test of a block opening the page first checks the page the layout starts it on.
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
The layout moves a layer stack or a shape container to a new page whole: both are atomic there. Word
re-paginates on its own and was told so only for a stack of one layer. Measured in Word 16 and
LibreOffice on Windows, with nothing in the report:
page moved to the next page stood with its first layer at the foot of the page above. This held
for a text band, a band with a picture as its second layer, one with a margin and one in a section;
Once the band stands whole on the new page, Word drops the space above its first paragraph there,
as at the top of any page. Its 14pt margin was lost, so was a band's with a backdrop laid first (the
text 14pt above the backdrop the page draws round it), the 14pt margin of the stack of one layer a
band is nested in, and a section's 10pt.
What changed
writePlacedNodekeeps every layer stack and shape container in the flow (movedWhole)through
keepOnOnePage, as it kept a stack of one layer:w:keepLineson each paragraph,w:keepNexton all but the last. In a table's or a panel's cell the row keeps or breaks them, asbefore.
keepThePanelMayBreakuses the same helper.writeOverlayBandcounts a band as opening its page in the flow, a stack of one layerincluded (
overlayDepth == oneLayerDepth, was== 0). The band's first block written in the bodyclears that: a paragraph, as before, and now a table too (
newTable). A table of text cellswrites no body paragraph, so a caption under one opening the band stood to be held as if it
opened the page.
opensItsPageInTheFlow(new) says when a paragraph, a picture or a spacer holds its topedge, and the three now ask it:
backdrop drawn first is on that page already, so the paragraph after it starts no page of its
own.
The holds are the ones the flow uses:
holdAParagraphsTopEdgeOnItsPagefor a paragraph and apicture,
holdTheGapAboveInTheLinefor a spacer.holdAParagraphsTopEdgeOnItsPagetakes over the space the band resumed (resumeHere())before adding the block's own edge. Left to the line's
newBodyParagraph,resumeHere()zeroedthat edge, and the block's own margin would be lost from above the line.
Docs:
Verification
Probe, before and after, Word and LibreOffice alike:
a backdrop laid first, nested in a stack of one layer, in a section;
Every band the layout moves to page 2 now stands whole there. Its first paragraph, picture or
spacer stands within 0 to 1.2pt of the page, and the backdrop within 0.3pt.
The same probe on the base, five kinds: text, picture second, own margin, nested, in a
section. Each split, or stood 10 to 14pt high. The band with a backdrop, measured kept whole but
without its hold, stood 14pt high.
Corpus, 62 DOCX against the base:
w:keepLinesandw:keepNextalone;before;
Example:
word-export-companion.docxwas regenerated. It differs from the committed one onlyin
docProps/core.xml, the export's time.Tests:
DocxBandOnANewPageTest(new, 12 tests). Each case that turns on the page first assertsthe page the block starts on.
margin, the filler's space whole above the line; a paragraph after a backdrop; a picture
first, without and with its own margin; a spacer first, kept with what follows; a band nested
in a stack of one layer; a band in a section;
page, a band in a row's cell.
DocxKeepTogetherTest:These replace
aBandIsNotChainedHere. The three…IsLeftToTheBandtests, which pinned the bandwriting no line, are gone with that behaviour.
11 sabotages, all caught:
./mvnw -B -ntp clean verify: BUILD SUCCESS.Knowledge pack: the API surfaces, stability doc, claims and routes checks pass, and core javadoc
passes with no warnings.
Notes for review
Measured, and left for their own changes:
top edge. A list opening a page loses it in the plain flow too, 14pt measured. Nor is the edge
held for a table, a panel or a line pair written first.
in its box, may reach above where the layers before it end. Such a layer stands that much low,
13pt measured, as its resume is clamped at zero (
DocxLayerColumns.flow). With the keep, such aband at the foot of a page the layout keeps it on moves to the next page whole instead of
splitting. A diagnostic run over the corpus found no such layer.
Word was not measured splitting them.
Lane: render-docx (semantic backend).