mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 09:55:40 +00:00
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:
+13
-6
@@ -116,6 +116,7 @@ type clipOp struct {
|
|||||||
|
|
||||||
// imageOpData is the shadow of paint.ImageOp.
|
// imageOpData is the shadow of paint.ImageOp.
|
||||||
type imageOpData struct {
|
type imageOpData struct {
|
||||||
|
rect image.Rectangle
|
||||||
src *image.RGBA
|
src *image.RGBA
|
||||||
handle interface{}
|
handle interface{}
|
||||||
}
|
}
|
||||||
@@ -148,7 +149,18 @@ func decodeImageOp(data []byte, refs []interface{}) imageOpData {
|
|||||||
if handle == nil {
|
if handle == nil {
|
||||||
return imageOpData{}
|
return imageOpData{}
|
||||||
}
|
}
|
||||||
|
bo := binary.LittleEndian
|
||||||
return imageOpData{
|
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),
|
src: refs[0].(*image.RGBA),
|
||||||
handle: handle,
|
handle: handle,
|
||||||
}
|
}
|
||||||
@@ -736,12 +748,7 @@ func (d *drawState) materialFor(cache *resourceCache, rect f32.Rectangle, off f3
|
|||||||
m.material = materialTexture
|
m.material = materialTexture
|
||||||
dr := boundRectF(rect.Add(off))
|
dr := boundRectF(rect.Add(off))
|
||||||
sz := d.image.src.Bounds().Size()
|
sz := d.image.src.Bounds().Size()
|
||||||
sr := f32.Rectangle{
|
sr := toRectF(d.image.rect)
|
||||||
Max: f32.Point{
|
|
||||||
X: float32(sz.X),
|
|
||||||
Y: float32(sz.Y),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if dx := float32(dr.Dx()); dx != 0 {
|
if dx := float32(dr.Dx()); dx != 0 {
|
||||||
// Don't clip 1 px width sources.
|
// Don't clip 1 px width sources.
|
||||||
if sdx := sr.Dx(); sdx > 1 {
|
if sdx := sr.Dx(); sdx > 1 {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const (
|
|||||||
TypeTransformLen = 1 + 4*2
|
TypeTransformLen = 1 + 4*2
|
||||||
TypeLayerLen = 1
|
TypeLayerLen = 1
|
||||||
TypeRedrawLen = 1 + 8
|
TypeRedrawLen = 1 + 8
|
||||||
TypeImageLen = 1
|
TypeImageLen = 1 + 4*4
|
||||||
TypePaintLen = 1 + 4*4
|
TypePaintLen = 1 + 4*4
|
||||||
TypeColorLen = 1 + 4
|
TypeColorLen = 1 + 4
|
||||||
TypeAreaLen = 1 + 1 + 4*4
|
TypeAreaLen = 1 + 1 + 4*4
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
|
|
||||||
// ImageOp sets the material to an image.
|
// ImageOp sets the material to an image.
|
||||||
type ImageOp struct {
|
type ImageOp struct {
|
||||||
|
Rect image.Rectangle
|
||||||
uniform bool
|
uniform bool
|
||||||
color color.RGBA
|
color color.RGBA
|
||||||
src *image.RGBA
|
src *image.RGBA
|
||||||
@@ -48,6 +49,7 @@ func NewImageOp(src image.Image) ImageOp {
|
|||||||
bounds := src.Bounds()
|
bounds := src.Bounds()
|
||||||
if bounds.Min == (image.Point{}) && src.Stride == bounds.Dx()*4 {
|
if bounds.Min == (image.Point{}) && src.Stride == bounds.Dx()*4 {
|
||||||
return ImageOp{
|
return ImageOp{
|
||||||
|
Rect: src.Bounds(),
|
||||||
src: src,
|
src: src,
|
||||||
handle: new(int),
|
handle: new(int),
|
||||||
}
|
}
|
||||||
@@ -82,6 +84,11 @@ func (i ImageOp) Add(o *op.Ops) {
|
|||||||
}
|
}
|
||||||
data := o.Write(opconst.TypeImageLen, i.src, i.handle)
|
data := o.Write(opconst.TypeImageLen, i.src, i.handle)
|
||||||
data[0] = byte(opconst.TypeImage)
|
data[0] = byte(opconst.TypeImage)
|
||||||
|
bo := binary.LittleEndian
|
||||||
|
bo.PutUint32(data[1:], uint32(i.Rect.Min.X))
|
||||||
|
bo.PutUint32(data[5:], uint32(i.Rect.Min.Y))
|
||||||
|
bo.PutUint32(data[9:], uint32(i.Rect.Max.X))
|
||||||
|
bo.PutUint32(data[13:], uint32(i.Rect.Max.Y))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c ColorOp) Add(o *op.Ops) {
|
func (c ColorOp) Add(o *op.Ops) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func (t *Theme) Image(img paint.ImageOp) Image {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (im Image) Layout(gtx *layout.Context) {
|
func (im Image) Layout(gtx *layout.Context) {
|
||||||
size := im.Src.Size()
|
size := im.Src.Rect.Size()
|
||||||
wf, hf := float32(size.X), float32(size.Y)
|
wf, hf := float32(size.X), float32(size.Y)
|
||||||
w, h := gtx.Px(unit.Dp(wf*im.Scale)), gtx.Px(unit.Dp(hf*im.Scale))
|
w, h := gtx.Px(unit.Dp(wf*im.Scale)), gtx.Px(unit.Dp(hf*im.Scale))
|
||||||
cs := gtx.Constraints
|
cs := gtx.Constraints
|
||||||
|
|||||||
Reference in New Issue
Block a user