Skip to content

Commit

Permalink
Split blocks in blocks when possible
Browse files Browse the repository at this point in the history
Related to #1476.
  • Loading branch information
liZe committed Nov 14, 2021
1 parent dd783ef commit 046f27b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 10 deletions.
43 changes: 43 additions & 0 deletions tests/layout/test_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -833,3 +833,46 @@ def test_continue_discard_children():
assert div_2.position_y == 2 + 25
assert div_3.position_y == 2 + 25 * 2
assert article.border_bottom_width == 1


@assert_no_logs
def test_block_in_block_with_bottom_padding():
# Test regression: https://github.com/Kozea/WeasyPrint/issues/1476
page_1, page_2 = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
@page { size: 8em 3.5em }
body { line-height: 1; orphans: 1; widows: 1; font-family: weasyprint }
div { padding-bottom: 1em }
</style>
abc def
<div>
<p>
ghi jkl
mno pqr
</p>
</div>
stu vwx''')

html, = page_1.children
body, = html.children
anon_body, div = body.children
line, = anon_body.children
assert line.height == 16
assert line.children[0].text == 'abc def'
p, = div.children
line, = p.children
assert line.height == 16
assert line.children[0].text == 'ghi jkl'

html, = page_2.children
body, = html.children
div, anon_body = body.children
p, = div.children
line, = p.children
assert line.height == 16
assert line.children[0].text == 'mno pqr'
line, = anon_body.children
assert line.height == 16
assert line.content_box_y() == 16 + 16 # p content + div padding
assert line.children[0].text == 'stu vwx'
38 changes: 28 additions & 10 deletions weasyprint/layout/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,6 @@ def _in_flow_layout(context, box, index, child, new_children, page_is_empty,
context, child, max_position_y, skip_stack, new_containing_block,
page_is_empty_with_no_children, absolute_boxes, fixed_boxes,
adjoining_margins, discard)
skip_stack = None

if new_child is not None:
# index in its non-laid-out parent, not in future new parent
Expand All @@ -425,28 +424,47 @@ def _in_flow_layout(context, box, index, child, new_children, page_is_empty,
offset_y = (
collapse_margin(adjoining_margins) - new_child.margin_top)
new_child.translate(0, offset_y)
adjoining_margins = []
# else: blocks handle that themselves.

adjoining_margins = next_adjoining_margins
adjoining_margins.append(new_child.margin_bottom)

if not collapsing_through:
new_content_position_y = (
new_child.content_box_y() + new_child.height)
new_position_y = (
new_child.border_box_y() + new_child.border_height())

if (new_position_y > allowed_max_position_y and
if (new_content_position_y > allowed_max_position_y and
not page_is_empty_with_no_children):
# The child overflows the page area, put it on the
# next page. (But don’t delay whole blocks if eg.
# only the bottom border overflows.)
# The child content overflows the page area, display it on the
# next page.
remove_placeholders([new_child], absolute_boxes, fixed_boxes)
new_child = None
elif (new_position_y > allowed_max_position_y and
not page_is_empty_with_no_children):
# The child border/padding overflows the page area, do the
# layout again with a lower max_y value.
remove_placeholders([new_child], absolute_boxes, fixed_boxes)
max_position_y -= (
new_child.padding_bottom + new_child.border_bottom_width)
(new_child, resume_at, next_page, next_adjoining_margins,
collapsing_through) = block_level_layout(
context, child, max_position_y, skip_stack,
new_containing_block, page_is_empty_with_no_children,
absolute_boxes, fixed_boxes, adjoining_margins, discard)
if new_child:
position_y = (
new_child.border_box_y() + new_child.border_height())
else:
position_y = new_position_y

if new_child is not None and new_child.clearance is not None:
adjoining_margins = next_adjoining_margins
if new_child:
adjoining_margins.append(new_child.margin_bottom)

if new_child and new_child.clearance:
position_y = new_child.border_box_y() + new_child.border_height()

skip_stack = None

if new_child is None:
# Nothing fits in the remaining space of this page: break
if page_break in ('avoid', 'avoid-page'):
Expand Down

0 comments on commit 046f27b

Please sign in to comment.