mirror of
https://github.com/Kozea/WeasyPrint.git
synced 2024-10-04 16:07:57 +03:00
Merge branch 'master' of github.com:Kozea/WeasyPrint
This commit is contained in:
commit
02d4c0032a
@ -327,12 +327,28 @@ def table_layout(context, table, max_position_y, skip_stack, containing_block,
|
|||||||
# Layout for row groups, rows and cells
|
# Layout for row groups, rows and cells
|
||||||
position_y = table.content_box_y() + border_spacing_y
|
position_y = table.content_box_y() + border_spacing_y
|
||||||
initial_position_y = position_y
|
initial_position_y = position_y
|
||||||
|
table_rows = [
|
||||||
|
child for child in table.children
|
||||||
|
if not child.is_header and not child.is_footer]
|
||||||
|
|
||||||
def all_groups_layout():
|
def all_groups_layout():
|
||||||
|
# If the page is not empty, we try to render the header and the footer
|
||||||
|
# on it. If the table does not fit on the page, we try to render it on
|
||||||
|
# the next page.
|
||||||
|
|
||||||
|
# If the page is empty and the header and footer are too big, there
|
||||||
|
# are not rendered. If no row can be rendered because of the header and
|
||||||
|
# the footer, the header and/or the footer are not rendered.
|
||||||
|
|
||||||
|
if page_is_empty:
|
||||||
|
header_footer_max_position_y = max_position_y
|
||||||
|
else:
|
||||||
|
header_footer_max_position_y = float('inf')
|
||||||
|
|
||||||
if table.children and table.children[0].is_header:
|
if table.children and table.children[0].is_header:
|
||||||
header = table.children[0]
|
header = table.children[0]
|
||||||
header, resume_at, next_page = group_layout(
|
header, resume_at, next_page = group_layout(
|
||||||
header, position_y, max_position_y,
|
header, position_y, header_footer_max_position_y,
|
||||||
skip_stack=None, page_is_empty=False)
|
skip_stack=None, page_is_empty=False)
|
||||||
if header and not resume_at:
|
if header and not resume_at:
|
||||||
header_height = header.height + border_spacing_y
|
header_height = header.height + border_spacing_y
|
||||||
@ -344,7 +360,7 @@ def table_layout(context, table, max_position_y, skip_stack, containing_block,
|
|||||||
if table.children and table.children[-1].is_footer:
|
if table.children and table.children[-1].is_footer:
|
||||||
footer = table.children[-1]
|
footer = table.children[-1]
|
||||||
footer, resume_at, next_page = group_layout(
|
footer, resume_at, next_page = group_layout(
|
||||||
footer, position_y, max_position_y,
|
footer, position_y, header_footer_max_position_y,
|
||||||
skip_stack=None, page_is_empty=False)
|
skip_stack=None, page_is_empty=False)
|
||||||
if footer and not resume_at:
|
if footer and not resume_at:
|
||||||
footer_height = footer.height + border_spacing_y
|
footer_height = footer.height + border_spacing_y
|
||||||
@ -370,7 +386,7 @@ def table_layout(context, table, max_position_y, skip_stack, containing_block,
|
|||||||
position_y=position_y + header_height,
|
position_y=position_y + header_height,
|
||||||
max_position_y=max_position_y - footer_height,
|
max_position_y=max_position_y - footer_height,
|
||||||
page_is_empty=avoid_breaks))
|
page_is_empty=avoid_breaks))
|
||||||
if new_table_children or not page_is_empty:
|
if new_table_children or not table_rows or not page_is_empty:
|
||||||
footer.translate(dy=end_position_y - footer.position_y)
|
footer.translate(dy=end_position_y - footer.position_y)
|
||||||
end_position_y += footer_height
|
end_position_y += footer_height
|
||||||
return (header, new_table_children, footer,
|
return (header, new_table_children, footer,
|
||||||
@ -387,7 +403,7 @@ def table_layout(context, table, max_position_y, skip_stack, containing_block,
|
|||||||
position_y=position_y + header_height,
|
position_y=position_y + header_height,
|
||||||
max_position_y=max_position_y,
|
max_position_y=max_position_y,
|
||||||
page_is_empty=avoid_breaks))
|
page_is_empty=avoid_breaks))
|
||||||
if new_table_children or not page_is_empty:
|
if new_table_children or not table_rows or not page_is_empty:
|
||||||
return (header, new_table_children, footer,
|
return (header, new_table_children, footer,
|
||||||
end_position_y, resume_at, next_page)
|
end_position_y, resume_at, next_page)
|
||||||
else:
|
else:
|
||||||
@ -402,7 +418,7 @@ def table_layout(context, table, max_position_y, skip_stack, containing_block,
|
|||||||
position_y=position_y,
|
position_y=position_y,
|
||||||
max_position_y=max_position_y - footer_height,
|
max_position_y=max_position_y - footer_height,
|
||||||
page_is_empty=avoid_breaks))
|
page_is_empty=avoid_breaks))
|
||||||
if new_table_children or not page_is_empty:
|
if new_table_children or not table_rows or not page_is_empty:
|
||||||
footer.translate(dy=end_position_y - footer.position_y)
|
footer.translate(dy=end_position_y - footer.position_y)
|
||||||
end_position_y += footer_height
|
end_position_y += footer_height
|
||||||
return (header, new_table_children, footer,
|
return (header, new_table_children, footer,
|
||||||
|
@ -2570,3 +2570,57 @@ def test_table_caption_margin_bottom():
|
|||||||
assert (tbody.content_box_x(), tbody.content_box_y()) == (20, 50)
|
assert (tbody.content_box_x(), tbody.content_box_y()) == (20, 50)
|
||||||
assert (caption.content_box_x(), caption.content_box_y()) == (40, 80)
|
assert (caption.content_box_x(), caption.content_box_y()) == (40, 80)
|
||||||
assert (h2.content_box_x(), h2.content_box_y()) == (20, 130)
|
assert (h2.content_box_x(), h2.content_box_y()) == (20, 130)
|
||||||
|
|
||||||
|
|
||||||
|
@assert_no_logs
|
||||||
|
@pytest.mark.parametrize('rows_expected, thead, tfoot, content', (
|
||||||
|
([[], ['Header', 'Footer']], 45, 45, '<p>content</p>'),
|
||||||
|
([[], ['Header', 'Footer']], 85, 5, '<p>content</p>'),
|
||||||
|
([['Header', 'Footer']], 30, 30, '<p>content</p>'),
|
||||||
|
([[], ['Header']], 30, 110, '<p>content</p>'),
|
||||||
|
([[], ['Header', 'Footer']], 30, 60, '<p>content</p>'),
|
||||||
|
([[], ['Footer']], 110, 30, '<p>content</p>'),
|
||||||
|
|
||||||
|
# We try to render the header and footer on the same page, but it does not
|
||||||
|
# fit. So we try to render the header or the footer on the next one, but
|
||||||
|
# nothing fit either.
|
||||||
|
([[], []], 110, 110, '<p>content</p>'),
|
||||||
|
|
||||||
|
([['Header', 'Footer']], 30, 30, ''),
|
||||||
|
([['Header']], 30, 110, ''),
|
||||||
|
([['Header', 'Footer']], 30, 60, ''),
|
||||||
|
([['Footer']], 110, 30, ''),
|
||||||
|
([[]], 110, 110, ''),
|
||||||
|
))
|
||||||
|
def test_table_empty_body(rows_expected, thead, tfoot, content):
|
||||||
|
html = '''
|
||||||
|
<style>
|
||||||
|
@page { size: 100px }
|
||||||
|
p { height: 20px }
|
||||||
|
thead th { height: %spx }
|
||||||
|
tfoot th { height: %spx }
|
||||||
|
</style>
|
||||||
|
%s
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>Header</th></tr></thead>
|
||||||
|
<tfoot><tr><th>Footer</th></tr></tfoot>
|
||||||
|
</table>
|
||||||
|
''' % (thead, tfoot, content)
|
||||||
|
pages = render_pages(html)
|
||||||
|
assert len(pages) == len(rows_expected)
|
||||||
|
for i, page in enumerate(pages):
|
||||||
|
rows = []
|
||||||
|
html, = page.children
|
||||||
|
body, = html.children
|
||||||
|
table_wrapper = body.children[-1]
|
||||||
|
if not table_wrapper.is_table_wrapper:
|
||||||
|
assert rows == rows_expected[i]
|
||||||
|
continue
|
||||||
|
table, = table_wrapper.children
|
||||||
|
for group in table.children:
|
||||||
|
for row in group.children:
|
||||||
|
cell, = row.children
|
||||||
|
line, = cell.children
|
||||||
|
text, = line.children
|
||||||
|
rows.append(text.text)
|
||||||
|
assert rows == rows_expected[i]
|
||||||
|
Loading…
Reference in New Issue
Block a user