shape ops work in progress

binary ops work for simple coincident case

git-svn-id: http://skia.googlecode.com/svn/trunk@6422 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/ShapeOps.cpp b/experimental/Intersection/ShapeOps.cpp
index 5356ca6..fa29ab7 100644
--- a/experimental/Intersection/ShapeOps.cpp
+++ b/experimental/Intersection/ShapeOps.cpp
@@ -78,6 +78,7 @@
         segment->debugShowSort(__FUNCTION__, sorted, firstIndex, winding, oWinding);
     #endif
         winding -= segment->spanSign(angle);
+        oWinding -= segment->oppSign(angle);
         bool firstOperand = segment->operand();
         do {
             SkASSERT(nextIndex != firstIndex);
@@ -87,14 +88,17 @@
             angle = sorted[nextIndex];
             segment = angle->segment();
             int deltaSum = segment->spanSign(angle);
+            int deltaOppSum = segment->oppSign(angle);
             bool angleIsOp = segment->operand() ^ firstOperand;
             int maxWinding;
             if (angleIsOp) {
                 maxWinding = oWinding;
                 oWinding -= deltaSum;
+                winding -= deltaOppSum;
             } else {
                 maxWinding = winding;
                 winding -= deltaSum;
+                oWinding -= deltaOppSum;
             }
     #if DEBUG_SORT
             SkDebugf("%s id=%d maxWinding=%d winding=%d oWinding=%d sign=%d\n", __FUNCTION__,
@@ -125,16 +129,31 @@
     return NULL;
 }
 
-static bool windingIsActive(int winding, int oppWinding, int spanWinding,
+static bool windingIsActive(int winding, int oppWinding, int spanWinding, int oppSpanWinding,
         bool windingIsOp, ShapeOp op) {
     bool active = windingIsActive(winding, spanWinding);
     if (!active) {
         return false;
     }
+    if (oppSpanWinding && windingIsActive(oppWinding, oppSpanWinding)) {
+        return op == kIntersect_Op || op == kUnion_Op;
+    }
     bool opActive = oppWinding != 0;
     return gOpLookup[op][opActive][windingIsOp];
 }
 
+static int updateWindings(const Segment* current, int index, int endIndex,
+        int& spanWinding, int& oppWinding, int& oppSpanWinding) {
+    int winding = updateWindings(current, index, endIndex, spanWinding);
+    int lesser = SkMin32(index, endIndex);
+    oppWinding = current->oppSum(lesser);
+    oppSpanWinding = current->oppSign(index, endIndex);
+    if (oppSpanWinding && useInnerWinding(oppWinding - oppSpanWinding, oppWinding)) {
+        oppWinding -= oppSpanWinding;
+    }
+    return winding;
+}
+
 static bool bridgeOp(SkTDArray<Contour*>& contourList, const ShapeOp op,
         const int aXorMask, const int bXorMask, PathWrapper& simple) {
     bool firstContour = true;
@@ -188,14 +207,15 @@
         int winding = contourWinding;
         int oppWinding = oppContourWinding;
         int spanWinding = current->spanSign(index, endIndex);
+        int oppSpanWinding = current->oppSign(index, endIndex);
         SkTDArray<Span*> chaseArray;
         do {
-            bool active = windingIsActive(winding, oppWinding, spanWinding,
+            bool active = windingIsActive(winding, oppWinding, spanWinding, oppSpanWinding,
                     current->operand(), op);
         #if DEBUG_WINDING
-            SkDebugf("%s active=%s winding=%d oppWinding=%d spanWinding=%d\n",
+            SkDebugf("%s active=%s winding=%d oppWinding=%d spanWinding=%d oppSpanWinding=%d\n",
                     __FUNCTION__, active ? "true" : "false",
-                    winding, oppWinding, spanWinding);
+                    winding, oppWinding, spanWinding, oppSpanWinding);
         #endif
             do {
         #if DEBUG_ACTIVE_SPANS
@@ -207,7 +227,7 @@
                 int nextStart = index;
                 int nextEnd = endIndex;
                 Segment* next = current->findNextOp(chaseArray, active,
-                        nextStart, nextEnd, winding, oppWinding, spanWinding,
+                        nextStart, nextEnd, winding, oppWinding, spanWinding, oppSpanWinding,
                         unsortable, op, aXorMask, bXorMask);
                 if (!next) {
                     SkASSERT(!unsortable);
@@ -244,7 +264,8 @@
             if (!current) {
                 break;
             }
-            winding = updateWindings(current, index, endIndex, spanWinding, &oppWinding);
+            winding = updateWindings(current, index, endIndex, spanWinding, oppWinding,
+                    oppSpanWinding);
         } while (true);
     } while (true);
     return closable;
@@ -281,7 +302,8 @@
         } while (addIntersectTs(current, next) && nextPtr != listEnd);
     } while (currentPtr != listEnd);
     // eat through coincident edges
-    coincidenceCheck(contourList);
+    coincidenceCheck(contourList, (aXorMask == kEvenOdd_Mask)
+            ^ (bXorMask == kEvenOdd_Mask));
     fixOtherTIndex(contourList);
     sortSegments(contourList);
 #if DEBUG_ACTIVE_SPANS