shape ops work in progress

git-svn-id: http://skia.googlecode.com/svn/trunk@4956 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/Simplify.cpp b/experimental/Intersection/Simplify.cpp
index 5fbf4e5..ac6b20d 100644
--- a/experimental/Intersection/Simplify.cpp
+++ b/experimental/Intersection/Simplify.cpp
@@ -1146,51 +1146,10 @@
         int otherInsertedAt = other.addT(otherT, this);
         addOtherT(insertedAt, otherT, otherInsertedAt);
         other.addOtherT(otherInsertedAt, t, insertedAt);
-        int nextDoorWind = SK_MaxS32;
-        if (insertedAt > 0) {
-            const Span& below = fTs[insertedAt - 1];
-            if (t - below.fT < FLT_EPSILON) {
-                nextDoorWind = below.fWindValue;
-            }
-        }
-        if (nextDoorWind == SK_MaxS32 && insertedAt < tCount) {
-            const Span& above = fTs[insertedAt + 1];
-            if (above.fT - t < FLT_EPSILON) {
-                nextDoorWind = above.fWindValue;
-            }
-        }
-        if (nextDoorWind != SK_MaxS32) {
-            Span& newSpan = fTs[insertedAt];
-            newSpan.fWindValue = nextDoorWind;
-            if (!nextDoorWind) {
-                newSpan.fDone = true;
-                ++fDoneSpans;
-            }
-        }
-        nextDoorWind = SK_MaxS32;
-        int oInsertedAt = newSpan.fOtherIndex;
-        if (oIndex > 0) {
-            const Span& oBelow = other.fTs[oInsertedAt - 1];
-            if (otherT - oBelow.fT < FLT_EPSILON) {
-                nextDoorWind = oBelow.fWindValue;
-            }
-        }
-        if (nextDoorWind == SK_MaxS32 && oInsertedAt + 1 < other.fTs.count()) {
-            const Span& oAbove = other.fTs[oInsertedAt + 1];
-            if (oAbove.fT - otherT < FLT_EPSILON) {
-                nextDoorWind = oAbove.fWindValue;
-            }
-        }
-        if (nextDoorWind != SK_MaxS32) {
-            Span& otherSpan = other.fTs[oInsertedAt];
-            otherSpan.fWindValue = nextDoorWind;
-            if (!oWind) {
-                otherSpan.fDone = true;
-                ++(other.fDoneSpans);
-            }
-        }
+        matchWindingValue(insertedAt, t);
+        other.matchWindingValue(otherInsertedAt, otherT);
     }
-
+    
     void addTwoAngles(int start, int end, SkTDArray<Angle>& angles) const {
         // add edge leading into junction
         if (fTs[SkMin32(end, start)].fWindValue > 0) {
@@ -1973,9 +1932,7 @@
                 continue;
             }
         #if DEBUG_MARK_DONE
-            const SkPoint& pt = xyAtT(&span);
-            SkDebugf("%s id=%d index=%d t=%1.9g pt=(%1.9g,%1.9g) wind=%d\n",
-                    __FUNCTION__, fID, lesser, span.fT, pt.fX, pt.fY, winding);
+            debugShowNewWinding(__FUNCTION__, span, winding);
         #endif
             span.fDone = true;
             SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
@@ -1990,9 +1947,7 @@
                 continue;
             }
         #if DEBUG_MARK_DONE
-            const SkPoint& pt = xyAtT(&span);
-            SkDebugf("%s id=%d index=%d t=%1.9g pt=(%1.9g,%1.9g) wind=%d\n",
-                    __FUNCTION__, fID, index, span.fT, pt.fX, pt.fY, winding);
+            debugShowNewWinding(__FUNCTION__, span, winding);
         #endif
             span.fDone = true;
             SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
@@ -2014,9 +1969,7 @@
       //      SkASSERT(span.fWindValue == 1 || winding == 0);
             SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
         #if DEBUG_MARK_DONE
-            const SkPoint& pt = xyAtT(&span);
-            SkDebugf("%s id=%d index=%d t=%1.9g pt=(%1.9g,%1.9g) wind=%d\n",
-                    __FUNCTION__, fID, lesser, span.fT, pt.fX, pt.fY, winding);
+            debugShowNewWinding(__FUNCTION__, span, winding);
         #endif
             SkASSERT(abs(winding) <= gDebugMaxWindSum);
             span.fWindSum = winding;
@@ -2030,15 +1983,37 @@
      //       SkASSERT(span.fWindValue == 1 || winding == 0);
             SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
         #if DEBUG_MARK_DONE
