gpu: close outline paths if not already closed

The new compute renderer is much less tolerant of discontinuous paths.
In particular, it requires that clip outlines form a closed loop.

Fixes TestPaintArc when GIORENDERER=forcecompute.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-01-01 15:31:04 +01:00
parent 62a1d8ae6e
commit 79016bcc4a
+24 -2
View File
@@ -1342,7 +1342,7 @@ func (d *drawOps) buildVerts(aux []byte, tr f32.Affine2D, outline bool, stroke c
case stroke.Width > 0:
// Stroke path.
quads := make(strokeQuads, 0, 2*len(aux)/(ops.QuadSize+4))
for qi := 0; len(aux) >= (ops.QuadSize + 4); qi++ {
for len(aux) >= ops.QuadSize+4 {
quad := strokeQuad{
contour: bo.Uint32(aux),
quad: ops.DecodeQuad(aux[4:]),
@@ -1360,15 +1360,37 @@ func (d *drawOps) buildVerts(aux []byte, tr f32.Affine2D, outline bool, stroke c
case outline:
// Outline path.
for qi := 0; len(aux) >= (ops.QuadSize + 4); qi++ {
first := true
var firstPt, lastPt f32.Point
for len(aux) >= ops.QuadSize+4 {
d.qs.contour = bo.Uint32(aux)
quad := ops.DecodeQuad(aux[4:])
quad = quad.Transform(tr)
if first {
first = false
firstPt = quad.From
lastPt = quad.From
}
if quad.From != lastPt {
if lastPt != firstPt {
// Close outline before starting a new.
mid := firstPt.Add(lastPt).Mul(.5)
d.qs.splitAndEncode(ops.Quad{From: lastPt, To: firstPt, Ctrl: mid})
}
firstPt = quad.From
}
lastPt = quad.To
d.qs.splitAndEncode(quad)
aux = aux[ops.QuadSize+4:]
}
// Close last outline if necessary.
if !first && lastPt != firstPt {
mid := firstPt.Add(lastPt).Mul(.5)
d.qs.splitAndEncode(ops.Quad{From: lastPt, To: firstPt, Ctrl: mid})
}
}
fillMaxY(d.vertCache[startLength:])