LibWeb: Apply the paint transformation in SVGGradientElement

In commit 1b82cb43c2 I accidentally
removed the paint transformation altogether. The result was that
zoomed-in SVGs, or SVG elements with a transformation applied could have
their gradient coordinates misplaced significantly.

This was also exposed in the `svg-text-effects` test by way of a slight
visual difference. Add a new test that very clearly exposes the fixed
issue by rotating the gradient coordinates by 45 degrees.
This commit is contained in:
Jelle Raaijmakers 2024-11-15 14:41:15 +01:00 committed by Andreas Kling
parent e21b5cab32
commit e5d71a6c82
Notes: github-actions[bot] 2024-11-15 22:37:58 +00:00
7 changed files with 25 additions and 1 deletions

View file

@ -106,6 +106,7 @@ void SVGPathPaintable::paint(PaintContext& context, PaintPhase phase) const
SVG::SVGPaintContext paint_context { SVG::SVGPaintContext paint_context {
.viewport = svg_viewport, .viewport = svg_viewport,
.path_bounding_box = computed_path()->bounding_box(), .path_bounding_box = computed_path()->bounding_box(),
.paint_transform = paint_transform,
}; };
auto fill_opacity = graphics_element.fill_opacity().value_or(1); auto fill_opacity = graphics_element.fill_opacity().value_or(1);

View file

@ -84,7 +84,7 @@ Optional<Gfx::AffineTransform> SVGGradientElement::gradient_transform_impl(HashT
// The gradient transform, appropriately scaled and combined with the paint transform. // The gradient transform, appropriately scaled and combined with the paint transform.
Gfx::AffineTransform SVGGradientElement::gradient_paint_transform(SVGPaintContext const& paint_context) const Gfx::AffineTransform SVGGradientElement::gradient_paint_transform(SVGPaintContext const& paint_context) const
{ {
Gfx::AffineTransform gradient_paint_transform; Gfx::AffineTransform gradient_paint_transform = paint_context.paint_transform;
auto const& bounding_box = paint_context.path_bounding_box; auto const& bounding_box = paint_context.path_bounding_box;
if (gradient_units() == SVGUnits::ObjectBoundingBox) { if (gradient_units() == SVGUnits::ObjectBoundingBox) {

View file

@ -19,6 +19,7 @@ namespace Web::SVG {
struct SVGPaintContext { struct SVGPaintContext {
Gfx::FloatRect viewport; Gfx::FloatRect viewport;
Gfx::FloatRect path_bounding_box; Gfx::FloatRect path_bounding_box;
Gfx::AffineTransform paint_transform;
}; };
inline Painting::SVGGradientPaintStyle::SpreadMethod to_painting_spread_method(SpreadMethod spread_method) inline Painting::SVGGradientPaintStyle::SpreadMethod to_painting_spread_method(SpreadMethod spread_method)

View file

@ -0,0 +1,9 @@
<style>
* {
margin: 0;
}
body {
background-color: white;
}
</style>
<img src="../images/svg-gradient-paint-transformation-ref.png">

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,13 @@
<link rel="match" href="../expected/svg-gradient-paint-transformation-ref.html" />
<svg height="150" width="150" xmlns="http://www.w3.org/2000/svg">
<style>
.hi {
font: bold 70px sans-serif;
}
</style>
<linearGradient id="gradient">
<stop offset="0%" stop-color="rgba(255, 0, 0, 1)"/>
<stop offset="100%" stop-color="rgba(0, 255, 0, 1)"/>
</linearGradient>
<text x="50" y="50" class="hi" fill="url(#gradient)" transform="rotate(45 50 50)">HI</text>
</svg>