ref: b25af47c45adcaef27ae241623f40208c53a1866 gio/ui/paint/paint.go -rw-r--r-- 1.9 KiB View raw
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// SPDX-License-Identifier: Unlicense OR MIT

package paint

import (
	"encoding/binary"
	"image"
	"image/color"
	"math"

	"gioui.org/ui"
	"gioui.org/ui/f32"
	"gioui.org/ui/internal/opconst"
)

// ImageOp sets the material to a section of an
// image.
type ImageOp struct {
	// Src is the image.
	Src image.Image
	// Rect defines the section of Src to use.
	Rect image.Rectangle
}

// ColorOp sets the material to a constant color.
type ColorOp struct {
	Color color.RGBA
}

// PaintOp draws the current material, respecting the
// clip path and transformation.
type PaintOp struct {
	Rect f32.Rectangle
}

func (i ImageOp) Add(o *ui.Ops) {
	data := make([]byte, opconst.TypeImageLen)
	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))
	o.Write(data, i.Src)
}

func (c ColorOp) Add(o *ui.Ops) {
	data := make([]byte, opconst.TypeColorLen)
	data[0] = byte(opconst.TypeColor)
	data[1] = c.Color.R
	data[2] = c.Color.G
	data[3] = c.Color.B
	data[4] = c.Color.A
	o.Write(data)
}

func (d PaintOp) Add(o *ui.Ops) {
	data := make([]byte, opconst.TypePaintLen)
	data[0] = byte(opconst.TypePaint)
	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)
}

// RectClip returns a ClipOp corresponding to a pixel aligned
// rectangular area.
func RectClip(r image.Rectangle) ClipOp {
	return ClipOp{bounds: toRectF(r)}
}

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)},
	}
}