aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2016-04-05 07:28:48 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-05 07:28:48 -0700
commit5c5cfe24efe4c728e787447dabffe345080d1fb9 (patch)
treec8b9c3d926c3e1806542c30b561a1be9dbceccce /src/pathops
parent3b597388b35967a751fb055d0b8fcc30b443b5a8 (diff)
give up if huge paths have unresolvable coincidence
This fuzzy test has enormous curves with coincidence runs that break numerics. If the computed intersections identify that the span of coincidence has been deleted, give up and return that the path op failed. TBR=reed@google.com BUG=597926 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1854333002 Review URL: https://codereview.chromium.org/1854333002
Diffstat (limited to 'src/pathops')
-rwxr-xr-xsrc/pathops/SkOpCoincidence.cpp11
-rw-r--r--src/pathops/SkOpCoincidence.h2
-rw-r--r--src/pathops/SkPathOpsCommon.cpp4
3 files changed, 13 insertions, 4 deletions
diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp
index c0147bcfd9..130d1daff7 100755
--- a/src/pathops/SkOpCoincidence.cpp
+++ b/src/pathops/SkOpCoincidence.cpp
@@ -634,16 +634,22 @@ void SkOpCoincidence::fixUp(SkOpPtT* deleted, SkOpPtT* kept) {
}
/* this sets up the coincidence links in the segments when the coincidence crosses multiple spans */
-void SkOpCoincidence::mark() {
+bool SkOpCoincidence::mark() {
SkCoincidentSpans* coin = fHead;
if (!coin) {
- return;
+ return true;
}
do {
SkOpSpanBase* end = coin->fCoinPtTEnd->span();
+ if (end->deleted()) {
+ return false;
+ }
SkOpSpanBase* oldEnd = end;
SkOpSpan* start = coin->fCoinPtTStart->span()->starter(&end);
SkOpSpanBase* oEnd = coin->fOppPtTEnd->span();
+ if (oEnd->deleted()) {
+ return false;
+ }
SkOpSpanBase* oOldEnd = oEnd;
SkOpSpanBase* oStart = coin->fOppPtTStart->span()->starter(&oEnd);
bool flipped = (end == oldEnd) != (oEnd == oOldEnd);
@@ -668,6 +674,7 @@ void SkOpCoincidence::mark() {
}
} while (true);
} while ((coin = coin->fNext));
+ return true;
}
bool SkOpCoincidence::overlap(const SkOpPtT* coin1s, const SkOpPtT* coin1e,
diff --git a/src/pathops/SkOpCoincidence.h b/src/pathops/SkOpCoincidence.h
index 96bd21ac48..344866ff36 100644
--- a/src/pathops/SkOpCoincidence.h
+++ b/src/pathops/SkOpCoincidence.h
@@ -92,7 +92,7 @@ public:
return !fHead;
}
- void mark();
+ bool mark();
private:
bool addIfMissing(const SkCoincidentSpans* outer, SkOpPtT* over1s, SkOpPtT* over1e,
diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp
index 829f8a50d5..86a8cb0bef 100644
--- a/src/pathops/SkPathOpsCommon.cpp
+++ b/src/pathops/SkPathOpsCommon.cpp
@@ -494,7 +494,9 @@ bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidenc
}
DEBUG_COINCIDENCE_HEALTH(contourList, "expand2");
// the expanded ranges may not align -- add the missing spans
- coincidence->mark(); // mark spans of coincident segments as coincident
+ if (!coincidence->mark()) { // mark spans of coincident segments as coincident
+ return false;
+ }
DEBUG_COINCIDENCE_HEALTH(contourList, "mark1");
// look for coincidence missed earlier
if (missingCoincidence(contourList, coincidence, allocator)) {