shape ops work in progress

git-svn-id: http://skia.googlecode.com/svn/trunk@4006 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/SimplifyAngle_Test.cpp b/experimental/Intersection/SimplifyAngle_Test.cpp
new file mode 100644
index 0000000..89123bd
--- /dev/null
+++ b/experimental/Intersection/SimplifyAngle_Test.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Simplify.h"
+
+namespace SimplifyAngleTest {
+
+#include "Simplify.cpp"
+
+} // end of SimplifyAngleTest namespace
+
+#include "Intersection_Tests.h"
+
+static const SkPoint lines[][2] = {
+    { { 10,  10}, { 10,  20} },
+    { { 10,  10}, { 20,  10} },
+    { { 10,  10}, {-20,  10} },
+    { { 10,  10}, { 10, -20} },
+    { { 10,  10}, { 20,  20} },
+    { { 10,  10}, {-20, -20} },
+    { { 10,  10}, {-20,  40} },
+    { { 10,  10}, { 40, -20} }
+};
+
+static const size_t lineCount = sizeof(lines) / sizeof(lines[0]);
+
+static const SkPoint quads[][3] = {
+    {{ 1,  1}, { 2,  2}, { 1,  3}}, // 0
+    {{ 1,  1}, { 3,  3}, { 1,  5}}, // 1
+    {{ 1,  1}, { 4,  4}, { 1,  7}}, // 2
+    {{ 1,  1}, { 5,  5}, { 9,  9}}, // 3
+    {{ 1,  1}, { 4,  4}, { 7,  1}}, // 4
+    {{ 1,  1}, { 3,  3}, { 5,  1}}, // 5
+    {{ 1,  1}, { 2,  2}, { 3,  1}}, // 6
+};
+
+static const size_t quadCount = sizeof(quads) / sizeof(quads[0]);
+
+static const SkPoint cubics[][4] = {
+    {{ 1,  1}, { 2,  2}, { 2,  3}, { 1,  4}},
+    {{ 1,  1}, { 3,  3}, { 3,  5}, { 1,  7}},
+    {{ 1,  1}, { 4,  4}, { 4,  7}, { 1,  10}},
+    {{ 1,  1}, { 5,  5}, { 8,  8}, { 9,  9}},
+    {{ 1,  1}, { 4,  4}, { 7,  4}, { 10, 1}},
+    {{ 1,  1}, { 3,  3}, { 5,  3}, { 7,  1}},
+    {{ 1,  1}, { 2,  2}, { 3,  2}, { 4,  1}},
+};
+
+static const size_t cubicCount = sizeof(cubics) / sizeof(cubics[0]);
+
+static void testLines(bool testFlat) {
+    // create angles in a circle
+    SkTDArray<SimplifyAngleTest::Angle> angles;
+    SkTDArray<SimplifyAngleTest::Angle* > angleList;
+    SkTDArray<double> arcTans;
+    size_t x;
+    for (x = 0; x < lineCount; ++x) {
+        SimplifyAngleTest::Angle* angle = angles.append();
+        if (testFlat) {
+            angle->setFlat(lines[x], SkPath::kLine_Verb, 0, x, x + 1, false);
+        } else {
+            angle->set(lines[x], SkPath::kLine_Verb, 0, x, x + 1, false);
+        }
+        double arcTan = atan2(lines[x][0].fX - lines[x][1].fX,
+                lines[x][0].fY - lines[x][1].fY);
+        arcTans.push(arcTan);
+    }
+    for (x = 0; x < lineCount; ++x) {
+        angleList.push(&angles[x]);
+    }
+    QSort<SimplifyAngleTest::Angle>(angleList.begin(), angleList.end() - 1);
+    bool first = true;
+    bool wrap = false;
+    double base, last;
+    for (size_t x = 0; x < lineCount; ++x) {
+        const SimplifyAngleTest::Angle* angle = angleList[x];
+        int span = angle->start();
+//        SkDebugf("%s [%d] %1.9g (%1.9g,%1.9g %1.9g,%1.9g)\n", __FUNCTION__,
+//                span, arcTans[span], lines[span][0].fX, lines[span][0].fY,
+//                lines[span][1].fX, lines[span][1].fY);
+        if (first) {
+            base = last = arcTans[span];
+            first = false;
+            continue;
+        }
+        if (last < arcTans[span]) {
+            last = arcTans[span];
+            continue;
+        }
+        if (!wrap) {
+            if (base < arcTans[span]) {
+                SkDebugf("%s !wrap [%d] %g\n", __FUNCTION__, span, arcTans[span]);
+                SkASSERT(0);
+            }
+            last = arcTans[span];
+            wrap = true;
+            continue;
+        }
+        SkDebugf("%s wrap [%d] %g\n", __FUNCTION__, span, arcTans[span]);
+        SkASSERT(0);
+    }
+}
+
+static void testQuads(bool testFlat) {
+    SkTDArray<SimplifyAngleTest::Angle> angles;
+    SkTDArray<SimplifyAngleTest::Angle* > angleList;
+    size_t x;
+    for (x = 0; x < quadCount; ++x) {
+        SimplifyAngleTest::Angle* angle = angles.append();
+        if (testFlat) {
+            angle->setFlat(quads[x], SkPath::kQuad_Verb, 0, x, x + 1, false);
+        } else {
+            angle->set(quads[x], SkPath::kQuad_Verb, 0, x, x + 1, false);
+        }
+    }
+    for (x = 0; x < quadCount; ++x) {
+        angleList.push(&angles[x]);
+    }
+    QSort<SimplifyAngleTest::Angle>(angleList.begin(), angleList.end() - 1);
+    for (size_t x = 0; x < quadCount; ++x) {
+        *angleList[x] < *angleList[x + 1];
+        SkASSERT(x == quadCount - 1 || *angleList[x] < *angleList[x + 1]);
+        const SimplifyAngleTest::Angle* angle = angleList[x];
+        if (x != angle->start()) {
+            SkDebugf("%s [%d] [%d]\n", __FUNCTION__, x, angle->start());
+            SkASSERT(0);
+        }
+    }
+}
+
+static void testCubics(bool testFlat) {
+    SkTDArray<SimplifyAngleTest::Angle> angles;
+    SkTDArray<SimplifyAngleTest::Angle* > angleList;
+    for (size_t x = 0; x < cubicCount; ++x) {
+        SimplifyAngleTest::Angle* angle = angles.append();
+        if (testFlat) {
+            angle->setFlat(cubics[x], SkPath::kCubic_Verb, 0, x, x + 1, false);
+        } else {
+            angle->set(cubics[x], SkPath::kCubic_Verb, 0, x, x + 1, false);
+        }
+        angleList.push(angle);
+    }
+    QSort<SimplifyAngleTest::Angle>(angleList.begin(), angleList.end() - 1);
+    for (size_t x = 0; x < cubicCount; ++x) {
+        const SimplifyAngleTest::Angle* angle = angleList[x];
+        if (x != angle->start()) {
+            SkDebugf("%s [%d] [%d]\n", __FUNCTION__, x, angle->start());
+            SkASSERT(0);
+        }
+    }
+}
+
+static void (*tests[])(bool) = {
+    testLines,
+    testQuads,
+    testCubics
+};
+
+static const size_t testCount = sizeof(tests) / sizeof(tests[0]);
+
+static void (*firstTest)(bool) = 0;
+static bool skipAll = false;
+
+void SimplifyAngle_Test() {
+    if (skipAll) {
+        return;
+    }
+    size_t index = 0;
+    if (firstTest) {
+        while (index < testCount && tests[index] != firstTest) {
+            ++index;
+        }
+    }
+    bool firstTestComplete = false;
+    for ( ; index < testCount; ++index) {
+        (*tests[index])(true);
+        firstTestComplete = true;
+    }
+}
\ No newline at end of file