diff --git a/Tests/LibWeb/Layout/expected/svg/svg-symbol-with-viewbox.txt b/Tests/LibWeb/Layout/expected/svg/svg-symbol-with-viewbox.txt new file mode 100644 index 0000000000000000000000000000000000000000..8e783f2eb7dc63ef218dfcb3cba20d3d05a3ba87 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/svg/svg-symbol-with-viewbox.txt @@ -0,0 +1,20 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x150 children: not-inline + BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline + TextNode <#text> + TextNode <#text> + BlockContainer
at (8,8) content-size 784x150 children: inline + line 0 width: 300, height: 150, bottom: 150, baseline: 150 + frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 300x150] + TextNode <#text> + SVGSVGBox at (8,8) content-size 300x150 [SVG] children: inline + TextNode <#text> + InlineNode + InlineNode + TextNode <#text> + SVGGeometryBox at (92.375,26.75) content-size 131.25x112.140625 children: inline + TextNode <#text> + TextNode <#text> + TextNode <#text> + TextNode <#text> diff --git a/Tests/LibWeb/Layout/input/svg/svg-symbol-with-viewbox.html b/Tests/LibWeb/Layout/input/svg/svg-symbol-with-viewbox.html new file mode 100644 index 0000000000000000000000000000000000000000..3c934502b930a0ec40426f2c3aba4b0e1f49cb9b --- /dev/null +++ b/Tests/LibWeb/Layout/input/svg/svg-symbol-with-viewbox.html @@ -0,0 +1,13 @@ + + + + + + + + +
+ + + diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp index a7d3013f17ff357f16ba4d2854725a48a7af4c14..b185dbb0ffe6e37d788e0f25699ea7479bd376bd 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp @@ -159,7 +159,7 @@ void SVGFormattingContext::run(Box const& box, LayoutMode layout_mode, Available auto path_transform = dom_node.get_transform(); double viewbox_scale = 1; - auto maybe_view_box = svg_svg_element.view_box(); + auto maybe_view_box = dom_node.view_box(); if (maybe_view_box.has_value()) { // FIXME: This should allow just one of width or height to be specified. // E.g. We should be able to layout where height is unspecified/auto. diff --git a/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp b/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp index 83744c80a80593b9da280cc363d5dc3e207c8024..ccf7caacd4a4662ebabba7945c338d28f6847e01 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp @@ -33,7 +33,7 @@ Optional SVGGeometryBox::layout_transform() const double scaling = 1; auto origin = viewbox_origin().to_type().to_type(); Gfx::FloatPoint paint_offset = {}; - if (svg_box && svg_box->view_box().has_value()) { + if (svg_box && geometry_element.view_box().has_value()) { // Note: SVGFormattingContext has already done the scaling based on the viewbox, // we now have to derive what it was from the original bounding box size. // FIXME: It would be nice if we could store the transform from layout somewhere, so we don't have to solve for it here. diff --git a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp index 77bf7a1e637a14e38ce6f216a322c0ac35fa2a8f..5835e5ab98357a7509979c8c43267c7549a1b48e 100644 --- a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp @@ -76,7 +76,7 @@ void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const auto offset = context.floored_device_point(svg_element_rect.location()).to_type().to_type(); painter.translate(offset); - auto maybe_view_box = svg_element->view_box(); + auto maybe_view_box = geometry_element.view_box(); auto transform = layout_box().layout_transform(); if (!transform.has_value()) diff --git a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp index caae6eaf813468ba1e9f3a0c0c98253df85c84c0..67835947610e9b0ff25e68518f67921a73226f6a 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace Web::SVG { @@ -230,4 +231,19 @@ Optional SVGGraphicsElement::stroke_width() const return width.to_px(*layout_node(), scaled_viewport_size).to_double(); } +Optional SVGGraphicsElement::view_box() const +{ + if (auto* svg_svg_element = shadow_including_first_ancestor_of_type()) { + if (svg_svg_element->view_box().has_value()) + return svg_svg_element->view_box(); + } + + if (auto* svg_symbol_element = shadow_including_first_ancestor_of_type()) { + if (svg_symbol_element->view_box().has_value()) + return svg_symbol_element->view_box(); + } + + return {}; +} + } diff --git a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.h b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.h index 68931c938e9391ed00e8db6748661ce9a6c8b1d7..060c05dc98b895f9a545769cab96d1c66a1bf8e3 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.h +++ b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace Web::SVG { @@ -45,6 +46,8 @@ public: Optional fill_paint_style(SVGPaintContext const&) const; Optional stroke_paint_style(SVGPaintContext const&) const; + Optional view_box() const; + protected: SVGGraphicsElement(DOM::Document&, DOM::QualifiedName); diff --git a/Userland/Libraries/LibWeb/SVG/SVGSymbolElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGSymbolElement.cpp index 5306a248c57f96606512e2d7929eb2a6c315257c..10af9b646f31a385c42b5f8c4a95fc3fa9441810 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGSymbolElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGSymbolElement.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -44,8 +45,12 @@ void SVGSymbolElement::apply_presentational_hints(CSS::StyleProperties& style) c // and this declaration must have importance over any other CSS rule or presentation attribute. style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::None)).release_value_but_fixme_should_propagate_errors()); } +} - // TODO: Parse viewBox and apply it in SVGGraphicsElement/SVGGraphicsPaintable +void SVGSymbolElement::attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value) +{ + if (name.equals_ignoring_ascii_case(SVG::AttributeNames::viewBox)) + m_view_box = try_parse_view_box(value); } bool SVGSymbolElement::is_direct_child_of_use_shadow_tree() const diff --git a/Userland/Libraries/LibWeb/SVG/SVGSymbolElement.h b/Userland/Libraries/LibWeb/SVG/SVGSymbolElement.h index 3b571d439797022f99b9a854c0182e858aa21aa6..0c690a13aa888f5638921a7a0ef54d39f1480881 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGSymbolElement.h +++ b/Userland/Libraries/LibWeb/SVG/SVGSymbolElement.h @@ -18,12 +18,18 @@ public: void apply_presentational_hints(CSS::StyleProperties& style) const override; + Optional view_box() const { return m_view_box; } + private: SVGSymbolElement(DOM::Document&, DOM::QualifiedName); virtual JS::ThrowCompletionOr initialize(JS::Realm&) override; bool is_direct_child_of_use_shadow_tree() const; + + virtual void attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value) override; + + Optional m_view_box; }; }