Index: src/pathops/SkPathOpsOp.cpp |
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp |
index 1105af5d70093be99259c861787f607320614181..f9a4fa3ca6993027dbddabbb28555e5b5d9606eb 100644 |
--- a/src/pathops/SkPathOpsOp.cpp |
+++ b/src/pathops/SkPathOpsOp.cpp |
@@ -98,41 +98,17 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpanBase*>& chase, SkOpSpanBase** |
return NULL; |
} |
-static bool bridgeOp(SkTDArray<SkOpContour* >& contourList, const SkPathOp op, |
+static bool bridgeOp(SkOpContourHead* contourList, const SkPathOp op, |
const int xorMask, const int xorOpMask, SkPathWriter* simple, SkChunkAlloc* allocator) { |
- bool firstContour = true; |
bool unsortable = false; |
- bool topUnsortable = false; |
- bool firstPass = true; |
- SkDPoint lastTopLeft; |
- SkDPoint topLeft = {SK_ScalarMin, SK_ScalarMin}; |
do { |
- SkOpSpanBase* start = NULL; |
- SkOpSpanBase* end = NULL; |
- bool topDone; |
- bool onlyVertical = false; |
- lastTopLeft = topLeft; |
- SkOpSegment* current = FindSortableTop(contourList, firstPass, SkOpAngle::kBinarySingle, |
- &firstContour, &start, &end, &topLeft, &topUnsortable, &topDone, &onlyVertical, |
- allocator); |
- if (!current) { |
- if ((!topUnsortable || firstPass) && !topDone) { |
- SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMin); |
- if (lastTopLeft.fX == SK_ScalarMin && lastTopLeft.fY == SK_ScalarMin) { |
- if (firstPass) { |
- firstPass = false; |
- } else { |
- break; |
- } |
- } |
- topLeft.fX = topLeft.fY = SK_ScalarMin; |
- continue; |
- } |
- break; |
- } else if (onlyVertical) { |
+ SkOpSpan* span = FindSortableTop(contourList); |
+ if (!span) { |
break; |
} |
- firstPass = !topUnsortable || lastTopLeft != topLeft; |
+ SkOpSegment* current = span->segment(); |
+ SkOpSpanBase* start = span->next(); |
+ SkOpSpanBase* end = span; |
SkTDArray<SkOpSpanBase*> chase; |
do { |
if (current->activeOp(start, end, xorMask, xorOpMask, op)) { |
@@ -260,11 +236,13 @@ static void dump_op(const SkPath& one, const SkPath& two, SkPathOp op) { |
} |
#endif |
-bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { |
+bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, |
+ bool expectSuccess) { |
SkChunkAlloc allocator(4096); // FIXME: add a constant expression here, tune |
SkOpContour contour; |
+ SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour); |
SkOpCoincidence coincidence; |
- SkOpGlobalState globalState(&coincidence SkDEBUGPARAMS(&contour)); |
+ SkOpGlobalState globalState(&coincidence, contourList); |
#if DEBUGGING_PATHOPS_FROM_HOST |
dump_op(one, two, op); |
#endif |
@@ -285,7 +263,7 @@ bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { |
subtrahend = &one; |
op = kDifference_SkPathOp; |
} |
-#if DEBUG_SORT || DEBUG_SWAP_TOP |
+#if DEBUG_SORT |
SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault; |
#endif |
// turn path into list of segments |
@@ -303,36 +281,24 @@ bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { |
#endif |
const int xorOpMask = builder.xorMask(); |
- SkTDArray<SkOpContour* > contourList; |
- MakeContourList(&contour, contourList, xorMask == kEvenOdd_PathOpsMask, |
- xorOpMask == kEvenOdd_PathOpsMask); |
- SkOpContour** currentPtr = contourList.begin(); |
- if (!currentPtr) { |
+ if (!SortContourList(&contourList, xorMask == kEvenOdd_PathOpsMask, |
+ xorOpMask == kEvenOdd_PathOpsMask)) { |
result->reset(); |
result->setFillType(fillType); |
return true; |
} |
- if ((*currentPtr)->count() == 0) { |
- SkASSERT((*currentPtr)->next() == NULL); |
- result->reset(); |
- result->setFillType(fillType); |
- return true; |
- } |
- SkOpContour** listEnd = contourList.end(); |
// find all intersections between segments |
+ SkOpContour* current = contourList; |
do { |
- SkOpContour** nextPtr = currentPtr; |
- SkOpContour* current = *currentPtr++; |
- SkOpContour* next; |
- do { |
- next = *nextPtr++; |
- } while (AddIntersectTs(current, next, &coincidence, &allocator) && nextPtr != listEnd); |
- } while (currentPtr != listEnd); |
+ SkOpContour* next = current; |
+ while (AddIntersectTs(current, next, &coincidence, &allocator) |
+ && (next = next->next())) |
+ ; |
+ } while ((current = current->next())); |
#if DEBUG_VALIDATE |
globalState.setPhase(SkOpGlobalState::kWalking); |
#endif |
- // eat through coincident edges |
- if (!HandleCoincidence(&contourList, &coincidence, &allocator, &globalState)) { |
+ if (!HandleCoincidence(contourList, &coincidence, &allocator)) { |
return false; |
} |
// construct closed contours |
@@ -350,3 +316,7 @@ bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { |
} |
return true; |
} |
+ |
+bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { |
+ return OpDebug(one, two, op, result, true); |
+} |