From 0c72ed305790eac315862eed0d23da1203e23b3b Mon Sep 17 00:00:00 2001 From: Stephen White Date: Thu, 13 Jun 2019 13:13:13 -0400 Subject: [PATCH] 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 Commit-Queue: Stephen White --- gm/crbug_908646.cpp | 29 +++++++++++++++++++++++++++++ gn/gm.gni | 1 + src/gpu/GrTessellator.cpp | 5 +++-- 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 gm/crbug_908646.cpp diff --git a/gm/crbug_908646.cpp b/gm/crbug_908646.cpp new file mode 100644 index 0000000000..843799ec22 --- /dev/null +++ b/gm/crbug_908646.cpp @@ -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); +} diff --git a/gn/gm.gni b/gn/gm.gni index 5608d5191d..c007bc25a1 100644 --- a/gn/gm.gni +++ b/gn/gm.gni @@ -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", diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp index 2739ae1515..ef1548381e 100644 --- a/src/gpu/GrTessellator.cpp +++ b/src/gpu/GrTessellator.cpp @@ -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.