srwiley / rasterx

Rasterx is an SVG 2.0 path compliant rasterizer that can use either scany, the golang vector or a derivative of the freetype anti-aliaser.
BSD 3-Clause "New" or "Revised" License
132 stars 11 forks source link

fix for radial gradients with UserSpaceOnUse, c == f #11

Closed rcoreilly closed 3 years ago

rcoreilly commented 3 years ago

I finally found the source of a radial gradient issue I'd noticed for a while: the fx, fy coordinates were not being transformed, and so the simple distance-based case was not triggering. Diff to fix is attached -- too lazy to do a PR but let me know if you prefer that.

Parens around the d's probably doesn't matter but anyway it might be slightly more precision-preserving?

diff --git a/gradient.go b/gradient.go
index 6be8fe7..8f00985 100644
--- a/gradient.go
+++ b/gradient.go
@@ -189,8 +189,10 @@ func (g *Gradient) GetColorFunctionUS(opacity float64, objMatrix Matrix2D) inter
            ry *= g.Bounds.H
        } else {
            cx, cy = g.Matrix.Transform(cx, cy)
+           fx, fy = g.Matrix.Transform(fx, fy)
            rx, ry = g.Matrix.TransformVector(rx, ry)
            cx, cy = objMatrix.Transform(cx, cy)
+           fx, fy = objMatrix.Transform(fx, fy)
            rx, ry = objMatrix.TransformVector(rx, ry)
        }

@@ -203,7 +205,7 @@ func (g *Gradient) GetColorFunctionUS(opacity float64, objMatrix Matrix2D) inter
                    x, y := gradT.Transform(float64(xi)+0.5, float64(yi)+0.5)
                    dx := float64(x) - cx
                    dy := float64(y) - cy
-                   return g.tColor(math.Sqrt(dx*dx/(rx*rx)+dy*dy/(ry*ry)), opacity)
+                   return g.tColor(math.Sqrt((dx*dx)/(rx*rx)+(dy*dy)/(ry*ry)), opacity)
                })
            }
            return ColorFunc(func(xi, yi int) color.Color {
@@ -211,7 +213,7 @@ func (g *Gradient) GetColorFunctionUS(opacity float64, objMatrix Matrix2D) inter
                y := float64(yi) + 0.5
                dx := x - cx
                dy := y - cy
-               return g.tColor(math.Sqrt(dx*dx/(rx*rx)+dy*dy/(ry*ry)), opacity)
+               return g.tColor(math.Sqrt((dx*dx)/(rx*rx)+(dy*dy)/(ry*ry)), opacity)
            })
        }
        fx /= rx
srwiley commented 3 years ago

Thanks Randall,

I have not been spending much time on rasterx stuff lately, but I will soon. I need to set aside a good chunk of time to work through the backlog, but I will soon.

hope you are doing well, Steve

On Sun, Jan 31, 2021 at 5:32 PM rcoreilly notifications@github.com wrote:

I finally found the source of a radial gradient issue I'd noticed for a while: the fx, fy coordinates were not being transformed, and so the simple distance-based case was not triggering. Diff to fix is attached -- too lazy to do a PR but let me know if you prefer that.

Parens around the d's probably doesn't matter but anyway it might be slightly more precision-preserving?

diff --git a/gradient.go b/gradient.goindex 6be8fe7..8f00985 100644--- a/gradient.go+++ b/gradient.go @@ -189,8 +189,10 @@ func (g Gradient) GetColorFunctionUS(opacity float64, objMatrix Matrix2D) inter ry = g.Bounds.H } else { cx, cy = g.Matrix.Transform(cx, cy)+ fx, fy = g.Matrix.Transform(fx, fy) rx, ry = g.Matrix.TransformVector(rx, ry) cx, cy = objMatrix.Transform(cx, cy)+ fx, fy = objMatrix.Transform(fx, fy) rx, ry = objMatrix.TransformVector(rx, ry) }

@@ -203,7 +205,7 @@ func (g Gradient) GetColorFunctionUS(opacity float64, objMatrix Matrix2D) inter x, y := gradT.Transform(float64(xi)+0.5, float64(yi)+0.5) dx := float64(x) - cx dy := float64(y) - cy- return g.tColor(math.Sqrt(dxdx/(rxrx)+dydy/(ryry)), opacity)+ return g.tColor(math.Sqrt((dxdx)/(rxrx)+(dydy)/(ryry)), opacity) }) } return ColorFunc(func(xi, yi int) color.Color { @@ -211,7 +213,7 @@ func (g Gradient) GetColorFunctionUS(opacity float64, objMatrix Matrix2D) inter y := float64(yi) + 0.5 dx := x - cx dy := y - cy- return g.tColor(math.Sqrt(dxdx/(rxrx)+dydy/(ryry)), opacity)+ return g.tColor(math.Sqrt((dxdx)/(rxrx)+(dydy)/(ryry)), opacity) }) } fx /= rx

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/srwiley/rasterx/issues/11, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4VOB44BKTVNGON3YXJYFLS4YAD3ANCNFSM4W35VASQ .

rcoreilly commented 3 years ago

Steve -- I'm working on a new svg-based drawing program, so you'll probably be hearing a bit from me :) I finally got fed up with how slow inkscape is on the mac, with no apparent fix in sight..

srwiley commented 3 years ago

Fix looks good. I don't have an explicit test showing the difference, but I think logically this is the right thing. The parentheses in the return statements make no material difference, but they enhance readability a bit so I kept them in.

thanks for your input, Steve