diff --git a/Libraries/LibWeb/CSS/Length.h b/Libraries/LibWeb/CSS/Length.h index ab93b8658a5..991ff9acda4 100644 --- a/Libraries/LibWeb/CSS/Length.h +++ b/Libraries/LibWeb/CSS/Length.h @@ -79,6 +79,8 @@ public: CSSPixels cap_height; CSSPixels zero_advance; CSSPixels line_height; + + bool operator==(FontMetrics const&) const = default; }; static Optional unit_from_name(StringView); @@ -159,12 +161,14 @@ public: StringView unit_name() const; struct ResolutionContext { - [[nodiscard]] static Length::ResolutionContext for_window(HTML::Window const&); - [[nodiscard]] static Length::ResolutionContext for_layout_node(Layout::Node const&); + [[nodiscard]] static ResolutionContext for_window(HTML::Window const&); + [[nodiscard]] static ResolutionContext for_layout_node(Layout::Node const&); CSSPixelRect viewport_rect; FontMetrics font_metrics; FontMetrics root_font_metrics; + + bool operator==(ResolutionContext const&) const = default; }; [[nodiscard]] CSSPixels to_px(ResolutionContext const&) const; diff --git a/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp index 79de2c24c8e..cbd085b62c4 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause @@ -38,8 +38,14 @@ String ConicGradientStyleValue::to_string(SerializationMode mode) const void ConicGradientStyleValue::resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const& node, CSSPixelSize size) const { - if (!m_resolved.has_value()) + ResolvedDataCacheKey cache_key { + .length_resolution_context = Length::ResolutionContext::for_layout_node(node), + .size = size, + }; + if (m_resolved_data_cache_key != cache_key) { + m_resolved_data_cache_key = move(cache_key); m_resolved = ResolvedData { Painting::resolve_conic_gradient_data(node, *this), {} }; + } m_resolved->position = m_properties.position->resolved(node, CSSPixelRect { { 0, 0 }, size }); } diff --git a/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h index b3e969f84c7..2604a0ac37a 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/ConicGradientStyleValue.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause @@ -60,11 +60,17 @@ private: bool operator==(Properties const&) const = default; } m_properties; + struct ResolvedDataCacheKey { + Length::ResolutionContext length_resolution_context; + CSSPixelSize size; + bool operator==(ResolvedDataCacheKey const&) const = default; + }; + mutable Optional m_resolved_data_cache_key; + struct ResolvedData { Painting::ConicGradientData data; CSSPixelPoint position; }; - mutable Optional m_resolved; }; diff --git a/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.cpp index 2092d886a52..681ad7bb050 100644 --- a/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.cpp @@ -1,13 +1,14 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause */ #include "LinearGradientStyleValue.h" +#include #include namespace Web::CSS { @@ -105,15 +106,20 @@ float LinearGradientStyleValue::angle_degrees(CSSPixelSize gradient_size) const void LinearGradientStyleValue::resolve_for_size(Layout::NodeWithStyleAndBoxModelMetrics const& node, CSSPixelSize size) const { - if (m_resolved.has_value() && m_resolved->size == size) - return; - m_resolved = ResolvedData { Painting::resolve_linear_gradient_data(node, size, *this), size }; + ResolvedDataCacheKey cache_key { + .length_resolution_context = Length::ResolutionContext::for_layout_node(node), + .size = size, + }; + if (m_resolved_data_cache_key != cache_key) { + m_resolved_data_cache_key = move(cache_key); + m_resolved = Painting::resolve_linear_gradient_data(node, size, *this); + } } void LinearGradientStyleValue::paint(PaintContext& context, DevicePixelRect const& dest_rect, CSS::ImageRendering) const { VERIFY(m_resolved.has_value()); - context.display_list_recorder().fill_rect_with_linear_gradient(dest_rect.to_type(), m_resolved->data); + context.display_list_recorder().fill_rect_with_linear_gradient(dest_rect.to_type(), m_resolved.value()); } } diff --git a/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.h index 3bd68fd2142..97911cf472d 100644 --- a/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/LinearGradientStyleValue.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause @@ -77,12 +77,13 @@ private: bool operator==(Properties const&) const = default; } m_properties; - struct ResolvedData { - Painting::LinearGradientData data; + struct ResolvedDataCacheKey { + Length::ResolutionContext length_resolution_context; CSSPixelSize size; + bool operator==(ResolvedDataCacheKey const&) const = default; }; - - mutable Optional m_resolved; + mutable Optional m_resolved_data_cache_key; + mutable Optional m_resolved; }; } diff --git a/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp index 4a32d2797e3..8616eeb59e7 100644 --- a/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause @@ -206,13 +206,19 @@ void RadialGradientStyleValue::resolve_for_size(Layout::NodeWithStyleAndBoxModel CSSPixelRect gradient_box { { 0, 0 }, paint_size }; auto center = m_properties.position->resolved(node, gradient_box); auto gradient_size = resolve_size(node, center, gradient_box); - if (m_resolved.has_value() && m_resolved->gradient_size == gradient_size) - return; - m_resolved = ResolvedData { - Painting::resolve_radial_gradient_data(node, gradient_size, *this), - gradient_size, - center, + + ResolvedDataCacheKey cache_key { + .length_resolution_context = Length::ResolutionContext::for_layout_node(node), + .size = paint_size, }; + if (m_resolved_data_cache_key != cache_key) { + m_resolved_data_cache_key = move(cache_key); + m_resolved = ResolvedData { + Painting::resolve_radial_gradient_data(node, gradient_size, *this), + gradient_size, + center, + }; + } } bool RadialGradientStyleValue::equals(CSSStyleValue const& other) const diff --git a/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.h index 47a2fd3cffd..946e14b2bcd 100644 --- a/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/RadialGradientStyleValue.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2023, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause @@ -86,12 +86,18 @@ private: bool operator==(Properties const&) const = default; } m_properties; + struct ResolvedDataCacheKey { + Length::ResolutionContext length_resolution_context; + CSSPixelSize size; + bool operator==(ResolvedDataCacheKey const&) const = default; + }; + mutable Optional m_resolved_data_cache_key; + struct ResolvedData { Painting::RadialGradientData data; CSSPixelSize gradient_size; CSSPixelPoint center; }; - mutable Optional m_resolved; }; diff --git a/Tests/LibWeb/Ref/expected/css/gradient-em-positions-ref.html b/Tests/LibWeb/Ref/expected/css/gradient-em-positions-ref.html new file mode 100644 index 00000000000..12e0dd767cf --- /dev/null +++ b/Tests/LibWeb/Ref/expected/css/gradient-em-positions-ref.html @@ -0,0 +1,24 @@ + + +
+
+
+
\ No newline at end of file diff --git a/Tests/LibWeb/Ref/input/css/gradient-em-positions.html b/Tests/LibWeb/Ref/input/css/gradient-em-positions.html new file mode 100644 index 00000000000..a51f19dd794 --- /dev/null +++ b/Tests/LibWeb/Ref/input/css/gradient-em-positions.html @@ -0,0 +1,25 @@ + + + +
+
+
+
\ No newline at end of file