diff --git a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index e2187fee2a3..c63585b8247 100644 --- a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -283,8 +283,7 @@ void InlineFormattingContext::generate_line_boxes() if (item.node) { auto introduce_clearance = parent().clear_floating_boxes(*item.node, *this); if (introduce_clearance == BlockFormattingContext::DidIntroduceClearance::Yes) { - if (vertical_float_clearance() > line_builder.current_block_offset()) - line_builder.set_current_block_offset(vertical_float_clearance()); + line_builder.did_introduce_clearance(vertical_float_clearance()); parent().reset_margin_state(); } } diff --git a/Libraries/LibWeb/Layout/LineBuilder.cpp b/Libraries/LibWeb/Layout/LineBuilder.cpp index e7f73b41063..aa9bf737b57 100644 --- a/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -75,9 +75,8 @@ void LineBuilder::begin_new_line(bool increment_y, bool is_first_break_in_sequen m_last_line_needs_update = true; // FIXME: Support text-indent with "each-line". - if (m_containing_block_used_values.line_boxes.size() <= 1) { + if (m_containing_block_used_values.line_boxes.size() <= 1) ensure_last_line_box().m_inline_length += m_text_indent; - } } LineBox& LineBuilder::ensure_last_line_box() @@ -421,4 +420,22 @@ void LineBuilder::recalculate_available_space() m_containing_block_used_values.line_boxes.last().m_original_available_width = m_available_width_for_current_line; } +void LineBuilder::did_introduce_clearance(CSSPixels clearance) +{ + // If clearance was introduced but our current line box starts beyond it, we don't need to do anything. + if (clearance <= m_current_block_offset) + return; + + // Increase the height of the previous line box so it matches the clearance, because the element's height is first + // determined by the bottom of the last line box (after trimming empty/whitespace boxes). + auto& line_boxes = m_containing_block_used_values.line_boxes; + if (line_boxes.size() > 1) { + auto& previous_line_box = line_boxes[line_boxes.size() - 2]; + previous_line_box.m_bottom = clearance; + } + + // The current line box will start directly after any cleared floats. + m_current_block_offset = clearance; +} + } diff --git a/Libraries/LibWeb/Layout/LineBuilder.h b/Libraries/LibWeb/Layout/LineBuilder.h index 26525e6d9bb..0f4f971d2dc 100644 --- a/Libraries/LibWeb/Layout/LineBuilder.h +++ b/Libraries/LibWeb/Layout/LineBuilder.h @@ -42,13 +42,14 @@ public: void remove_last_line_if_empty(); CSSPixels current_block_offset() const { return m_current_block_offset; } - void set_current_block_offset(CSSPixels block_offset) { m_current_block_offset = block_offset; } void recalculate_available_space(); CSSPixels y_for_float_to_be_inserted_here(Box const&); auto& inline_formatting_context() { return m_context; } + void did_introduce_clearance(CSSPixels); + private: void begin_new_line(bool increment_y, bool is_first_break_in_sequence = true); diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-at-end-of-block.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-at-end-of-block.txt new file mode 100644 index 00000000000..f9cf9ec1a8c --- /dev/null +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-at-end-of-block.txt @@ -0,0 +1,26 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x416 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x400 children: not-inline + BlockContainer at (8,8) content-size 784x200 children: inline + frag 0 from TextNode start: 1, length: 3, rect: [8,8 27.15625x17] baseline: 13.296875 + "foo" + TextNode <#text> + BlockContainer at (292,8) content-size 500x200 floating [BFC] children: not-inline + TextNode <#text> + BreakNode + TextNode <#text> + BlockContainer <(anonymous)> at (8,208) content-size 784x0 children: inline + TextNode <#text> + BlockContainer at (8,208) content-size 500x200 children: not-inline + BlockContainer <(anonymous)> at (8,408) content-size 784x0 children: inline + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x416] + PaintableWithLines (BlockContainer) [8,8 784x400] + PaintableWithLines (BlockContainer
.a) [8,8 784x200] + PaintableWithLines (BlockContainer
.b) [292,8 500x200] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer(anonymous)) [8,208 784x0] + PaintableWithLines (BlockContainer
.d) [8,208 500x200] + PaintableWithLines (BlockContainer(anonymous)) [8,408 784x0] diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-block.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-block.txt index a05bd3ab745..ba0a21eaab1 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-block.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-block.txt @@ -2,7 +2,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (0,0) content-size 800x157 [BFC] children: not-inline BlockContainer at (8,8) content-size 784x133 children: not-inline BlockContainer at (8,8) content-size 100x100 floating [BFC] children: not-inline - BlockContainer <(anonymous)> at (8,8) content-size 784x17 children: inline + BlockContainer <(anonymous)> at (8,8) content-size 784x100 children: inline TextNode <#text> BreakNode TextNode <#text> @@ -17,7 +17,7 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x157] PaintableWithLines (BlockContainer) [8,8 784x133] PaintableWithLines (BlockContainer
.a) [8,8 100x100] - PaintableWithLines (BlockContainer(anonymous)) [8,8 784x17] + PaintableWithLines (BlockContainer(anonymous)) [8,8 784x100] PaintableWithLines (BlockContainer

) [8,124 784x17] TextPaintable (TextNode<#text>) PaintableWithLines (BlockContainer(anonymous)) [8,157 784x0] diff --git a/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-at-end-of-block.html b/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-at-end-of-block.html new file mode 100644 index 00000000000..c1d67c38691 --- /dev/null +++ b/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-at-end-of-block.html @@ -0,0 +1,26 @@ + + +

+
+ foo +
+
+
diff --git a/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-block.html b/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-block.html index b14b79a9186..a96d489b3b0 100644 --- a/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-block.html +++ b/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-block.html @@ -1,14 +1,14 @@