diff --git a/weasyprint/layout/__init__.py b/weasyprint/layout/__init__.py index be4ecfdde..e15e88e19 100644 --- a/weasyprint/layout/__init__.py +++ b/weasyprint/layout/__init__.py @@ -241,6 +241,11 @@ def __init__(self, style_for, get_image_from_uri, font_config, self.tables = {} self.dictionaries = {} + def overflows_page(self, bottom_space, position_y): + # Use a small fudge factor to avoid floating numbers errors. + # The 1e-9 value comes from PEP 485. + return position_y > (self.page_bottom - bottom_space) * (1 + 1e-9) + def create_block_formatting_context(self): self.excluded_shapes = [] self._excluded_shapes_lists.append(self.excluded_shapes) diff --git a/weasyprint/layout/block.py b/weasyprint/layout/block.py index a7c45701a..5bd1ec058 100644 --- a/weasyprint/layout/block.py +++ b/weasyprint/layout/block.py @@ -234,9 +234,9 @@ def _out_of_flow_layout(context, box, index, child, new_children, context, child, box, absolute_boxes, fixed_boxes, bottom_space, skip_stack=None) # New page if overflow - if (page_is_empty and not new_children) or not ( - new_child.position_y + new_child.height > - context.page_bottom - bottom_space): + page_overflow = context.overflows_page( + bottom_space, new_child.position_y + new_child.height) + if (page_is_empty and not new_children) or not page_overflow: new_child.index = index new_children.append(new_child) else: @@ -315,7 +315,7 @@ def _linebox_layout(context, box, index, child, new_children, page_is_empty, # page and can advance in the context. overflow = ( (new_children or not page_is_empty) and - (new_position_y + offset_y > context.page_bottom - bottom_space)) + context.overflows_page(bottom_space, new_position_y + offset_y)) if overflow: abort, stop, resume_at = _break_line( box, new_children, lines_iterator, page_is_empty, index, @@ -327,8 +327,8 @@ def _linebox_layout(context, box, index, child, new_children, page_is_empty, # "When an unforced page break occurs here, both the adjoining # ‘margin-top’ and ‘margin-bottom’ are set to zero." # See https://github.com/Kozea/WeasyPrint/issues/115 - elif page_is_empty and ( - new_position_y > context.page_bottom - bottom_space): + elif page_is_empty and context.overflows_page( + bottom_space, new_position_y): # Remove the top border when a page is empty and the box is # too high to be drawn in one page new_position_y -= box.margin_top @@ -343,9 +343,10 @@ def _linebox_layout(context, box, index, child, new_children, page_is_empty, for footnote in footnotes: context.layout_footnote(footnote) new_footnotes.append(footnote) - overflow = context.reported_footnotes or ( - new_position_y + offset_y > - context.page_bottom - bottom_space) + overflow = ( + context.reported_footnotes or + context.overflows_page( + bottom_space, new_position_y + offset_y)) if overflow: context.report_footnote(footnote) if footnote.style['footnote_policy'] == 'line': @@ -464,22 +465,16 @@ def _in_flow_layout(context, box, index, child, new_children, page_is_empty, new_position_y = ( new_child.border_box_y() + new_child.border_height()) - # Use a small fudge factor on this due to box splitting setting the - # height of some elements to the remaining height of the page: - # https://www.w3.org/TR/css-break-3/#box-splitting - # (Occasionally the order of this calculation would otherwise come - # out with unequal float values, forcing the box to the next page.) - # The 1e-9 value comes from PEP 485. - if (new_content_position_y > - (context.page_bottom - bottom_space) * (1 + 1e-9) and - not page_is_empty_with_no_children): + page_overflow = context.overflows_page( + bottom_space, new_content_position_y) + if page_overflow and not page_is_empty_with_no_children: # The child content overflows the page area, display it on the # next page. remove_placeholders( context, [new_child], absolute_boxes, fixed_boxes) new_child = None - elif (new_position_y > context.page_bottom - bottom_space and - not page_is_empty_with_no_children): + elif not page_is_empty_with_no_children and context.overflows_page( + bottom_space, new_position_y): # The child border/padding overflows the page area, do the # layout again with a higher bottom_space value. remove_placeholders( diff --git a/weasyprint/layout/table.py b/weasyprint/layout/table.py index b551641d7..80d0f6231 100644 --- a/weasyprint/layout/table.py +++ b/weasyprint/layout/table.py @@ -288,8 +288,8 @@ def group_layout(group, position_y, bottom_space, page_is_empty, # Break if this row overflows the page, unless there is no # other content on the page. - if not page_is_empty and ( - next_position_y > context.page_bottom - bottom_space): + if not page_is_empty and context.overflows_page( + bottom_space, next_position_y): if new_group_children: previous_row = new_group_children[-1] page_break = block_level_page_break(previous_row, row)