diff --git a/tests/draw/test_float.py b/tests/draw/test_float.py index 49665d83..f31326f5 100644 --- a/tests/draw/test_float.py +++ b/tests/draw/test_float.py @@ -659,3 +659,84 @@ def test_float_split_10(assert_pixels):
bbbbb bbbbb
aa aa
bbb bbb
''') + + +@assert_no_logs +def test_float_split_11(assert_pixels): + assert_pixels(''' + BBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBB + BBBBGG______BBBB + BBBBGG______BBBB + BBBB________BBBB + BBBB________BBBB + ________________ + ''', ''' + +
+ a +

aa

aa

+

bb

bb

''') + + +@assert_no_logs +def test_float_split_12(assert_pixels): + assert_pixels(''' + BBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBB + BBBBBBBBBBBBBBBB + BBBBGG______BBBB + BBBBGG______BBBB + BBBB________BBBB + BBBB________BBBB + ________________ + ''', ''' + +
+
+

aa

aa

+ a +

bb

bb

''') diff --git a/weasyprint/layout/__init__.py b/weasyprint/layout/__init__.py index d9774b16..7fdda763 100644 --- a/weasyprint/layout/__init__.py +++ b/weasyprint/layout/__init__.py @@ -233,7 +233,7 @@ class LayoutContext: self.running_elements = defaultdict(lambda: defaultdict(lambda: [])) self.current_page = None self.forced_break = False - self.broken_out_of_flow = [] + self.broken_out_of_flow = {} self.in_column = False # Cache diff --git a/weasyprint/layout/absolute.py b/weasyprint/layout/absolute.py index f7d82e03..6640c09c 100644 --- a/weasyprint/layout/absolute.py +++ b/weasyprint/layout/absolute.py @@ -229,7 +229,8 @@ def absolute_layout(context, placeholder, containing_block, fixed_boxes, context, box, containing_block, fixed_boxes, bottom_space, skip_stack) placeholder.set_laid_out_box(new_box) if resume_at: - context.broken_out_of_flow.append((box, containing_block, resume_at)) + context.broken_out_of_flow[placeholder] = ( + box, containing_block, resume_at) def absolute_box_layout(context, box, containing_block, fixed_boxes, diff --git a/weasyprint/layout/block.py b/weasyprint/layout/block.py index b3406f29..951622ed 100644 --- a/weasyprint/layout/block.py +++ b/weasyprint/layout/block.py @@ -230,7 +230,7 @@ def _out_of_flow_layout(context, box, index, child, new_children, child.position_y += collapse_margin(adjoining_margins) if child.is_absolutely_positioned(): - placeholder = AbsolutePlaceholder(child) + new_child = placeholder = AbsolutePlaceholder(child) placeholder.index = index new_children.append(placeholder) if child.style['position'] == 'absolute': @@ -262,7 +262,7 @@ def _out_of_flow_layout(context, box, index, child, new_children, page = context.current_page context.running_elements[running_name][page].append(child) - return stop, resume_at, out_of_flow_resume_at + return stop, resume_at, new_child, out_of_flow_resume_at def _break_line(context, box, line, new_children, lines_iterator, @@ -629,7 +629,7 @@ def block_container_layout(context, box, bottom_space, skip_stack, new_children = [] next_page = {'break': 'any', 'page': None} all_footnotes = [] - broken_out_of_flow = [] + broken_out_of_flow = {} last_in_flow_child = None @@ -649,12 +649,14 @@ def block_container_layout(context, box, bottom_space, skip_stack, if not child.is_in_normal_flow(): abort = False - stop, resume_at, out_of_flow_resume_at = _out_of_flow_layout( - context, box, index, child, new_children, page_is_empty, - absolute_boxes, fixed_boxes, adjoining_margins, - bottom_space) + stop, resume_at, new_child, out_of_flow_resume_at = ( + _out_of_flow_layout( + context, box, index, child, new_children, page_is_empty, + absolute_boxes, fixed_boxes, adjoining_margins, + bottom_space)) if out_of_flow_resume_at: - broken_out_of_flow.append((child, box, out_of_flow_resume_at)) + broken_out_of_flow[new_child] = ( + child, box, out_of_flow_resume_at) elif isinstance(child, boxes.LineBox): (abort, stop, resume_at, position_y, @@ -696,6 +698,8 @@ def block_container_layout(context, box, bottom_space, skip_stack, if abort: page = child.page_values()[0] + remove_placeholders( + context, box.children[skip:], absolute_boxes, fixed_boxes) for footnote in new_footnotes: context.unlayout_footnote(footnote) return ( @@ -720,7 +724,8 @@ def block_container_layout(context, box, bottom_space, skip_stack, return ( None, None, {'break': 'any', 'page': None}, [], False, max_lines) - context.broken_out_of_flow.extend(broken_out_of_flow) + for key, value in broken_out_of_flow.items(): + context.broken_out_of_flow[key] = value if collapsing_with_children: box.position_y += ( @@ -1005,6 +1010,8 @@ def remove_placeholders(context, box_list, absolute_boxes, fixed_boxes): For boxes that have been removed in find_earlier_page_break(), remove the matching placeholders in absolute_boxes and fixed_boxes. + Also takes care of removed footnotes and floats. + """ for box in box_list: if isinstance(box, boxes.ParentBox): @@ -1017,6 +1024,8 @@ def remove_placeholders(context, box_list, absolute_boxes, fixed_boxes): fixed_boxes.remove(box) if box.footnote: context.unlayout_footnote(box.footnote) + if box in context.broken_out_of_flow: + context.broken_out_of_flow.pop(box) def avoid_page_break(page_break, context): diff --git a/weasyprint/layout/inline.py b/weasyprint/layout/inline.py index b6171543..e818da2d 100644 --- a/weasyprint/layout/inline.py +++ b/weasyprint/layout/inline.py @@ -169,8 +169,8 @@ def get_next_linebox(context, linebox, position_y, bottom_space, skip_stack, fixed_boxes, bottom_space, skip_stack=None) float_children.append(new_waiting_float) if waiting_float_resume_at: - context.broken_out_of_flow.append( - (waiting_float, containing_block, waiting_float_resume_at)) + context.broken_out_of_flow[new_waiting_float] = ( + waiting_float, containing_block, waiting_float_resume_at) if float_children: line.children += tuple(float_children) @@ -559,8 +559,8 @@ def _out_of_flow_layout(context, box, containing_block, index, child, context, child, containing_block, absolute_boxes, fixed_boxes, bottom_space, skip_stack=None) if float_resume_at: - context.broken_out_of_flow.append( - (child, containing_block, float_resume_at)) + context.broken_out_of_flow[child] = ( + child, containing_block, float_resume_at) waiting_children.append((index, new_child, child)) child = new_child diff --git a/weasyprint/layout/page.py b/weasyprint/layout/page.py index 054364e1..8865e68b 100644 --- a/weasyprint/layout/page.py +++ b/weasyprint/layout/page.py @@ -564,8 +564,9 @@ def make_page(context, root_box, page_type, resume_at, page_number, adjoining_margins = [] positioned_boxes = [] # Mixed absolute and fixed out_of_flow_boxes = [] - broken_out_of_flow = [] - for box, containing_block, skip_stack in context.broken_out_of_flow: + broken_out_of_flow = {} + context_out_of_flow = context.broken_out_of_flow.values() + for box, containing_block, skip_stack in context_out_of_flow: box.position_y = 0 if box.is_floated(): out_of_flow_box, out_of_flow_resume_at = float_layout( @@ -578,8 +579,8 @@ def make_page(context, root_box, page_type, resume_at, page_number, skip_stack) out_of_flow_boxes.append(out_of_flow_box) if out_of_flow_resume_at: - broken_out_of_flow.append( - (box, containing_block, out_of_flow_resume_at)) + broken_out_of_flow[out_of_flow_box] = ( + box, containing_block, out_of_flow_resume_at) context.broken_out_of_flow = broken_out_of_flow root_box, resume_at, next_page, _, _, _ = block_level_layout( context, root_box, 0, resume_at, initial_containing_block,