| Index: src/pathops/SkOpAngle.cpp
|
| diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp
|
| index 820b5dceeef83b71a04044ad3d4c16464273cb8c..99f93dd544981acabe770be8177343e358373667 100644
|
| --- a/src/pathops/SkOpAngle.cpp
|
| +++ b/src/pathops/SkOpAngle.cpp
|
| @@ -320,7 +320,7 @@ recomputeSector:
|
| return !fUnorderable;
|
| }
|
|
|
| -int SkOpAngle::convexHullOverlaps(const SkOpAngle* rh) const {
|
| +int SkOpAngle::convexHullOverlaps(const SkOpAngle* rh) {
|
| const SkDVector* sweep = this->fPart.fSweep;
|
| const SkDVector* tweep = rh->fPart.fSweep;
|
| double s0xs1 = sweep[0].crossCheck(sweep[1]);
|
| @@ -593,20 +593,20 @@ SkOpGlobalState* SkOpAngle::globalState() const {
|
|
|
| // OPTIMIZE: if this loops to only one other angle, after first compare fails, insert on other side
|
| // OPTIMIZE: return where insertion succeeded. Then, start next insertion on opposite side
|
| -void SkOpAngle::insert(SkOpAngle* angle) {
|
| +bool SkOpAngle::insert(SkOpAngle* angle) {
|
| if (angle->fNext) {
|
| if (loopCount() >= angle->loopCount()) {
|
| if (!merge(angle)) {
|
| - return;
|
| + return true;
|
| }
|
| } else if (fNext) {
|
| if (!angle->merge(this)) {
|
| - return;
|
| + return true;
|
| }
|
| } else {
|
| angle->insert(this);
|
| }
|
| - return;
|
| + return true;
|
| }
|
| bool singleton = nullptr == fNext;
|
| if (singleton) {
|
| @@ -622,20 +622,27 @@ void SkOpAngle::insert(SkOpAngle* angle) {
|
| angle->fNext = this;
|
| }
|
| debugValidateNext();
|
| - return;
|
| + return true;
|
| }
|
| SkOpAngle* last = this;
|
| + bool flipAmbiguity = false;
|
| do {
|
| SkASSERT(last->fNext == next);
|
| - if (angle->after(last)) {
|
| + if (angle->after(last) ^ (angle->tangentsAmbiguous() & flipAmbiguity)) {
|
| last->fNext = angle;
|
| angle->fNext = next;
|
| debugValidateNext();
|
| - return;
|
| + return true;
|
| }
|
| last = next;
|
| + if (last == this) {
|
| + FAIL_IF(flipAmbiguity);
|
| + // We're in a loop. If a sort was ambiguous, flip it to end the loop.
|
| + flipAmbiguity = true;
|
| + }
|
| next = next->fNext;
|
| } while (true);
|
| + return true;
|
| }
|
|
|
| SkOpSpanBase* SkOpAngle::lastMarked() const {
|
| @@ -815,7 +822,7 @@ void SkOpAngle::set(SkOpSpanBase* start, SkOpSpanBase* end) {
|
| fComputedEnd = fEnd = end;
|
| SkASSERT(start != end);
|
| fNext = nullptr;
|
| - fComputeSector = fComputedSector = fCheckCoincidence = false;
|
| + fComputeSector = fComputedSector = fCheckCoincidence = fTangentsAmbiguous = false;
|
| setSpans();
|
| setSector();
|
| SkDEBUGCODE(fID = start ? start->globalState()->nextAngleID() : -1);
|
| @@ -966,7 +973,7 @@ SkOpSpan* SkOpAngle::starter() {
|
| return fStart->starter(fEnd);
|
| }
|
|
|
| -bool SkOpAngle::tangentsDiverge(const SkOpAngle* rh, double s0xt0) const {
|
| +bool SkOpAngle::tangentsDiverge(const SkOpAngle* rh, double s0xt0) {
|
| if (s0xt0 == 0) {
|
| return false;
|
| }
|
| @@ -991,5 +998,6 @@ bool SkOpAngle::tangentsDiverge(const SkOpAngle* rh, double s0xt0) const {
|
| double tDist = tweep[0].length() * m;
|
| bool useS = fabs(sDist) < fabs(tDist);
|
| double mFactor = fabs(useS ? this->distEndRatio(sDist) : rh->distEndRatio(tDist));
|
| + fTangentsAmbiguous = mFactor >= 50 && mFactor < 200;
|
| return mFactor < 50; // empirically found limit
|
| }
|
|
|