Index: src/pathops/SkPathOpsSimplify.cpp |
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp |
index 14c6837c1ba9936b6555fabaa5adf309474a9460..d37998b448b3b5e0113a4e9b4f0bd1be8ffd6f75 100644 |
--- a/src/pathops/SkPathOpsSimplify.cpp |
+++ b/src/pathops/SkPathOpsSimplify.cpp |
@@ -10,41 +10,17 @@ |
#include "SkPathOpsCommon.h" |
#include "SkPathWriter.h" |
-static bool bridgeWinding(SkTDArray<SkOpContour* >& contourList, SkPathWriter* simple, |
+static bool bridgeWinding(SkOpContourHead* contourList, 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::kUnaryWinding, |
- &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->activeWinding(start, end)) { |
@@ -93,7 +69,6 @@ static bool bridgeWinding(SkTDArray<SkOpContour* >& contourList, SkPathWriter* s |
if (last && !last->chased()) { |
last->setChased(true); |
SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last)); |
- // assert that last isn't already in array |
*chase.append() = last; |
#if DEBUG_WINDING |
SkDebugf("%s chase.append id=%d", __FUNCTION__, last->segment()->debugID()); |
@@ -117,7 +92,7 @@ static bool bridgeWinding(SkTDArray<SkOpContour* >& contourList, SkPathWriter* s |
} |
// returns true if all edges were processed |
-static bool bridgeXor(SkTDArray<SkOpContour* >& contourList, SkPathWriter* simple, |
+static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple, |
SkChunkAlloc* allocator) { |
SkOpSegment* current; |
SkOpSpanBase* start; |
@@ -191,8 +166,9 @@ bool Simplify(const SkPath& path, SkPath* result) { |
// turn path into list of segments |
SkOpCoincidence coincidence; |
SkOpContour contour; |
- SkOpGlobalState globalState(&coincidence SkDEBUGPARAMS(&contour)); |
-#if DEBUG_SORT || DEBUG_SWAP_TOP |
+ SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour); |
+ SkOpGlobalState globalState(&coincidence, contourList); |
+#if DEBUG_SORT |
SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault; |
#endif |
SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState); |
@@ -202,34 +178,22 @@ bool Simplify(const SkPath& path, SkPath* result) { |
#if DEBUG_DUMP_SEGMENTS |
contour.dumpSegments((SkPathOp) -1); |
#endif |
- SkTDArray<SkOpContour* > contourList; |
- MakeContourList(&contour, contourList, false, false); |
- SkOpContour** currentPtr = contourList.begin(); |
- if (!currentPtr) { |
+ if (!SortContourList(&contourList, false, false)) { |
result->reset(); |
result->setFillType(fillType); |
return true; |
} |
- if ((*currentPtr)->count() == 0) { |
- SkASSERT((*currentPtr)->next() == NULL); |
- result->reset(); |
- result->setFillType(fillType); |
- return true; |
- } |
- SkOpContour** listEnd2 = 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 != listEnd2); |
- } while (currentPtr != listEnd2); |
+ SkOpContour* next = current; |
+ while (AddIntersectTs(current, next, &coincidence, &allocator) |
+ && (next = next->next())); |
+ } while ((current = current->next())); |
#if DEBUG_VALIDATE |
globalState.setPhase(SkOpGlobalState::kWalking); |
#endif |
- if (!HandleCoincidence(&contourList, &coincidence, &allocator, &globalState)) { |
+ if (!HandleCoincidence(contourList, &coincidence, &allocator)) { |
return false; |
} |
// construct closed contours |