Skip to content

fix(api): honor negative bottom margin, reject negative page margin#232

Merged
DemchaAV merged 1 commit into
developfrom
fix/negative-margin
Jun 25, 2026
Merged

fix(api): honor negative bottom margin, reject negative page margin#232
DemchaAV merged 1 commit into
developfrom
fix/negative-margin

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Why

Two sides of the same gap in how the layout flow treats a negative margin:

  • A negative bottom margin on a section/container was silently dropped — the vertical flow's bottom-edge advance early-returned on any non-positive amount, so the "pull the next block up" you'd expect (and that a negative top margin already gives) just didn't happen.
  • A negative page margin was silently accepted, which makes the content area larger than the sheet, so content quietly overflowed the trimmed page.

What changed

  • Engine: composites now close their bottom edge through a new closeBottomSpace. A positive bottom inset advances the flow as before; a negative one pulls the following sibling up — symmetric with a negative top margin, which already offsets via placementTopY. The top-of-node reservation, the inter-child spacing, and the row/leaf paths are untouched (rows/leaves already fold the bottom inset into their positive content height), so every existing layout is byte-identical.
  • Public API: DocumentSession.margin(...) (and the builder's margin(...)) now reject a negative page margin with IllegalArgumentException, pointing the caller at a node's bleed(...) to reach the page edge. Node margins still allow negatives — they're a legitimate overlap/inset trick (e.g. a widget pulling up over the band above it).

Lane: shared-engine (LayoutCompiler) + canonical (DocumentSession). Purely additive at the signature level → japicmp-safe.

Verification

  • ./mvnw test -pl .1530 green, 0 visual baselines changed (the engine change is byte-identical for all existing content; the EPS boundary was checked to confirm no divergence for non-negative bottom insets).
  • NegativeMarginTest: negative page margin rejected via the builder and via the session setter, zero/positive accepted, and a section with a negative bottom margin shifts the following section up by exactly that margin.

Behavior note: callers that previously passed a negative page margin (and got silent overflow) now get a clear exception — intended, and called out in the CHANGELOG.

A negative bottom margin on a composite was silently dropped by the
vertical flow — its bottom-edge advance early-returned on a non-positive
amount — while a negative page margin was accepted and silently
overflowed the sheet.

Composites now close their bottom edge through closeBottomSpace, which
lets a negative bottom margin pull the following sibling up, symmetric
with a negative top margin (which already offsets via placementTopY). The
top-of-node reservation and the row/leaf paths are untouched, so existing
layouts are byte-identical. DocumentSession now rejects a negative page
margin with IllegalArgumentException pointing to bleed(); node margins
still allow negatives for overlap tricks.

Tests: NegativeMarginTest covers the page margin rejected via the builder
and via the session setter, zero/positive accepted, and a negative bottom
margin shifting the following section up by the margin. Full suite green,
no visual baselines changed.
@DemchaAV DemchaAV force-pushed the fix/negative-margin branch from 71e7cd0 to d85fc12 Compare June 25, 2026 11:09
@DemchaAV DemchaAV merged commit 34d89b4 into develop Jun 25, 2026
11 checks passed
@DemchaAV DemchaAV deleted the fix/negative-margin branch June 25, 2026 11:14
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