From 099247d502e733c606ddae996db08ea0296c20e8 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Tue, 9 Sep 2025 09:56:53 +0100 Subject: [PATCH] LibWeb: Return `letter-spacing` computed value as CSSPixels --- Libraries/LibWeb/CSS/ComputedProperties.cpp | 20 ++++++++++--------- Libraries/LibWeb/CSS/ComputedProperties.h | 2 +- Libraries/LibWeb/CSS/ComputedValues.h | 8 ++++---- .../LibWeb/Layout/InlineLevelIterator.cpp | 2 +- Libraries/LibWeb/Layout/Node.cpp | 4 +--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index 7fcc75d3825..5aa2914eb0a 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -946,20 +946,22 @@ WhiteSpaceTrimData ComputedProperties::white_space_trim() const VERIFY_NOT_REACHED(); } -Optional ComputedProperties::letter_spacing() const +CSSPixels ComputedProperties::letter_spacing() const { auto const& value = property(PropertyID::LetterSpacing); - if (value.is_calculated()) { - auto const& math_value = value.as_calculated(); - if (math_value.resolves_to_length()) { - return LengthOrCalculated { math_value }; - } - } + if (value.is_keyword() && value.to_keyword() == Keyword::Normal) + return 0; if (value.is_length()) - return LengthOrCalculated { value.as_length().length() }; + return value.as_length().length().absolute_length_to_px(); - return {}; + if (value.is_percentage()) + return font_size().scale_by(value.as_percentage().percentage().as_fraction()); + + if (value.is_calculated()) + return value.as_calculated().resolve_length({ .percentage_basis = Length::make_px(font_size()), .length_resolution_context = {} })->absolute_length_to_px(); + + VERIFY_NOT_REACHED(); } LineStyle ComputedProperties::line_style(PropertyID property_id) const diff --git a/Libraries/LibWeb/CSS/ComputedProperties.h b/Libraries/LibWeb/CSS/ComputedProperties.h index cd7d733dd87..c04e050846d 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.h +++ b/Libraries/LibWeb/CSS/ComputedProperties.h @@ -112,7 +112,7 @@ public: WhiteSpaceTrimData white_space_trim() const; WordBreak word_break() const; Optional word_spacing() const; - Optional letter_spacing() const; + CSSPixels letter_spacing() const; LineStyle line_style(PropertyID) const; OutlineStyle outline_style() const; Vector text_decoration_line() const; diff --git a/Libraries/LibWeb/CSS/ComputedValues.h b/Libraries/LibWeb/CSS/ComputedValues.h index 3ea013cb9db..06cd4348184 100644 --- a/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Libraries/LibWeb/CSS/ComputedValues.h @@ -140,7 +140,7 @@ public: static CSS::WhiteSpaceCollapse white_space_collapse() { return CSS::WhiteSpaceCollapse::Collapse; } static CSS::WordBreak word_break() { return CSS::WordBreak::Normal; } static LengthPercentage word_spacing() { return CSS::Length::make_px(0); } - static LengthOrCalculated letter_spacing() { return CSS::Length::make_px(0); } + static CSSPixels letter_spacing() { return 0; } static Variant tab_size() { return NumberOrCalculated(8.0f); } static CSS::TextAlign text_align() { return CSS::TextAlign::Start; } static CSS::TextJustify text_justify() { return CSS::TextJustify::Auto; } @@ -492,7 +492,7 @@ public: CSS::WhiteSpaceCollapse white_space_collapse() const { return m_inherited.white_space_collapse; } WhiteSpaceTrimData white_space_trim() const { return m_noninherited.white_space_trim; } LengthPercentage const& word_spacing() const { return m_inherited.word_spacing; } - LengthOrCalculated letter_spacing() const { return m_inherited.letter_spacing; } + CSSPixels letter_spacing() const { return m_inherited.letter_spacing; } CSS::FlexDirection flex_direction() const { return m_noninherited.flex_direction; } CSS::FlexWrap flex_wrap() const { return m_noninherited.flex_wrap; } FlexBasis const& flex_basis() const { return m_noninherited.flex_basis; } @@ -701,7 +701,7 @@ protected: CSS::WhiteSpaceCollapse white_space_collapse { InitialValues::white_space_collapse() }; CSS::WordBreak word_break { InitialValues::word_break() }; LengthPercentage word_spacing { InitialValues::word_spacing() }; - LengthOrCalculated letter_spacing { InitialValues::letter_spacing() }; + CSSPixels letter_spacing { InitialValues::letter_spacing() }; CSS::ListStyleType list_style_type { InitialValues::list_style_type() }; CSS::ListStylePosition list_style_position { InitialValues::list_style_position() }; CSS::Visibility visibility { InitialValues::visibility() }; @@ -921,7 +921,7 @@ public: void set_white_space_trim(WhiteSpaceTrimData value) { m_noninherited.white_space_trim = value; } void set_word_spacing(CSS::LengthPercentage value) { m_inherited.word_spacing = move(value); } void set_word_break(CSS::WordBreak value) { m_inherited.word_break = value; } - void set_letter_spacing(CSS::LengthOrCalculated value) { m_inherited.letter_spacing = value; } + void set_letter_spacing(CSSPixels value) { m_inherited.letter_spacing = value; } void set_width(CSS::Size const& width) { m_noninherited.width = width; } void set_min_width(CSS::Size const& width) { m_noninherited.min_width = width; } void set_max_width(CSS::Size const& width) { m_noninherited.max_width = width; } diff --git a/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Libraries/LibWeb/Layout/InlineLevelIterator.cpp index f4ee713664d..4dfadef96e0 100644 --- a/Libraries/LibWeb/Layout/InlineLevelIterator.cpp +++ b/Libraries/LibWeb/Layout/InlineLevelIterator.cpp @@ -527,7 +527,7 @@ Optional InlineLevelIterator::next_without_lookahead( } CSS::CalculationResolutionContext calculation_context { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(text_node) }; - auto letter_spacing = text_node.computed_values().letter_spacing().resolved(calculation_context).map([&](auto& it) { return it.to_px(text_node); }).value_or(0); + auto letter_spacing = text_node.computed_values().letter_spacing(); // FIXME: We should apply word spacing to all word-separator characters not just breaking tabs auto word_spacing = text_node.computed_values().word_spacing().resolved(text_node, CSS::Length::make_px(chunk.font->glyph_width(' ')).to_px(text_node)).absolute_length_to_px(); diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 5b31a73a172..9f4ea679a35 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -620,9 +620,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) if (auto word_spacing = computed_style.word_spacing(); word_spacing.has_value()) computed_values.set_word_spacing(word_spacing.value()); - auto letter_spacing = computed_style.letter_spacing(); - if (letter_spacing.has_value()) - computed_values.set_letter_spacing(letter_spacing.value()); + computed_values.set_letter_spacing(computed_style.letter_spacing()); computed_values.set_float(computed_style.float_());