GrTessellator: fix for even/odd fill type and path holes.

When extracting contours for the even/odd fill type, connected holes
in the interior of a shape don't get rendered correctly.

The fix is to extract the subcontours separately from the outer contour.
To do this, we abort contour extraction the first time we re-encounter
the starting vertex.  This causes the hole to be extracted as a
separate contour.

Bug: 908646
Change-Id: I047b77c74605987c40c12a228fd2898c9aa74e55
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/220776
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White 2019-06-13 13:13:13 -04:00 committed by Skia Commit-Bot
parent f71c3d4a7d
commit 0c72ed3057
3 changed files with 33 additions and 2 deletions

29
gm/crbug_908646.cpp Normal file
View File

@ -0,0 +1,29 @@
/*
* Copyright 2019 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
DEF_SIMPLE_GM(crbug_908646, canvas, 300, 300) {
SkPaint paint;
paint.setAntiAlias(true);
SkPath path;
path.setFillType(SkPath::kEvenOdd_FillType);
path.moveTo(50, 50);
path.lineTo(50, 300);
path.lineTo(250, 300);
path.lineTo(250, 50);
path.moveTo(200, 100);
path.lineTo(100, 100);
path.lineTo(150, 200);
path.moveTo(100, 250);
path.lineTo(150, 150);
path.lineTo(200, 250);
canvas->drawPath(path, paint);
}

View File

@ -108,6 +108,7 @@ gm_sources = [
"$_gm/crbug_892988.cpp",
"$_gm/crbug_899512.cpp",
"$_gm/crbug_905548.cpp",
"$_gm/crbug_908646.cpp",
"$_gm/crbug_913349.cpp",
"$_gm/crbug_918512.cpp",
"$_gm/crbug_938592.cpp",

View File

@ -2109,7 +2109,8 @@ void stroke_boundary(EdgeList* boundary, VertexList* innerMesh, VertexList* oute
void extract_boundary(EdgeList* boundary, Edge* e, SkPath::FillType fillType, SkArenaAlloc& alloc) {
LOG("\nextracting boundary\n");
bool down = apply_fill_type(fillType, e->fWinding);
while (e) {
Vertex* start = down ? e->fTop : e->fBottom;
do {
e->fWinding = down ? 1 : -1;
Edge* next;
e->fLine.normalize();
@ -2136,7 +2137,7 @@ void extract_boundary(EdgeList* boundary, Edge* e, SkPath::FillType fillType, Sk
}
disconnect(e);
e = next;
}
} while (e && (down ? e->fTop : e->fBottom) != start);
}
// Stage 5b: Extract boundaries from mesh, simplify and stroke them into a new mesh.