gpu: don't alias stroked paths with outline paths

The default renderer caches pre-processed paths for efficient re-use,
but failed to distinguish outline paths from stroke paths.

Fixes gio#294

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-10-20 09:59:07 +02:00
parent 9c16954bef
commit aac53ad0b5
3 changed files with 30 additions and 7 deletions
+8 -7
View File
@@ -149,6 +149,8 @@ type quadsOp struct {
} }
type opKey struct { type opKey struct {
outline bool
strokeWidth float32
sx, hx, sy, hy float32 sx, hx, sy, hy float32
ops.Key ops.Key
} }
@@ -904,9 +906,8 @@ func (k opKey) SetTransform(t f32.Affine2D) opKey {
func (d *drawOps) collectOps(r *ops.Reader, viewport f32.Rectangle) { func (d *drawOps) collectOps(r *ops.Reader, viewport f32.Rectangle) {
var ( var (
quads quadsOp quads quadsOp
strWidth float32 state drawState
state drawState
) )
reset := func() { reset := func() {
state = drawState{ state = drawState{
@@ -931,7 +932,7 @@ loop:
d.transStack = d.transStack[:n-1] d.transStack = d.transStack[:n-1]
case ops.TypeStroke: case ops.TypeStroke:
strWidth = decodeStrokeOp(encOp.Data) quads.key.strokeWidth = decodeStrokeOp(encOp.Data)
case ops.TypePath: case ops.TypePath:
encOp, ok = r.Decode() encOp, ok = r.Decode()
@@ -939,11 +940,12 @@ loop:
break loop break loop
} }
quads.aux = encOp.Data[ops.TypeAuxLen:] quads.aux = encOp.Data[ops.TypeAuxLen:]
quads.key = opKey{Key: encOp.Key} quads.key.Key = encOp.Key
case ops.TypeClip: case ops.TypeClip:
var op clipOp var op clipOp
op.decode(encOp.Data) op.decode(encOp.Data)
quads.key.outline = op.outline
bounds := op.bounds bounds := op.bounds
trans, off := splitTransform(state.t) trans, off := splitTransform(state.t)
if len(quads.aux) > 0 { if len(quads.aux) > 0 {
@@ -957,7 +959,7 @@ loop:
op.bounds = v.bounds op.bounds = v.bounds
} else { } else {
pathData, bounds := d.buildVerts( pathData, bounds := d.buildVerts(
quads.aux, trans, op.outline, strWidth, quads.aux, trans, quads.key.outline, quads.key.strokeWidth,
) )
op.bounds = bounds op.bounds = bounds
quads.aux = pathData quads.aux = pathData
@@ -971,7 +973,6 @@ loop:
} }
d.addClipPath(&state, quads.aux, quads.key, op.bounds, off, op.push) d.addClipPath(&state, quads.aux, quads.key, op.bounds, off, op.push)
quads = quadsOp{} quads = quadsOp{}
strWidth = 0
case ops.TypePopClip: case ops.TypePopClip:
for { for {
push := state.cpath.push push := state.cpath.push
+22
View File
@@ -4,6 +4,7 @@ package rendertest
import ( import (
"image" "image"
"image/color"
"math" "math"
"testing" "testing"
@@ -183,3 +184,24 @@ func TestStrokedPathZeroWidth(t *testing.T) {
r.expect(65, 50, transparent) 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) {
})
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB