shape ops work in progress

mostly working on cubic/cubic intersect

git-svn-id: http://skia.googlecode.com/svn/trunk@7266 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/Intersections.cpp b/experimental/Intersection/Intersections.cpp
index 3f4e8cf..d1e0f9b 100644
--- a/experimental/Intersection/Intersections.cpp
+++ b/experimental/Intersection/Intersections.cpp
@@ -8,9 +8,108 @@
 #include "DataTypes.h"
 #include "Intersections.h"
 
+void Intersections::addCoincident(double s1, double e1, double s2, double e2) {
+    assert((fCoincidentUsed & 1) != 1);
+    for (int index = 0; index < fCoincidentUsed; index += 2) {
+        double cs1 = fCoincidentT[fSwap][index];
+        double ce1 = fCoincidentT[fSwap][index + 1];
+        bool s1in = approximately_between(cs1, s1, ce1);
+        bool e1in = approximately_between(cs1, e1, ce1);
+        double cs2 = fCoincidentT[fSwap ^ 1][index];
+        double ce2 = fCoincidentT[fSwap ^ 1][index + 1];
+        bool s2in = approximately_between(cs2, s2, ce2);
+        bool e2in = approximately_between(cs2, e2, ce2);
+        if ((s1in | e1in) & (s2in | e2in)) {
+            double lesser1 = std::min(cs1, ce1);
+            index += cs1 > ce1;
+            if (s1in < lesser1) {
+                fCoincidentT[fSwap][index] = s1in;
+            } else if (e1in < lesser1) {
+                fCoincidentT[fSwap][index] = e1in;
+            }
+            index ^= 1;
+            double greater1 = fCoincidentT[fSwap][index];
+            if (s1in > greater1) {
+                fCoincidentT[fSwap][index] = s1in;
+            } else if (e1in > greater1) {
+                fCoincidentT[fSwap][index] = e1in;
+            }
+            index &= ~1;
+            double lesser2 = std::min(cs2, ce2);
+            index += cs2 > ce2;
+            if (s2in < lesser2) {
+                fCoincidentT[fSwap ^ 1][index] = s2in;
+            } else if (e2in < lesser2) {
+                fCoincidentT[fSwap ^ 1][index] = e2in;
+            }
+            index ^= 1;
+            double greater2 = fCoincidentT[fSwap ^ 1][index];
+            if (s2in > greater2) {
+                fCoincidentT[fSwap ^ 1][index] = s2in;
+            } else if (e2in > greater2) {
+                fCoincidentT[fSwap ^ 1][index] = e2in;
+            }
+            return;
+        }
+    }
+    assert(fCoincidentUsed < 9);
+    fCoincidentT[fSwap][fCoincidentUsed] = s1;
+    fCoincidentT[fSwap ^ 1][fCoincidentUsed] = s2;
+    ++fCoincidentUsed;
+    fCoincidentT[fSwap][fCoincidentUsed] = e1;
+    fCoincidentT[fSwap ^ 1][fCoincidentUsed] = e2;
+    ++fCoincidentUsed;
+}
+
 void Intersections::cleanUp() {
     assert(fCoincidentUsed);
     assert(fUsed);
     // find any entries in fT that could be part of the coincident range
 
 }
+
+void Intersections::insert(double one, double two) {
+    assert(fUsed <= 1 || fT[0][0] < fT[0][1]);
+    int index;
+    for (index = 0; index < fUsed; ++index) {
+        if (approximately_equal(fT[0][index], one)
+                && approximately_equal(fT[1][index], two)) {
+            return;
+        }
+        if (fT[0][index] > one) {
+            break;
+        }
+    }
+    assert(fUsed < 9);
+    int remaining = fUsed - index;
+    if (remaining > 0) {
+        memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining);
+        memmove(&fT[1][index + 1], &fT[1][index], sizeof(fT[1][0]) * remaining);
+    }
+    fT[0][index] = one;
+    fT[1][index] = two;
+    ++fUsed;
+}
+
+// FIXME: all callers should be moved to regular insert. Failures are likely
+// if two separate callers differ on whether ts are equal or not
+void Intersections::insertOne(double t, int side) {
+    int used = side ? fUsed2 : fUsed;
+    assert(used <= 1 || fT[side][0] < fT[side][1]);
+    int index;
+    for (index = 0; index < used; ++index) {
+        if (approximately_equal(fT[side][index], t)) {
+            return;
+        }
+        if (fT[side][index] > t) {
+            break;
+        }
+    }
+    assert(used < 9);
+    int remaining = used - index;
+    if (remaining > 0) {
+        memmove(&fT[side][index + 1], &fT[side][index], sizeof(fT[side][0]) * remaining);
+    }
+    fT[side][index] = t;
+    side ? ++fUsed2 : ++fUsed;
+}