path ops work in progress
fix bugs in tests on 32 bit release
Most changes revolve around pinning computed t values
very close to zero and one.
git-svn-id: http://skia.googlecode.com/svn/trunk@8745 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pathops/SkDLineIntersection.cpp b/src/pathops/SkDLineIntersection.cpp
index 8b02030..93f0353 100644
--- a/src/pathops/SkDLineIntersection.cpp
+++ b/src/pathops/SkDLineIntersection.cpp
@@ -158,7 +158,7 @@
return result;
}
double xIntercept = line[0].fX + fT[0][0] * (line[1].fX - line[0].fX);
- if (xIntercept > right || xIntercept < left) {
+ if (!precisely_between(left, xIntercept, right)) {
return fUsed = 0;
}
return result;
@@ -172,7 +172,7 @@
break;
case 1: {
double xIntercept = line[0].fX + fT[0][0] * (line[1].fX - line[0].fX);
- if (xIntercept > right || xIntercept < left) {
+ if (!precisely_between(left, xIntercept, right)) {
return fUsed = 0;
}
fT[1][0] = (xIntercept - left) / (right - left);
@@ -213,7 +213,7 @@
if (min > max) {
SkTSwap(min, max);
}
- if (min > x || max < x) {
+ if (!precisely_between(min, x, max)) {
return fUsed = 0;
}
if (AlmostEqualUlps(min, max)) {
@@ -233,7 +233,7 @@
break;
case 1: {
double yIntercept = line[0].fY + fT[0][0] * (line[1].fY - line[0].fY);
- if (yIntercept > bottom || yIntercept < top) {
+ if (!precisely_between(top, yIntercept, bottom)) {
return fUsed = 0;
}
fT[1][0] = (yIntercept - top) / (bottom - top);
diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp
index 7cdfd8c..f67dfd0 100644
--- a/src/pathops/SkOpAngle.cpp
+++ b/src/pathops/SkOpAngle.cpp
@@ -58,7 +58,7 @@
return fSide < rh.fSide;
}
// see if either curve can be lengthened and try the tangent compare again
- if (cmp && (*fSpans)[fEnd].fOther != rh.fSegment // tangents not absolutely identical
+ if (/* cmp && */ (*fSpans)[fEnd].fOther != rh.fSegment // tangents not absolutely identical
&& (*rh.fSpans)[rh.fEnd].fOther != fSegment) { // and not intersecting
SkOpAngle longer = *this;
SkOpAngle rhLonger = rh;
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
index 30e78f5..e221f68 100644
--- a/src/pathops/SkOpSegment.cpp
+++ b/src/pathops/SkOpSegment.cpp
@@ -214,8 +214,12 @@
SkPoint angle0Pt = (*CurvePointAtT[angles[0].verb()])(angles[0].pts(),
(*angles[0].spans())[angles[0].start()].fT);
SkPoint newPt = (*CurvePointAtT[fVerb])(fPts, fTs[start].fT);
- SkASSERT(AlmostEqualUlps(angle0Pt.fX, newPt.fX));
- SkASSERT(AlmostEqualUlps(angle0Pt.fY, newPt.fY));
+ bool match = AlmostEqualUlps(angle0Pt.fX, newPt.fX);
+ match &= AlmostEqualUlps(angle0Pt.fY, newPt.fY);
+ if (!match) {
+ SkDebugf("%s no match\n", __FUNCTION__);
+ SkASSERT(0);
+ }
}
#endif
angle->set(fPts, fVerb, this, start, end, fTs);
@@ -394,13 +398,11 @@
// add 2 to edge or out of range values to get T extremes
void SkOpSegment::addOtherT(int index, double otherT, int otherIndex) {
SkOpSpan& span = fTs[index];
-#if PIN_ADD_T
- if (precisely_less_than_zero(otherT)) {
+ if (precisely_zero(otherT)) {
otherT = 0;
- } else if (precisely_greater_than_one(otherT)) {
+ } else if (precisely_equal(otherT, 1)) {
otherT = 1;
}
-#endif
span.fOtherT = otherT;
span.fOtherIndex = otherIndex;
}
@@ -418,6 +420,11 @@
// add non-coincident intersection. Resulting edges are sorted in T.
int SkOpSegment::addT(SkOpSegment* other, const SkPoint& pt, double newT) {
+ if (precisely_zero(newT)) {
+ newT = 0;
+ } else if (precisely_equal(newT, 1)) {
+ newT = 1;
+ }
// FIXME: in the pathological case where there is a ton of intercepts,
// binary search?
int insertedAt = -1;
@@ -2721,9 +2728,7 @@
SkDebugf(" tStart=%1.9g tEnd=%1.9g", sSpan.fT, eSpan.fT);
#endif
SkDebugf(" sign=%d windValue=%d windSum=", angle.sign(), mSpan.fWindValue);
- #ifdef SK_DEBUG
- winding_printf(mSpan.fWindSum);
- #endif
+ winding_printf(mSpan.fWindSum);
int last, wind;
if (opp) {
last = oppLastSum;
diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
index f4f2aa5..093bf60 100644
--- a/src/pathops/SkOpSegment.h
+++ b/src/pathops/SkOpSegment.h
@@ -134,12 +134,6 @@
fOppXor = isOppXor;
}
- void setSpanT(int index, double t) {
- SkOpSpan& span = fTs[index];
- span.fT = t;
- span.fOther->fTs[span.fOtherIndex].fOtherT = t;
- }
-
void setUpWinding(int index, int endIndex, int* maxWinding, int* sumWinding) {
int deltaSum = spanSign(index, endIndex);
*maxWinding = *sumWinding;
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index bef129c..ece3b14 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -28,7 +28,9 @@
num = str[idx] >= '0' && str[idx] <= '9';
}
}
+#endif
+#if DEBUG_SORT || DEBUG_SWAP_TOP
bool valid_wind(int wind) {
return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
}
diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h
index a642af4..b11bd76 100644
--- a/src/pathops/SkPathOpsDebug.h
+++ b/src/pathops/SkPathOpsDebug.h
@@ -32,8 +32,6 @@
#if defined SK_DEBUG || !FORCE_RELEASE
void mathematica_ize(char* str, size_t bufferSize);
-bool valid_wind(int winding);
-void winding_printf(int winding);
extern int gDebugMaxWindSum;
extern int gDebugMaxWindValue;
@@ -56,6 +54,7 @@
#define DEBUG_FLOW 0
#define DEBUG_MARK_DONE 0
#define DEBUG_PATH_CONSTRUCTION 0
+#define DEBUG_SHOW_TEST_NAME 0
#define DEBUG_SHOW_TEST_PROGRESS 0
#define DEBUG_SHOW_WINDING 0
#define DEBUG_SORT 0
@@ -81,6 +80,7 @@
#define DEBUG_FLOW 1
#define DEBUG_MARK_DONE 1
#define DEBUG_PATH_CONSTRUCTION 1
+#define DEBUG_SHOW_TEST_NAME 1
#define DEBUG_SHOW_TEST_PROGRESS 1
#define DEBUG_SHOW_WINDING 0
#define DEBUG_SORT 1
@@ -123,6 +123,9 @@
#if DEBUG_SORT || DEBUG_SWAP_TOP
extern int gDebugSortCountDefault;
extern int gDebugSortCount;
+
+bool valid_wind(int winding);
+void winding_printf(int winding);
#endif
#if DEBUG_ACTIVE_OP
diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h
index aadaca8..c3c0cd5 100644
--- a/src/pathops/SkPathOpsTypes.h
+++ b/src/pathops/SkPathOpsTypes.h
@@ -177,6 +177,11 @@
: approximately_negative(b - a) && approximately_negative(c - b);
}
+inline bool precisely_between(double a, double b, double c) {
+ return a <= c ? precisely_negative(a - b) && precisely_negative(b - c)
+ : precisely_negative(b - a) && precisely_negative(c - b);
+}
+
// returns true if (a <= b <= c) || (a >= b >= c)
inline bool between(double a, double b, double c) {
SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0));