diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/inline-block-baseline-1.txt b/Tests/LibWeb/Layout/expected/block-and-inline/inline-block-baseline-1.txt new file mode 100644 index 0000000000..ce7e4680cc --- /dev/null +++ b/Tests/LibWeb/Layout/expected/block-and-inline/inline-block-baseline-1.txt @@ -0,0 +1,22 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (1,1) content-size 798x600 [BFC] children: not-inline + BlockContainer at (10,10) content-size 780x92.9375 children: inline + line 0 width: 307.140625, height: 92.9375, bottom: 92.9375, baseline: 35 + frag 0 from TextNode start: 0, length: 13, rect: [10,31.46875 103.140625x17.46875] + "Hello friends" + frag 1 from BlockContainer start: 0, length: 0, rect: [114.140625,11 202x90.9375] + TextNode <#text> + BlockContainer at (114.140625,11) content-size 202x90.9375 inline-block [BFC] children: not-inline + BlockContainer
at (115.140625,12) content-size 200x17.46875 children: inline + line 0 width: 22.546875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 3, rect: [115.140625,12 22.546875x17.46875] + "1st" + TextNode <#text> + BlockContainer
at (115.140625,31.46875) content-size 200x17.46875 children: inline + line 0 width: 26.28125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 3, rect: [115.140625,31.46875 26.28125x17.46875] + "2nd" + TextNode <#text> + BlockContainer at (115.140625,50.9375) content-size 200x50 children: not-inline + BlockContainer <(anonymous)> at (114.140625,101.9375) content-size 202x0 children: inline + TextNode <#text> diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/inline-block-baseline-2.txt b/Tests/LibWeb/Layout/expected/block-and-inline/inline-block-baseline-2.txt new file mode 100644 index 0000000000..d9722abe9c --- /dev/null +++ b/Tests/LibWeb/Layout/expected/block-and-inline/inline-block-baseline-2.txt @@ -0,0 +1,26 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (1,1) content-size 798x600 [BFC] children: not-inline + BlockContainer at (10,10) content-size 780x60.40625 children: inline + line 0 width: 144.375, height: 60.40625, bottom: 60.40625, baseline: 35 + frag 0 from TextNode start: 0, length: 13, rect: [10,31.46875 103.140625x17.46875] + "Hello friends" + frag 1 from BlockContainer start: 0, length: 0, rect: [114.140625,11 39.234375x58.40625] + TextNode <#text> + BlockContainer at (114.140625,11) content-size 39.234375x58.40625 inline-block [BFC] children: not-inline + BlockContainer
at (115.140625,12) content-size 37.234375x17.46875 children: inline + line 0 width: 22.546875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 3, rect: [115.140625,12 22.546875x17.46875] + "1st" + TextNode <#text> + BlockContainer
at (115.140625,31.46875) content-size 37.234375x17.46875 children: inline + line 0 width: 26.28125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 3, rect: [115.140625,31.46875 26.28125x17.46875] + "2nd" + TextNode <#text> + BlockContainer at (115.140625,50.9375) content-size 37.234375x17.46875 floating [BFC] children: inline + line 0 width: 37.234375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 5, rect: [115.140625,50.9375 37.234375x17.46875] + "float" + TextNode <#text> + BlockContainer <(anonymous)> at (114.140625,49.9375) content-size 39.234375x0 children: inline + TextNode <#text> diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/margin-collapse-5.txt b/Tests/LibWeb/Layout/expected/block-and-inline/margin-collapse-5.txt index e23782854e..d0e188aade 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/margin-collapse-5.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/margin-collapse-5.txt @@ -1,12 +1,12 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline - BlockContainer at (1,1) content-size 798x135 [BFC] children: inline - line 0 width: 170.96875, height: 135, bottom: 135, baseline: 13.53125 - frag 0 from BlockContainer start: 0, length: 0, rect: [2,15.53125 168.96875x119.46875] - BlockContainer at (2,15.53125) content-size 168.96875x119.46875 inline-block [BFC] children: not-inline - BlockContainer at (3,16.53125) content-size 166.96875x17.46875 children: inline + BlockContainer at (1,1) content-size 798x121.46875 [BFC] children: inline + line 0 width: 170.96875, height: 121.46875, bottom: 121.46875, baseline: 15.53125 + frag 0 from BlockContainer start: 0, length: 0, rect: [2,2 168.96875x119.46875] + BlockContainer at (2,2) content-size 168.96875x119.46875 inline-block [BFC] children: not-inline + BlockContainer at (3,3) content-size 166.96875x17.46875 children: inline line 0 width: 166.96875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 21, rect: [3,16.53125 166.96875x17.46875] + frag 0 from TextNode start: 0, length: 21, rect: [3,3 166.96875x17.46875] "suspiciously tall box" TextNode <#text> - BlockContainer <(anonymous)> at (2,135) content-size 168.96875x0 children: inline + BlockContainer <(anonymous)> at (2,121.46875) content-size 168.96875x0 children: inline TextNode <#text> diff --git a/Tests/LibWeb/Layout/input/block-and-inline/inline-block-baseline-1.html b/Tests/LibWeb/Layout/input/block-and-inline/inline-block-baseline-1.html new file mode 100644 index 0000000000..d91e0117ba --- /dev/null +++ b/Tests/LibWeb/Layout/input/block-and-inline/inline-block-baseline-1.html @@ -0,0 +1,16 @@ +Hello friends
1st
2nd
diff --git a/Tests/LibWeb/Layout/input/block-and-inline/inline-block-baseline-2.html b/Tests/LibWeb/Layout/input/block-and-inline/inline-block-baseline-2.html new file mode 100644 index 0000000000..49a21a02c8 --- /dev/null +++ b/Tests/LibWeb/Layout/input/block-and-inline/inline-block-baseline-2.html @@ -0,0 +1,15 @@ +Hello friends
1st
2nd
float
diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 283bd954a4..fce3be6a4e 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -1686,6 +1686,24 @@ CSSPixelRect FormattingContext::absolute_content_rect(Box const& box) const return rect; } +Box const* FormattingContext::box_child_to_derive_baseline_from(Box const& box) const +{ + // To find the baseline of a box, we first look for the last in-flow child with at least one line box. + auto const* last_box_child = box.last_child_of_type(); + for (Node const* child = last_box_child; child; child = child->previous_sibling()) { + if (!child->is_box()) + continue; + auto& child_box = static_cast(*child); + if (child_box.is_out_of_flow(*this)) + continue; + if (m_state.get(child_box).line_boxes.is_empty()) + continue; + return &child_box; + } + // If none of the children has a line box, the baseline is formed by the last in-flow child. + return last_box_child; +} + CSSPixels FormattingContext::box_baseline(Box const& box) const { auto const& box_state = m_state.get(box); @@ -1714,7 +1732,7 @@ CSSPixels FormattingContext::box_baseline(Box const& box) const if (!box_state.line_boxes.is_empty()) return box_state.margin_box_top() + box_state.offset.y() + box_state.line_boxes.last().baseline(); if (box.has_children() && !box.children_are_inline()) { - auto const* child_box = box.last_child_of_type(); + auto const* child_box = box_child_to_derive_baseline_from(box); VERIFY(child_box); return box_baseline(*child_box); } diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.h b/Userland/Libraries/LibWeb/Layout/FormattingContext.h index 12d626cc3e..d628027921 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.h @@ -151,6 +151,8 @@ protected: [[nodiscard]] Optional compute_auto_height_for_absolutely_positioned_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout) const; + [[nodiscard]] Box const* box_child_to_derive_baseline_from(Box const&) const; + Type m_type {}; FormattingContext* m_parent { nullptr };