op/paint: add NewImageOp, unexport ImageOp fields

With public ImageOp fields there was no way to mark an image.Image as modified.
Replace them with NewImageOp that always make a copy, and use the opportunity
to ensure the copy is ready to upload to a GPU texture.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-10-14 17:37:18 +02:00
parent 2e22edbb99
commit 74407a50d5
4 changed files with 77 additions and 74 deletions
+15 -9
View File
@@ -41,7 +41,7 @@ type Icon struct {
size unit.Value
// Cached values.
img image.Image
op paint.ImageOp
imgSize int
}
@@ -112,9 +112,11 @@ func (b IconButton) Layout(gtx *layout.Context, button *widget.Button) {
layout.UniformInset(b.Padding).Layout(gtx, func() {
size := gtx.Px(b.Size) - gtx.Px(b.Padding)
ico := b.Icon.image(size)
paint.ImageOp{Src: ico, Rect: ico.Bounds()}.Add(gtx.Ops)
ico.Add(gtx.Ops)
paint.PaintOp{
Rect: toRectF(ico.Bounds()),
Rect: f32.Rectangle{
Max: toPointF(ico.Size()),
},
}.Add(gtx.Ops)
gtx.Dimensions = layout.Dimensions{
Size: image.Point{X: size, Y: size},
@@ -143,9 +145,9 @@ func (b IconButton) Layout(gtx *layout.Context, button *widget.Button) {
st.Layout(gtx, bg, ico)
}
func (ic *Icon) image(sz int) image.Image {
func (ic *Icon) image(sz int) paint.ImageOp {
if sz == ic.imgSize {
return ic.img
return ic.op
}
m, _ := iconvg.DecodeMetadata(ic.src)
dx, dy := m.ViewBox.AspectRatio()
@@ -157,15 +159,19 @@ func (ic *Icon) image(sz int) image.Image {
iconvg.Decode(&ico, ic.src, &iconvg.DecodeOptions{
Palette: &m.Palette,
})
ic.img = img
ic.op = paint.NewImageOp(img)
ic.imgSize = sz
return img
return ic.op
}
func toPointF(p image.Point) f32.Point {
return f32.Point{X: float32(p.X), Y: float32(p.Y)}
}
func toRectF(r image.Rectangle) f32.Rectangle {
return f32.Rectangle{
Min: f32.Point{X: float32(r.Min.X), Y: float32(r.Min.Y)},
Max: f32.Point{X: float32(r.Max.X), Y: float32(r.Max.Y)},
Min: toPointF(r.Min),
Max: toPointF(r.Max),
}
}
+1 -4
View File
@@ -15,8 +15,6 @@ import (
type Image struct {
// Src is the image to display.
Src image.Image
// Rect is the source rectangle.
Rect image.Rectangle
// Scale is the ratio of image pixels to
// dps.
Scale float32
@@ -25,7 +23,6 @@ type Image struct {
func (t *Theme) Image(img image.Image) Image {
return Image{
Src: img,
Rect: img.Bounds(),
Scale: 160 / 72, // About 72 DPI.
}
}
@@ -47,7 +44,7 @@ func (im Image) Layout(gtx *layout.Context) {
dr := f32.Rectangle{
Max: f32.Point{X: float32(d.X), Y: float32(d.Y)},
}
paint.ImageOp{Src: im.Src, Rect: im.Rect}.Add(gtx.Ops)
paint.NewImageOp(im.Src).Add(gtx.Ops)
paint.PaintOp{Rect: dr}.Add(gtx.Ops)
gtx.Dimensions = layout.Dimensions{Size: d, Baseline: d.Y}
}