GrTessellator: fix winding merged to zero on split edge.

Occasionally, the top edge of a split edge can be merged out of
existence (if it can't be mathematically distinguished from one of its
adjacent edges). In this case, we need to save its winding count
before it's merged so that the other half of the split doesn't also
get zero winding.

NOTE: this adds a new test case to the concavepaths GM.

Bug: skia:7785
Change-Id: Iff8b0a2ed3065e57b737ff915ff436146987caf6
Reviewed-on: https://skia-review.googlesource.com/131223
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White 2018-06-01 09:49:39 -04:00 committed by Skia Commit-Bot
parent 39ccf5d386
commit 531a48ed78
2 changed files with 21 additions and 1 deletions

View File

@ -234,6 +234,24 @@ void test_partners(SkCanvas* canvas, const SkPaint& paint) {
canvas->restore();
}
// A split edge causes one half to be merged to zero winding (destroyed).
// Test that the other half of the split doesn't also get zero winding.
void test_winding_merged_to_zero(SkCanvas* canvas, const SkPaint& paint) {
SkPath path;
canvas->save();
canvas->translate(400, 350);
path.moveTo(20, 80);
path.moveTo(70, -0.000001f);
path.lineTo(70, 0.0);
path.lineTo(60, -30.0);
path.lineTo(40, 20.0);
path.moveTo(50, 50.0);
path.lineTo(50, -50.0);
path.lineTo(10, 50.0);
canvas->drawPath(path, paint);
canvas->restore();
}
// Monotone test 1 (point in the middle)
void test_monotone_1(SkCanvas* canvas, const SkPaint& paint) {
SkPath path;
@ -429,6 +447,7 @@ DEF_SIMPLE_GM(concavepaths, canvas, 500, 600) {
test_stairstep2(canvas, paint);
test_overlapping(canvas, paint);
test_partners(canvas, paint);
test_winding_merged_to_zero(canvas, paint);
test_monotone_1(canvas, paint);
test_monotone_2(canvas, paint);
test_monotone_3(canvas, paint);

View File

@ -1082,6 +1082,7 @@ void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Vertex** current,
v->fID, v->fPoint.fX, v->fPoint.fY);
Vertex* top;
Vertex* bottom;
int winding = edge->fWinding;
if (c.sweep_lt(v->fPoint, edge->fTop->fPoint)) {
top = v;
bottom = edge->fTop;
@ -1095,7 +1096,7 @@ void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Vertex** current,
bottom = edge->fBottom;
set_bottom(edge, v, activeEdges, current, c);
}
Edge* newEdge = alloc.make<Edge>(top, bottom, edge->fWinding, edge->fType);
Edge* newEdge = alloc.make<Edge>(top, bottom, winding, edge->fType);
insert_edge_below(newEdge, top, c);
insert_edge_above(newEdge, bottom, c);
merge_collinear_edges(newEdge, activeEdges, current, c);