mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 14:27:35 +00:00
LibWeb: Ensure transform of SVG <use> updates with x and y attributes
Rather than modify the transform of the parent (which could change independently), this adds a new override element_transform() where element specific tranfroms can be applied. This will always stay in sync with the attributes. A ref test comparing a .svg and .html version of the same file is added as due to differences in attribute parsing order, the .svg version was previously drawn incorrectly. Fixes #20859
This commit is contained in:
parent
90af21aef4
commit
720c27efbd
7 changed files with 38 additions and 6 deletions
|
@ -111,7 +111,7 @@ Gfx::AffineTransform SVGGraphicsElement::get_transform() const
|
|||
{
|
||||
Gfx::AffineTransform transform = m_transform;
|
||||
for (auto* svg_ancestor = shadow_including_first_ancestor_of_type<SVGGraphicsElement>(); svg_ancestor; svg_ancestor = svg_ancestor->shadow_including_first_ancestor_of_type<SVGGraphicsElement>()) {
|
||||
transform = Gfx::AffineTransform { svg_ancestor->m_transform }.multiply(transform);
|
||||
transform = Gfx::AffineTransform { svg_ancestor->element_transform() }.multiply(transform);
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,11 @@ protected:
|
|||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
virtual Gfx::AffineTransform element_transform() const
|
||||
{
|
||||
return m_transform;
|
||||
}
|
||||
|
||||
Optional<Gfx::PaintStyle const&> svg_paint_computed_value_to_gfx_paint_style(SVGPaintContext const& paint_context, Optional<CSS::SVGPaint> const& paint_value) const;
|
||||
|
||||
Gfx::AffineTransform m_transform = {};
|
||||
|
|
|
@ -72,13 +72,16 @@ Optional<StringView> SVGUseElement::parse_id_from_href(DeprecatedString const& h
|
|||
return href.substring_view(id_seperator.value() + 1);
|
||||
}
|
||||
|
||||
Gfx::AffineTransform SVGUseElement::element_transform() const
|
||||
{
|
||||
// The x and y properties define an additional transformation (translate(x,y), where x and y represent the computed value of the corresponding property)
|
||||
// to be applied to the ‘use’ element, after any transformations specified with other properties
|
||||
return Base::element_transform().translate(m_x.value_or(0), m_y.value_or(0));
|
||||
}
|
||||
|
||||
void SVGUseElement::inserted()
|
||||
{
|
||||
Base::inserted();
|
||||
|
||||
// The x and y properties define an additional transformation (translate(x,y), where x and y represent the computed value of the corresponding property)
|
||||
// to be applied to the ‘use’ element, after any transformations specified with other properties
|
||||
m_transform.translate(m_x.value_or(0), m_y.value_or(0));
|
||||
}
|
||||
|
||||
void SVGUseElement::svg_element_changed(SVGElement& svg_element)
|
||||
|
|
|
@ -34,6 +34,8 @@ public:
|
|||
JS::GCPtr<SVGElement> instance_root() const;
|
||||
JS::GCPtr<SVGElement> animated_instance_root() const;
|
||||
|
||||
virtual Gfx::AffineTransform element_transform() const override;
|
||||
|
||||
private:
|
||||
SVGUseElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue