aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/pathops/SkOpSegment.cpp20
-rw-r--r--src/pathops/SkOpSegment.h2
-rw-r--r--src/pathops/SkPathOpsOp.cpp5
-rw-r--r--src/pathops/SkPathOpsSimplify.cpp5
4 files changed, 24 insertions, 8 deletions
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
index bfbf9dc687..3bd925c0c3 100644
--- a/src/pathops/SkOpSegment.cpp
+++ b/src/pathops/SkOpSegment.cpp
@@ -599,7 +599,7 @@ SkOpSegment* SkOpSegment::findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBa
continue;
}
if (!activeAngle) {
- (void) nextSegment->markAndChaseDone(nextAngle->start(), nextAngle->end());
+ (void) nextSegment->markAndChaseDone(nextAngle->start(), nextAngle->end(), nullptr);
}
SkOpSpanBase* last = nextAngle->lastMarked();
if (last) {
@@ -695,7 +695,7 @@ SkOpSegment* SkOpSegment::findNextWinding(SkTDArray<SkOpSpanBase*>* chase,
continue;
}
if (!activeAngle) {
- (void) nextSegment->markAndChaseDone(nextAngle->start(), nextAngle->end());
+ (void) nextSegment->markAndChaseDone(nextAngle->start(), nextAngle->end(), nullptr);
}
SkOpSpanBase* last = nextAngle->lastMarked();
if (last) {
@@ -843,7 +843,7 @@ void SkOpSegment::markAllDone() {
} while ((span = span->next()->upCastable()));
}
-SkOpSpanBase* SkOpSegment::markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end) {
+ bool SkOpSegment::markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end, SkOpSpanBase** found) {
int step = start->step(end);
SkOpSpan* minSpan = start->starter(end);
markDone(minSpan);
@@ -851,19 +851,29 @@ SkOpSpanBase* SkOpSegment::markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* e
SkOpSegment* other = this;
SkOpSpan* priorDone = nullptr;
SkOpSpan* lastDone = nullptr;
+ int safetyNet = 100000;
while ((other = other->nextChase(&start, &step, &minSpan, &last))) {
+ if (!--safetyNet) {
+ return false;
+ }
if (other->done()) {
SkASSERT(!last);
break;
}
if (lastDone == minSpan || priorDone == minSpan) {
- return nullptr;
+ if (found) {
+ *found = nullptr;
+ }
+ return true;
}
other->markDone(minSpan);
priorDone = lastDone;
lastDone = minSpan;
}
- return last;
+ if (found) {
+ *found = last;
+ }
+ return true;
}
bool SkOpSegment::markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
index a68b30a289..a38d785250 100644
--- a/src/pathops/SkOpSegment.h
+++ b/src/pathops/SkOpSegment.h
@@ -274,7 +274,7 @@ public:
}
void markAllDone();
- SkOpSpanBase* markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end);
+ bool markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end, SkOpSpanBase** found);
bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
SkOpSpanBase** lastPtr);
bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp
index 09c6f0e1ce..f8b8a65eec 100644
--- a/src/pathops/SkPathOpsOp.cpp
+++ b/src/pathops/SkPathOpsOp.cpp
@@ -157,7 +157,10 @@ static bool bridgeOp(SkOpContourHead* contourList, const SkPathOp op,
}
simple->finishContour();
} else {
- SkOpSpanBase* last = current->markAndChaseDone(start, end);
+ SkOpSpanBase* last;
+ if (!current->markAndChaseDone(start, end, &last)) {
+ return false;
+ }
if (last && !last->chased()) {
last->setChased(true);
SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last));
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp
index d9d0879986..bfb3b8d7c1 100644
--- a/src/pathops/SkPathOpsSimplify.cpp
+++ b/src/pathops/SkPathOpsSimplify.cpp
@@ -58,7 +58,10 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple) {
}
simple->finishContour();
} else {
- SkOpSpanBase* last = current->markAndChaseDone(start, end);
+ SkOpSpanBase* last;
+ if (!current->markAndChaseDone(start, end, &last)) {
+ return false;
+ }
if (last && !last->chased()) {
last->setChased(true);
SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last));