op/paint: add support for efficient ImageOp subimages

The new field ImageOp.Rect is initialized to cover the entire source
image, but can be modified to draw only a section of it.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-13 13:02:41 +01:00
parent fd5dfacb40
commit 69dfd2e3a5
4 changed files with 22 additions and 8 deletions
+13 -6
View File
@@ -116,6 +116,7 @@ type clipOp struct {
// imageOpData is the shadow of paint.ImageOp.
type imageOpData struct {
rect image.Rectangle
src *image.RGBA
handle interface{}
}
@@ -148,7 +149,18 @@ func decodeImageOp(data []byte, refs []interface{}) imageOpData {
if handle == nil {
return imageOpData{}
}
bo := binary.LittleEndian
return imageOpData{
rect: image.Rectangle{
Min: image.Point{
X: int(bo.Uint32(data[1:])),
Y: int(bo.Uint32(data[5:])),
},
Max: image.Point{
X: int(bo.Uint32(data[9:])),
Y: int(bo.Uint32(data[13:])),
},
},
src: refs[0].(*image.RGBA),
handle: handle,
}
@@ -736,12 +748,7 @@ func (d *drawState) materialFor(cache *resourceCache, rect f32.Rectangle, off f3
m.material = materialTexture
dr := boundRectF(rect.Add(off))
sz := d.image.src.Bounds().Size()
sr := f32.Rectangle{
Max: f32.Point{
X: float32(sz.X),
Y: float32(sz.Y),
},
}
sr := toRectF(d.image.rect)
if dx := float32(dr.Dx()); dx != 0 {
// Don't clip 1 px width sources.
if sdx := sr.Dx(); sdx > 1 {