diff options
author | caryclark <caryclark@google.com> | 2015-06-29 11:41:52 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-29 11:41:52 -0700 |
commit | 218f21ac09c70b98a10cb8e1999b85a22fa0b151 (patch) | |
tree | fa8dc18cd996409a98406536baa38bb2ef22185b | |
parent | f657b1093ef22390d3ce1eb56686a8185408a84f (diff) |
don't fix winding for empty paths
A path can be non-empty but become empty when it is simplified.
For instance, a path with the same rectangle, twice, with opposite
windings.
No contours are created for empty paths, so don't try to
fix their winding direction.
Additionally, check for a NULL coincidence since the
OpBuilder assumes that no concidence edges can be present
after the paths are simplified. This code should not get
called, but it's worth the future-proofing to check.
R=fmalita@chromium.org
BUG=502792
Review URL: https://codereview.chromium.org/1218863005
-rw-r--r-- | src/pathops/SkOpBuilder.cpp | 8 | ||||
-rwxr-xr-x | src/pathops/SkOpSpan.cpp | 5 | ||||
-rw-r--r-- | tests/PathOpsBuilderTest.cpp | 15 |
3 files changed, 24 insertions, 4 deletions
diff --git a/src/pathops/SkOpBuilder.cpp b/src/pathops/SkOpBuilder.cpp index 2fbd4f0460..0d229a8c40 100644 --- a/src/pathops/SkOpBuilder.cpp +++ b/src/pathops/SkOpBuilder.cpp @@ -158,9 +158,11 @@ bool SkOpBuilder::resolve(SkPath* result) { *result = original; return false; } - // convert the even odd result back to winding form before accumulating it - FixWinding(&fPathRefs[index]); - sum.addPath(fPathRefs[index]); + if (!fPathRefs[index].isEmpty()) { + // convert the even odd result back to winding form before accumulating it + FixWinding(&fPathRefs[index]); + sum.addPath(fPathRefs[index]); + } } reset(); bool success = Simplify(sum, result); diff --git a/src/pathops/SkOpSpan.cpp b/src/pathops/SkOpSpan.cpp index e89ec3e204..ae4771cffc 100755 --- a/src/pathops/SkOpSpan.cpp +++ b/src/pathops/SkOpSpan.cpp @@ -279,7 +279,10 @@ void SkOpSpan::detach(SkOpPtT* kept) { prev->setNext(next); next->setPrev(prev); this->segment()->detach(this); - this->globalState()->coincidence()->fixUp(this->ptT(), kept); + SkOpCoincidence* coincidence = this->globalState()->coincidence(); + if (coincidence) { + coincidence->fixUp(this->ptT(), kept); + } this->ptT()->setDeleted(); } diff --git a/tests/PathOpsBuilderTest.cpp b/tests/PathOpsBuilderTest.cpp index d36072f077..df77100b01 100644 --- a/tests/PathOpsBuilderTest.cpp +++ b/tests/PathOpsBuilderTest.cpp @@ -135,3 +135,18 @@ DEF_TEST(BuilderIssue3838_3, reporter) { int pixelDiff = comparePaths(reporter, __FUNCTION__, path, result); REPORTER_ASSERT(reporter, pixelDiff == 0); } + +DEF_TEST(BuilderIssue502792_2, reporter) { + SkPath path, pathB; + path.setFillType(SkPath::kWinding_FillType); + path.addRect(0, 0, 1, 1, SkPath::kCW_Direction); + path.addRect(2, 2, 3, 3, SkPath::kCW_Direction); + pathB.setFillType(SkPath::kEvenOdd_FillType); + pathB.addRect(3, 3, 4, 4, SkPath::kCW_Direction); + pathB.addRect(3, 3, 4, 4, SkPath::kCW_Direction); + SkOpBuilder builder; + builder.add(path, kUnion_SkPathOp); + builder.add(pathB, kDifference_SkPathOp); + SkPath result; + builder.resolve(&result); +} |