From b5faeb7840927f55ccb1395ca1fc07456f804eba Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 10 Apr 2022 20:16:47 +0200 Subject: [PATCH] LibWeb: Resolve SVG "scaled viewport size" without triggering layout Percentage stroke widths are resolved against the scaled viewport size which we were retrieving by calling client_width() and client_height() on the element. Now that those accessors may trigger layout, this means that we can't use them from the stroke_width() getter, which is itself used *from within* layout. --- Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp index 9d62b0759c4..1de18fc444a 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp @@ -6,7 +6,9 @@ */ #include +#include #include +#include namespace Web::SVG { @@ -64,7 +66,15 @@ Optional SVGGraphicsElement::stroke_width() const if (auto width = layout_node()->computed_values().stroke_width(); width.has_value()) { // Resolved relative to the "Scaled viewport size": https://www.w3.org/TR/2017/WD-fill-stroke-3-20170413/#scaled-viewport-size // FIXME: This isn't right, but it's something. - auto scaled_viewport_size = CSS::Length::make_px((client_width() + client_height()) * 0.5f); + float viewport_width = 0; + float viewport_height = 0; + if (auto* svg_svg_element = first_ancestor_of_type()) { + if (auto* svg_svg_layout_node = svg_svg_element->layout_node()) { + viewport_width = svg_svg_layout_node->computed_values().width().value().resolved(*svg_svg_layout_node, { 0, CSS::Length::Type::Px }).to_px(*svg_svg_layout_node); + viewport_height = svg_svg_layout_node->computed_values().height().value().resolved(*svg_svg_layout_node, { 0, CSS::Length::Type::Px }).to_px(*svg_svg_layout_node); + } + } + auto scaled_viewport_size = CSS::Length::make_px((viewport_width + viewport_height) * 0.5f); return width->resolved(*layout_node(), scaled_viewport_size).to_px(*layout_node()); } return {};