LibWeb: Resolve percentage vertical-align values against line-height

...instead of not resolving them at all. :^)
This commit is contained in:
Andreas Kling 2023-03-29 13:04:51 +02:00
parent 7447a91d7e
commit e4b71495f5
Notes: sideshowbarker 2024-07-18 04:46:35 +09:00
3 changed files with 44 additions and 7 deletions

View file

@ -0,0 +1,10 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (1,1) content-size 798x62.506248 children: not-inline
BlockContainer <body> at (2,2) content-size 796x60.506248 children: inline
line 0 width: 34, height: 28.50625, bottom: 28.50625, baseline: 28.50625
frag 0 from BlockContainer start: 0, length: 0, rect: [4,3 30x30]
line 1 width: 32, height: 28.506248, bottom: 60.506248, baseline: 28.50625
frag 0 from BlockContainer start: 0, length: 0, rect: [3,35 30x30]
BlockContainer <div.clump> at (4,3) content-size 30x30 inline-block children: not-inline
BreakNode <br>
BlockContainer <div.clump> at (3,35) content-size 30x30 inline-block children: not-inline

View file

@ -0,0 +1,14 @@
<!DOCTYPE html><html><head><style>
* {
border: 1px solid black;
margin: 0;
padding: 0;
font: 16px SerenitySans;
}
.clump {
display: inline-block;
vertical-align: -20%;
width: 30px;
height: 30px;
}
</style></head><body><div class="clump"></div><br><div class="clump"></div>

View file

@ -216,8 +216,12 @@ void LineBuilder::update_last_line()
// NOTE: For fragments with a <length> vertical-align, shift the line box baseline down by the length.
// This ensures that we make enough vertical space on the line for any manually-aligned fragments.
if (auto length_percentage = fragment.layout_node().computed_values().vertical_align().template get_pointer<CSS::LengthPercentage>(); length_percentage && length_percentage->is_length())
fragment_baseline += length_percentage->length().to_px(fragment.layout_node());
if (auto const* length_percentage = fragment.layout_node().computed_values().vertical_align().get_pointer<CSS::LengthPercentage>()) {
if (length_percentage->is_length())
fragment_baseline += length_percentage->length().to_px(fragment.layout_node());
else if (length_percentage->is_percentage())
fragment_baseline += length_percentage->percentage().as_fraction() * line_height;
}
line_box_baseline = max(line_box_baseline, fragment_baseline);
}
@ -265,9 +269,14 @@ void LineBuilder::update_last_line()
if (vertical_align.has<CSS::VerticalAlign>()) {
new_fragment_y = y_value_for_alignment(vertical_align.get<CSS::VerticalAlign>());
} else {
if (auto length_percentage = vertical_align.get_pointer<CSS::LengthPercentage>(); length_percentage && length_percentage->is_length()) {
auto vertical_align_amount = length_percentage->length().to_px(fragment.layout_node());
new_fragment_y = y_value_for_alignment(CSS::VerticalAlign::Baseline) - vertical_align_amount;
if (auto const* length_percentage = vertical_align.get_pointer<CSS::LengthPercentage>()) {
if (length_percentage->is_length()) {
auto vertical_align_amount = length_percentage->length().to_px(fragment.layout_node());
new_fragment_y = y_value_for_alignment(CSS::VerticalAlign::Baseline) - vertical_align_amount;
} else if (length_percentage->is_percentage()) {
auto vertical_align_amount = length_percentage->percentage().as_fraction() * m_context.containing_block().line_height();
new_fragment_y = y_value_for_alignment(CSS::VerticalAlign::Baseline) - vertical_align_amount;
}
}
}
@ -289,8 +298,12 @@ void LineBuilder::update_last_line()
top_of_inline_box = (fragment.offset().y() + fragment.baseline() - font_metrics.ascent - half_leading);
bottom_of_inline_box = (fragment.offset().y() + fragment.baseline() + font_metrics.descent + half_leading);
}
if (auto length_percentage = fragment.layout_node().computed_values().vertical_align().template get_pointer<CSS::LengthPercentage>(); length_percentage && length_percentage->is_length())
bottom_of_inline_box += length_percentage->length().to_px(fragment.layout_node());
if (auto const* length_percentage = fragment.layout_node().computed_values().vertical_align().get_pointer<CSS::LengthPercentage>()) {
if (length_percentage->is_length())
bottom_of_inline_box += length_percentage->length().to_px(fragment.layout_node());
else if (length_percentage->is_percentage())
bottom_of_inline_box += length_percentage->percentage().as_fraction() * m_context.containing_block().line_height();
}
}
uppermost_box_top = min(uppermost_box_top, top_of_inline_box);