Skip to content

Commit 11010d0

Browse files
authored
Merge pull request #366 from Mitsutan/fix/scaled-gradient-svg-renderer
fix: scaled gradient svg renderer
2 parents 84eb06f + 537894c commit 11010d0

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

renderers/svg/svg.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -561,9 +561,15 @@ func (r *SVG) writePaint(paint canvas.Paint, m canvas.Matrix) string {
561561
return fmt.Sprintf("url(#%v)", v[0])
562562
} else if linearGradient, ok := paint.Gradient.(*canvas.LinearGradient); ok {
563563
sb := strings.Builder{}
564-
start := m.Dot(linearGradient.Start)
565-
end := m.Dot(linearGradient.End)
566-
fmt.Fprintf(&sb, `<linearGradient id="%v" gradientUnits="userSpaceOnUse" x1="%v" y1="%v" x2="%v" y2="%v">`, ref, dec(start.X), dec(r.height-start.Y), dec(end.X), dec(r.height-end.Y))
564+
if m.IsSimilarity() {
565+
start := m.Dot(linearGradient.Start)
566+
end := m.Dot(linearGradient.End)
567+
fmt.Fprintf(&sb, `<linearGradient id="%v" gradientUnits="userSpaceOnUse" x1="%v" y1="%v" x2="%v" y2="%v">`, ref, dec(start.X), dec(r.height-start.Y), dec(end.X), dec(r.height-end.Y))
568+
} else {
569+
// negate the Y coordinates because ToSVG(r.height) applies Y-axis reflection in its translation component,
570+
// so negating the gradient coordinates cancels out the double Y-axis reflection to achieve correct positioning.
571+
fmt.Fprintf(&sb, `<linearGradient id="%v" gradientUnits="userSpaceOnUse" gradientTransform="%v" x1="%v" y1="%v" x2="%v" y2="%v">`, ref, m.ToSVG(r.height), dec(linearGradient.Start.X), -dec(linearGradient.Start.Y), dec(linearGradient.End.X), -dec(linearGradient.End.Y))
572+
}
567573
for _, stop := range linearGradient.Grad {
568574
fmt.Fprintf(&sb, `<stop offset="%v" stop-color="%v"/>`, dec(stop.Offset), canvas.CSSColor(stop.Color))
569575
}
@@ -574,12 +580,14 @@ func (r *SVG) writePaint(paint canvas.Paint, m canvas.Matrix) string {
574580
if m.IsSimilarity() {
575581
c0 := m.Dot(radialGradient.C0)
576582
c1 := m.Dot(radialGradient.C1)
577-
det := math.Abs(m.Det())
578-
r0 := det * radialGradient.R0
579-
r1 := det * radialGradient.R1
583+
scale := math.Sqrt(math.Abs(m.Det()))
584+
r0 := scale * radialGradient.R0
585+
r1 := scale * radialGradient.R1
580586
fmt.Fprintf(&sb, `<radialGradient id="%v" gradientUnits="userSpaceOnUse" fx="%v" fy="%v" fr="%v" cx="%v" cy="%v" r="%v">`, ref, dec(c0.X), dec(r.height-c0.Y), dec(r0), dec(c1.X), dec(r.height-c1.Y), dec(r1))
581587
} else {
582-
fmt.Fprintf(&sb, `<radialGradient id="%v" gradientUnits="userSpaceOnUse" gradientTransform="%v" fx="%v" fy="%v" fr="%v" cx="%v" cy="%v" r="%v">`, ref, m.ToSVG(r.height), dec(radialGradient.C0.X), dec(radialGradient.C0.Y), dec(radialGradient.R0), dec(radialGradient.C1.X), dec(radialGradient.C1.Y), dec(radialGradient.R1))
588+
// negate the Y coordinates because ToSVG(r.height) applies Y-axis reflection in its translation component,
589+
// so negating the gradient coordinates cancels out the double Y-axis reflection to achieve correct positioning.
590+
fmt.Fprintf(&sb, `<radialGradient id="%v" gradientUnits="userSpaceOnUse" gradientTransform="%v" fx="%v" fy="%v" fr="%v" cx="%v" cy="%v" r="%v">`, ref, m.ToSVG(r.height), dec(radialGradient.C0.X), -dec(radialGradient.C0.Y), dec(radialGradient.R0), dec(radialGradient.C1.X), -dec(radialGradient.C1.Y), dec(radialGradient.R1))
583591
}
584592
for _, stop := range radialGradient.Grad {
585593
fmt.Fprintf(&sb, `<stop offset="%v" stop-color="%v"/>`, dec(stop.Offset), canvas.CSSColor(stop.Color))

0 commit comments

Comments
 (0)