diff --git a/gpu/gpu.go b/gpu/gpu.go index 0ca6b689..a01eb1ff 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -149,6 +149,8 @@ type quadsOp struct { } type opKey struct { + outline bool + strokeWidth float32 sx, hx, sy, hy float32 ops.Key } @@ -904,9 +906,8 @@ func (k opKey) SetTransform(t f32.Affine2D) opKey { func (d *drawOps) collectOps(r *ops.Reader, viewport f32.Rectangle) { var ( - quads quadsOp - strWidth float32 - state drawState + quads quadsOp + state drawState ) reset := func() { state = drawState{ @@ -931,7 +932,7 @@ loop: d.transStack = d.transStack[:n-1] case ops.TypeStroke: - strWidth = decodeStrokeOp(encOp.Data) + quads.key.strokeWidth = decodeStrokeOp(encOp.Data) case ops.TypePath: encOp, ok = r.Decode() @@ -939,11 +940,12 @@ loop: break loop } quads.aux = encOp.Data[ops.TypeAuxLen:] - quads.key = opKey{Key: encOp.Key} + quads.key.Key = encOp.Key case ops.TypeClip: var op clipOp op.decode(encOp.Data) + quads.key.outline = op.outline bounds := op.bounds trans, off := splitTransform(state.t) if len(quads.aux) > 0 { @@ -957,7 +959,7 @@ loop: op.bounds = v.bounds } else { pathData, bounds := d.buildVerts( - quads.aux, trans, op.outline, strWidth, + quads.aux, trans, quads.key.outline, quads.key.strokeWidth, ) op.bounds = bounds quads.aux = pathData @@ -971,7 +973,6 @@ loop: } d.addClipPath(&state, quads.aux, quads.key, op.bounds, off, op.push) quads = quadsOp{} - strWidth = 0 case ops.TypePopClip: for { push := state.cpath.push diff --git a/gpu/internal/rendertest/clip_test.go b/gpu/internal/rendertest/clip_test.go index dbee98fc..22703617 100644 --- a/gpu/internal/rendertest/clip_test.go +++ b/gpu/internal/rendertest/clip_test.go @@ -4,6 +4,7 @@ package rendertest import ( "image" + "image/color" "math" "testing" @@ -183,3 +184,24 @@ func TestStrokedPathZeroWidth(t *testing.T) { r.expect(65, 50, transparent) }) } + +func TestPathReuse(t *testing.T) { + run(t, func(o *op.Ops) { + var path clip.Path + path.Begin(o) + path.MoveTo(f32.Pt(60, 10)) + path.LineTo(f32.Pt(110, 75)) + path.LineTo(f32.Pt(10, 75)) + path.Close() + spec := path.End() + + outline := clip.Outline{Path: spec}.Op().Push(o) + paint.Fill(o, color.NRGBA{R: 0xFF, A: 0xFF}) + outline.Pop() + + stroke := clip.Stroke{Path: spec, Width: 3}.Op().Push(o) + paint.Fill(o, color.NRGBA{B: 0xFF, A: 0xFF}) + stroke.Pop() + }, func(r result) { + }) +} diff --git a/gpu/internal/rendertest/refs/TestPathReuse.png b/gpu/internal/rendertest/refs/TestPathReuse.png new file mode 100644 index 00000000..7a178e54 Binary files /dev/null and b/gpu/internal/rendertest/refs/TestPathReuse.png differ