diff options
author | Andreas Kling <kling@serenityos.org> | 2022-04-10 20:16:47 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-04-10 20:18:38 +0200 |
commit | b5faeb7840927f55ccb1395ca1fc07456f804eba (patch) | |
tree | 0c06fe8473f77a85ba526e1d02b3cfceeea51ee2 | |
parent | 5e35167e05c6e92073aef4223bffc6130519dc43 (diff) | |
download | serenity-b5faeb7840927f55ccb1395ca1fc07456f804eba.zip |
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.
-rw-r--r-- | Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp index 9d62b0759c..1de18fc444 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp @@ -6,7 +6,9 @@ */ #include <LibWeb/CSS/Parser/Parser.h> +#include <LibWeb/Layout/Node.h> #include <LibWeb/SVG/SVGGraphicsElement.h> +#include <LibWeb/SVG/SVGSVGElement.h> namespace Web::SVG { @@ -64,7 +66,15 @@ Optional<float> 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<SVGSVGElement>()) { + 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 {}; |