diff --git a/context.go b/context.go index 58ca153..3c5f2d9 100644 --- a/context.go +++ b/context.go @@ -47,6 +47,7 @@ type Context struct { fillRule FillRule fontFace font.Face matrix Matrix + stack []*Context } func NewContext(width, height int) *Context { @@ -362,3 +363,35 @@ func (dc *Context) Shear(x, y float64) { func (dc *Context) TransformPoint(x, y float64) (tx, ty float64) { return dc.matrix.TransformPoint(x, y) } + +// Stack + +func (dc *Context) Push() { + path := make(raster.Path, len(dc.path)) + copy(path, dc.path) + dc.stack = append(dc.stack, &Context{ + color: dc.color, + path: path, + start: dc.start, + lineWidth: dc.lineWidth, + lineCap: dc.lineCap, + lineJoin: dc.lineJoin, + fillRule: dc.fillRule, + fontFace: dc.fontFace, + matrix: dc.matrix, + }) +} + +func (dc *Context) Pop() { + s := dc.stack + x, s := s[len(s)-1], s[:len(s)-1] + dc.color = x.color + dc.path = x.path + dc.start = x.start + dc.lineWidth = x.lineWidth + dc.lineCap = x.lineCap + dc.lineJoin = x.lineJoin + dc.fillRule = x.fillRule + dc.fontFace = x.fontFace + dc.matrix = x.matrix +} diff --git a/examples/ellipse.go b/examples/ellipse.go index 3519bbb..5fefe68 100644 --- a/examples/ellipse.go +++ b/examples/ellipse.go @@ -7,12 +7,13 @@ func main() { dc := gg.NewContext(S, S) dc.SetRGB(1, 1, 1) dc.Clear() + dc.SetRGBA(0, 0, 0, 0.1) for i := 0; i < 360; i += 15 { - dc.Identity() + dc.Push() dc.RotateAbout(gg.Radians(float64(i)), S/2, S/2) dc.DrawEllipse(S/2, S/2, S*7/16, S/8) - dc.SetRGBA(0, 0, 0, 0.1) dc.Fill() + dc.Pop() } dc.WritePNG("out.png") } diff --git a/matrix.go b/matrix.go index 0066dd6..6694247 100644 --- a/matrix.go +++ b/matrix.go @@ -41,10 +41,10 @@ func Rotate(angle float64) Matrix { } func RotateAbout(angle, x, y float64) Matrix { - a := Translate(x, y) + a := Translate(-x, -y) b := Rotate(angle) - c := Translate(-x, -y) - return c.Multiply(b).Multiply(a) + c := Translate(x, y) + return a.Multiply(b).Multiply(c) } func Shear(x, y float64) Matrix {