greatly improve clipping performance
This commit is contained in:
parent
62c697d628
commit
bc0c0e9e67
@ -173,8 +173,6 @@ ClipPreserve()
|
|||||||
ResetClip()
|
ResetClip()
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: As currently implemented, clipping isn't very fast, but it works.
|
|
||||||
|
|
||||||
## Helper Functions
|
## Helper Functions
|
||||||
|
|
||||||
Sometimes you just don't want to write these yourself.
|
Sometimes you just don't want to write these yourself.
|
||||||
|
26
context.go
26
context.go
@ -402,17 +402,8 @@ func (dc *Context) fill(painter raster.Painter) {
|
|||||||
// line cap, line join and dash settings. The path is preserved after this
|
// line cap, line join and dash settings. The path is preserved after this
|
||||||
// operation.
|
// operation.
|
||||||
func (dc *Context) StrokePreserve() {
|
func (dc *Context) StrokePreserve() {
|
||||||
if dc.mask == nil {
|
painter := newPatternPainter(dc.im, dc.mask, dc.strokePattern)
|
||||||
painter := newPatternPainter(dc.im)
|
dc.stroke(painter)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stroke strokes the current path with the current color, line width,
|
// 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
|
// FillPreserve fills the current path with the current color. Open subpaths
|
||||||
// are implicity closed. The path is preserved after this operation.
|
// are implicity closed. The path is preserved after this operation.
|
||||||
func (dc *Context) FillPreserve() {
|
func (dc *Context) FillPreserve() {
|
||||||
if dc.mask == nil {
|
painter := newPatternPainter(dc.im, dc.mask, dc.fillPattern)
|
||||||
painter := newPatternPainter(dc.im)
|
dc.fill(painter)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill fills the current path with the current color. Open subpaths
|
// Fill fills the current path with the current color. Open subpaths
|
||||||
|
22
pattern.go
22
pattern.go
@ -65,8 +65,9 @@ func NewSurfacePattern(im image.Image, op RepeatOp) Pattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type patternPainter struct {
|
type patternPainter struct {
|
||||||
im *image.RGBA
|
im *image.RGBA
|
||||||
p Pattern
|
mask *image.Alpha
|
||||||
|
p Pattern
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paint satisfies the Painter interface.
|
// Paint satisfies the Painter interface.
|
||||||
@ -88,15 +89,20 @@ func (r *patternPainter) Paint(ss []raster.Span, done bool) {
|
|||||||
if s.X0 >= s.X1 {
|
if s.X0 >= s.X1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ma := s.Alpha
|
|
||||||
const m = 1<<16 - 1
|
const m = 1<<16 - 1
|
||||||
y := s.Y - r.im.Rect.Min.Y
|
y := s.Y - r.im.Rect.Min.Y
|
||||||
x0 := s.X0 - r.im.Rect.Min.X
|
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
|
// 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
|
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
|
i1 := i0 + (s.X1-s.X0)*4
|
||||||
for i, x := i0, x0; i < i1; i, x = i+4, x+1 {
|
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)
|
c := r.p.ColorAt(x, y)
|
||||||
cr, cg, cb, ca := c.RGBA()
|
cr, cg, cb, ca := c.RGBA()
|
||||||
dr := uint32(r.im.Pix[i+0])
|
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) {
|
func newPatternPainter(im *image.RGBA, mask *image.Alpha, p Pattern) *patternPainter {
|
||||||
r.p = pattern
|
return &patternPainter{im, mask, p}
|
||||||
}
|
|
||||||
|
|
||||||
func newPatternPainter(im *image.RGBA) *patternPainter {
|
|
||||||
return &patternPainter{im: im}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user