diff --git a/op/op.go b/op/op.go index de851ef1..526c229f 100644 --- a/op/op.go +++ b/op/op.go @@ -210,17 +210,22 @@ func (o *Ops) Write(op []byte, refs ...interface{}) { } o.auxLen += len(op) default: - if o.inAux { - o.inAux = false - bo := binary.LittleEndian - bo.PutUint32(o.data[o.auxOff+1:], uint32(o.auxLen)) - } + o.endAux() } o.write(op, refs...) } -func (d *Ops) pc() pc { - return pc{data: len(d.data), refs: len(d.refs)} +func (o *Ops) endAux() { + if !o.inAux { + return + } + o.inAux = false + bo := binary.LittleEndian + bo.PutUint32(o.data[o.auxOff+1:], uint32(o.auxLen)) +} + +func (o *Ops) pc() pc { + return pc{data: len(o.data), refs: len(o.refs)} } // Record a macro of operations. @@ -242,6 +247,7 @@ func (m *MacroOp) Stop() { if !m.recording { panic("not recording") } + m.ops.endAux() m.ops.macroDepth-- m.recording = false m.fill() diff --git a/op/paint/path.go b/op/paint/path.go index 29dd29f6..b259aea3 100644 --- a/op/paint/path.go +++ b/op/paint/path.go @@ -25,14 +25,17 @@ type Path struct { pen f32.Point bounds f32.Rectangle hasBounds bool + macro op.MacroOp } // ClipOp sets the current clip path. type ClipOp struct { + macro op.MacroOp bounds f32.Rectangle } func (p ClipOp) Add(o *op.Ops) { + p.macro.Add(o) data := make([]byte, opconst.TypeClipLen) data[0] = byte(opconst.TypeClip) bo := binary.LittleEndian @@ -46,6 +49,7 @@ func (p ClipOp) Add(o *op.Ops) { // Begin the path, storing the path data and final ClipOp into ops. func (p *Path) Begin(ops *op.Ops) { p.ops = ops + p.macro.Record(ops) } // MoveTo moves the pen to the given position. @@ -280,11 +284,12 @@ func (p *Path) simpleQuadTo(ctrl, to f32.Point) { p.pen = to } -// End the path and add the resulting ClipOp to -// the operation list passed to Init. -func (p *Path) End() { +// End the path and return the resulting ClipOp. +func (p *Path) End() ClipOp { p.end() - ClipOp{ + p.macro.Stop() + return ClipOp{ + macro: p.macro, bounds: p.bounds, - }.Add(p.ops) + } } diff --git a/text/measure.go b/text/measure.go index a948d3a6..092a70e2 100644 --- a/text/measure.go +++ b/text/measure.go @@ -7,7 +7,7 @@ import ( "image" "gioui.org/layout" - "gioui.org/op" + "gioui.org/op/paint" "golang.org/x/image/math/fixed" ) @@ -64,8 +64,8 @@ type Family interface { // Layout returns the text layout for a string given a set of // options. Layout(face Face, size float32, s string, opts LayoutOptions) *Layout - // Path returns the ClipOp outline of a text recorded in a macro. - Shape(face Face, size float32, s String) op.MacroOp + // Path returns the ClipOp outline of a text. + Shape(face Face, size float32, s String) paint.ClipOp } type Alignment uint8 diff --git a/text/shape/lru.go b/text/shape/lru.go index 2f7f429f..7977e159 100644 --- a/text/shape/lru.go +++ b/text/shape/lru.go @@ -3,7 +3,7 @@ package shape import ( - "gioui.org/op" + "gioui.org/op/paint" "gioui.org/text" "golang.org/x/image/font/sfnt" "golang.org/x/image/math/fixed" @@ -28,7 +28,7 @@ type layout struct { type path struct { next, prev *path key pathKey - val op.MacroOp + val paint.ClipOp } type layoutKey struct { @@ -85,16 +85,16 @@ func (l *layoutCache) insert(lt *layout) { lt.next.prev = lt } -func (c *pathCache) Get(k pathKey) (op.MacroOp, bool) { +func (c *pathCache) Get(k pathKey) (paint.ClipOp, bool) { if v, ok := c.m[k]; ok { c.remove(v) c.insert(v) return v.val, true } - return op.MacroOp{}, false + return paint.ClipOp{}, false } -func (c *pathCache) Put(k pathKey, v op.MacroOp) { +func (c *pathCache) Put(k pathKey, v paint.ClipOp) { if c.m == nil { c.m = make(map[pathKey]*path) c.head = new(path) diff --git a/text/shape/lru_test.go b/text/shape/lru_test.go index fa72ea4c..4b35bf79 100644 --- a/text/shape/lru_test.go +++ b/text/shape/lru_test.go @@ -6,7 +6,7 @@ import ( "strconv" "testing" - "gioui.org/op" + "gioui.org/op/paint" ) func TestLayoutLRU(t *testing.T) { @@ -24,7 +24,7 @@ func TestLayoutLRU(t *testing.T) { func TestuPathLRU(t *testing.T) { c := new(pathCache) put := func(i int) { - c.Put(pathKey{str: strconv.Itoa(i)}, op.MacroOp{}) + c.Put(pathKey{str: strconv.Itoa(i)}, paint.ClipOp{}) } get := func(i int) bool { _, ok := c.Get(pathKey{str: strconv.Itoa(i)}) diff --git a/text/shape/measure.go b/text/shape/measure.go index 4041fca0..bb73af9a 100644 --- a/text/shape/measure.go +++ b/text/shape/measure.go @@ -64,7 +64,7 @@ func (f *Family) Layout(face text.Face, size float32, str string, opts text.Layo return l } -func (f *Family) Shape(face text.Face, size float32, str text.String) op.MacroOp { +func (f *Family) Shape(face text.Face, size float32, str text.String) paint.ClipOp { fnt := f.fontFor(face) ppem := fixed.Int26_6(size * 64) pk := pathKey{ @@ -169,14 +169,12 @@ func layoutText(buf *sfnt.Buffer, ppem fixed.Int26_6, str string, f *opentype, o return &text.Layout{Lines: lines} } -func textPath(buf *sfnt.Buffer, ppem fixed.Int26_6, f *opentype, str text.String) op.MacroOp { +func textPath(buf *sfnt.Buffer, ppem fixed.Int26_6, f *opentype, str text.String) paint.ClipOp { var lastPos f32.Point var builder paint.Path ops := new(op.Ops) var x fixed.Int26_6 var advIdx int - var m op.MacroOp - m.Record(ops) builder.Begin(ops) for _, r := range str.String { if !unicode.IsSpace(r) { @@ -229,7 +227,5 @@ func textPath(buf *sfnt.Buffer, ppem fixed.Int26_6, f *opentype, str text.String x += str.Advances[advIdx] advIdx++ } - builder.End() - m.Stop() - return m + return builder.End() }