From b85a8a23a704c61326381afbb93a0903bf505dff Mon Sep 17 00:00:00 2001 From: Gingeh <39150378+Gingeh@users.noreply.github.com> Date: Tue, 24 Jun 2025 16:03:27 +1000 Subject: [PATCH] LibWeb: Handle percentage font-size values --- Libraries/LibWeb/CSS/ComputedProperties.h | 3 + Libraries/LibWeb/CSS/StyleComputer.cpp | 11 +++- Libraries/LibWeb/Layout/Node.cpp | 2 +- .../Layout/expected/percentage-font-size.txt | 55 +++++++++++++++++++ .../Layout/input/percentage-font-size.html | 8 +++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/percentage-font-size.txt create mode 100644 Tests/LibWeb/Layout/input/percentage-font-size.html diff --git a/Libraries/LibWeb/CSS/ComputedProperties.h b/Libraries/LibWeb/CSS/ComputedProperties.h index e3f03c2e12b..a692755af74 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.h +++ b/Libraries/LibWeb/CSS/ComputedProperties.h @@ -218,6 +218,8 @@ public: [[nodiscard]] CSSPixels line_height() const { return *m_line_height; } void set_line_height(Badge const&, CSSPixels line_height) { m_line_height = line_height; } + [[nodiscard]] CSSPixels font_size() const { return *m_font_size; } + void set_font_size(Badge const&, CSSPixels font_size) { m_font_size = font_size; } bool operator==(ComputedProperties const&) const; @@ -271,6 +273,7 @@ private: RefPtr m_first_available_computed_font; Optional m_line_height; + Optional m_font_size; PseudoClassBitmap m_attempted_pseudo_class_matches; }; diff --git a/Libraries/LibWeb/CSS/StyleComputer.cpp b/Libraries/LibWeb/CSS/StyleComputer.cpp index e20e3f3e6b7..b92a7a9f7ed 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -2492,8 +2492,17 @@ void StyleComputer::absolutize_values(ComputedProperties& style, GC::Ptris_percentage()) { + auto parent_font_size = get_inherit_value(CSS::PropertyID::FontSize, element)->as_length().length().to_px(viewport_rect(), font_metrics, m_root_element_font_metrics); + font_size_value_slot = LengthStyleValue::create( + Length::make_px(CSSPixels::nearest_value_for(parent_font_size * font_size_value_slot->as_percentage().percentage().as_fraction()))); + } + + auto font_size = font_size_value_slot->as_length().length().to_px(viewport_rect(), font_metrics, m_root_element_font_metrics); font_metrics.font_size = font_size; + style.set_font_size({}, font_size); // NOTE: Percentage line-height values are relative to the font-size of the element. // We have to resolve them right away, so that the *computed* line-height is ready for inheritance. diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index e4c1f0f0eaa..48c7ef3cb29 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -385,7 +385,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) // m_font is used by Length::to_px() when resolving sizes against this layout node. // That's why it has to be set before everything else. computed_values.set_font_list(computed_style.computed_font_list()); - computed_values.set_font_size(computed_style.property(CSS::PropertyID::FontSize).as_length().length().to_px(*this)); + computed_values.set_font_size(computed_style.font_size()); computed_values.set_font_weight(round_to(computed_style.property(CSS::PropertyID::FontWeight).as_number().number())); computed_values.set_font_kerning(computed_style.font_kerning()); computed_values.set_line_height(computed_style.line_height()); diff --git a/Tests/LibWeb/Layout/expected/percentage-font-size.txt b/Tests/LibWeb/Layout/expected/percentage-font-size.txt new file mode 100644 index 00000000000..e9ad87191ef --- /dev/null +++ b/Tests/LibWeb/Layout/expected/percentage-font-size.txt @@ -0,0 +1,55 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x98 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x82 children: not-inline + BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline + TextNode <#text> + BlockContainer
at (8,8) content-size 784x18 children: inline + frag 0 from TextNode start: 0, length: 1, rect: [8,8 11.5625x18] baseline: 13.796875 + "X" + TextNode <#text> + BlockContainer <(anonymous)> at (8,26) content-size 784x0 children: inline + TextNode <#text> + BlockContainer
at (8,26) content-size 784x0 children: inline + frag 0 from TextNode start: 0, length: 1, rect: [8,26 0x0] baseline: 0.296875 + "X" + TextNode <#text> + BlockContainer <(anonymous)> at (8,26) content-size 784x0 children: inline + TextNode <#text> + BlockContainer
at (8,26) content-size 784x9 children: inline + frag 0 from TextNode start: 0, length: 1, rect: [8,26 5.78125x9] baseline: 6.90625 + "X" + TextNode <#text> + BlockContainer <(anonymous)> at (8,35) content-size 784x0 children: inline + TextNode <#text> + BlockContainer
at (8,35) content-size 784x18 children: inline + frag 0 from TextNode start: 0, length: 1, rect: [8,35 11.5625x18] baseline: 13.796875 + "X" + TextNode <#text> + BlockContainer <(anonymous)> at (8,53) content-size 784x0 children: inline + TextNode <#text> + BlockContainer
at (8,53) content-size 784x37 children: inline + frag 0 from TextNode start: 0, length: 1, rect: [8,53 23.125x37] baseline: 28.09375 + "X" + TextNode <#text> + BlockContainer <(anonymous)> at (8,90) content-size 784x0 children: inline + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x98] + PaintableWithLines (BlockContainer) [8,8 784x82] + PaintableWithLines (BlockContainer(anonymous)) [8,8 784x0] + PaintableWithLines (BlockContainer
) [8,8 784x18] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer(anonymous)) [8,26 784x0] + PaintableWithLines (BlockContainer
) [8,26 784x0] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer(anonymous)) [8,26 784x0] + PaintableWithLines (BlockContainer
) [8,26 784x9] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer(anonymous)) [8,35 784x0] + PaintableWithLines (BlockContainer
) [8,35 784x18] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer(anonymous)) [8,53 784x0] + PaintableWithLines (BlockContainer
) [8,53 784x37] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer(anonymous)) [8,90 784x0] diff --git a/Tests/LibWeb/Layout/input/percentage-font-size.html b/Tests/LibWeb/Layout/input/percentage-font-size.html new file mode 100644 index 00000000000..3fda3d4e3da --- /dev/null +++ b/Tests/LibWeb/Layout/input/percentage-font-size.html @@ -0,0 +1,8 @@ + + +
X
+
X
+
X
+
X
+
X
+