diff options
-rw-r--r-- | src/gpu/GrTessellator.cpp | 17 | ||||
-rw-r--r-- | tests/TessellatingPathRendererTests.cpp | 16 |
2 files changed, 33 insertions, 0 deletions
diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp index 5f25e5a5fb..2cb9adcbf8 100644 --- a/src/gpu/GrTessellator.cpp +++ b/src/gpu/GrTessellator.cpp @@ -1078,6 +1078,17 @@ uint8_t max_edge_alpha(Edge* a, Edge* b) { } } +bool out_of_range_and_collinear(const SkPoint& p, Edge* edge, Comparator& c) { + if (c.sweep_lt(p, edge->fTop->fPoint) && + !Line(p, edge->fBottom->fPoint).dist(edge->fTop->fPoint)) { + return true; + } else if (c.sweep_lt(edge->fBottom->fPoint, p) && + !Line(edge->fTop->fPoint, p).dist(edge->fBottom->fPoint)) { + return true; + } + return false; +} + bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vertex** current, VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) { if (!edge || !other) { @@ -1086,6 +1097,12 @@ bool check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Vert SkPoint p; uint8_t alpha; if (edge->intersect(*other, &p, &alpha) && p.isFinite()) { + // Ignore any out-of-range intersections which are also collinear, + // since the resulting edges would cancel each other out by merging. + if (out_of_range_and_collinear(p, edge, c) || + out_of_range_and_collinear(p, other, c)) { + return false; + } Vertex* v; LOG("found intersection, pt is %g, %g\n", p.fX, p.fY); Vertex* top = *current; diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp index f8b69839aa..dbb328e3e3 100644 --- a/tests/TessellatingPathRendererTests.cpp +++ b/tests/TessellatingPathRendererTests.cpp @@ -347,6 +347,21 @@ static SkPath create_path_22() { return path; } +// A path which contains out-of-range colinear intersections. +static SkPath create_path_23() { + SkPath path; + path.moveTo( 0, 63.39080047607421875); + path.lineTo(-0.70804601907730102539, 63.14350128173828125); + path.lineTo(-7.8608899287380243391e-17, 64.14080047607421875); + path.moveTo( 0, 64.14080047607421875); + path.lineTo(44.285900115966796875, 64.14080047607421875); + path.lineTo( 0, 62.64080047607421875); + path.moveTo(21.434900283813476562, -0.24732701480388641357); + path.lineTo(-0.70804601907730102539, 63.14350128173828125); + path.lineTo(0.70804601907730102539, 63.6381988525390625); + return path; +} + static std::unique_ptr<GrFragmentProcessor> create_linear_gradient_processor(GrContext* ctx) { SkPoint pts[2] = { {0, 0}, {1, 1} }; SkColor colors[2] = { SK_ColorGREEN, SK_ColorBLUE }; @@ -427,5 +442,6 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) { test_path(ctx, rtc.get(), create_path_20(), SkMatrix(), GrAAType::kCoverage); test_path(ctx, rtc.get(), create_path_21(), SkMatrix(), GrAAType::kCoverage); test_path(ctx, rtc.get(), create_path_22()); + test_path(ctx, rtc.get(), create_path_23()); } #endif |