| Index: src/pathops/SkPathOpsCommon.cpp
|
| diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp
|
| index 734b5f0819edf601a38f66f5acd2dd4a2585e1ee..98cce15fb29554df3bc5622ac84d53bea331f2e3 100644
|
| --- a/src/pathops/SkPathOpsCommon.cpp
|
| +++ b/src/pathops/SkPathOpsCommon.cpp
|
| @@ -11,6 +11,55 @@
|
| #include "SkPathWriter.h"
|
| #include "SkTSort.h"
|
|
|
| +const SkOpAngle* AngleWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* windingPtr,
|
| + bool* sortablePtr) {
|
| + // find first angle, initialize winding to computed fWindSum
|
| + SkOpSegment* segment = start->segment();
|
| + const SkOpAngle* angle = segment->spanToAngle(start, end);
|
| + if (!angle) {
|
| + *windingPtr = SK_MinS32;
|
| + return NULL;
|
| + }
|
| + bool computeWinding = false;
|
| + const SkOpAngle* firstAngle = angle;
|
| + bool loop = false;
|
| + bool unorderable = false;
|
| + int winding = SK_MinS32;
|
| + do {
|
| + angle = angle->next();
|
| + unorderable |= angle->unorderable();
|
| + if ((computeWinding = unorderable || (angle == firstAngle && loop))) {
|
| + break; // if we get here, there's no winding, loop is unorderable
|
| + }
|
| + loop |= angle == firstAngle;
|
| + segment = angle->segment();
|
| + winding = segment->windSum(angle);
|
| + } while (winding == SK_MinS32);
|
| + // if the angle loop contains an unorderable span, the angle order may be useless
|
| + // directly compute the winding in this case for each span
|
| + if (computeWinding) {
|
| + firstAngle = angle;
|
| + winding = SK_MinS32;
|
| + do {
|
| + SkOpSpanBase* startSpan = angle->start();
|
| + SkOpSpanBase* endSpan = angle->end();
|
| + SkOpSpan* lesser = startSpan->starter(endSpan);
|
| + int testWinding = lesser->windSum();
|
| + if (testWinding == SK_MinS32) {
|
| + testWinding = lesser->computeWindSum();
|
| + }
|
| + if (testWinding != SK_MinS32) {
|
| + segment = angle->segment();
|
| + winding = testWinding;
|
| + }
|
| + angle = angle->next();
|
| + } while (angle != firstAngle);
|
| + }
|
| + *sortablePtr = !unorderable;
|
| + *windingPtr = winding;
|
| + return angle;
|
| +}
|
| +
|
| SkOpSegment* FindUndone(SkOpContourHead* contourList, SkOpSpanBase** startPtr,
|
| SkOpSpanBase** endPtr) {
|
| SkOpSegment* result;
|
| @@ -31,14 +80,9 @@ SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr,
|
| chase->pop(&span);
|
| SkOpSegment* segment = span->segment();
|
| *startPtr = span->ptT()->next()->span();
|
| - bool sortable = true;
|
| bool done = true;
|
| *endPtr = NULL;
|
| - if (SkOpAngle* last = segment->activeAngle(*startPtr, startPtr, endPtr, &done,
|
| - &sortable)) {
|
| - if (last->unorderable()) {
|
| - continue;
|
| - }
|
| + if (SkOpAngle* last = segment->activeAngle(*startPtr, startPtr, endPtr, &done)) {
|
| *startPtr = last->start();
|
| *endPtr = last->end();
|
| #if TRY_ROTATE
|
| @@ -51,46 +95,38 @@ SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr,
|
| if (done) {
|
| continue;
|
| }
|
| - if (!sortable) {
|
| - continue;
|
| - }
|
| // find first angle, initialize winding to computed wind sum
|
| - const SkOpAngle* angle = segment->spanToAngle(*startPtr, *endPtr);
|
| - if (!angle) {
|
| + int winding;
|
| + bool sortable;
|
| + const SkOpAngle* angle = AngleWinding(*startPtr, *endPtr, &winding, &sortable);
|
| + if (winding == SK_MinS32) {
|
| continue;
|
| }
|
| - const SkOpAngle* firstAngle = angle;
|
| - bool loop = false;
|
| - int winding = SK_MinS32;
|
| - do {
|
| - angle = angle->next();
|
| - if (angle == firstAngle && loop) {
|
| - break; // if we get here, there's no winding, loop is unorderable
|
| - }
|
| - loop |= angle == firstAngle;
|
| + int sumWinding SK_INIT_TO_AVOID_WARNING;
|
| + if (sortable) {
|
| segment = angle->segment();
|
| - winding = segment->windSum(angle);
|
| - } while (winding == SK_MinS32);
|
| - if (winding == SK_MinS32) {
|
| - continue;
|
| + sumWinding = segment->updateWindingReverse(angle);
|
| }
|
| - int sumWinding = segment->updateWindingReverse(angle);
|
| SkOpSegment* first = NULL;
|
| - firstAngle = angle;
|
| + const SkOpAngle* firstAngle = angle;
|
| while ((angle = angle->next()) != firstAngle) {
|
| segment = angle->segment();
|
| SkOpSpanBase* start = angle->start();
|
| SkOpSpanBase* end = angle->end();
|
| int maxWinding;
|
| - segment->setUpWinding(start, end, &maxWinding, &sumWinding);
|
| + if (sortable) {
|
| + segment->setUpWinding(start, end, &maxWinding, &sumWinding);
|
| + }
|
| if (!segment->done(angle)) {
|
| - if (!first) {
|
| + if (!first && (sortable || start->starter(end)->windSum() != SK_MinS32)) {
|
| first = segment;
|
| *startPtr = start;
|
| *endPtr = end;
|
| }
|
| // OPTIMIZATION: should this also add to the chase?
|
| - (void) segment->markAngle(maxWinding, sumWinding, angle);
|
| + if (sortable) {
|
| + (void) segment->markAngle(maxWinding, sumWinding, angle);
|
| + }
|
| }
|
| }
|
| if (first) {
|
|
|