| Index: src/pathops/SkPathOpsOp.cpp
|
| diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp
|
| index 1b7b03b95ba6e2b28f78675dbb967055cfa1c1fe..130d4983f9cc2d728ebe80ade042a0b0ccee1dbf 100644
|
| --- a/src/pathops/SkPathOpsOp.cpp
|
| +++ b/src/pathops/SkPathOpsOp.cpp
|
| @@ -9,23 +9,20 @@
|
| #include "SkPathOpsCommon.h"
|
| #include "SkPathWriter.h"
|
|
|
| -// FIXME: this and find chase should be merge together, along with
|
| -// other code that walks winding in angles
|
| -// OPTIMIZATION: Probably, the walked winding should be rolled into the angle structure
|
| -// so it isn't duplicated by walkers like this one
|
| -static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int& nextStart, int& nextEnd) {
|
| +static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int* tIndex, int* endIndex) {
|
| while (chase.count()) {
|
| SkOpSpan* span;
|
| chase.pop(&span);
|
| const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex);
|
| SkOpSegment* segment = backPtr.fOther;
|
| - nextStart = backPtr.fOtherIndex;
|
| - SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles;
|
| - int done = 0;
|
| - if (segment->activeAngle(nextStart, &done, &angles)) {
|
| - SkOpAngle* last = angles.end() - 1;
|
| - nextStart = last->start();
|
| - nextEnd = last->end();
|
| + *tIndex = backPtr.fOtherIndex;
|
| + bool sortable = true;
|
| + bool done = true;
|
| + *endIndex = -1;
|
| + if (const SkOpAngle* last = segment->activeAngle(*tIndex, tIndex, endIndex, &done,
|
| + &sortable)) {
|
| + *tIndex = last->start();
|
| + *endIndex = last->end();
|
| #if TRY_ROTATE
|
| *chase.insert(0) = span;
|
| #else
|
| @@ -33,52 +30,31 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int& nextStart, int
|
| #endif
|
| return last->segment();
|
| }
|
| - if (done == angles.count()) {
|
| + if (done) {
|
| continue;
|
| }
|
| - SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted;
|
| - bool sortable = SkOpSegment::SortAngles(angles, &sorted,
|
| - SkOpSegment::kMayBeUnordered_SortAngleKind);
|
| - int angleCount = sorted.count();
|
| -#if DEBUG_SORT
|
| - sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0, sortable);
|
| -#endif
|
| if (!sortable) {
|
| continue;
|
| }
|
| // find first angle, initialize winding to computed fWindSum
|
| - int firstIndex = -1;
|
| - const SkOpAngle* angle;
|
| - bool foundAngle = true;
|
| + const SkOpAngle* angle = segment->spanToAngle(*tIndex, *endIndex);
|
| + const SkOpAngle* firstAngle = angle;
|
| + SkDEBUGCODE(bool loop = false);
|
| + int winding;
|
| do {
|
| - ++firstIndex;
|
| - if (firstIndex >= angleCount) {
|
| - foundAngle = false;
|
| - break;
|
| - }
|
| - angle = sorted[firstIndex];
|
| + angle = angle->next();
|
| + SkASSERT(angle != firstAngle || !loop);
|
| + SkDEBUGCODE(loop |= angle == firstAngle);
|
| segment = angle->segment();
|
| - } while (segment->windSum(angle) == SK_MinS32);
|
| - if (!foundAngle) {
|
| - continue;
|
| - }
|
| - #if DEBUG_SORT
|
| - segment->debugShowSort(__FUNCTION__, sorted, firstIndex, sortable);
|
| - #endif
|
| + winding = segment->windSum(angle);
|
| + } while (winding == SK_MinS32);
|
| int sumMiWinding = segment->updateWindingReverse(angle);
|
| int sumSuWinding = segment->updateOppWindingReverse(angle);
|
| if (segment->operand()) {
|
| SkTSwap<int>(sumMiWinding, sumSuWinding);
|
| }
|
| - int nextIndex = firstIndex + 1;
|
| - int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
|
| SkOpSegment* first = NULL;
|
| - do {
|
| - SkASSERT(nextIndex != firstIndex);
|
| - if (nextIndex == angleCount) {
|
| - nextIndex = 0;
|
| - }
|
| - angle = sorted[nextIndex];
|
| + while ((angle = angle->next()) != firstAngle) {
|
| segment = angle->segment();
|
| int start = angle->start();
|
| int end = angle->end();
|
| @@ -88,13 +64,13 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int& nextStart, int
|
| if (!segment->done(angle)) {
|
| if (!first) {
|
| first = segment;
|
| - nextStart = start;
|
| - nextEnd = end;
|
| + *tIndex = start;
|
| + *endIndex = end;
|
| }
|
| (void) segment->markAngle(maxWinding, sumWinding, oppMaxWinding,
|
| oppSumWinding, angle);
|
| }
|
| - } while (++nextIndex != lastIndex);
|
| + }
|
| if (first) {
|
| #if TRY_ROTATE
|
| *chase.insert(0) = span;
|
| @@ -160,9 +136,6 @@ static bool bridgeOp(SkTArray<SkOpContour*, true>& contourList, const SkPathOp o
|
| if (current->activeOp(index, endIndex, xorMask, xorOpMask, op)) {
|
| do {
|
| if (!unsortable && current->done()) {
|
| - #if DEBUG_ACTIVE_SPANS
|
| - DebugShowActiveSpans(contourList);
|
| - #endif
|
| if (simple->isEmpty()) {
|
| simple->init();
|
| }
|
| @@ -199,7 +172,6 @@ static bool bridgeOp(SkTArray<SkOpContour*, true>& contourList, const SkPathOp o
|
| if (!unsortable && !simple->isEmpty()) {
|
| unsortable = current->checkSmall(min);
|
| }
|
| - SkASSERT(unsortable || simple->isEmpty());
|
| if (!current->done(min)) {
|
| current->addCurveTo(index, endIndex, simple, true);
|
| current->markDoneBinary(min);
|
| @@ -208,11 +180,13 @@ static bool bridgeOp(SkTArray<SkOpContour*, true>& contourList, const SkPathOp o
|
| simple->close();
|
| } else {
|
| SkOpSpan* last = current->markAndChaseDoneBinary(index, endIndex);
|
| - if (last && !last->fLoop) {
|
| + if (last && !last->fChased && !last->fLoop) {
|
| + last->fChased = true;
|
| + SkASSERT(!SkPathOpsDebug::ChaseContains(chaseArray, last));
|
| *chaseArray.append() = last;
|
| }
|
| }
|
| - current = findChaseOp(chaseArray, index, endIndex);
|
| + current = findChaseOp(chaseArray, &index, &endIndex);
|
| #if DEBUG_ACTIVE_SPANS
|
| DebugShowActiveSpans(contourList);
|
| #endif
|
| @@ -304,7 +278,9 @@ bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) {
|
| for (index = 0; index < contourList.count(); ++index) {
|
| total += contourList[index]->segments().count();
|
| }
|
| - HandleCoincidence(&contourList, total);
|
| + if (!HandleCoincidence(&contourList, total)) {
|
| + return false;
|
| + }
|
| // construct closed contours
|
| SkPathWriter wrapper(*result);
|
| bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper);
|
|
|