We were already trying to get the correct top margin of the child, but we
didn’t include subtleties introduced by unforced page breaks. The logic is
still duplicated, it already was, but at least now the copy-paste is correctly
done.
Fix#1058.
The bug in the code was caused by the page_is_empty variable. It’s useless to
test this variable here because we know that we rendered at least the current
line. It’s not updated earlier, but if it were it would always be True.
This commit also fixes minor bugs in the tests.
Fix#1674.
Before this commit, when we had to break previously rendered waiting children
in a line, we re-rendered the already-rendered children. That was bad, because
the tree of the children that were already rendered were different from the
original tree, that may include leading spaces for example. It also required a
complex mix of the original resume-at with the original skip-stack.
This new solution includes both the original child (to render it from a fresh
start) and the already-rendered child (to get the previous positions). The
skip-stack mix is now useless, removing a lot of complex code.
This change is scary and will probably break some corner cases. But tests pass,
and a new one has been added to avoid future regressions.
Fix#1638.
Previously, if a footnote triggered an overflow (that is, it was too
large for the containing space), but footnote-policy didn't make us push
down the line containing it, any subsequent footnotes in the same
linebox would not be set into a footnote area, because they would never
be passed to layout_footnote and report_footnote. (Their call sites
would be set, but their content would not be.)
This also fixes a potential infinite loop where using footnote-policy
could have forced the first line of a page to be pushed to the next
page: that will just result in an infinite loop, so instead we set the
line and move on if we are on the first line of a page. (This behavior
is not specified in GCPM, but no other behavior seems practical: the
only alternative would be to expand the page, which is almost certainly
less desirable.)
The default "2" value for orphans and widows is really useful for real
documents, but it can be very disturbing for tests and introduce false
negatives and false positives.
The primary change here is that the column calculation algorithm now
attempts to render columns as if they were the full remaining height on
the page, rather than to render the entire content regardless of how
long the page is.
The worst-case behavior is effectively the same as that of the previous
algorithm (as at least one additional pass would be required to
determine how high balanced columns should be, but this applies in both
cases), but if content would not fit on the page, this can bail and set
the page immediately, rather than continuing significantly more
calculations.
As an associated benefit, this closes#1020, as we now handle multiple
column breaks (which would force a page break) correctly. A test for
this behavior is included.
This fixes a bug accidentally introduced in #1566, where we would try to
unlayout a footnote that had not yet been laid out, if the algorithm
decided that there would be insufficient space on a page before laying
out a further footnote.
If a footnote has been output but we then decide to cancel the line it
was output on, we should cancel the output of the footnote itself.
This requires a bit of extra bookkeeping, so we know which footnotes are
relevant, but otherwise largely works using the existing
remove_placeholders code.
Includes a minor refactor of footnote area management in LayoutContext,
and a new testing utility: `tree_position`.
Closes#1564.
When a box would break over the edge of a page, its height is extended
to the bottom of that page (per
https://www.w3.org/TR/css-break-3/#box-splitting , primarily to allow
backgrounds and borders to continue to the end of the page).
When this happened, sometimes the values that would be calculated for
the height of the extended element would be rounded *over* the
calculated height that remained on the page, forcing the entire
containing box to wrap to the next page.
Rather than trying to carefully manage the order of operations to try to
be safe in IEEE floats for directions, we apply a small "fudge factor":
if an element fits very nearly (within a thousandth of a pixel) into the
remaining space, it is still accepted.