LibWeb: Derive box baseline from last child *with line boxes*
Before this change, we always derived a box's baseline from its last child, even if the last child didn't have any line boxes inside. This caused baselines to slip further down vertically than expected. There are more baseline alignment issues to fix, but this one was responsible for a fair chunk of trouble. :^)
This commit is contained in:
parent
7b3902e3d5
commit
ccf35a973f
Notes:
sideshowbarker
2024-07-17 08:27:05 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/ccf35a973f Pull-request: https://github.com/SerenityOS/serenity/pull/20189 Reviewed-by: https://github.com/linusg ✅
7 changed files with 107 additions and 8 deletions
|
@ -0,0 +1,22 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (1,1) content-size 798x600 [BFC] children: not-inline
|
||||
BlockContainer <body> 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 <div.ib> at (114.140625,11) content-size 202x90.9375 inline-block [BFC] children: not-inline
|
||||
BlockContainer <div> 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 <div> 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 <div.whee> 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>
|
|
@ -0,0 +1,26 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (1,1) content-size 798x600 [BFC] children: not-inline
|
||||
BlockContainer <body> 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 <div.ib> at (114.140625,11) content-size 39.234375x58.40625 inline-block [BFC] children: not-inline
|
||||
BlockContainer <div> 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 <div> 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 <div.float> 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>
|
|
@ -1,12 +1,12 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> 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 <body> at (2,15.53125) content-size 168.96875x119.46875 inline-block [BFC] children: not-inline
|
||||
BlockContainer <div.hmm> at (3,16.53125) content-size 166.96875x17.46875 children: inline
|
||||
BlockContainer <html> 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 <body> at (2,2) content-size 168.96875x119.46875 inline-block [BFC] children: not-inline
|
||||
BlockContainer <div.hmm> 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>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<style>
|
||||
* {
|
||||
border: 1px solid black;
|
||||
}
|
||||
.ib {
|
||||
display: inline-block;
|
||||
}
|
||||
.ib div {
|
||||
background: pink;
|
||||
}
|
||||
.ib div.whee {
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
background: orange;
|
||||
}
|
||||
</style><body>Hello friends<div class=ib><div>1st</div><div>2nd</div><div class="whee"></div>
|
|
@ -0,0 +1,15 @@
|
|||
<style>
|
||||
* {
|
||||
border: 1px solid black;
|
||||
}
|
||||
.ib {
|
||||
display: inline-block;
|
||||
}
|
||||
.ib div {
|
||||
background: pink;
|
||||
}
|
||||
.ib div.float {
|
||||
background: orange;
|
||||
float: left;
|
||||
}
|
||||
</style><body>Hello friends<div class=ib><div>1st</div><div>2nd</div><div class="float">float</div>
|
|
@ -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<Box>();
|
||||
for (Node const* child = last_box_child; child; child = child->previous_sibling()) {
|
||||
if (!child->is_box())
|
||||
continue;
|
||||
auto& child_box = static_cast<Box const&>(*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<Box>();
|
||||
auto const* child_box = box_child_to_derive_baseline_from(box);
|
||||
VERIFY(child_box);
|
||||
return box_baseline(*child_box);
|
||||
}
|
||||
|
|
|
@ -151,6 +151,8 @@ protected:
|
|||
|
||||
[[nodiscard]] Optional<CSSPixels> 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 };
|
||||
|
|
Loading…
Add table
Reference in a new issue