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

Unified Diff: src/pathops/SkOpAngle.cpp

Issue 14798004: path ops -- fix skp bugs (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 7 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/SkIntersections.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
===================================================================
--- src/pathops/SkOpAngle.cpp (revision 9040)
+++ src/pathops/SkOpAngle.cpp (working copy)
@@ -9,6 +9,10 @@
#include "SkPathOpsCurve.h"
#include "SkTSort.h"
+#if DEBUG_SORT || DEBUG_SORT_SINGLE
+#include "SkOpSegment.h"
+#endif
+
// FIXME: this is bogus for quads and cubics
// if the quads and cubics' line from end pt to ctrl pt are coincident,
// there's no obvious way to determine the curve ordering from the
@@ -27,14 +31,10 @@
maybe I could set up LineParameters lazily
*/
-bool SkOpAngle::operator<(const SkOpAngle& rh) const {
- double y = dy();
- double ry = rh.dy();
+static int simple_compare(double x, double y, double rx, double ry) {
if ((y < 0) ^ (ry < 0)) { // OPTIMIZATION: better to use y * ry < 0 ?
return y < 0;
}
- double x = dx();
- double rx = rh.dx();
if (y == 0 && ry == 0 && x * rx < 0) {
return x < rx;
}
@@ -48,6 +48,18 @@
&& !approximately_zero_squared(cmp)) {
return cmp < 0;
}
+ return -1;
+}
+
+bool SkOpAngle::operator<(const SkOpAngle& rh) const {
+ double x = dx();
+ double y = dy();
+ double rx = rh.dx();
+ double ry = rh.dy();
+ int simple = simple_compare(x, y, rx, ry);
+ if (simple >= 0) {
+ return simple;
+ }
// at this point, the initial tangent line is coincident
// see if edges curl away from each other
if (fSide * rh.fSide <= 0 && (!approximately_zero(fSide)
@@ -93,8 +105,10 @@
SkIntersections i, ri;
int roots, rroots;
bool flip = false;
+ bool useThis;
+ bool leftLessThanRight = fSide > 0;
do {
- bool useThis = (len < rlen) ^ flip;
+ useThis = (len < rlen) ^ flip;
const SkDCubic& part = useThis ? fCurvePart : rh.fCurvePart;
SkPath::Verb partVerb = useThis ? fVerb : rh.fVerb;
ray[0] = partVerb == SkPath::kCubic_Verb && part[0].approximatelyEqual(part[1]) ?
@@ -113,28 +127,65 @@
rh.fUnsortable = true;
return this < &rh; // even with no solution, return a stable sort
}
- SkDPoint loc;
+ SkASSERT(fSide != 0 && rh.fSide != 0);
+ SkASSERT(fSide * rh.fSide > 0); // both are the same sign
+ SkDPoint lLoc;
double best = SK_ScalarInfinity;
- SkDVector dxy;
- double dist;
- int index;
- for (index = 0; index < roots; ++index) {
- loc = (*CurveDPointAtT[fVerb])(fPts, i[0][index]);
- dxy = loc - ray[0];
- dist = dxy.lengthSquared();
+#if DEBUG_SORT
+ SkDebugf("lh=%d rh=%d use-lh=%d ray={{%1.9g,%1.9g}, {%1.9g,%1.9g}} %c\n",
+ fSegment->debugID(), rh.fSegment->debugID(), useThis, ray[0].fX, ray[0].fY,
+ ray[1].fX, ray[1].fY, "-+"[fSide > 0]);
+#endif
+ for (int index = 0; index < roots; ++index) {
+ SkDPoint loc = i.pt(index);
+ SkDVector dxy = loc - ray[0];
+ double dist = dxy.lengthSquared();
+#if DEBUG_SORT
+ SkDebugf("best=%1.9g dist=%1.9g loc={%1.9g,%1.9g} dxy={%1.9g,%1.9g}\n",
+ best, dist, loc.fX, loc.fY, dxy.fX, dxy.fY);
+#endif
if (best > dist) {
+ lLoc = loc;
best = dist;
}
}
- for (index = 0; index < rroots; ++index) {
- loc = (*CurveDPointAtT[rh.fVerb])(rh.fPts, ri[0][index]);
- dxy = loc - ray[0];
- dist = dxy.lengthSquared();
+ flip = false;
+ SkDPoint rLoc;
+ for (int index = 0; index < rroots; ++index) {
+ rLoc = ri.pt(index);
+ SkDVector dxy = rLoc - ray[0];
+ double dist = dxy.lengthSquared();
+#if DEBUG_SORT
+ SkDebugf("best=%1.9g dist=%1.9g %c=(fSide < 0) rLoc={%1.9g,%1.9g} dxy={%1.9g,%1.9g}\n",
+ best, dist, "><"[fSide < 0], rLoc.fX, rLoc.fY, dxy.fX, dxy.fY);
+#endif
if (best > dist) {
- return fSide < 0;
+ flip = true;
+ break;
}
}
- return fSide > 0;
+ #if 0
+ SkDVector lRay = lLoc - fCurvePart[0];
+ SkDVector rRay = rLoc - fCurvePart[0];
+ int rayDir = simple_compare(lRay.fX, lRay.fY, rRay.fX, rRay.fY);
+ SkASSERT(rayDir >= 0);
+ if (rayDir < 0) {
+ fUnsortable = true;
+ rh.fUnsortable = true;
+ return this < &rh; // even with no solution, return a stable sort
+ }
+#endif
+ if (flip) {
+ leftLessThanRight = !leftLessThanRight;
+ // rayDir = !rayDir;
+ }
+#if 0 && (DEBUG_SORT || DEBUG_SORT_SINGLE)
+ SkDebugf("%d %c %d (fSide %c 0) loc={{%1.9g,%1.9g}, {%1.9g,%1.9g}} flip=%d rayDir=%d\n",
+ fSegment->debugID(), "><"[leftLessThanRight], rh.fSegment->debugID(),
+ "<>"[fSide > 0], lLoc.fX, lLoc.fY, rLoc.fX, rLoc.fY, flip, rayDir);
+#endif
+// SkASSERT(leftLessThanRight == (bool) rayDir);
+ return leftLessThanRight;
}
bool SkOpAngle::lengthen() {
« no previous file with comments | « src/pathops/SkIntersections.h ('k') | src/pathops/SkOpContour.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698