work in progress

git-svn-id: http://skia.googlecode.com/svn/trunk@3291 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/EdgeWalker_TestUtility.cpp b/experimental/Intersection/EdgeWalker_TestUtility.cpp
new file mode 100644
index 0000000..eb1509e
--- /dev/null
+++ b/experimental/Intersection/EdgeWalker_TestUtility.cpp
@@ -0,0 +1,190 @@
+#include "EdgeWalker_Test.h"
+#include "Intersection_Tests.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
+
+static bool gDrawLastAsciiPaths = true;
+static bool gDrawAllAsciiPaths = false;
+static bool gShowPath = true;
+
+static void showPath(const char* str, const SkPath& path) {
+    if (!gShowPath) {
+        return;
+    }
+    SkDebugf("%s\n", str);
+    SkPath::Iter iter(path, true);
+    uint8_t verb;
+    SkPoint pts[4];
+    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+        switch (verb) {
+            case SkPath::kMove_Verb:
+                SkDebugf("path.moveTo(%g, %g);\n", pts[0].fX, pts[0].fY);
+                continue;
+            case SkPath::kLine_Verb:
+                SkDebugf("path.lineTo(%g, %g);\n", pts[1].fX, pts[1].fY);
+                break;
+            case SkPath::kQuad_Verb:
+                SkDebugf("path.quadTo(%g, %g, %g, %g);\n",
+                    pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
+                break;
+            case SkPath::kCubic_Verb:
+                SkDebugf("path.cubicTo(%g, %g, %g, %g);\n",
+                    pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY,
+                    pts[3].fX, pts[3].fY);
+                break;
+            case SkPath::kClose_Verb:
+                SkDebugf("path.close();\n");
+                continue;
+            default:
+                SkDEBUGFAIL("bad verb");
+                return;
+        }
+    }
+}
+
+static bool pathsDrawTheSame(const SkPath& one, const SkPath& two) {
+    const SkRect& bounds1 = one.getBounds();
+    const SkRect& bounds2 = two.getBounds();
+    SkRect larger = bounds1;
+    larger.join(bounds2);
+    SkBitmap bits;
+    int bitWidth = SkScalarCeil(larger.width()) + 2;
+    int bitHeight = SkScalarCeil(larger.height()) + 2;
+    bits.setConfig(SkBitmap::kARGB_8888_Config, bitWidth * 2, bitHeight);
+    bits.allocPixels();
+    SkCanvas canvas(bits);
+    canvas.drawColor(SK_ColorWHITE);
+    SkPaint paint;
+    canvas.save();
+    canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
+    canvas.drawPath(one, paint);
+    canvas.restore();
+    canvas.save();
+    canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1);
+    canvas.drawPath(two, paint);
+    canvas.restore();
+    for (int y = 0; y < bitHeight; ++y) {
+        uint32_t* addr1 = bits.getAddr32(0, y);
+        uint32_t* addr2 = bits.getAddr32(bitWidth, y);
+        for (int x = 0; x < bitWidth; ++x) {
+            if (addr1[x] != addr2[x]) {
+                return false;
+                break;
+            }
+        }
+    }
+    return true;
+}
+
+static void drawAsciiPaths(const SkPath& one, const SkPath& two,
+        bool drawPaths) {
+    if (!drawPaths) {
+        return;
+    }
+    if (0) {
+        showPath("one:", one);
+        showPath("two:", two);
+    }
+    const SkRect& bounds1 = one.getBounds();
+    const SkRect& bounds2 = two.getBounds();
+    SkRect larger = bounds1;
+    larger.join(bounds2);
+    SkBitmap bits;
+    int bitWidth = SkScalarCeil(larger.width()) + 2;
+    int bitHeight = SkScalarCeil(larger.height()) + 2;
+    bits.setConfig(SkBitmap::kARGB_8888_Config, bitWidth * 2, bitHeight);
+    bits.allocPixels();
+    SkCanvas canvas(bits);
+    canvas.drawColor(SK_ColorWHITE);
+    SkPaint paint;
+    canvas.save();
+    canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
+    canvas.drawPath(one, paint);
+    canvas.restore();
+    canvas.save();
+    canvas.translate(-bounds2.fLeft + 1 + bitWidth, -bounds2.fTop + 1);
+    canvas.drawPath(two, paint);
+    canvas.restore();
+    char out[1024];
+    SkASSERT(bitWidth * 2 + 1 < (int) sizeof(out));
+    for (int y = 0; y < bitHeight; ++y) {
+        uint32_t* addr1 = bits.getAddr32(0, y);
+        int x;
+        char* outPtr = out;
+        for (x = 0; x < bitWidth; ++x) {
+            *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x';
+        }
+        *outPtr++ = '|';
+        for (x = bitWidth; x < bitWidth * 2; ++x) {
+            *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x';
+        }
+        *outPtr++ = '\0';
+        SkDebugf("%s\n", out);
+    }
+}
+
+static bool scaledDrawTheSame(const SkPath& one, const SkPath& two,
+        int a, int b, bool drawPaths) {
+    SkMatrix scale;
+    scale.reset();
+    scale.preScale(a * 1.21f, b * 1.11f);
+    SkPath scaledOne, scaledTwo;
+    one.transform(scale, &scaledOne);
+    two.transform(scale, &scaledTwo);
+    if (pathsDrawTheSame(scaledOne, scaledTwo)) {
+        return true;
+    }
+    drawAsciiPaths(scaledOne, scaledTwo, drawPaths);
+    return false;
+}
+
+void comparePaths(const SkPath& one, const SkPath& two) {
+    if (pathsDrawTheSame(one, two)) {
+        return;
+    }
+    drawAsciiPaths(one, two, gDrawAllAsciiPaths);
+    for (int x = 9; x <= 33; ++x) {
+        if (scaledDrawTheSame(one, two, x, x - (x >> 2), gDrawAllAsciiPaths)) {
+            return;
+        }
+    }
+    if (!gDrawAllAsciiPaths) {
+        scaledDrawTheSame(one, two, 9, 7, gDrawLastAsciiPaths);
+    }
+    showPath("original:", one);
+    showPath("simplified:", two);
+    SkASSERT(0);
+}
+
+// doesn't work yet
+void comparePathsTiny(const SkPath& one, const SkPath& two) {
+    const SkRect& bounds1 = one.getBounds();
+    const SkRect& bounds2 = two.getBounds();
+    SkRect larger = bounds1;
+    larger.join(bounds2);
+    SkBitmap bits;
+    int bitWidth = SkScalarCeil(larger.width()) + 2;
+    int bitHeight = SkScalarCeil(larger.height()) + 2;
+    bits.setConfig(SkBitmap::kA1_Config, bitWidth * 2, bitHeight);
+    bits.allocPixels();
+    SkCanvas canvas(bits);
+    canvas.drawColor(SK_ColorWHITE);
+    SkPaint paint;
+    canvas.save();
+    canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
+    canvas.drawPath(one, paint);
+    canvas.restore();
+    canvas.save();
+    canvas.translate(-bounds2.fLeft + 1, -bounds2.fTop + 1);
+    canvas.drawPath(two, paint);
+    canvas.restore();
+    for (int y = 0; y < bitHeight; ++y) {
+        uint8_t* addr1 = bits.getAddr1(0, y);
+        uint8_t* addr2 = bits.getAddr1(bitWidth, y);
+        for (int x = 0; x < bits.rowBytes(); ++x) {
+            SkASSERT(addr1[x] == addr2[x]);
+        }
+    }
+}
+