diff --git a/internal/ops/ops.go b/internal/ops/ops.go index 0c8e0cf2..91deb819 100644 --- a/internal/ops/ops.go +++ b/internal/ops/ops.go @@ -126,7 +126,7 @@ const ( TypeStrokeLen = 1 + 4 ) -func (o *Ops) Reset() { +func Reset(o *Ops) { o.macroStack = stack{} for i := range o.stacks { o.stacks[i] = stack{} @@ -141,21 +141,21 @@ func (o *Ops) Reset() { o.version++ } -func (o *Ops) Write(n int) []byte { +func Write(o *Ops, n int) []byte { o.data = append(o.data, make([]byte, n)...) return o.data[len(o.data)-n:] } -func (o *Ops) PushMacro() StackID { +func PushMacro(o *Ops) StackID { return o.macroStack.push() } -func (o *Ops) PopMacro(id StackID) { +func PopMacro(o *Ops, id StackID) { o.macroStack.pop(id) } -func (o *Ops) FillMacro(startPC PC) { - pc := o.PC() +func FillMacro(o *Ops, startPC PC) { + pc := PCFor(o) // Fill out the macro definition reserved in Record. data := o.data[startPC.data:] data = data[:TypeMacroLen] @@ -165,38 +165,38 @@ func (o *Ops) FillMacro(startPC PC) { bo.PutUint32(data[5:], uint32(pc.refs)) } -func (o *Ops) AddCall(callOps *Ops, pc PC) { - data := o.Write1(TypeCallLen, callOps) +func AddCall(o *Ops, callOps *Ops, pc PC) { + data := Write1(o, TypeCallLen, callOps) data[0] = byte(TypeCall) bo := binary.LittleEndian bo.PutUint32(data[1:], uint32(pc.data)) bo.PutUint32(data[5:], uint32(pc.refs)) } -func (o *Ops) PushOp(kind StackKind) (StackID, int) { +func PushOp(o *Ops, kind StackKind) (StackID, int) { return o.stacks[kind].push(), o.macroStack.currentID } -func (o *Ops) PopOp(kind StackKind, sid StackID, macroID int) { +func PopOp(o *Ops, kind StackKind, sid StackID, macroID int) { if o.macroStack.currentID != macroID { panic("stack push and pop must not cross macro boundary") } o.stacks[kind].pop(sid) } -func (o *Ops) Write1(n int, ref1 interface{}) []byte { +func Write1(o *Ops, n int, ref1 interface{}) []byte { o.data = append(o.data, make([]byte, n)...) o.refs = append(o.refs, ref1) return o.data[len(o.data)-n:] } -func (o *Ops) Write2(n int, ref1, ref2 interface{}) []byte { +func Write2(o *Ops, n int, ref1, ref2 interface{}) []byte { o.data = append(o.data, make([]byte, n)...) o.refs = append(o.refs, ref1, ref2) return o.data[len(o.data)-n:] } -func (o *Ops) PC() PC { +func PCFor(o *Ops) PC { return PC{data: len(o.data), refs: len(o.refs)} } @@ -222,7 +222,7 @@ func (s *stack) pop(sid StackID) { } // Save the effective transformation. -func (o *Ops) Save() StateOP { +func Save(o *Ops) StateOP { o.nextStateID++ s := StateOP{ ops: o, @@ -230,7 +230,7 @@ func (o *Ops) Save() StateOP { macroID: o.macroStack.currentID, } bo := binary.LittleEndian - data := o.Write(TypeSaveLen) + data := Write(o, TypeSaveLen) data[0] = byte(TypeSave) bo.PutUint32(data[1:], uint32(s.id)) return s @@ -240,7 +240,7 @@ func (o *Ops) Save() StateOP { // its ID. func (s StateOP) Load() { bo := binary.LittleEndian - data := s.ops.Write(TypeLoadLen) + data := Write(s.ops, TypeLoadLen) data[0] = byte(TypeLoad) bo.PutUint32(data[1:], uint32(s.id)) } diff --git a/internal/ops/reader.go b/internal/ops/reader.go index 7aafdac3..99b8cb64 100644 --- a/internal/ops/reader.go +++ b/internal/ops/reader.go @@ -60,7 +60,7 @@ func (r *Reader) Reset(ops *Ops) { // ResetAt is like Reset, except it starts reading from pc. func (r *Reader) ResetAt(ops *Ops, pc PC) { r.stack = r.stack[:0] - r.deferOps.Reset() + Reset(&r.deferOps) r.deferDone = false r.pc = pc r.ops = ops @@ -120,7 +120,7 @@ func (r *Reader) Decode() (EncodedOp, bool) { if t.NumRefs() != 1 { panic("internal error: unexpected number of macro refs") } - deferData := r.deferOps.Write1(t.Size(), refs[0]) + deferData := Write1(&r.deferOps, t.Size(), refs[0]) copy(deferData, data) r.pc.data += n r.pc.refs += nrefs diff --git a/io/clipboard/clipboard.go b/io/clipboard/clipboard.go index de331f73..ae4a4359 100644 --- a/io/clipboard/clipboard.go +++ b/io/clipboard/clipboard.go @@ -25,12 +25,12 @@ type WriteOp struct { } func (h ReadOp) Add(o *op.Ops) { - data := o.Internal.Write1(ops.TypeClipboardReadLen, h.Tag) + data := ops.Write1(&o.Internal, ops.TypeClipboardReadLen, h.Tag) data[0] = byte(ops.TypeClipboardRead) } func (h WriteOp) Add(o *op.Ops) { - data := o.Internal.Write1(ops.TypeClipboardWriteLen, &h.Text) + data := ops.Write1(&o.Internal, ops.TypeClipboardWriteLen, &h.Text) data[0] = byte(ops.TypeClipboardWrite) } diff --git a/io/key/key.go b/io/key/key.go index 6b0ddc29..7402effc 100644 --- a/io/key/key.go +++ b/io/key/key.go @@ -145,13 +145,13 @@ func (h InputOp) Add(o *op.Ops) { if h.Tag == nil { panic("Tag must be non-nil") } - data := o.Internal.Write1(ops.TypeKeyInputLen, h.Tag) + data := ops.Write1(&o.Internal, ops.TypeKeyInputLen, h.Tag) data[0] = byte(ops.TypeKeyInput) data[1] = byte(h.Hint) } func (h SoftKeyboardOp) Add(o *op.Ops) { - data := o.Internal.Write(ops.TypeKeySoftKeyboardLen) + data := ops.Write(&o.Internal, ops.TypeKeySoftKeyboardLen) data[0] = byte(ops.TypeKeySoftKeyboard) if h.Show { data[1] = 1 @@ -159,7 +159,7 @@ func (h SoftKeyboardOp) Add(o *op.Ops) { } func (h FocusOp) Add(o *op.Ops) { - data := o.Internal.Write1(ops.TypeKeyFocusLen, h.Tag) + data := ops.Write1(&o.Internal, ops.TypeKeyFocusLen, h.Tag) data[0] = byte(ops.TypeKeyFocus) } diff --git a/io/pointer/pointer.go b/io/pointer/pointer.go index d30e4338..f7c82714 100644 --- a/io/pointer/pointer.go +++ b/io/pointer/pointer.go @@ -202,13 +202,13 @@ func Ellipse(size image.Rectangle) AreaOp { // Push the current area to the stack and intersects the current area with the // area represented by o. func (a AreaOp) Push(o *op.Ops) AreaStack { - id, macroID := o.Internal.PushOp(ops.AreaStack) + id, macroID := ops.PushOp(&o.Internal, ops.AreaStack) a.add(o, true) return AreaStack{ops: &o.Internal, id: id, macroID: macroID} } func (a AreaOp) add(o *op.Ops, push bool) { - data := o.Internal.Write(ops.TypeAreaLen) + data := ops.Write(&o.Internal, ops.TypeAreaLen) data[0] = byte(ops.TypeArea) data[1] = byte(a.kind) bo := binary.LittleEndian @@ -219,27 +219,27 @@ func (a AreaOp) add(o *op.Ops, push bool) { } func (o AreaStack) Pop() { - o.ops.PopOp(ops.AreaStack, o.id, o.macroID) - data := o.ops.Write(ops.TypePopAreaLen) + ops.PopOp(o.ops, ops.AreaStack, o.id, o.macroID) + data := ops.Write(o.ops, ops.TypePopAreaLen) data[0] = byte(ops.TypePopArea) } // Push the current pass mode to the pass stack and set the pass mode. func (p PassOp) Push(o *op.Ops) PassStack { - id, mid := o.Internal.PushOp(ops.PassStack) - data := o.Internal.Write(ops.TypePassLen) + id, mid := ops.PushOp(&o.Internal, ops.PassStack) + data := ops.Write(&o.Internal, ops.TypePassLen) data[0] = byte(ops.TypePass) return PassStack{ops: &o.Internal, id: id, macroID: mid} } func (p PassStack) Pop() { - p.ops.PopOp(ops.PassStack, p.id, p.macroID) - data := p.ops.Write(ops.TypePopPassLen) + ops.PopOp(p.ops, ops.PassStack, p.id, p.macroID) + data := ops.Write(p.ops, ops.TypePopPassLen) data[0] = byte(ops.TypePopPass) } func (op CursorNameOp) Add(o *op.Ops) { - data := o.Internal.Write1(ops.TypeCursorLen, op.Name) + data := ops.Write1(&o.Internal, ops.TypeCursorLen, op.Name) data[0] = byte(ops.TypeCursor) } @@ -251,7 +251,7 @@ func (op InputOp) Add(o *op.Ops) { if b := op.ScrollBounds; b.Min.X > 0 || b.Max.X < 0 || b.Min.Y > 0 || b.Max.Y < 0 { panic(fmt.Errorf("invalid scroll range value %v", b)) } - data := o.Internal.Write1(ops.TypePointerInputLen, op.Tag) + data := ops.Write1(&o.Internal, ops.TypePointerInputLen, op.Tag) data[0] = byte(ops.TypePointerInput) if op.Grab { data[1] = 1 diff --git a/io/profile/profile.go b/io/profile/profile.go index 471fe965..b9a4476e 100644 --- a/io/profile/profile.go +++ b/io/profile/profile.go @@ -24,7 +24,7 @@ type Event struct { } func (p Op) Add(o *op.Ops) { - data := o.Internal.Write1(ops.TypeProfileLen, p.Tag) + data := ops.Write1(&o.Internal, ops.TypeProfileLen, p.Tag) data[0] = byte(ops.TypeProfile) } diff --git a/op/clip/clip.go b/op/clip/clip.go index ad79e2db..8539bc0c 100644 --- a/op/clip/clip.go +++ b/op/clip/clip.go @@ -40,7 +40,7 @@ func init() { // Push saves the current clip state on the stack and updates the current // state to the intersection of the current p. func (p Op) Push(o *op.Ops) Stack { - id, macroID := o.Internal.PushOp(ops.ClipStack) + id, macroID := ops.PushOp(&o.Internal, ops.ClipStack) p.add(o, true) return Stack{ops: &o.Internal, id: id, macroID: macroID} } @@ -58,7 +58,7 @@ func (p Op) add(o *op.Ops, push bool) { bo := binary.LittleEndian if path.hasSegments { - data := o.Internal.Write(ops.TypePathLen) + data := ops.Write(&o.Internal, ops.TypePathLen) data[0] = byte(ops.TypePath) bo.PutUint64(data[1:], path.hash) path.spec.Add(o) @@ -72,13 +72,13 @@ func (p Op) add(o *op.Ops, push bool) { bounds.Min.Y -= half bounds.Max.X += half bounds.Max.Y += half - data := o.Internal.Write(ops.TypeStrokeLen) + data := ops.Write(&o.Internal, ops.TypeStrokeLen) data[0] = byte(ops.TypeStroke) bo := binary.LittleEndian bo.PutUint32(data[1:], math.Float32bits(p.width)) } - data := o.Internal.Write(ops.TypeClipLen) + data := ops.Write(&o.Internal, ops.TypeClipLen) data[0] = byte(ops.TypeClip) bo.PutUint32(data[1:], uint32(bounds.Min.X)) bo.PutUint32(data[5:], uint32(bounds.Min.Y)) @@ -93,8 +93,8 @@ func (p Op) add(o *op.Ops, push bool) { } func (s Stack) Pop() { - s.ops.PopOp(ops.ClipStack, s.id, s.macroID) - data := s.ops.Write(ops.TypePopClipLen) + ops.PopOp(s.ops, ops.ClipStack, s.id, s.macroID) + data := ops.Write(s.ops, ops.TypePopClipLen) data[0] = byte(ops.TypePopClip) } @@ -137,7 +137,7 @@ func (p *Path) Begin(o *op.Ops) { p.ops = &o.Internal p.macro = op.Record(o) // Write the TypeAux opcode - data := p.ops.Write(ops.TypeAuxLen) + data := ops.Write(p.ops, ops.TypeAuxLen) data[0] = byte(ops.TypeAux) } @@ -180,7 +180,7 @@ func (p *Path) Line(delta f32.Point) { // LineTo moves the pen to the absolute point specified, recording a line. func (p *Path) LineTo(to f32.Point) { - data := p.ops.Write(scene.CommandSize + 4) + data := ops.Write(p.ops, scene.CommandSize+4) bo := binary.LittleEndian bo.PutUint32(data[0:], uint32(p.contour)) p.cmd(data[4:], scene.Line(p.pen, to)) @@ -248,7 +248,7 @@ func (p *Path) Quad(ctrl, to f32.Point) { // QuadTo records a quadratic Bézier from the pen to end // with the control point ctrl, with absolute coordinates. func (p *Path) QuadTo(ctrl, to f32.Point) { - data := p.ops.Write(scene.CommandSize + 4) + data := ops.Write(p.ops, scene.CommandSize+4) bo := binary.LittleEndian bo.PutUint32(data[0:], uint32(p.contour)) p.cmd(data[4:], scene.Quad(p.pen, ctrl, to)) @@ -294,7 +294,7 @@ func (p *Path) CubeTo(ctrl0, ctrl1, to f32.Point) { if ctrl0 == p.pen && ctrl1 == p.pen && to == p.pen { return } - data := p.ops.Write(scene.CommandSize + 4) + data := ops.Write(p.ops, scene.CommandSize+4) bo := binary.LittleEndian bo.PutUint32(data[0:], uint32(p.contour)) p.cmd(data[4:], scene.Cubic(p.pen, ctrl0, ctrl1, to)) diff --git a/op/op.go b/op/op.go index 0ec4033c..a20d8009 100644 --- a/op/op.go +++ b/op/op.go @@ -127,7 +127,7 @@ func Defer(o *Ops, c CallOp) { if c.ops == nil { return } - state := o.Internal.Save() + state := ops.Save(&o.Internal) // Wrap c in a macro that loads the saved state before execution. m := Record(o) state.Load() @@ -135,7 +135,7 @@ func Defer(o *Ops, c CallOp) { c = m.Stop() // A Defer is recorded as a TypeDefer followed by the // wrapped macro. - data := o.Internal.Write(ops.TypeDeferLen) + data := ops.Write(&o.Internal, ops.TypeDeferLen) data[0] = byte(ops.TypeDefer) c.Add(o) } @@ -159,10 +159,10 @@ func Save(o *Ops) SaveStack { const inf = 1e6 bounds := image.Rectangle{Min: image.Pt(-inf, -inf), Max: image.Pt(inf, inf)} { - st.clip.id, st.clip.macroID = o.Internal.PushOp(ops.ClipStack) + st.clip.id, st.clip.macroID = ops.PushOp(&o.Internal, ops.ClipStack) // Push clip stack with no-op (infinite) clipping rect. Copied from clip.Op.Push. bo := binary.LittleEndian - data := o.Internal.Write(ops.TypeClipLen) + data := ops.Write(&o.Internal, ops.TypeClipLen) data[0] = byte(ops.TypeClip) bo.PutUint32(data[1:], uint32(bounds.Min.X)) bo.PutUint32(data[5:], uint32(bounds.Min.Y)) @@ -176,8 +176,8 @@ func Save(o *Ops) SaveStack { func (s SaveStack) Load() { // Pop clip. - s.ops.PopOp(ops.ClipStack, s.clip.id, s.clip.macroID) - data := s.ops.Write(ops.TypePopClipLen) + ops.PopOp(s.ops, ops.ClipStack, s.clip.id, s.clip.macroID) + data := ops.Write(s.ops, ops.TypePopClipLen) data[0] = byte(ops.TypePopClip) s.trans.Pop() @@ -186,18 +186,18 @@ func (s SaveStack) Load() { // Reset the Ops, preparing it for re-use. Reset invalidates // any recorded macros. func (o *Ops) Reset() { - o.Internal.Reset() + ops.Reset(&o.Internal) } // Record a macro of operations. func Record(o *Ops) MacroOp { m := MacroOp{ ops: &o.Internal, - id: o.Internal.PushMacro(), - pc: o.Internal.PC(), + id: ops.PushMacro(&o.Internal), + pc: ops.PCFor(&o.Internal), } // Reserve room for a macro definition. Updated in Stop. - m.ops.Write(ops.TypeMacroLen) + ops.Write(m.ops, ops.TypeMacroLen) m.fill() return m } @@ -205,7 +205,7 @@ func Record(o *Ops) MacroOp { // Stop ends a previously started recording and returns an // operation for replaying it. func (m MacroOp) Stop() CallOp { - m.ops.PopMacro(m.id) + ops.PopMacro(m.ops, m.id) m.fill() return CallOp{ ops: m.ops, @@ -214,7 +214,7 @@ func (m MacroOp) Stop() CallOp { } func (m MacroOp) fill() { - m.ops.FillMacro(m.pc) + ops.FillMacro(m.ops, m.pc) } // Add the recorded list of operations. Add @@ -224,11 +224,11 @@ func (c CallOp) Add(o *Ops) { if c.ops == nil { return } - o.Internal.AddCall(c.ops, c.pc) + ops.AddCall(&o.Internal, c.ops, c.pc) } func (r InvalidateOp) Add(o *Ops) { - data := o.Internal.Write(ops.TypeRedrawLen) + data := ops.Write(&o.Internal, ops.TypeRedrawLen) data[0] = byte(ops.TypeInvalidate) bo := binary.LittleEndian // UnixNano cannot represent the zero time. @@ -253,7 +253,7 @@ func Affine(a f32.Affine2D) TransformOp { // Push the current transformation to the stack and then multiply the // current transformation with t. func (t TransformOp) Push(o *Ops) TransformStack { - id, macroID := o.Internal.PushOp(ops.TransStack) + id, macroID := ops.PushOp(&o.Internal, ops.TransStack) t.add(o, true) return TransformStack{ops: &o.Internal, id: id, macroID: macroID} } @@ -265,7 +265,7 @@ func (t TransformOp) Add(o *Ops) { } func (t TransformOp) add(o *Ops, push bool) { - data := o.Internal.Write(ops.TypeTransformLen) + data := ops.Write(&o.Internal, ops.TypeTransformLen) data[0] = byte(ops.TypeTransform) if push { data[1] = 1 @@ -281,7 +281,7 @@ func (t TransformOp) add(o *Ops, push bool) { } func (t TransformStack) Pop() { - t.ops.PopOp(ops.TransStack, t.id, t.macroID) - data := t.ops.Write(ops.TypePopTransformLen) + ops.PopOp(t.ops, ops.TransStack, t.id, t.macroID) + data := ops.Write(t.ops, ops.TypePopTransformLen) data[0] = byte(ops.TypePopTransform) } diff --git a/op/paint/paint.go b/op/paint/paint.go index f39bafbe..17145f54 100644 --- a/op/paint/paint.go +++ b/op/paint/paint.go @@ -96,12 +96,12 @@ func (i ImageOp) Add(o *op.Ops) { } else if i.src == nil || i.src.Bounds().Empty() { return } - data := o.Internal.Write2(ops.TypeImageLen, i.src, i.handle) + data := ops.Write2(&o.Internal, ops.TypeImageLen, i.src, i.handle) data[0] = byte(ops.TypeImage) } func (c ColorOp) Add(o *op.Ops) { - data := o.Internal.Write(ops.TypeColorLen) + data := ops.Write(&o.Internal, ops.TypeColorLen) data[0] = byte(ops.TypeColor) data[1] = c.Color.R data[2] = c.Color.G @@ -110,7 +110,7 @@ func (c ColorOp) Add(o *op.Ops) { } func (c LinearGradientOp) Add(o *op.Ops) { - data := o.Internal.Write(ops.TypeLinearGradientLen) + data := ops.Write(&o.Internal, ops.TypeLinearGradientLen) data[0] = byte(ops.TypeLinearGradient) bo := binary.LittleEndian @@ -130,7 +130,7 @@ func (c LinearGradientOp) Add(o *op.Ops) { } func (d PaintOp) Add(o *op.Ops) { - data := o.Internal.Write(ops.TypePaintLen) + data := ops.Write(&o.Internal, ops.TypePaintLen) data[0] = byte(ops.TypePaint) }