Skip to content

fix(docx): keep the space above a picture moved to a new page - #927

Merged
DemchaAV merged 2 commits into
2.5-devfrom
fix/docx-picture-page-top
Oct 20, 2026
Merged

DemchaAV merged 2 commits into
2.5-devfrom
fix/docx-picture-page-top

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Why

The page starts a block the layout moves to a new page at its own top edge. Word drops a
paragraph's space above at the top of a page, and a picture's paragraph is no exception, so
everything above a picture opening its page was lost.

Measured in Word 16 and LibreOffice on Windows, a 100pt picture opening page 2 (picture top, y):

Page Before, in Word / LibreOffice After, in Word / LibreOffice
20pt top margin 92 72 / 72 92 / 92
15pt top padding 87 72 / 72 87 / 87
200×100 contained in a 100pt square 97 72 / 72 97 / 97
in a section padded 10pt 82 72 / 72 82 / 82
margin 10, padding 5, contained, after a 12pt flow gap 112 72 / 72 112 / 112
in a section with a 14pt margin, contained 111 72 / 72 111 / 111

Nothing was named. In every case, the page broke where it did before, with the same lines on
page 1. Below each picture nothing moved: in both editors, the distance from its foot to the
baseline of the paragraph under it is what it was before the change, within 0.1pt.

What changed

  • writeImage: a picture in the flow (not in a cell, not in an overlay) that the layout
    starts on a later page than the block before it has its top edge held on that page by
    holdAParagraphsTopEdgeOnItsPage, before its paragraph is created. This is the mechanism a
    text paragraph opening its page already goes through.

  • holdAParagraphsTopEdgeOnItsPage takes any block and the room it has above its content
    inside its box. For a contained picture that is the room roomRound gives above it. The line
    holds:

    • the space above the box on that page;
    • its padding;
    • that room.

    The paragraph's own space above loses as much (applyVerticalSpacing). A text paragraph
    passes no room, so it is written as before, and the two-argument form it called is gone.

  • A pull, a border or a hanging line left by the block above now stays on the page above
    for a picture opening the next page too, as it does for a paragraph and a spacer.

    • Before, a plain picture opening a page after a paragraph that pulls 5pt up was named as
      standing 5pt lower ("space above").
    • On the new page that was false: Word sets the picture at the page's top.
  • Docs:

    • the recipe's images row, and its tables row's pointer to the rows that hold a carried gap;
    • the capability matrix's image row;
    • CHANGELOG v2.5.0.
    • A stale {@link} in the applyVerticalSpacing Javadoc now names roomRound.

Verification

  • Corpus, 62 DOCX before and after: all 62 are byte-identical, and the report's 1246 notes
    are identical.
  • Example: word-export-companion.docx was regenerated. It differs from the committed one only
    in docProps/core.xml, the export's time.
  • DocxPictureOnANewPageTest (new, 10 tests):
    • a margin, a padding, a contained picture's room above and a section's padding, each held in a
      line kept with the picture, which keeps no space above of its own;
    • a gap carried to the new page held with the margin;
    • a plain picture: no line;
    • a pull out of the paragraph above: named on that paragraph's page, not on the next;
    • a picture on the page of the block before it: written as before;
    • in a row's cell: left to the table;
    • opening a band moved to a new page: left to the band, the same paragraphs as on one page.
  • 6 sabotages, all caught:
    • no hold;
    • no room held;
    • the room left out of the line;
    • the room left out of the edge held;
    • held in a cell;
    • held in an overlay.
  • ./mvnw -B -ntp clean verify: BUILD SUCCESS. The knowledge pack's --check passes.

Two things this leaves as they were, each a separate step, for text and pictures alike:

  • The first block of a stack of one layer that the layout moves to a new page still loses
    its top edge. A paragraph or picture with a 20pt margin stands 20pt high in both editors.
  • A layer stack opening a page breaks in Word. Its first layer stays at the foot of the page
    above, while the page sets the whole stack on the next.

Lane: render-docx (semantic backend). DOCX output changes only for a picture the layout
moves to a new page. One with space above it gains the line holding it. Without such space, a
pull, border or hanging line left by the block above no longer reaches it.

Word drops a paragraph's space above at the top of a page, a picture's
paragraph's too. Measured in Word and LibreOffice, a 100pt picture the
layout moves to a new page stood at the page's top: 20pt high with a
20pt margin, 15pt with a 15pt padding, 25pt contained in a box with
25pt of room above it, 10pt in a section padded 10pt.

In the flow, that space is now held in an empty line that tall before
the picture, kept with it, as a text paragraph's top edge already is.
@DemchaAV
DemchaAV marked this pull request as draft October 19, 2026 21:14
A picture the layout moves to a new page now leaves a pull out of the
block above on that block's page, as a paragraph does. Before, a plain
picture opening a page after a paragraph pulling 5pt up was named as
standing 5pt lower, which on the new page it does not. The test pins
both sides: named on the paragraph's page, not on the next.
@DemchaAV
DemchaAV marked this pull request as ready for review October 19, 2026 21:27
@DemchaAV
DemchaAV merged commit 91a1b3a into 2.5-dev Oct 20, 2026
13 checks passed
@DemchaAV
DemchaAV deleted the fix/docx-picture-page-top branch October 20, 2026 03:32
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