-            const SkPoint& pt = xyAtT(&span);
-            SkDebugf("%s id=%d index=%d t=%1.9g pt=(%1.9g,%1.9g) wind=%d\n",
-                    __FUNCTION__, fID, index, span.fT, pt.fX, pt.fY, winding);
+            debugShowNewWinding(__FUNCTION__, span, winding);
         #endif
             SkASSERT(abs(winding) <= gDebugMaxWindSum);
             span.fWindSum = winding;
         } while (++index < fTs.count() && fTs[index].fT - referenceT < FLT_EPSILON);
     }
 
+    void matchWindingValue(int tIndex, double t) {
+        int nextDoorWind = SK_MaxS32;
+        if (tIndex > 0) {
+            const Span& below = fTs[tIndex - 1];
+            if (t - below.fT < FLT_EPSILON) {
+                nextDoorWind = below.fWindValue;
+            }
+        }
+        if (nextDoorWind == SK_MaxS32 && tIndex + 1 < fTs.count()) {
+            const Span& above = fTs[tIndex + 1];
+            if (above.fT - t < FLT_EPSILON) {
+                nextDoorWind = above.fWindValue;
+            }
+        }
+        if (nextDoorWind != SK_MaxS32) {
+            Span& newSpan = fTs[tIndex];
+            newSpan.fWindValue = nextDoorWind;
+            if (!nextDoorWind) {
+                newSpan.fDone = true;
+                ++fDoneSpans;
+            }
+        }
+    }
+
     // return span if when chasing, two or more radiating spans are not done
     // OPTIMIZATION: ? multiple spans is detected when there is only one valid
     // candidate and the remaining spans have windValue == 0 (canceled by
@@ -2235,8 +2210,8 @@
                 SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
             }
             const Span* span = &fTs[i];
-            SkDebugf(") fT=%d (%1.9g) (%1.9g,%1.9g)", i, fTs[i].fT, 
-                     xAtT(span), yAtT(i));
+            SkDebugf(") t=%1.9g (%1.9g,%1.9g)", fTs[i].fT, 
+                     xAtT(span), yAtT(span));
             const Segment* other = fTs[i].fOther;
             SkDebugf(" other=%d otherT=%1.9g otherIndex=%d windSum=",
                     other->fID, fTs[i].fOtherT, fTs[i].fOtherIndex);
@@ -2250,6 +2225,25 @@
     }
 #endif
 
+#if DEBUG_MARK_DONE
+    void debugShowNewWinding(const char* fun, const Span& span, int winding) {
+        const SkPoint& pt = xyAtT(&span);
+        SkDebugf("%s id=%d", fun, fID);
+        SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+        for (int vIndex = 1; vIndex <= fVerb; ++vIndex) {
+            SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+        }
+        SkDebugf(") t=%1.9g (%1.9g,%1.9g) newWindSum=%d windSum=",
+                span.fT, pt.fX, pt.fY, winding);
+        if (span.fWindSum == SK_MinS32) {
+            SkDebugf("?");
+        } else {
+            SkDebugf("%d", span.fWindSum);
+        }
+        SkDebugf(" windValue=%d\n", span.fWindValue);
+    }
+#endif
+
 #if DEBUG_SORT
     void debugShowSort(const SkTDArray<Angle*>& angles, int first,
             const int contourWinding) const {
diff --git a/experimental/Intersection/SimplifyNew_Test.cpp b/experimental/Intersection/SimplifyNew_Test.cpp
index 20944ad..190684b 100644
--- a/experimental/Intersection/SimplifyNew_Test.cpp
+++ b/experimental/Intersection/SimplifyNew_Test.cpp
@@ -775,12 +775,21 @@
     testSimplifyx(path);
 }
 
-static void (*firstTest)() = testLine51;
+static void testLine74() {
+    SkPath path, simple;
+    path.addRect(20, 30, 40, 40, (SkPath::Direction) 0);
+    path.addRect(24, 20, 36, 30, (SkPath::Direction) 1);
+    path.addRect(32, 24, 36, 41, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
+static void (*firstTest)() = testLine74;
 
 static struct {
     void (*fun)();
     const char* str;
 } tests[] = {
+    TEST(testLine74),
     TEST(testLine73),
     TEST(testLine72),
     TEST(testLine71),
diff --git a/experimental/Intersection/op.htm b/experimental/Intersection/op.htm
index 778dd4a..8dda3fa 100644
--- a/experimental/Intersection/op.htm
+++ b/experimental/Intersection/op.htm
@@ -708,11 +708,18 @@
     path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
 </div>
 
+<div id="testLine74">
+    path.addRect(20, 30, 40, 40, (SkPath::Direction) 0);
+    path.addRect(24, 20, 36, 30, (SkPath::Direction) 1);
+    path.addRect(32, 24, 36, 41, (SkPath::Direction) 1);
+</div>
+
 </div>
 
 <script type="text/javascript">
 
 var testDivs = [
+    testLine74,
     testLine73,
     testLine72,
     testLine71,