fix open fill paths

This commit is contained in:
Michael Fogleman 2016-02-20 15:10:16 -05:00
parent b77c5f2881
commit 8014fc54f3
2 changed files with 62 additions and 12 deletions

View File

@ -39,7 +39,8 @@ type Context struct {
height int height int
im *image.RGBA im *image.RGBA
color color.Color color color.Color
path raster.Path strokePath raster.Path
fillPath raster.Path
start fixed.Point26_6 start fixed.Point26_6
lineWidth float64 lineWidth float64
lineCap LineCap lineCap LineCap
@ -168,38 +169,49 @@ func (dc *Context) SetRGB(r, g, b float64) {
// Path Manipulation // Path Manipulation
func (dc *Context) MoveTo(x, y float64) { func (dc *Context) MoveTo(x, y float64) {
if len(dc.fillPath) > 0 {
dc.fillPath.Add1(dc.start)
}
x, y = dc.TransformPoint(x, y) x, y = dc.TransformPoint(x, y)
dc.start = fp(x, y) dc.start = fp(x, y)
dc.path.Start(dc.start) dc.strokePath.Start(dc.start)
dc.fillPath.Start(dc.start)
} }
func (dc *Context) LineTo(x, y float64) { func (dc *Context) LineTo(x, y float64) {
x, y = dc.TransformPoint(x, y) x, y = dc.TransformPoint(x, y)
if len(dc.path) == 0 { if len(dc.strokePath) == 0 {
dc.MoveTo(x, y) dc.MoveTo(x, y)
} else { } else {
dc.path.Add1(fp(x, y)) p := fp(x, y)
dc.strokePath.Add1(p)
dc.fillPath.Add1(p)
} }
} }
func (dc *Context) QuadraticTo(x1, y1, x2, y2 float64) { func (dc *Context) QuadraticTo(x1, y1, x2, y2 float64) {
x1, y1 = dc.TransformPoint(x1, y1) x1, y1 = dc.TransformPoint(x1, y1)
x2, y2 = dc.TransformPoint(x2, y2) x2, y2 = dc.TransformPoint(x2, y2)
if len(dc.path) == 0 { if len(dc.strokePath) == 0 {
dc.MoveTo(x1, y1) dc.MoveTo(x1, y1)
} else { } else {
dc.path.Add2(fp(x1, y1), fp(x2, y2)) p1 := fp(x1, y1)
p2 := fp(x2, y2)
dc.strokePath.Add2(p1, p2)
dc.fillPath.Add2(p1, p2)
} }
} }
func (dc *Context) ClosePath() { func (dc *Context) ClosePath() {
if len(dc.path) > 0 { if len(dc.strokePath) > 0 {
dc.path.Add1(dc.start) dc.strokePath.Add1(dc.start)
dc.fillPath.Add1(dc.start)
} }
} }
func (dc *Context) ClearPath() { func (dc *Context) ClearPath() {
dc.path.Clear() dc.strokePath.Clear()
dc.fillPath.Clear()
} }
// Path Drawing // Path Drawing
@ -231,7 +243,7 @@ func (dc *Context) StrokePreserve() {
painter.SetColor(dc.color) painter.SetColor(dc.color)
r := raster.NewRasterizer(dc.width, dc.height) r := raster.NewRasterizer(dc.width, dc.height)
r.UseNonZeroWinding = true r.UseNonZeroWinding = true
r.AddStroke(dc.path, fi(dc.lineWidth), dc.capper(), dc.joiner()) r.AddStroke(dc.strokePath, fi(dc.lineWidth), dc.capper(), dc.joiner())
r.Rasterize(painter) r.Rasterize(painter)
} }
@ -241,11 +253,17 @@ func (dc *Context) Stroke() {
} }
func (dc *Context) FillPreserve() { func (dc *Context) FillPreserve() {
var path raster.Path
if len(dc.fillPath) > 0 {
path = make(raster.Path, len(dc.fillPath))
copy(path, dc.fillPath)
path.Add1(dc.start)
}
painter := raster.NewRGBAPainter(dc.im) painter := raster.NewRGBAPainter(dc.im)
painter.SetColor(dc.color) painter.SetColor(dc.color)
r := raster.NewRasterizer(dc.width, dc.height) r := raster.NewRasterizer(dc.width, dc.height)
r.UseNonZeroWinding = dc.fillRule == FillRuleWinding r.UseNonZeroWinding = dc.fillRule == FillRuleWinding
r.AddPath(dc.path) r.AddPath(path)
r.Rasterize(painter) r.Rasterize(painter)
} }
@ -429,5 +447,6 @@ func (dc *Context) Pop() {
s := dc.stack s := dc.stack
x, s := s[len(s)-1], s[:len(s)-1] x, s := s[len(s)-1], s[:len(s)-1]
*dc = *x *dc = *x
dc.path = before.path dc.strokePath = before.strokePath
dc.fillPath = before.fillPath
} }

31
examples/openfill.go Normal file
View File

@ -0,0 +1,31 @@
package main
import (
"math"
"math/rand"
"github.com/fogleman/gg"
)
func main() {
dc := gg.NewContext(1000, 1000)
for j := 0; j < 10; j++ {
for i := 0; i < 10; i++ {
x := float64(i)*100 + 50
y := float64(j)*100 + 50
a1 := rand.Float64() * 2 * math.Pi
a2 := a1 + rand.Float64()*math.Pi + math.Pi/2
dc.DrawArc(x, y, 40, a1, a2)
// dc.ClosePath()
}
}
dc.SetRGB(0, 0, 0)
dc.FillPreserve()
dc.SetRGB(1, 1, 1)
dc.SetLineWidth(8)
dc.StrokePreserve()
dc.SetRGB(1, 0, 0)
dc.SetLineWidth(4)
dc.StrokePreserve()
dc.SavePNG("out.png")
}