@@ -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