forked from joejulian/gio
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:
+6
-5
@@ -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
|
||||||
}
|
}
|
||||||
@@ -905,7 +907,6 @@ 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() {
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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 |
Reference in New Issue
Block a user