Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(822)

Unified Diff: src/pathops/SkOpAngle.cpp

Issue 2426753002: break ambiguous angle sorting loop (Closed)
Patch Set: fix linux warning Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pathops/SkOpAngle.h ('k') | src/pathops/SkOpContour.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
}
« no previous file with comments | « src/pathops/SkOpAngle.h ('k') | src/pathops/SkOpContour.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698