| Index: src/pathops/SkOpAngle.cpp
|
| diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp
|
| index 62cf4b0e3abca23028415c56f6f1af3e9ff533e1..094b22c7e5bf622563244308d23b68451cd0d300 100644
|
| --- a/src/pathops/SkOpAngle.cpp
|
| +++ b/src/pathops/SkOpAngle.cpp
|
| @@ -321,9 +321,11 @@ recomputeSector:
|
| fUnorderable = true;
|
| return false;
|
| }
|
| + int saveEnd = fEnd;
|
| fEnd = checkEnd - step;
|
| setSpans();
|
| setSector();
|
| + fEnd = saveEnd;
|
| return !fUnorderable;
|
| }
|
|
|
| @@ -658,6 +660,9 @@ void SkOpAngle::insert(SkOpAngle* angle) {
|
| }
|
| SkOpAngle* next = fNext;
|
| if (next->fNext == this) {
|
| + if (angle->overlap(*this)) {
|
| + return;
|
| + }
|
| if (singleton || angle->after(this)) {
|
| this->fNext = angle;
|
| angle->fNext = next;
|
| @@ -671,6 +676,9 @@ void SkOpAngle::insert(SkOpAngle* angle) {
|
| SkOpAngle* last = this;
|
| do {
|
| SkASSERT(last->fNext == next);
|
| + if (angle->overlap(*last) || angle->overlap(*next)) {
|
| + return;
|
| + }
|
| if (angle->after(last)) {
|
| last->fNext = angle;
|
| angle->fNext = next;
|
| @@ -701,6 +709,33 @@ SkOpSpan* SkOpAngle::lastMarked() const {
|
| return fLastMarked;
|
| }
|
|
|
| +bool SkOpAngle::loopContains(const SkOpAngle& test) const {
|
| + if (!fNext) {
|
| + return false;
|
| + }
|
| + const SkOpAngle* first = this;
|
| + const SkOpAngle* loop = this;
|
| + const SkOpSegment* tSegment = test.fSegment;
|
| + double tStart = tSegment->span(test.fStart).fT;
|
| + double tEnd = tSegment->span(test.fEnd).fT;
|
| + do {
|
| + const SkOpSegment* lSegment = loop->fSegment;
|
| + // FIXME : use precisely_equal ? or compare points exactly ?
|
| + if (lSegment != tSegment) {
|
| + continue;
|
| + }
|
| + double lStart = lSegment->span(loop->fStart).fT;
|
| + if (lStart != tEnd) {
|
| + continue;
|
| + }
|
| + double lEnd = lSegment->span(loop->fEnd).fT;
|
| + if (lEnd == tStart) {
|
| + return true;
|
| + }
|
| + } while ((loop = loop->fNext) != first);
|
| + return false;
|
| +}
|
| +
|
| int SkOpAngle::loopCount() const {
|
| int count = 0;
|
| const SkOpAngle* first = this;
|
| @@ -813,6 +848,23 @@ unorderable:
|
| return true;
|
| }
|
|
|
| +bool SkOpAngle::overlap(const SkOpAngle& other) const {
|
| + int min = SkTMin(fStart, fEnd);
|
| + const SkOpSpan& span = fSegment->span(min);
|
| + const SkOpSegment* oSeg = other.fSegment;
|
| + int oMin = SkTMin(other.fStart, other.fEnd);
|
| + const SkOpSpan& oSpan = oSeg->span(oMin);
|
| + if (!span.fSmall && !oSpan.fSmall) {
|
| + return false;
|
| + }
|
| + if (fSegment->span(fStart).fPt != oSeg->span(other.fStart).fPt) {
|
| + return false;
|
| + }
|
| + // see if small span is contained by opposite span
|
| + return span.fSmall ? oSeg->containsPt(fSegment->span(fEnd).fPt, other.fEnd, other.fStart)
|
| + : fSegment->containsPt(oSeg->span(other.fEnd).fPt, fEnd, fStart);
|
| +}
|
| +
|
| // OPTIMIZE: if this shows up in a profile, add a previous pointer
|
| // as is, this should be rarely called
|
| SkOpAngle* SkOpAngle::previous() const {
|
|
|