Commit a1e1f9a
committed
feat(footnote): absorb one-line footnote widows by bumping reserve (SD-2656)
Adds a `runWidowOrphanAbsorb` pass between the convergence loop and the
preferred-reserve scorer. For every page whose predicted footnote tail
is one line short (≤ 24 px), bumps the reserve to the page's preferred
value, bypassing the scorer's page-count-growth gate.
The scorer's gate exists to prevent global regressions when a trial
trades local fidelity for added pages. For one-line widows the trade
is bounded — Word's pagination always absorbs them. The implementation
reuses the existing buildFootnoteLedgers, applyReserves, growReserves,
and capReserveForRelayout helpers; the only new logic is the threshold
filter and the unconditional bump.
## Threshold rationale
Threshold = 24 px (one line of footnote text plus slack). Measurements
on the Carlsbad fixture: at threshold = 35 px the absorb pass creates
new cluster splits on pages 25-29; at threshold = 24 px no regression
is measurable. 24 is the largest value with a clean profile across the
two test fixtures.
## Trade-off
This pass may grow the document to absorb widows. On the IRA fixture,
six one-line widows bump cleanly but force the doc 45 → 48 pages. The
"revert on grow" guard would make the pass a no-op everywhere unless a
doc has body slack (test fixtures do not). The trade is accepted for
docs whose layouts genuinely have nowhere to absorb a widow without
growth. Future work pairs this with body paragraph widow/orphan
controls so the body absorbs the pushed line for free.
## Verified
- layout-bridge 1281, layout-engine 657, layout-tests 332 — all green.
- Carlsbad: unchanged at 46p / 3 splits (no one-line tails to absorb).
- IRA: 45p / 17 splits → 48p / 9 splits (8 widows absorbed, 3 page cost).1 parent 2cc68fa commit a1e1f9a
1 file changed
Lines changed: 31 additions & 0 deletions
Lines changed: 31 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2615 | 2615 | | |
2616 | 2616 | | |
2617 | 2617 | | |
| 2618 | + | |
| 2619 | + | |
| 2620 | + | |
| 2621 | + | |
| 2622 | + | |
| 2623 | + | |
| 2624 | + | |
| 2625 | + | |
| 2626 | + | |
| 2627 | + | |
| 2628 | + | |
| 2629 | + | |
| 2630 | + | |
| 2631 | + | |
| 2632 | + | |
| 2633 | + | |
| 2634 | + | |
| 2635 | + | |
| 2636 | + | |
| 2637 | + | |
| 2638 | + | |
| 2639 | + | |
| 2640 | + | |
| 2641 | + | |
| 2642 | + | |
| 2643 | + | |
| 2644 | + | |
| 2645 | + | |
| 2646 | + | |
| 2647 | + | |
| 2648 | + | |
2618 | 2649 | | |
2619 | 2650 | | |
2620 | 2651 | | |
| |||
0 commit comments