Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include floats in calculation of minimum cell height #2301

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 82 additions & 11 deletions tests/layout/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -1966,17 +1966,50 @@ def test_table_vertical_align(assert_pixels):

@assert_no_logs
def test_table_vertical_align_float():
# Test regression: https://github.com/Kozea/WeasyPrint/issues/2216
# Test regressions:
# https://github.com/Kozea/WeasyPrint/issues/2216
# https://github.com/Kozea/WeasyPrint/issues/2293
page, = render_pages('''
<style>
@page { size: 100px }
td { width: 50px; height: 100px }
div { width: 25px; height: 20px }
@page { size: 100px 400px }
td { width: 50px; height: 100px; line-height: 0 }
</style>
<table>
<tr>
<td style="vertical-align: middle"><div style="float: left"></div></td>
<td style="vertical-align: bottom"><div style="float: right"></div></td>
<td style="vertical-align: middle">
<div style="float: left; height: 20px; width: 20px"></div>
<div style="display: inline-block; height: 30px; width: 30px"></div>
</td>
<td style="vertical-align: bottom">
<div style="display: inline-block; height: 30px; width: 30px"></div>
<div style="float: right; height: 20px; width: 20px"></div>
</td>
</tr>
<tr>
<td style="vertical-align: middle">
<div style="float: left; height: 20px; width: 20px"></div>
<div style="display: inline-block; height: 10px; width: 10px"></div>
</td>
<td style="vertical-align: bottom">
<div style="display: inline-block; height: 10px; width: 10px"></div>
<div style="float: right; height: 20px; width: 20px"></div>
</td>
</tr>
<tr>
<td style="vertical-align: middle">
<div style="display: inline-block; height: 10px; width: 10px"></div>
</td>
<td style="vertical-align: bottom">
<div style="display: inline-block; height: 10px; width: 10px"></div>
</td>
</tr>
<tr>
<td style="vertical-align: middle">
<div style="float: left; height: 20px; width: 20px"></div>
</td>
<td style="vertical-align: bottom">
<div style="float: right; height: 20px; width: 20px"></div>
</td>
</tr>
</table>
''')
Expand All @@ -1986,14 +2019,52 @@ def test_table_vertical_align_float():
table, = wrapper.children
table, = wrapper.children
row_group, = table.children
row, = row_group.children
td_1, td_2 = row.children
row_1, row_2, row_3, row_4, = row_group.children

td_1, td_2 = row_1.children
div_1, line_wrapper = td_1.children
assert div_1.position_x == 0
assert div_1.position_y == (100 - 30) / 2
div_2 = line_wrapper.children[0].children[0]
assert div_2.position_x == 20
assert div_2.position_y == (100 - 30) / 2
line_box, = td_2.children
div_1, _, div_2 = line_box.children
assert div_1.position_x == 50
assert div_1.position_y == 100 - 30
assert div_2.position_x == 80
assert div_2.position_y == 100 - 30

td_1, td_2 = row_2.children
div_1, line_wrapper = td_1.children
assert div_1.position_x == 0
assert div_1.position_y == 100 + (100 - 20) / 2
div_2 = line_wrapper.children[0].children[0]
assert div_2.position_x == 20
assert div_2.position_y == 100 + (100 - 20) / 2
line_box, = td_2.children
div_1, _, div_2 = line_box.children
assert div_1.position_x == 50
assert div_1.position_y == 100 + (100 - 20)
assert div_2.position_x == 80
assert div_2.position_y == 100 + (100 - 20)

td_1, td_2 = row_3.children
line_box, = td_1.children
div, _ = line_box.children
assert div.position_x == 0
assert div.position_y == 200 + (100 - 10) / 2
div, = td_2.children
assert div.position_x == 50
assert div.position_y == 200 + (100 - 10)

td_1, td_2 = row_4.children
div, = td_1.children
assert div.position_x == 0
assert div.position_y == 40 # (100 - 20) / 2
assert div.position_y == 300 + (100 - 20) / 2
div, = td_2.children
assert div.position_x == 75
assert div.position_y == 80 # 100 - 20
assert div.position_x == 80
assert div.position_y == 300 + (100 - 20)


@assert_no_logs
Expand Down
17 changes: 10 additions & 7 deletions weasyprint/layout/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,6 @@ def group_layout(group, position_y, bottom_space, page_is_empty, skip_stack):
sum(spanned_widths) +
border_spacing_x * (cell.colspan - 1) -
borders_plus_padding)
# Set computed height as a minimum.
cell.computed_height = cell.height
cell.height = 'auto'
if skip_stack:
if index_cell in skip_stack:
cell_skip_stack = skip_stack[index_cell]
Expand Down Expand Up @@ -175,11 +172,20 @@ def group_layout(group, position_y, bottom_space, page_is_empty, skip_stack):
# force to render something if the page is actually empty, or
# just draw an empty cell otherwise. See
# test_table_break_children_margin.
# Pretend that height is not set, keeping computed height as a minimum.
cell.computed_height = cell.height
cell.height = 'auto'
original_style = cell.style
if cell.style['height'] != 'auto':
style_copy = cell.style.copy()
style_copy['height'] = 'auto'
cell.style = style_copy
new_cell, cell_resume_at, _, _, _, _ = block_container_layout(
context, cell, bottom_space, cell_skip_stack,
page_is_empty=page_is_empty, absolute_boxes=absolute_boxes,
fixed_boxes=fixed_boxes, adjoining_margins=None,
discard=False, max_lines=None)
cell.style = original_style
if new_cell is None:
cell = cell.copy_with_children([])
cell, _, _, _, _, _ = block_container_layout(
Expand Down Expand Up @@ -289,10 +295,7 @@ def group_layout(group, position_y, bottom_space, page_is_empty, skip_stack):
cell.computed_height - cell.content_height)
if vertical_align_shift > 0:
for child in cell.children:
child_shift = child.margin_height()
if cell.vertical_align == 'middle':
child_shift /= 2
child.translate(dy=vertical_align_shift - child_shift)
child.translate(dy=vertical_align_shift)

next_position_y = row.position_y + row.height
if resume_at is None:
Expand Down
Loading