greatly improve clipping performance

This commit is contained in:
Michael Fogleman 2016-12-14 17:06:16 -05:00
parent 62c697d628
commit bc0c0e9e67
3 changed files with 16 additions and 34 deletions

View File

@ -173,8 +173,6 @@ ClipPreserve()
ResetClip()
```
Note: As currently implemented, clipping isn't very fast, but it works.
## Helper Functions
Sometimes you just don't want to write these yourself.

View File

@ -402,17 +402,8 @@ func (dc *Context) fill(painter raster.Painter) {
// line cap, line join and dash settings. The path is preserved after this
// operation.
func (dc *Context) StrokePreserve() {
if dc.mask == nil {
painter := newPatternPainter(dc.im)
painter.setPattern(dc.strokePattern)
dc.stroke(painter)
} else {
im := image.NewRGBA(image.Rect(0, 0, dc.width, dc.height))
painter := newPatternPainter(im)
painter.setPattern(dc.strokePattern)
dc.stroke(painter)
draw.DrawMask(dc.im, dc.im.Bounds(), im, image.ZP, dc.mask, image.ZP, draw.Over)
}
painter := newPatternPainter(dc.im, dc.mask, dc.strokePattern)
dc.stroke(painter)
}
// Stroke strokes the current path with the current color, line width,
@ -426,17 +417,8 @@ func (dc *Context) Stroke() {
// FillPreserve fills the current path with the current color. Open subpaths
// are implicity closed. The path is preserved after this operation.
func (dc *Context) FillPreserve() {
if dc.mask == nil {
painter := newPatternPainter(dc.im)
painter.setPattern(dc.fillPattern)
dc.fill(painter)
} else {
im := image.NewRGBA(image.Rect(0, 0, dc.width, dc.height))
painter := newPatternPainter(im)
painter.setPattern(dc.fillPattern)
dc.fill(painter)
draw.DrawMask(dc.im, dc.im.Bounds(), im, image.ZP, dc.mask, image.ZP, draw.Over)
}
painter := newPatternPainter(dc.im, dc.mask, dc.fillPattern)
dc.fill(painter)
}
// Fill fills the current path with the current color. Open subpaths

View File

@ -65,8 +65,9 @@ func NewSurfacePattern(im image.Image, op RepeatOp) Pattern {
}
type patternPainter struct {
im *image.RGBA
p Pattern
im *image.RGBA
mask *image.Alpha
p Pattern
}
// Paint satisfies the Painter interface.
@ -88,15 +89,20 @@ func (r *patternPainter) Paint(ss []raster.Span, done bool) {
if s.X0 >= s.X1 {
continue
}
ma := s.Alpha
const m = 1<<16 - 1
y := s.Y - r.im.Rect.Min.Y
x0 := s.X0 - r.im.Rect.Min.X
// x1 := x0 + s.X1 - s.X0
// RGBAPainter.Paint() in $GOPATH/src/github.com/golang/freetype/raster/paint.go
i0 := (s.Y-r.im.Rect.Min.Y)*r.im.Stride + (s.X0-r.im.Rect.Min.X)*4
i1 := i0 + (s.X1-s.X0)*4
for i, x := i0, x0; i < i1; i, x = i+4, x+1 {
ma := s.Alpha
if r.mask != nil {
ma = ma * uint32(r.mask.AlphaAt(x, y).A) / 255
if ma == 0 {
continue
}
}
c := r.p.ColorAt(x, y)
cr, cg, cb, ca := c.RGBA()
dr := uint32(r.im.Pix[i+0])
@ -112,10 +118,6 @@ func (r *patternPainter) Paint(ss []raster.Span, done bool) {
}
}
func (r *patternPainter) setPattern(pattern Pattern) {
r.p = pattern
}
func newPatternPainter(im *image.RGBA) *patternPainter {
return &patternPainter{im: im}
func newPatternPainter(im *image.RGBA, mask *image.Alpha, p Pattern) *patternPainter {
return &patternPainter{im, mask, p}
}