diff --git a/gpu/gpu.go b/gpu/gpu.go index 334f03a4..0cb78a4a 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -69,7 +69,7 @@ type drawOps struct { type drawState struct { clip f32.Rectangle - t op.TransformOp + t f32.Affine2D cpath *pathOp rect bool z int @@ -691,8 +691,8 @@ loop: case opconst.TypeProfile: d.profile = true case opconst.TypeTransform: - dop := ops.DecodeTransformOp(encOp.Data) - state.t = state.t.Multiply(op.TransformOp(dop)) + dop := ops.DecodeTransform(encOp.Data) + state.t = state.t.Mul(dop) case opconst.TypeAux: aux = encOp.Data[opconst.TypeAuxLen:] auxKey = encOp.Key diff --git a/internal/opconst/ops.go b/internal/opconst/ops.go index aca341f9..62365b8f 100644 --- a/internal/opconst/ops.go +++ b/internal/opconst/ops.go @@ -31,7 +31,7 @@ const ( const ( TypeMacroLen = 1 + 4 + 4 TypeCallLen = 1 + 4 + 4 - TypeTransformLen = 1 + 4*2 + TypeTransformLen = 1 + 4*6 TypeLayerLen = 1 TypeRedrawLen = 1 + 8 TypeImageLen = 1 + 4*4 diff --git a/internal/ops/ops.go b/internal/ops/ops.go index 80994e17..721f4628 100644 --- a/internal/ops/ops.go +++ b/internal/ops/ops.go @@ -8,7 +8,6 @@ import ( "gioui.org/f32" "gioui.org/internal/opconst" - "gioui.org/op" ) const QuadSize = 4 * 2 * 3 @@ -38,13 +37,23 @@ func DecodeQuad(d []byte) (q Quad) { return } -func DecodeTransformOp(d []byte) op.TransformOp { - bo := binary.LittleEndian +func DecodeTransform(d []byte) (t f32.Affine2D) { if opconst.OpType(d[0]) != opconst.TypeTransform { panic("invalid op") } - return op.TransformOp{}.Offset(f32.Point{ - X: math.Float32frombits(bo.Uint32(d[1:])), - Y: math.Float32frombits(bo.Uint32(d[5:])), - }) + if len(d) < 1+6*4 { + panic("too short buffer") + } + return decodeAffine2D(d[1:]) +} + +func decodeAffine2D(data []byte) f32.Affine2D { + bo := binary.LittleEndian + a := math.Float32frombits(bo.Uint32(data)) + b := math.Float32frombits(bo.Uint32(data[4*1:])) + c := math.Float32frombits(bo.Uint32(data[4*2:])) + d := math.Float32frombits(bo.Uint32(data[4*3:])) + e := math.Float32frombits(bo.Uint32(data[4*4:])) + f := math.Float32frombits(bo.Uint32(data[4*5:])) + return f32.NewAffine2D(a, b, c, d, e, f) } diff --git a/io/router/pointer.go b/io/router/pointer.go index ec3bb397..0d0977f6 100644 --- a/io/router/pointer.go +++ b/io/router/pointer.go @@ -56,7 +56,7 @@ type areaOp struct { } type areaNode struct { - trans op.TransformOp + trans f32.Affine2D next int area areaOp } @@ -68,7 +68,7 @@ const ( areaEllipse ) -func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t op.TransformOp, area, node int, pass bool) { +func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t f32.Affine2D, area, node int, pass bool) { for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() { switch opconst.OpType(encOp.Data[0]) { case opconst.TypePush: @@ -90,8 +90,8 @@ func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t o }) node = len(q.hitTree) - 1 case opconst.TypeTransform: - dop := ops.DecodeTransformOp(encOp.Data) - t = t.Multiply(op.TransformOp(dop)) + dop := ops.DecodeTransform(encOp.Data) + t = t.Mul(dop) case opconst.TypePointerInput: op := decodePointerInputOp(encOp.Data, encOp.Refs) q.hitTree = append(q.hitTree, hitNode{ @@ -175,7 +175,7 @@ func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) { q.hitTree = q.hitTree[:0] q.areas = q.areas[:0] q.reader.Reset(root) - q.collectHandlers(&q.reader, events, op.TransformOp{}, -1, -1, false) + q.collectHandlers(&q.reader, events, f32.Affine2D{}, -1, -1, false) for k, h := range q.handlers { if !h.active { q.dropHandlers(events, k) diff --git a/op/op.go b/op/op.go index 82f1457a..3aafbc33 100644 --- a/op/op.go +++ b/op/op.go @@ -290,8 +290,13 @@ func (t TransformOp) Add(o *Ops) { data := o.Write(opconst.TypeTransformLen) data[0] = byte(opconst.TypeTransform) bo := binary.LittleEndian - bo.PutUint32(data[1:], math.Float32bits(t.offset.X)) - bo.PutUint32(data[5:], math.Float32bits(t.offset.Y)) + // write it out as an affine matrix although we only support offset yet + bo.PutUint32(data[1:], math.Float32bits(1.0)) + bo.PutUint32(data[1+4*1:], math.Float32bits(0)) + bo.PutUint32(data[1+4*2:], math.Float32bits(t.offset.X)) + bo.PutUint32(data[1+4*3:], math.Float32bits(0)) + bo.PutUint32(data[1+4*4:], math.Float32bits(1)) + bo.PutUint32(data[1+4*5:], math.Float32bits(t.offset.Y)) } func (s *stack) push() stackID {