path ops work in progress

path ops work in progress

BUG=

Review URL: https://codereview.chromium.org/21359002

git-svn-id: http://skia.googlecode.com/svn/trunk@11291 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h
index 456e6c0..a5635fe 100644
--- a/src/pathops/SkOpContour.h
+++ b/src/pathops/SkOpContour.h
@@ -15,7 +15,7 @@
 class SkPathWriter;
 
 struct SkCoincidence {
-    SkOpContour* fContours[2];
+    SkOpContour* fOther;
     int fSegments[2];
     double fTs[2][2];
     SkPoint fPts[2];
@@ -25,8 +25,8 @@
 public:
     SkOpContour() {
         reset();
-#if DEBUG_DUMP
-        fID = ++gContourID;
+#ifdef SK_DEBUG
+        fID = ++SkPathOpsDebug::gContourID;
 #endif
     }
 
@@ -63,15 +63,19 @@
         fSegments[segIndex].addOtherT(tIndex, otherT, otherIndex);
     }
 
+    void addPartialCoincident(int index, SkOpContour* other, int otherIndex,
+                       const SkIntersections& ts, int ptIndex, bool swap);
+
     int addQuad(const SkPoint pts[3]) {
         fSegments.push_back().addQuad(pts, fOperand, fXor);
         fContainsCurves = true;
         return fSegments.count();
     }
 
-    int addT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) {
+    int addT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT,
+            bool isNear) {
         setContainsIntercepts();
-        return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT);
+        return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT, isNear);
     }
 
     int addSelfT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) {
@@ -79,16 +83,12 @@
         return fSegments[segIndex].addSelfT(&other->fSegments[otherIndex], pt, newT);
     }
 
-    int addUnsortableT(int segIndex, SkOpContour* other, int otherIndex, bool start,
-                       const SkPoint& pt, double newT) {
-        return fSegments[segIndex].addUnsortableT(&other->fSegments[otherIndex], start, pt, newT);
-    }
-
     const SkPathOpsBounds& bounds() const {
         return fBounds;
     }
 
     void calcCoincidentWinding();
+    void calcPartialCoincidentWinding();
 
     void checkEnds() {
         if (!fContainsCurves) {
@@ -100,7 +100,18 @@
             if (segment->verb() == SkPath::kLine_Verb) {
                 continue;
             }
-            fSegments[sIndex].checkEnds();
+            segment->checkEnds();
+        }
+    }
+
+    // if same point has different T values, choose a common T
+    void checkTiny() {
+        int segmentCount = fSegments.count();
+        if (segmentCount <= 2) {
+            return;
+        }
+        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
+            fSegments[sIndex].checkTiny();
         }
     }
 
@@ -131,13 +142,6 @@
         return segment.pts()[SkPathOpsVerbToPoints(segment.verb())];
     }
 
-    void findTooCloseToCall() {
-        int segmentCount = fSegments.count();
-        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
-            fSegments[sIndex].findTooCloseToCall();
-        }
-    }
-
     void fixOtherTIndex() {
         int segmentCount = fSegments.count();
         for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
@@ -232,12 +236,14 @@
 #endif
 
 private:
+    void calcCommonCoincidentWinding(const SkCoincidence& coincidence);
     void setBounds();
 
     SkTArray<SkOpSegment> fSegments;
     SkTArray<SkOpSegment*, true> fSortedSegments;
     int fFirstSorted;
     SkTArray<SkCoincidence, true> fCoincidences;
+    SkTArray<SkCoincidence, true> fPartialCoincidences;
     SkTArray<const SkOpContour*, true> fCrosses;
     SkPathOpsBounds fBounds;
     bool fContainsIntercepts;  // FIXME: is this used by anybody?
@@ -247,7 +253,7 @@
     bool fOperand;  // true for the second argument to a binary operator
     bool fXor;
     bool fOppXor;
-#if DEBUG_DUMP
+#ifdef SK_DEBUG
     int fID;
 #endif
 };