From 3b52b1139a99b687465fe525b71a9e2571bf4fdc Mon Sep 17 00:00:00 2001 From: Callum Law Date: Sat, 19 Jul 2025 16:00:37 +1200 Subject: [PATCH] LibWeb: Support relative lengths in `stop-color` calcs --- Libraries/LibWeb/CSS/ComputedProperties.cpp | 18 ------------------ Libraries/LibWeb/CSS/ComputedProperties.h | 1 - Libraries/LibWeb/Layout/Node.cpp | 5 +++-- Libraries/LibWeb/SVG/SVGStopElement.cpp | 6 +++--- Libraries/LibWeb/SVG/SVGStopElement.h | 2 +- .../expected/stop-color-non-trival-ref.html | 12 ++++++++++++ .../Ref/input/stop-color-non-trival.html | 13 +++++++++++++ 7 files changed, 32 insertions(+), 25 deletions(-) create mode 100644 Tests/LibWeb/Ref/expected/stop-color-non-trival-ref.html create mode 100644 Tests/LibWeb/Ref/input/stop-color-non-trival.html diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index 2a3b71b8607..fb351da93c9 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -1813,24 +1813,6 @@ MaskType ComputedProperties::mask_type() const return keyword_to_mask_type(value.to_keyword()).release_value(); } -Color ComputedProperties::stop_color() const -{ - NonnullRawPtr value = property(PropertyID::StopColor); - if (value->is_keyword()) { - // Workaround lack of layout node to resolve current color. - auto const& keyword = value->as_keyword(); - if (keyword.keyword() == Keyword::Currentcolor) - value = property(PropertyID::Color); - } - if (value->has_color()) { - // FIXME: This is used by the SVGStopElement, which does not participate in layout, so we can't pass a layout - // node or CalculationResolutionContext. This means we don't support all valid colors (e.g. palette - // colors, calculated values which depend on length resolution, etc) - return value->to_color({}).value_or(Color::Black); - } - return Color::Black; -} - void ComputedProperties::set_math_depth(int math_depth) { m_math_depth = math_depth; diff --git a/Libraries/LibWeb/CSS/ComputedProperties.h b/Libraries/LibWeb/CSS/ComputedProperties.h index 3fb47f3e35f..8e9c5168b48 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.h +++ b/Libraries/LibWeb/CSS/ComputedProperties.h @@ -185,7 +185,6 @@ public: Optional scale() const; MaskType mask_type() const; - Color stop_color() const; float stop_opacity() const; float fill_opacity() const; StrokeLinecap stroke_linecap() const; diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 97622bc4987..f24ba87906e 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -881,8 +881,9 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) computed_values.set_stroke(stroke.to_color(CSS::ColorResolutionContext::for_layout_node_with_style(*this)).value()); else if (stroke.is_url()) computed_values.set_stroke(stroke.as_url().url()); - if (auto const& stop_color = computed_style.property(CSS::PropertyID::StopColor); stop_color.has_color()) - computed_values.set_stop_color(stop_color.to_color(CSS::ColorResolutionContext::for_layout_node_with_style(*this)).value()); + + computed_values.set_stop_color(computed_style.color_or_fallback(CSS::PropertyID::StopColor, CSS::ColorResolutionContext::for_layout_node_with_style(*this), CSS::InitialValues::stop_color())); + auto const& stroke_width = computed_style.property(CSS::PropertyID::StrokeWidth); // FIXME: Converting to pixels isn't really correct - values should be in "user units" // https://svgwg.org/svg2-draft/coords.html#TermUserUnits diff --git a/Libraries/LibWeb/SVG/SVGStopElement.cpp b/Libraries/LibWeb/SVG/SVGStopElement.cpp index 82a37118b94..02f677db915 100644 --- a/Libraries/LibWeb/SVG/SVGStopElement.cpp +++ b/Libraries/LibWeb/SVG/SVGStopElement.cpp @@ -46,11 +46,11 @@ void SVGStopElement::apply_presentational_hints(GC::Ref }); } -Gfx::Color SVGStopElement::stop_color() const +Gfx::Color SVGStopElement::stop_color() { if (auto computed_properties = this->computed_properties()) - return computed_properties->stop_color(); - return Color::Black; + return computed_properties->color_or_fallback(CSS::PropertyID::StopColor, CSS::ColorResolutionContext::for_element({ *this }), CSS::InitialValues::stop_color()); + return CSS::InitialValues::stop_color(); } float SVGStopElement::stop_opacity() const diff --git a/Libraries/LibWeb/SVG/SVGStopElement.h b/Libraries/LibWeb/SVG/SVGStopElement.h index 6aa45453a31..de8241ada2e 100644 --- a/Libraries/LibWeb/SVG/SVGStopElement.h +++ b/Libraries/LibWeb/SVG/SVGStopElement.h @@ -27,7 +27,7 @@ public: virtual void apply_presentational_hints(GC::Ref) const override; float stop_offset() { return offset()->base_val(); } - Gfx::Color stop_color() const; + Gfx::Color stop_color(); float stop_opacity() const; private: diff --git a/Tests/LibWeb/Ref/expected/stop-color-non-trival-ref.html b/Tests/LibWeb/Ref/expected/stop-color-non-trival-ref.html new file mode 100644 index 00000000000..04c582f31e8 --- /dev/null +++ b/Tests/LibWeb/Ref/expected/stop-color-non-trival-ref.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Tests/LibWeb/Ref/input/stop-color-non-trival.html b/Tests/LibWeb/Ref/input/stop-color-non-trival.html new file mode 100644 index 00000000000..d843ad1da43 --- /dev/null +++ b/Tests/LibWeb/Ref/input/stop-color-non-trival.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + +