shape ops work in progress

basic functionality works at this point

git-svn-id: http://skia.googlecode.com/svn/trunk@7004 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/EdgeWalker_TestUtility.cpp b/experimental/Intersection/EdgeWalker_TestUtility.cpp
index f07eebe..de5967c 100644
--- a/experimental/Intersection/EdgeWalker_TestUtility.cpp
+++ b/experimental/Intersection/EdgeWalker_TestUtility.cpp
@@ -53,109 +53,10 @@
 static bool gPathStrAssert = true;
 static bool gUsePhysicalFiles = false;
 
-static bool isRectContour(SkPath::Iter& iter, SkRect& rect, SkPath::Direction& direction) {
-    int corners = 0;
-    SkPoint first, last;
-    first.set(0, 0);
-    last.set(0, 0);
-    int firstDirection = 0;
-    int lastDirection = 0;
-    int nextDirection = 0;
-    bool closedOrMoved = false;
-    bool autoClose = false;
-    rect.setEmpty();
-    uint8_t verb;
-    SkPoint data[4];
-    SkTDArray<SkPoint> sides;
-    bool empty = true;
-    while ((verb = iter.next(data)) != SkPath::kDone_Verb && !autoClose) {
-        empty = false;
-        SkPoint* pts = &data[1];
-        switch (verb) {
-            case SkPath::kClose_Verb:
-                pts = &last;
-                autoClose = true;
-            case SkPath::kLine_Verb: {
-                SkScalar left = last.fX;
-                SkScalar top = last.fY;
-                SkScalar right = pts->fX;
-                SkScalar bottom = pts->fY;
-                *sides.append() = *pts;
-                ++pts;
-                if (left != right && top != bottom) {
-                    return false; // diagonal
-                }
-                if (left == right && top == bottom) {
-                    break; // single point on side OK
-                }
-                nextDirection = (left != right) << 0 |
-                    (left < right || top < bottom) << 1;
-                if (0 == corners) {
-                    firstDirection = nextDirection;
-                    first = last;
-                    last = pts[-1];
-                    corners = 1;
-                    closedOrMoved = false;
-                    break;
-                }
-                if (closedOrMoved) {
-                    return false; // closed followed by a line
-                }
-                if (autoClose && nextDirection == firstDirection) {
-                    break; // colinear with first
-                }
-                closedOrMoved = autoClose;
-                if (lastDirection != nextDirection) {
-                    if (++corners > 4) {
-                        return false; // too many direction changes
-                    }
-                }
-                last = pts[-1];
-                if (lastDirection == nextDirection) {
-                    break; // colinear segment
-                }
-                // Possible values for corners are 2, 3, and 4.
-                // When corners == 3, nextDirection opposes firstDirection.
-                // Otherwise, nextDirection at corner 2 opposes corner 4.
-                int turn = firstDirection ^ (corners - 1);
-                int directionCycle = 3 == corners ? 0 : nextDirection ^ turn;
-                if ((directionCycle ^ turn) != nextDirection) {
-                    return false; // direction didn't follow cycle
-                }
-                break;
-            }
-            case SkPath::kQuad_Verb:
-            case SkPath::kCubic_Verb:
-                return false; // quadratic, cubic not allowed
-            case SkPath::kMove_Verb:
-                last = *pts++;
-                *sides.append() = last;
-                closedOrMoved = true;
-                break;
-        }
-        lastDirection = nextDirection;
-    }
-    // Success if 4 corners and first point equals last
-    bool result = 4 == corners && (first == last || autoClose);
-    if (result) {
-        direction = firstDirection == (lastDirection + 1 & 3) ? SkPath::kCCW_Direction
-                : SkPath::kCW_Direction;
-        rect.set(&sides[0], sides.count());
-    } else {
-        rect.setEmpty();
-    }
-    return !empty;
-}
-
-static void showPathContour(SkPath::Iter& iter, bool skip) {
+static void showPathContour(SkPath::Iter& iter) {
     uint8_t verb;
     SkPoint pts[4];
     while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
-        if (skip) {
-            if (verb == SkPath::kClose_Verb) {
-                return;
-            }
-        }
         switch (verb) {
             case SkPath::kMove_Verb:
                 SkDebugf("path.moveTo(%1.9g, %1.9g);\n", pts[0].fX, pts[0].fY);
@@ -174,7 +75,7 @@
                 break;
             case SkPath::kClose_Verb:
                 SkDebugf("path.close();\n");
-                return;
+                break;
             default:
                 SkDEBUGFAIL("bad verb");
                 return;
@@ -185,25 +86,23 @@
 void showPath(const SkPath& path, const char* str) {
     SkDebugf("%s\n", !str ? "original:" : str);
     SkPath::Iter iter(path, true);
-    SkTDArray<SkRect> rects;
-    SkTDArray<SkPath::Direction> directions;
-    SkRect rect;
-    SkPath::Direction direction;
-    while (isRectContour(iter, rect, direction)) {
-        *rects.append() = rect;
-        *directions.append() = direction;
-    }
-    iter.setPath(path, true);
-    for (int contour = 0; contour < rects.count(); ++contour) {
-        const SkRect& rect = rects[contour];
-        bool useRect = !rect.isEmpty();
-        showPathContour(iter, useRect);
-        if (useRect) {
+    int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0;
+    if (rectCount > 0) {
+        SkTDArray<SkRect> rects;
+        SkTDArray<SkPath::Direction> directions;
+        rects.setCount(rectCount);
+        directions.setCount(rectCount);
+        path.rectContours(rects.begin(), directions.begin());
+        for (int contour = 0; contour < rectCount; ++contour) {
+            const SkRect& rect = rects[contour];
             SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop,
                     rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction
                     ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
         }
+        return;
     }
+    iter.setPath(path, true);
+    showPathContour(iter);
 }
 
 static int pathsDrawTheSame(const SkPath& one, const SkPath& two,
@@ -331,7 +230,7 @@
     if (errors2x2 == 0) {
         return 0;
     }
-    const int MAX_ERRORS = 8;
+    const int MAX_ERRORS = 9;
     if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) {
         showSimplifiedPath(one, two, scaledOne, scaledTwo);
     }
@@ -682,7 +581,7 @@
 
     outFile.writeText("static void ");
     writeTestName(nameSuffix, outFile);
-    outFile.writeText("() {\n    SkPath path, pathB;\n");
+    outFile.writeText("() {\n    SkPath path;\n");
     if (pathPrefix) {
         outFile.writeText(pathPrefix);
     }
@@ -699,7 +598,7 @@
     outFile.writeText("    const char* str;\n");
     outFile.writeText("} tests[] = {\n");
     outFile.writeText("    TEST(");
-    writeTestName(pathPrefix, outFile);
+    writeTestName(nameSuffix, outFile);
     outFile.writeText("),\n");
     outFile.flush();
 }