Files
gio/ui/draw/draw.go
T
Elias Naur 0061c73a89 ui: split OpImage into OpImage and OpDraw
In preparation for an OpColor (and future OpGradient and similar).

Label and Editor no longer take an explicit source image. They
draw with the current image.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-06-01 12:44:49 +02:00

118 lines
2.5 KiB
Go

// SPDX-License-Identifier: Unlicense OR MIT
package draw
import (
"encoding/binary"
"image"
"math"
"gioui.org/ui"
"gioui.org/ui/f32"
"gioui.org/ui/internal/ops"
"gioui.org/ui/internal/path"
)
type OpImage struct {
Img image.Image
Rect image.Rectangle
}
type OpDraw struct {
Rect f32.Rectangle
}
func (i OpImage) Add(o *ui.Ops) {
data := make([]byte, ops.TypeImageLen)
data[0] = byte(ops.TypeImage)
bo := binary.LittleEndian
ref := o.Ref(i.Img)
bo.PutUint32(data[1:], uint32(ref))
bo.PutUint32(data[5:], uint32(i.Rect.Min.X))
bo.PutUint32(data[9:], uint32(i.Rect.Min.Y))
bo.PutUint32(data[13:], uint32(i.Rect.Max.X))
bo.PutUint32(data[17:], uint32(i.Rect.Max.Y))
o.Write(data)
}
func (i *OpImage) Decode(data []byte, refs []interface{}) {
bo := binary.LittleEndian
if ops.OpType(data[0]) != ops.TypeImage {
panic("invalid op")
}
ref := int(bo.Uint32(data[1:]))
sr := image.Rectangle{
Min: image.Point{
X: int(bo.Uint32(data[5:])),
Y: int(bo.Uint32(data[9:])),
},
Max: image.Point{
X: int(bo.Uint32(data[13:])),
Y: int(bo.Uint32(data[17:])),
},
}
*i = OpImage{
Img: refs[ref].(image.Image),
Rect: sr,
}
}
func (d OpDraw) Add(o *ui.Ops) {
data := make([]byte, ops.TypeDrawLen)
data[0] = byte(ops.TypeDraw)
bo := binary.LittleEndian
bo.PutUint32(data[1:], math.Float32bits(d.Rect.Min.X))
bo.PutUint32(data[5:], math.Float32bits(d.Rect.Min.Y))
bo.PutUint32(data[9:], math.Float32bits(d.Rect.Max.X))
bo.PutUint32(data[13:], math.Float32bits(d.Rect.Max.Y))
o.Write(data)
}
func (d *OpDraw) Decode(data []byte, refs []interface{}) {
bo := binary.LittleEndian
if ops.OpType(data[0]) != ops.TypeDraw {
panic("invalid op")
}
r := f32.Rectangle{
Min: f32.Point{
X: math.Float32frombits(bo.Uint32(data[1:])),
Y: math.Float32frombits(bo.Uint32(data[5:])),
},
Max: f32.Point{
X: math.Float32frombits(bo.Uint32(data[9:])),
Y: math.Float32frombits(bo.Uint32(data[13:])),
},
}
*d = OpDraw{
Rect: r,
}
}
// RectPath constructs a path corresponding to
// a pixel aligned rectangular area.
func RectPath(r image.Rectangle) *Path {
return &Path{
data: &path.Path{
Bounds: toRectF(r),
},
}
}
func itof(i int) float32 {
switch i {
case ui.Inf:
return float32(math.Inf(+1))
case -ui.Inf:
return float32(math.Inf(-1))
default:
return float32(i)
}
}
func toRectF(r image.Rectangle) f32.Rectangle {
return f32.Rectangle{
Min: f32.Point{X: itof(r.Min.X), Y: itof(r.Min.Y)},
Max: f32.Point{X: itof(r.Max.X), Y: itof(r.Max.Y)},
}
}