Skip to content

Commit

Permalink
Fix split table headers’ top border when rows are split
Browse files Browse the repository at this point in the history
  • Loading branch information
liZe committed Jul 7, 2022
1 parent cb9540b commit 76d174f
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 17 deletions.
70 changes: 69 additions & 1 deletion tests/draw/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,7 @@ def test_tables_9(assert_pixels):
______________________
______________________
______________________
______________________
_BBBBBBBBBBBBBBBBBBBB_
_BBBBBBBBBBBBBBBBBBBB_
_BBBBBBBBBBBBBBBBBBBB_
Expand All @@ -745,7 +746,6 @@ def test_tables_9(assert_pixels):
______________________
______________________
______________________
______________________
''', '''
<style>
@page { size: 22px 18px; margin: 1px }
Expand Down Expand Up @@ -1235,3 +1235,71 @@ def test_tables_21(assert_pixels):
<table>
<tr><td>abc</td><td>abc</td></tr>
<tr><td>abc</td><td></td></tr>''')


@assert_no_logs
def test_tables_22(assert_pixels):
assert_pixels('''
_________________________
_rrrrrrrrrrrrrrrrrrrrrrr_
_rKKKKKKKKKKrKKKKKKKKKKr_
_rKKKKKKKKKKrKKKKKKKKKKr_
_rrrrrrrrrrrrrrrrrrrrrrr_
_rKKKKKKBBBBrBBBBBBBBBBr_
_rKKKKKKBBBBrBBBBBBBBBBr_
_rBBBBBBBBBBrBBBBBBBBBBr_
_________________________
_________________________
_rrrrrrrrrrrrrrrrrrrrrrr_
_rKKKKKKKKKKrKKKKKKKKKKr_
_rKKKKKKKKKKrKKKKKKKKKKr_
_rrrrrrrrrrrrrrrrrrrrrrr_
_rKKKKKKBBBBrBBBBBBBBBBr_
_rKKKKKKBBBBrBBBBBBBBBBr_
_rrrrrrrrrrrrrrrrrrrrrrr_
_________________________
''', '''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
@page { size: 25px 9px; margin: 1px }
table { border-collapse: collapse; font: 2px/1 weasyprint }
td { background: blue; border: 1px solid red }
</style>
<table>
<thead><tr><td>abcde</td><td>abcde</td></tr></thead>
<tbody><tr><td>abc abc</td><td></td></tr></tbody>''')


@pytest.mark.xfail
@assert_no_logs
def test_tables_23(assert_pixels):
assert_pixels('''
_________________________
_rrrrrrrrrrrrrrrrrrrrrrr_
_rKKKKKKKKKKrKKKKKKKKKKr_
_rKKKKKKKKKKrKKKKKKKKKKr_
_rrrrrrrrrrrrrrrrrrrrrrr_
_rKKKKKKBBBBrBBBBBBBBBBr_
_rKKKKKKBBBBrBBBBBBBBBBr_
_rBBBBBBBBBBrBBBBBBBBBBr_
_________________________
_________________________
_rrrrrrrrrrrrrrrrrrrrrrr_
_rKKKKKKKKKKrKKKKKKKKKKr_
_rKKKKKKKKKKrKKKKKKKKKKr_
_rKKKKKKBBBBrBBBBBBBBBBr_
_rKKKKKKBBBBrBBBBBBBBBBr_
_rrrrrrrrrrrrrrrrrrrrrrr_
_________________________
_________________________
''', '''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
@page { size: 25px 9px; margin: 1px }
table { border-collapse: collapse; font: 2px/1 weasyprint }
td { background: blue; border: 1px solid red }
thead td { border-bottom: none }
</style>
<table>
<thead><tr><td>abcde</td><td>abcde</td></tr></thead>
<tbody><tr><td>abc abc</td><td></td></tr></tbody>''')
46 changes: 30 additions & 16 deletions weasyprint/layout/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@ def table_layout(context, table, bottom_space, skip_stack, containing_block,
avoid_page_break, block_container_layout, block_level_page_break,
find_earlier_page_break, force_page_break)

table.remove_decoration(start=skip_stack is not None, end=False)
has_header = table.children and table.children[0].is_header
has_footer = table.children and table.children[-1].is_footer
collapse = table.style['border_collapse'] == 'collapse'
remove_start_decoration = skip_stack is not None and not has_header
table.remove_decoration(remove_start_decoration, end=False)

column_widths = table.column_widths

if table.style['border_collapse'] == 'separate':
border_spacing_x, border_spacing_y = table.style['border_spacing']
if collapse:
border_spacing_x = border_spacing_y = 0
else:
border_spacing_x = 0
border_spacing_y = 0
border_spacing_x, border_spacing_y = table.style['border_spacing']

column_positions = table.column_positions = []
rows_left_x = table.content_box_x() + border_spacing_x
Expand All @@ -44,7 +47,7 @@ def table_layout(context, table, bottom_space, skip_stack, containing_block,
column_positions.append(position_x)
rows_width = rows_x - position_x

if table.style['border_collapse'] == 'collapse':
if collapse:
table.skip_cell_border_top = False
table.skip_cell_border_bottom = False
split_cells = False
Expand All @@ -60,7 +63,7 @@ def table_layout(context, table, bottom_space, skip_stack, containing_block,
skipped_rows += len(group.children)
else:
skipped_rows = 0
if not split_cells:
if not split_cells and not has_header:
_, horizontal_borders = table.collapsed_border_grid
if horizontal_borders:
table.border_top_width = max(
Expand Down Expand Up @@ -149,9 +152,20 @@ def group_layout(group, position_y, bottom_space, page_is_empty,
cell_skip_stack = {len(cell.children): None}
else:
cell_skip_stack = None
if cell_skip_stack:
cell.remove_decoration(start=True, end=False)
if table.style['border_collapse'] == 'collapse':

# Adapt cell and table collapsing borders when a row is split
if cell_skip_stack and collapse:
if has_header:
# We have a header, we have to adapt the position of
# the split cell to match the header’s bottom border
header_rows = table.children[0].children
if header_rows and header_rows[-1].children:
cell.position_y += max(
header.border_bottom_width
for header in header_rows[-1].children)
else:
# We don’t have a header, we have to skip the
# decoration at the top of the table when it’s drawn
table.skip_cell_border_top = True

# First try to render content as if there was already something
Expand Down Expand Up @@ -308,7 +322,7 @@ def group_layout(group, position_y, bottom_space, page_is_empty,
page_is_empty = False
skip_stack = None

if break_cell and table.style['border_collapse'] == 'collapse':
if break_cell and collapse and not has_footer:
table.skip_cell_border_bottom = True

if break_cell or resume_at:
Expand Down Expand Up @@ -422,7 +436,7 @@ def all_groups_layout():
else:
header_footer_bottom_space = -inf

if table.children and table.children[0].is_header:
if has_header:
header = table.children[0]
header, resume_at, next_page = group_layout(
header, position_y, header_footer_bottom_space,
Expand All @@ -434,7 +448,7 @@ def all_groups_layout():
else:
header = None

if table.children and table.children[-1].is_footer:
if has_footer:
footer = table.children[-1]
footer, resume_at, next_page = group_layout(
footer, position_y, header_footer_bottom_space,
Expand Down Expand Up @@ -536,9 +550,9 @@ def get_column_cells(table, column):
([header] if header is not None else []) +
new_table_children +
([footer] if footer is not None else []))
table.remove_decoration(
start=skip_stack is not None, end=resume_at is not None)
if table.style['border_collapse'] == 'collapse':
remove_end_decoration = resume_at is not None and not has_footer
table.remove_decoration(remove_start_decoration, remove_end_decoration)
if collapse:
table.skipped_rows = skipped_rows

# If the height property has a bigger value, just add blank space
Expand Down

0 comments on commit 76d174f

Please sign in to comment.