shape ops work in progress
add xor spot tests
rewrite path compare
work on quadratic, angle, tooCloseToCall code

git-svn-id: http://skia.googlecode.com/svn/trunk@5255 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/DataTypes.h b/experimental/Intersection/DataTypes.h
index 6218a65..c06e6ee 100644
--- a/experimental/Intersection/DataTypes.h
+++ b/experimental/Intersection/DataTypes.h
@@ -63,6 +63,11 @@
     return fabs(x) < FLT_EPSILON;
 }
 
+inline bool approximately_zero(float x) {
+    
+    return fabs(x) < FLT_EPSILON;
+}
+
 inline bool approximately_equal(double x, double y) {
     if (approximately_zero(x - y)) {
         return true;
@@ -82,6 +87,14 @@
     return approximately_equal(x, y) ? false : x < y;
 }
 
+inline double approximately_pin(double x) {
+    return approximately_zero(x) ? 0 : x;
+}
+
+inline float approximately_pin(float x) {
+    return approximately_zero(x) ? 0 : x;
+}
+
 inline bool approximately_zero_squared(double x) {
     return approximately_zero(x);
 }
diff --git a/experimental/Intersection/EdgeDemoApp.mm b/experimental/Intersection/EdgeDemoApp.mm
index e3be2ca..f5ed426 100644
--- a/experimental/Intersection/EdgeDemoApp.mm
+++ b/experimental/Intersection/EdgeDemoApp.mm
@@ -15,9 +15,10 @@
     };
 protected:
     virtual void onDraw(SkCanvas* canvas) {
-        static int step = -1;
+        static int step = 0; // useNew triggers error at 23275
+                             // error is not easy to debug in its current state
         static double seconds;
-        static bool useOld = true;
+        static bool useOld = false;
         if (step == -1) {
             timeval t;
             gettimeofday(&t, NULL);
@@ -27,7 +28,7 @@
         canvas->drawColor(SK_ColorWHITE);
         if (DrawEdgeDemo(canvas, step, useOld)) {
             ++step;
-            if (step == 3200) {
+            if (step == 23270) {
                 timeval t;
                 gettimeofday(&t, NULL);
                 double last = seconds;
@@ -43,6 +44,9 @@
     typedef SkView INHERITED; 
 };
 
+void application_init();
+void application_term();
+
 void application_init() {
     SkGraphics::Init();
     SkEvent::Init();
@@ -66,7 +70,7 @@
 @implementation SimpleNSView
 
 - (id)initWithDefaults {
-    if (self = [super initWithDefaults]) {
+    if ((self = [super initWithDefaults])) {
         fWind = new SkOSWindow(self); 
         fWind->setLayout(new FillLayout, false);
         fWind->attachChildToFront(new SkSampleView)->unref();
diff --git a/experimental/Intersection/EdgeWalker_TestUtility.cpp b/experimental/Intersection/EdgeWalker_TestUtility.cpp
index ebc6e14..4129ab4 100644
--- a/experimental/Intersection/EdgeWalker_TestUtility.cpp
+++ b/experimental/Intersection/EdgeWalker_TestUtility.cpp
@@ -29,8 +29,9 @@
 static bool gShowPath = false;
 static bool gComparePaths = true;
 //static bool gDrawLastAsciiPaths = true;
-static bool gDrawAllAsciiPaths = false;
-static bool gShowAsciiPaths = false;
+//static bool gDrawAllAsciiPaths = false;
+static bool gShowOutputProgress = false;
+static bool gShowAsciiPaths = true;
 static bool gComparePathsAssert = false;
 static bool gPathStrAssert = true;
 
@@ -67,52 +68,79 @@
 }
 
 static int pathsDrawTheSame(const SkPath& one, const SkPath& two,
-        SkBitmap& bits, SkCanvas* c) {
+        SkBitmap& bits, SkCanvas* c, int& error2x2) {
     SkCanvas* canvasPtr = c;
     if (!c) {
         canvasPtr = new SkCanvas(bits);
     }
-    const SkRect& bounds1 = one.getBounds();
-    const SkRect& bounds2 = two.getBounds();
-    SkRect larger = bounds1;
-    larger.join(bounds2);
-    int bitWidth = SkScalarCeil(larger.width()) + 2;
-    int bitHeight = SkScalarCeil(larger.height()) + 2;
-    if (bits.width() < bitWidth * 2 || bits.height() < bitHeight) {
-        if (bits.width() >= 200 && false) {
-            SkDebugf("%s bitWidth=%d bitHeight=%d\n", __FUNCTION__, bitWidth, bitHeight);
-        }
+    const int bitWidth = 64;
+    const int bitHeight = 64;
+    if (bits.width() == 0) {
         bits.setConfig(SkBitmap::kARGB_8888_Config, bitWidth * 2, bitHeight);
         bits.allocPixels();
         canvasPtr->setBitmapDevice(bits);
     }
+    SkRect larger = one.getBounds();
+    larger.join(two.getBounds());
+    SkScalar largerWidth = larger.width();
+    if (largerWidth < 4) {
+        largerWidth = 4;
+    }
+    SkScalar largerHeight = larger.height();
+    if (largerHeight < 4) {
+        largerHeight = 4;
+    }
+    SkScalar hScale = (bitWidth - 2) / largerWidth;
+    SkScalar vScale = (bitHeight - 2) / largerHeight;
+    SkMatrix scale;
+    scale.reset();
+    scale.preScale(hScale, vScale);
+    SkPath scaledOne, scaledTwo;
+    one.transform(scale, &scaledOne);
+    two.transform(scale, &scaledTwo);
+    const SkRect& bounds1 = scaledOne.getBounds();
     SkCanvas& canvas = *canvasPtr;
     canvas.drawColor(SK_ColorWHITE);
     SkPaint paint;
     canvas.save();
     canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
-    canvas.drawPath(one, paint);
+    canvas.drawPath(scaledOne, paint);
     canvas.restore();
     canvas.save();
     canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1);
-    canvas.drawPath(two, paint);
+    canvas.drawPath(scaledTwo, paint);
     canvas.restore();
+    int errors2 = 0;
     int errors = 0;
-    for (int y = 0; y < bitHeight; ++y) {
+    for (int y = 0; y < bitHeight - 1; ++y) {
         uint32_t* addr1 = bits.getAddr32(0, y);
-        uint32_t* addr2 = bits.getAddr32(bitWidth, y);
-        for (int x = 0; x < bitWidth; ++x) {
-            errors += addr1[x] != addr2[x];
+        uint32_t* addr2 = bits.getAddr32(0, y + 1);
+        uint32_t* addr3 = bits.getAddr32(bitWidth, y);
+        uint32_t* addr4 = bits.getAddr32(bitWidth, y + 1);
+        for (int x = 0; x < bitWidth - 1; ++x) {
+            // count 2x2 blocks
+            bool err = addr1[x] != addr3[x];
+            if (err) {
+                errors2 += addr1[x + 1] != addr3[x + 1]
+                        && addr2[x] != addr4[x] && addr2[x + 1] != addr4[x + 1];
+                errors++;
+            }
         }
     }
     if (!c) {
         delete canvasPtr;
     }
+    if (errors2 >= 2 || errors > 96) {
+        SkDebugf("%s errors2=%d errors=%d\n", __FUNCTION__, errors2, errors);
+    }
+    if (errors2 >= 3 || errors > 192) {
+        drawAsciiPaths(scaledOne, scaledTwo, true);
+    }
+    error2x2 = errors2;
     return errors;
 }
 
-bool drawAsciiPaths(const SkPath& one, const SkPath& two,
-        bool drawPaths) {
+bool drawAsciiPaths(const SkPath& one, const SkPath& two, bool drawPaths) {
     if (!drawPaths) {
         return true;
     }
@@ -164,73 +192,21 @@
     return true;
 }
 
-static int scaledDrawTheSame(const SkPath& one, const SkPath& two,
-        SkScalar a, SkScalar b, bool drawPaths, SkBitmap& bitmap,
-        SkCanvas* canvas) {
-    SkMatrix scale;
-    scale.reset();
-    float aScale = 1.21f;
-    float bScale = 1.11f;
-    scale.preScale(a * aScale, b * bScale);
-    SkPath scaledOne, scaledTwo;
-    one.transform(scale, &scaledOne);
-    two.transform(scale, &scaledTwo);
-    int errors = pathsDrawTheSame(scaledOne, scaledTwo, bitmap, canvas);
-    if (errors == 0) {
-        return 0;
-    }
-    while (!drawAsciiPaths(scaledOne, scaledTwo, drawPaths)) {
-        scale.reset();
-        aScale *= 0.5f;
-        bScale *= 0.5f;
-        scale.preScale(a * aScale, b * bScale);
-        one.transform(scale, &scaledOne);
-        two.transform(scale, &scaledTwo);
-    }
-    return errors;
-}
-
-static int max = 0;
-
 int comparePaths(const SkPath& one, const SkPath& two, SkBitmap& bitmap,
         SkCanvas* canvas) {
-    int errors = pathsDrawTheSame(one, two, bitmap, canvas);
-    if (errors == 0) {
+    int errors2x2;
+    int errors = pathsDrawTheSame(one, two, bitmap, canvas, errors2x2);
+    if (errors2x2 == 0) {
         return 0;
     }
-    drawAsciiPaths(one, two, gDrawAllAsciiPaths);
-    for (int x = 9; x <= 33; ++x) {
-        errors = scaledDrawTheSame(one, two, x, x - (x >> 2), gDrawAllAsciiPaths,
-            bitmap, canvas);
-        if (errors == 0) {
-            return 0;
-        }
-    }
-    if (!gDrawAllAsciiPaths) {
-        const SkRect& bounds1 = one.getBounds();
-        const SkRect& bounds2 = two.getBounds();
-        SkRect larger = bounds1;
-        larger.join(bounds2);
-        SkScalar xScale = std::max(32.0f / larger.width(), 1.0f);
-        SkScalar yScale = std::max(24.0f / larger.height(), 1.0f);
-        errors = scaledDrawTheSame(one, two, xScale, yScale, false, bitmap, canvas);
-        if (errors > 5) {
-            SkDebugf("\n");
-            scaledDrawTheSame(one, two, xScale, yScale, true, bitmap, canvas);
-        }
-    }
-    const int MAX_ERRORS = 20;
-    if (errors > max && errors <= MAX_ERRORS) {
-        SkDebugf("%s errors=%d\n", __FUNCTION__, errors); 
-        max = errors;
-    }
-    if (errors > MAX_ERRORS && gComparePathsAssert) {
+    const int MAX_ERRORS = 4;
+    if (errors2x2 > MAX_ERRORS && gComparePathsAssert) {
         SkDebugf("%s errors=%d\n", __FUNCTION__, errors); 
         showPath(one);
         showPath(two, "simplified:");
         SkASSERT(0);
     }
-    return errors > MAX_ERRORS ? errors : 0;
+    return errors2x2 > MAX_ERRORS ? errors2x2 : 0;
 }
 
 // doesn't work yet
@@ -381,6 +357,7 @@
         pthread_mutex_unlock(&State4::addQueue);
     } else {
         statePtr = &threadState[0];
+        testsRun += statePtr->testsRun;
         statePtr->testsRun = 0;
         statePtr->a = a;
         statePtr->b = b;
@@ -390,7 +367,6 @@
         statePtr->index = threadIndex;
         statePtr->last = false;
         (*testFun)(statePtr);
-        testsRun++;
     }
     return testsRun;
 }
@@ -441,7 +417,7 @@
 }
 
 void outputProgress(const State4& state, const char* pathStr, SkPath::FillType pathFillType) {
-    if (gRunTestsInOneThread) {
+    if (gRunTestsInOneThread && gShowOutputProgress) {
         if (pathFillType == SkPath::kEvenOdd_FillType) {
             SkDebugf("    path.setFillType(SkPath::kEvenOdd_FillType);\n", pathStr);
         }
diff --git a/experimental/Intersection/Intersection_Tests.cpp b/experimental/Intersection/Intersection_Tests.cpp
index 39faad1..bf28ccb 100644
--- a/experimental/Intersection/Intersection_Tests.cpp
+++ b/experimental/Intersection/Intersection_Tests.cpp
@@ -8,6 +8,7 @@
 
 void Intersection_Tests() {
     int testsRun = 0;
+//    SimplifyAngle_Test();
     SimplifyNew_Test();
     Simplify4x4QuadraticsThreaded_Test(testsRun);
     QuadLineIntersectThreaded_Test(testsRun);
@@ -19,7 +20,6 @@
     SkDebugf("%s total testsRun=%d\n", __FUNCTION__, testsRun);
     SimplifyFindNext_Test();
     SimplifyFindTop_Test();
-    SimplifyAngle_Test();
     QuadraticReduceOrder_Test();
     QuadraticBezierClip_Test();
     QuadraticIntersection_Test();
diff --git a/experimental/Intersection/QuadraticUtilities.cpp b/experimental/Intersection/QuadraticUtilities.cpp
index cc15bc1..88524ca 100644
--- a/experimental/Intersection/QuadraticUtilities.cpp
+++ b/experimental/Intersection/QuadraticUtilities.cpp
@@ -39,7 +39,9 @@
         } else if (ratio > 1 - FLT_EPSILON) {
             ratio = 1;
         }
-        t[foundRoots++] = ratio;
+        if (foundRoots == 0 || fabs(t[0] - ratio) >= FLT_EPSILON) {
+            t[foundRoots++] = ratio;
+        }
     }
     return foundRoots;
 }
diff --git a/experimental/Intersection/Simplify.cpp b/experimental/Intersection/Simplify.cpp
index 45f9696..9606589 100644
--- a/experimental/Intersection/Simplify.cpp
+++ b/experimental/Intersection/Simplify.cpp
@@ -27,13 +27,14 @@
 
 #define DEBUG_UNUSED 0 // set to expose unused functions
 
-#if 1 // set to 1 for multiple thread -- no debugging
+#if 0 // set to 1 for multiple thread -- no debugging
 
 const bool gRunTestsInOneThread = false;
 
 #define DEBUG_ACTIVE_SPANS 0
 #define DEBUG_ADD_INTERSECTING_TS 0
 #define DEBUG_ADD_T_PAIR 0
+#define DEBUG_ANGLE 0
 #define DEBUG_CONCIDENT 0
 #define DEBUG_CROSS 0
 #define DEBUG_DUMP 0
@@ -48,12 +49,13 @@
 const bool gRunTestsInOneThread = true;
 
 #define DEBUG_ACTIVE_SPANS 1
-#define DEBUG_ADD_INTERSECTING_TS 1
+#define DEBUG_ADD_INTERSECTING_TS 0
 #define DEBUG_ADD_T_PAIR 0
-#define DEBUG_CONCIDENT 1
+#define DEBUG_ANGLE 0
+#define DEBUG_CONCIDENT 0
 #define DEBUG_CROSS 0
 #define DEBUG_DUMP 1
-#define DEBUG_MARK_DONE 1
+#define DEBUG_MARK_DONE 0
 #define DEBUG_PATH_CONSTRUCTION 1
 #define DEBUG_SORT 1
 #define DEBUG_WIND_BUMP 0
@@ -451,35 +453,35 @@
         if ((fDy < 0) ^ (rh.fDy < 0)) {
             return fDy < 0;
         }
-        if (fDy == 0 && rh.fDy == 0 && fDx != rh.fDx) {
+        if (fDy == 0 && rh.fDy == 0 && fDx * rh.fDx < 0) {
             return fDx < rh.fDx;
         }
         SkScalar cmp = fDx * rh.fDy - rh.fDx * fDy;
-        if (cmp) {
+        if (!approximately_zero(cmp)) {
             return cmp < 0;
         }
-        SkScalar dy = fDy + fDDy;
-        SkScalar rdy = rh.fDy + rh.fDDy;
-        if ((dy < 0) ^ (rdy < 0)) {
+        SkScalar dy = approximately_pin(fDy + fDDy);
+        SkScalar rdy = approximately_pin(rh.fDy + rh.fDDy);
+        if (dy * rdy < 0) {
             return dy < 0;
         }
-        SkScalar dx = fDx + fDDx;
-        SkScalar rdx = rh.fDx + rh.fDDx;
-        if (dy == 0 && rdy == 0 && dx != rdx) {
+        SkScalar dx = approximately_pin(fDx + fDDx);
+        SkScalar rdx = approximately_pin(rh.fDx + rh.fDDx);
+        if (dy == 0 && rdy == 0 && dx * rdx < 0) {
             return dx < rdx;
         }
         cmp = dx * rdy - rdx * dy;
-        if (cmp) {
+        if (!approximately_zero(cmp)) {
             return cmp < 0;
         }
-        dy += fDDDy;
-        rdy += rh.fDDDy;
-        if ((dy < 0) ^ (rdy < 0)) {
+        dy = approximately_pin(dy + fDDDy);
+        rdy = approximately_pin(rdy + rh.fDDDy);
+        if (dy * rdy < 0) {
             return dy < 0;
         }
-        dx += fDDDx;
-        rdx += rh.fDDDx;
-        if (dy == 0 && rdy == 0 && dx != rdx) {
+        dx = approximately_pin(dx + fDDDx);
+        rdx = approximately_pin(rdx + rh.fDDDx);
+        if (dy == 0 && rdy == 0 && dx * rdx < 0) {
             return dx < rdx;
         }
         return dx * rdy < rdx * dy;
@@ -510,20 +512,20 @@
         fSegment = segment;
         fStart = start;
         fEnd = end;
-        fDx = pts[1].fX - pts[0].fX; // b - a
-        fDy = pts[1].fY - pts[0].fY;
+        fDx = approximately_pin(pts[1].fX - pts[0].fX); // b - a
+        fDy = approximately_pin(pts[1].fY - pts[0].fY);
         if (verb == SkPath::kLine_Verb) {
             fDDx = fDDy = fDDDx = fDDDy = 0;
             return;
         }
-        fDDx = pts[2].fX - pts[1].fX - fDx; // a - 2b + c
-        fDDy = pts[2].fY - pts[1].fY - fDy;
+        fDDx = approximately_pin(pts[2].fX - pts[1].fX - fDx); // a - 2b + c
+        fDDy = approximately_pin(pts[2].fY - pts[1].fY - fDy);
         if (verb == SkPath::kQuad_Verb) {
             fDDDx = fDDDy = 0;
             return;
         }
-        fDDDx = pts[3].fX + 3 * (pts[1].fX - pts[2].fX) - pts[0].fX;
-        fDDDy = pts[3].fY + 3 * (pts[1].fY - pts[2].fY) - pts[0].fY;
+        fDDDx = approximately_pin(pts[3].fX + 3 * (pts[1].fX - pts[2].fX) - pts[0].fX);
+        fDDDy = approximately_pin(pts[3].fY + 3 * (pts[1].fY - pts[2].fY) - pts[0].fY);
     }
 
     // noncoincident quads/cubics may have the same initial angle
@@ -586,6 +588,31 @@
         return fStart;
     }
 
+#if DEBUG_ANGLE
+    void debugShow(const SkPoint& a) const {
+        SkDebugf("    d=(%1.9g,%1.9g) dd=(%1.9g,%1.9g) ddd=(%1.9g,%1.9g)",
+                fDx, fDy, fDDx, fDDy, fDDDx, fDDDy);
+        SkPoint b, c, d;
+        b.fX = a.fX + fDx; // add b - a
+        b.fY = a.fY + fDy;
+        c.fX = a.fX + 2 * fDx + fDDx; // add a + 2(b - a) to a - 2b + c
+        c.fY = a.fY + 2 * fDy + fDDy;
+        if (fDDDx == 0 && fDDDy == 0) {
+            if (fDDx == 0 && fDDy == 0) {
+                SkDebugf(" line=(%1.9g,%1.9g %1.9g,%1.9g)\n", a.fX, a.fY, b.fX, b.fY);
+            } else {
+                SkDebugf(" quad=(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)\n",
+                        a.fX, a.fY, b.fX, b.fY, c.fX, c.fY);
+            }
+        } else {
+            d.fX = fDDDx - a.fX - 3 * (c.fX - b.fX);
+            d.fY = fDDDy - a.fY - 3 * (c.fY - b.fY);
+            SkDebugf(" cubic=(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)\n",
+                    a.fX, a.fY, b.fX, b.fY, c.fX, c.fY, d.fX, d.fY);
+        }
+    }
+#endif
+
 private:
     SkScalar fDx;
     SkScalar fDy;
@@ -962,6 +989,13 @@
         //  binary search?
         int insertedAt = -1;
         size_t tCount = fTs.count();
+        // FIXME: only do this pinning here (e.g. this is done also in quad/line intersect)
+        if (newT < FLT_EPSILON) {
+            newT = 0;
+        }
+        if (newT > 1 - FLT_EPSILON) {
+            newT = 1;
+        }
         for (size_t index = 0; index < tCount; ++index) {
             // OPTIMIZATION: if there are three or more identical Ts, then
             // the fourth and following could be further insertion-sorted so
@@ -1712,7 +1746,7 @@
     }
 
     // FIXME: this is tricky code; needs its own unit test
-    void findTooCloseToCall(int /* winding */ ) { // FIXME: winding should be considered
+    void findTooCloseToCall(int xorMask) {
         int count = fTs.count();
         if (count < 3) { // require t=0, x, 1 at minimum
             return;
@@ -1724,9 +1758,12 @@
         do {
             match = &fTs[matchIndex];
             mOther = match->fOther;
-            moCount = mOther->fTs.count();
-            if (moCount >= 3) {
-                break;
+            // FIXME: allow quads, cubics to be near coincident?
+            if (mOther->fVerb == SkPath::kLine_Verb) {
+                moCount = mOther->fTs.count();
+                if (moCount >= 3) {
+                    break;
+                }
             }
             if (++matchIndex >= count) {
                 return;
@@ -1743,6 +1780,9 @@
                 continue;
             }
             Segment* tOther = test->fOther;
+            if (tOther->fVerb != SkPath::kLine_Verb) {
+                continue; // FIXME: allow quads, cubics to be near coincident?
+            }
             int toCount = tOther->fTs.count();
             if (toCount < 3) { // require t=0, x, 1 at minimum
                 continue;
@@ -1772,6 +1812,10 @@
                     continue;
                 }
                 if (moSpan.fOther == tOther) {
+                    if (tOther->fTs[moSpan.fOtherIndex].fWindValue == 0) {
+                        moStart = -1;
+                        break;
+                    }
                     SkASSERT(moEnd == -1);
                     moEnd = moIndex;
                     moEndT = moSpan.fT;
@@ -1789,6 +1833,9 @@
             double toStartT, toEndT;
             for (int toIndex = 0; toIndex < toCount; ++toIndex) {
                 Span& toSpan = tOther->fTs[toIndex];
+                if (toSpan.fDone) {
+                    continue;
+                }
                 if (toSpan.fOther == this) {
                     if (toSpan.fOtherT == test->fT) {
                         toStart = toIndex;
@@ -1797,6 +1844,10 @@
                     continue;
                 }
                 if (toSpan.fOther == mOther && toSpan.fOtherT == moEndT) {
+                    if (mOther->fTs[toSpan.fOtherIndex].fWindValue == 0) {
+                        moStart = -1;
+                        break;
+                    }
                     SkASSERT(toEnd == -1);
                     toEnd = toIndex;
                     toEndT = toSpan.fT;
@@ -1814,16 +1865,16 @@
                     || !tOther->isLinear(toStart, toEnd)) {
                 continue;
             }
-            // FIXME: defer implementation until the rest works
-            // this may share code with regular coincident detection
-            SkASSERT(0);
-        #if 0
+            bool flipped = (moStart - moEnd) * (toStart - toEnd) < 1;
+            double tStart = tOther->fTs[toStart].fT;
+            double tEnd = tOther->fTs[toEnd].fT;
+            double mStart = mOther->fTs[moStart].fT;
+            double mEnd = mOther->fTs[moEnd].fT;
             if (flipped) {
-                mOther->addTCancel(moStart, moEnd, tOther, tStart, tEnd);
+                mOther->addTCancel(mStart, mEnd, *tOther, tEnd, tStart);
             } else {
-                mOther->addTCoincident(moStart, moEnd, tOther, tStart, tEnd);
+                mOther->addTCoincident(xorMask, mStart, mEnd, *tOther, tStart, tEnd);
             }
-        #endif
         }
     }
 
@@ -2409,13 +2460,16 @@
                 windSum -= segment.spanSign(&angle);
             }
             SkDebugf("%s [%d] id=%d %s start=%d (%1.9g,%,1.9g) end=%d (%1.9g,%,1.9g)"
-                     " sign=%d windValue=%d winding: %d->%d (max=%d) done=%d\n",
-                     __FUNCTION__, index, segment.fID, kLVerbStr[segment.fVerb],
-                     start, segment.xAtT(&sSpan),
-                     segment.yAtT(&sSpan), end, segment.xAtT(&eSpan),
-                     segment.yAtT(&eSpan), angle.sign(), mSpan.fWindValue,
-                     lastSum, windSum, useInnerWinding(lastSum, windSum)
-                     ? windSum : lastSum, mSpan.fDone);
+                    " sign=%d windValue=%d winding: %d->%d (max=%d) done=%d\n",
+                    __FUNCTION__, index, segment.fID, kLVerbStr[segment.fVerb],
+                    start, segment.xAtT(&sSpan),
+                    segment.yAtT(&sSpan), end, segment.xAtT(&eSpan),
+                    segment.yAtT(&eSpan), angle.sign(), mSpan.fWindValue,
+                    lastSum, windSum, useInnerWinding(lastSum, windSum)
+                    ? windSum : lastSum, mSpan.fDone);
+#if DEBUG_ANGLE
+            angle.debugShow(segment.xyAtT(&sSpan));
+#endif
             ++index;
             if (index == angles.count()) {
                 index = 0;
@@ -2587,10 +2641,10 @@
         return false;
     }
 
-    void findTooCloseToCall(int winding) {
+    void findTooCloseToCall(int xorMask) {
         int segmentCount = fSegments.count();
         for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
-            fSegments[sIndex].findTooCloseToCall(winding);
+            fSegments[sIndex].findTooCloseToCall(xorMask);
         }
     }
 
@@ -3303,11 +3357,11 @@
     int contourCount = contourList.count();
     for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
         Contour* contour = contourList[cIndex];
-        contour->findTooCloseToCall(xorMask);
+        contour->resolveCoincidence(xorMask);
     }
     for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
         Contour* contour = contourList[cIndex];
-        contour->resolveCoincidence(xorMask);
+        contour->findTooCloseToCall(xorMask);
     }
 }
 
@@ -3693,6 +3747,10 @@
                 Segment* next = current->findNextWinding(chaseArray, active,
                         nextStart, nextEnd, winding, spanWinding);
                 if (!next) {
+                    if (active && firstPt && current->verb() != SkPath::kLine_Verb && *firstPt != lastPt) {
+                        lastPt = current->addCurveTo(index, endIndex, simple, true);
+                        SkASSERT(*firstPt == lastPt);
+                    }
                     break;
                 }
                 if (!firstPt) {
@@ -3748,6 +3806,10 @@
             int nextEnd = end;
             Segment* next = current->findNextXor(nextStart, nextEnd);
             if (!next) {
+                if (firstPt && current->verb() != SkPath::kLine_Verb && *firstPt != lastPt) {
+                    lastPt = current->addCurveTo(start, end, simple, true);
+                    SkASSERT(*firstPt == lastPt);
+                }
                 break;
             }
             if (!firstPt) {
diff --git a/experimental/Intersection/SimplifyAngle_Test.cpp b/experimental/Intersection/SimplifyAngle_Test.cpp
index 7391588..33b5fe2 100644
--- a/experimental/Intersection/SimplifyAngle_Test.cpp
+++ b/experimental/Intersection/SimplifyAngle_Test.cpp
@@ -52,6 +52,52 @@
 
 static const size_t cubicCount = sizeof(cubics) / sizeof(cubics[0]);
 
+struct segment {
+    SkPath::Verb verb;
+    SkPoint pts[4];
+};
+
+static const segment segmentTest1[] = {
+    {SkPath::kLine_Verb, {{2, 1}, {1, 0}        }},
+    {SkPath::kQuad_Verb, {{2, 1}, {1, 0}, {0, 0}}},
+    {SkPath::kQuad_Verb, {{2, 1}, {3, 2}, {2, 3}}},
+    {SkPath::kLine_Verb, {{2, 1}, {3, 2}        }},
+    {SkPath::kMove_Verb                          }
+};
+
+static const segment* segmentTests[] = {
+    segmentTest1
+};
+
+static const size_t segmentTestCount = sizeof(segmentTests) / sizeof(segmentTests[0]);
+
+static void testSegments(bool testFlat) {
+    for (size_t testIndex = 0; testIndex < segmentTestCount; ++testIndex) {
+        const segment* segPtr = segmentTests[testIndex];
+        SimplifyAngleTest::Angle lesser, greater;
+        int index = 0;
+        do {
+            int next = index + 1;
+            if (testFlat) {
+                lesser.setFlat(segPtr[index].pts, segPtr[index].verb, 0, index, next);
+            } else {
+                lesser.set(segPtr[index].pts, segPtr[index].verb, 0, index, next);
+            }
+            if (segPtr[next].verb == SkPath::kMove_Verb) {
+                break;
+            }
+            if (testFlat) {
+                greater.setFlat(segPtr[next].pts, segPtr[next].verb, 0, index, next);
+            } else {
+                greater.set(segPtr[next].pts, segPtr[next].verb, 0, index, next);
+            }
+            bool result = lesser < greater;
+            SkASSERT(result);
+            index = next;
+        } while (true);
+    }
+}
+
 static void testLines(bool testFlat) {
     // create angles in a circle
     SkTDArray<SimplifyAngleTest::Angle> angles;
@@ -155,6 +201,7 @@
 }
 
 static void (*tests[])(bool) = {
+    testSegments,
     testLines,
     testQuads,
     testCubics
@@ -177,7 +224,7 @@
     }
     bool firstTestComplete = false;
     for ( ; index < testCount; ++index) {
-        (*tests[index])(true);
+        (*tests[index])(false); // set to true to exercise setFlat
         firstTestComplete = true;
     }
 }
diff --git a/experimental/Intersection/SimplifyNew_Test.cpp b/experimental/Intersection/SimplifyNew_Test.cpp
index 828da54..8d6bb50 100644
--- a/experimental/Intersection/SimplifyNew_Test.cpp
+++ b/experimental/Intersection/SimplifyNew_Test.cpp
@@ -20,6 +20,16 @@
     testSimplifyx(path);
 }
 
+static void testLine1x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(2,0);
+    path.lineTo(1,1);
+    path.lineTo(0,0);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void addInnerCWTriangle(SkPath& path) {
     path.moveTo(3,0);
     path.lineTo(4,1);
@@ -50,6 +60,15 @@
 
 static void testLine2() {
     SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addInnerCWTriangle(path);
+    addOuterCWTriangle(path);
+    testSimplifyx(path);
+}
+
+static void testLine2x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
     addInnerCWTriangle(path);
     addOuterCWTriangle(path);
     testSimplifyx(path);
@@ -57,6 +76,15 @@
 
 static void testLine3() {
     SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addInnerCCWTriangle(path);
+    addOuterCWTriangle(path);
+    testSimplifyx(path);
+}
+
+static void testLine3x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
     addInnerCCWTriangle(path);
     addOuterCWTriangle(path);
     testSimplifyx(path);
@@ -69,6 +97,14 @@
     testSimplifyx(path);
 }
 
+static void testLine3ax() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addInnerCWTriangle(path);
+    addOuterCCWTriangle(path);
+    testSimplifyx(path);
+}
+
 static void testLine3b() {
     SkPath path;
     addInnerCCWTriangle(path);
@@ -76,6 +112,14 @@
     testSimplifyx(path);
 }
 
+static void testLine3bx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addInnerCCWTriangle(path);
+    addOuterCCWTriangle(path);
+    testSimplifyx(path);
+}
+
 static void testLine4() {
     SkPath path;
     addOuterCCWTriangle(path);
@@ -83,6 +127,14 @@
     testSimplifyx(path);
 }
 
+static void testLine4x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addOuterCCWTriangle(path);
+    addOuterCWTriangle(path);
+    testSimplifyx(path);
+}
+
 static void testLine5() {
     SkPath path;
     addOuterCWTriangle(path);
@@ -90,6 +142,14 @@
     testSimplifyx(path);
 }
 
+static void testLine5x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addOuterCWTriangle(path);
+    addOuterCWTriangle(path);
+    testSimplifyx(path);
+}
+
 static void testLine6() {
     SkPath path;
     path.moveTo(0,0);
@@ -103,6 +163,20 @@
     testSimplifyx(path);
 }
 
+static void testLine6x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0,0);
+    path.lineTo(4,0);
+    path.lineTo(2,2);
+    path.close();
+    path.moveTo(2,0);
+    path.lineTo(6,0);
+    path.lineTo(4,2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testLine7() {
     SkPath path;
     path.moveTo(0,0);
@@ -116,6 +190,20 @@
     testSimplifyx(path);
 }
 
+static void testLine7x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0,0);
+    path.lineTo(4,0);
+    path.lineTo(2,2);
+    path.close();
+    path.moveTo(6,0);
+    path.lineTo(2,0);
+    path.lineTo(4,2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testLine7a() {
     SkPath path;
     path.moveTo(0,0);
@@ -125,6 +213,16 @@
     testSimplifyx(path);
 }
 
+static void testLine7ax() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0,0);
+    path.lineTo(4,0);
+    path.lineTo(2,2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testLine7b() {
     SkPath path;
     path.moveTo(0,0);
@@ -137,6 +235,19 @@
     testSimplifyx(path);
 }
 
+static void testLine7bx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0,0);
+    path.lineTo(4,0);
+    path.close();
+    path.moveTo(6,0);
+    path.lineTo(2,0);
+    path.lineTo(4,2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testLine8() {
     SkPath path;
     path.moveTo(0,4);
@@ -150,6 +261,20 @@
     testSimplifyx(path);
 }
 
+static void testLine8x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0,4);
+    path.lineTo(4,4);
+    path.lineTo(2,2);
+    path.close();
+    path.moveTo(2,4);
+    path.lineTo(6,4);
+    path.lineTo(4,2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testLine9() {
     SkPath path;
     path.moveTo(0,4);
@@ -163,6 +288,20 @@
     testSimplifyx(path);
 }
 
+static void testLine9x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0,4);
+    path.lineTo(4,4);
+    path.lineTo(2,2);
+    path.close();
+    path.moveTo(6,4);
+    path.lineTo(2,4);
+    path.lineTo(4,2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testLine10() {
     SkPath path;
     path.moveTo(0,4);
@@ -176,6 +315,20 @@
     testSimplifyx(path);
 }
 
+static void testLine10x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0,4);
+    path.lineTo(4,4);
+    path.lineTo(2,2);
+    path.close();
+    path.moveTo(2,1);
+    path.lineTo(3,4);
+    path.lineTo(6,1);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testLine10a() {
     SkPath path;
     path.moveTo(0,4);
@@ -189,6 +342,20 @@
     testSimplifyx(path);
 }
 
+static void testLine10ax() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0,4);
+    path.lineTo(8,4);
+    path.lineTo(4,0);
+    path.close();
+    path.moveTo(2,2);
+    path.lineTo(3,3);
+    path.lineTo(4,2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void addCWContainer(SkPath& path) {
     path.moveTo(6,4);
     path.lineTo(0,4);
@@ -224,6 +391,14 @@
     testSimplifyx(path);
 }
 
+static void testLine11x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addCWContainer(path);
+    addCWContents(path);
+    testSimplifyx(path);
+}
+
 static void testLine12() {
     SkPath path;
     addCCWContainer(path);
@@ -231,6 +406,14 @@
     testSimplifyx(path);
 }
 
+static void testLine12x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addCCWContainer(path);
+    addCWContents(path);
+    testSimplifyx(path);
+}
+
 static void testLine13() {
     SkPath path;
     addCWContainer(path);
@@ -238,6 +421,14 @@
     testSimplifyx(path);
 }
 
+static void testLine13x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addCWContainer(path);
+    addCCWContents(path);
+    testSimplifyx(path);
+}
+
 static void testLine14() {
     SkPath path;
     addCCWContainer(path);
@@ -245,12 +436,27 @@
     testSimplifyx(path);
 }
 
+static void testLine14x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    addCCWContainer(path);
+    addCCWContents(path);
+    testSimplifyx(path);
+}
+
 static void testLine15() {
     SkPath path;
     path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
     testSimplifyx(path);
 }
 
+static void testLine15x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine16() {
     SkPath path;
     path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
@@ -258,6 +464,14 @@
     testSimplifyx(path);
 }
 
+static void testLine16x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(0, 4, 9, 9, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine17() {
     SkPath path;
     path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
@@ -265,6 +479,14 @@
     testSimplifyx(path);
 }
 
+static void testLine17x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine18() {
     SkPath path;
     path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
@@ -272,6 +494,14 @@
     testSimplifyx(path);
 }
 
+static void testLine18x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(12, 4, 21, 21, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine19() {
     SkPath path;
     path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
@@ -279,6 +509,14 @@
     testSimplifyx(path);
 }
 
+static void testLine19x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(12, 16, 21, 21, (SkPath::Direction) 0);    
+    testSimplifyx(path);
+}
+
 static void testLine20() {
     SkPath path;
     path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
@@ -286,6 +524,14 @@
     testSimplifyx(path);
 }
 
+static void testLine20x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
+    path.addRect(0, 12, 9, 9, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine21() {
     SkPath path;
     path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
@@ -293,6 +539,14 @@
     testSimplifyx(path);
 }
 
+static void testLine21x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
+    path.addRect(0, 16, 9, 9, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine22() {
     SkPath path;
     path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
@@ -300,6 +554,14 @@
     testSimplifyx(path);
 }
 
+static void testLine22x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
+    path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine23() {
     SkPath path;
     path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
@@ -307,7 +569,13 @@
     testSimplifyx(path);
 }
 
-
+static void testLine23x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
+    path.addRect(12, 0, 21, 21, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
 
 static void testLine24a() {
     SkPath path;
@@ -322,6 +590,20 @@
     testSimplifyx(path);
 }
 
+static void testLine24ax() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(2,0);
+    path.lineTo(4,4);
+    path.lineTo(0,4);
+    path.close();
+    path.moveTo(2,0);
+    path.lineTo(1,2);
+    path.lineTo(2,2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testLine24() {
     SkPath path;
     path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
@@ -329,6 +611,14 @@
     testSimplifyx(path);
 }
 
+static void testLine24x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
+    path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine25() {
     SkPath path;
     path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
@@ -336,6 +626,14 @@
     testSimplifyx(path);
 }
 
+static void testLine25x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
+    path.addRect(12, 0, 21, 21, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine26() {
     SkPath path;
     path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
@@ -343,6 +641,14 @@
     testSimplifyx(path);
 }
 
+static void testLine26x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
+    path.addRect(0, 12, 9, 9, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine27() {
     SkPath path;
     path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
@@ -350,6 +656,14 @@
     testSimplifyx(path);
 }
 
+static void testLine27x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
+    path.addRect(12, 8, 21, 21, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine28() {
     SkPath path;
     path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
@@ -357,6 +671,14 @@
     testSimplifyx(path);
 }
 
+static void testLine28x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
+    path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine29() {
     SkPath path;
     path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
@@ -364,6 +686,14 @@
     testSimplifyx(path);
 }
 
+static void testLine29x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
+    path.addRect(12, 12, 21, 21, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine30() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -372,6 +702,15 @@
     testSimplifyx(path);
 }
 
+static void testLine30x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(4, 4, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine31() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -380,6 +719,15 @@
     testSimplifyx(path);
 }
 
+static void testLine31x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(0, 4, 9, 9, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine32() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -388,6 +736,15 @@
     testSimplifyx(path);
 }
 
+static void testLine32x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine33() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -396,6 +753,15 @@
     testSimplifyx(path);
 }
 
+static void testLine33x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine34() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -404,6 +770,15 @@
     testSimplifyx(path);
 }
 
+static void testLine34x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
+    path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine35() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -412,6 +787,15 @@
     testSimplifyx(path);
 }
 
+static void testLine35x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(6, 0, 18, 18, (SkPath::Direction) 0);
+    path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine36() {
     SkPath path;
     path.addRect(0, 10, 20, 20, (SkPath::Direction) 0);
@@ -420,6 +804,15 @@
     testSimplifyx(path);
 }
 
+static void testLine36x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 10, 20, 20, (SkPath::Direction) 0);
+    path.addRect(6, 12, 18, 18, (SkPath::Direction) 0);
+    path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine37() {
     SkPath path;
     path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
@@ -428,6 +821,15 @@
     testSimplifyx(path);
 }
 
+static void testLine37x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
+    path.addRect(18, 24, 30, 30, (SkPath::Direction) 0);
+    path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine38() {
     SkPath path;
     path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
@@ -436,6 +838,15 @@
     testSimplifyx(path);
 }
 
+static void testLine38x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
+    path.addRect(6, 12, 18, 18, (SkPath::Direction) 0);
+    path.addRect(12, 12, 21, 21, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine40() {
     SkPath path;
     path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
@@ -444,6 +855,15 @@
     testSimplifyx(path);
 }
 
+static void testLine40x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
+    path.addRect(12, 18, 24, 24, (SkPath::Direction) 0);
+    path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine41() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -452,6 +872,15 @@
     testSimplifyx(path);
 }
 
+static void testLine41x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(18, 24, 30, 30, (SkPath::Direction) 0);
+    path.addRect(12, 0, 21, 21, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine42() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -460,6 +889,15 @@
     testSimplifyx(path);
 }
 
+static void testLine42x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(8, 16, 17, 17, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine43() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -468,6 +906,15 @@
     testSimplifyx(path);
 }
 
+static void testLine43x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(6, 24, 18, 18, (SkPath::Direction) 0);
+    path.addRect(0, 32, 9, 36, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine44() {
     SkPath path;
     path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
@@ -476,6 +923,15 @@
     testSimplifyx(path);
 }
 
+static void testLine44x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
+    path.addRect(18, 0, 30, 30, (SkPath::Direction) 0);
+    path.addRect(18, 32, 27, 36, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine45() {
     SkPath path;
     path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
@@ -484,6 +940,15 @@
     testSimplifyx(path);
 }
 
+static void testLine45x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
+    path.addRect(18, 0, 30, 30, (SkPath::Direction) 0);
+    path.addRect(24, 32, 33, 36, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine46() {
     SkPath path;
     path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
@@ -492,6 +957,15 @@
     testSimplifyx(path);
 }
 
+static void testLine46x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
+    path.addRect(24, 0, 36, 36, (SkPath::Direction) 0);
+    path.addRect(24, 32, 33, 36, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine47() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -500,6 +974,15 @@
     testSimplifyx(path);
 }
 
+static void testLine47x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine48() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -508,6 +991,15 @@
     testSimplifyx(path);
 }
 
+static void testLine48x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
+    path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine49() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -516,6 +1008,15 @@
     testSimplifyx(path);
 }
 
+static void testLine49x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
+    path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine50() {
     SkPath path;
     path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
@@ -523,6 +1024,13 @@
     testSimplifyx(path);
 }
 
+static void testLine50x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
+    path.addRect(24, 20, 36, 30, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
 
 static void testLine51() {
     SkPath path;
@@ -532,6 +1040,15 @@
     testSimplifyx(path);
 }
 
+static void testLine51x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
+    path.addRect(4, 12, 13, 13, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine52() {
     SkPath path;
     path.addRect(0, 30, 20, 20, (SkPath::Direction) 0);
@@ -540,6 +1057,15 @@
     testSimplifyx(path);
 }
 
+static void testLine52x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 30, 20, 20, (SkPath::Direction) 0);
+    path.addRect(6, 20, 18, 30, (SkPath::Direction) 0);
+    path.addRect(32, 0, 36, 41, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine53() {
     SkPath path;
     path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
@@ -548,6 +1074,15 @@
     testSimplifyx(path);
 }
 
+static void testLine53x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
+    path.addRect(12, 20, 24, 30, (SkPath::Direction) 0);
+    path.addRect(12, 32, 21, 36, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine54() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -556,6 +1091,15 @@
     testSimplifyx(path);
 }
 
+static void testLine54x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(6, 0, 18, 18, (SkPath::Direction) 0);
+    path.addRect(8, 4, 17, 17, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine55() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -564,6 +1108,15 @@
     testSimplifyx(path);
 }
 
+static void testLine55x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(6, 6, 18, 18, (SkPath::Direction) 0);
+    path.addRect(4, 4, 13, 13, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine56() {
     SkPath path;
     path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
@@ -572,6 +1125,15 @@
     testSimplifyx(path);
 }
 
+static void testLine56x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
+    path.addRect(18, 20, 30, 30, (SkPath::Direction) 0);
+    path.addRect(12, 0, 21, 21, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine57() {
     SkPath path;
     path.addRect(20, 0, 40, 40, (SkPath::Direction) 0);
@@ -580,6 +1142,15 @@
     testSimplifyx(path);
 }
 
+static void testLine57x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(20, 0, 40, 40, (SkPath::Direction) 0);
+    path.addRect(20, 0, 30, 40, (SkPath::Direction) 0);
+    path.addRect(12, 0, 21, 21, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine58() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -588,6 +1159,15 @@
     testSimplifyx(path);
 }
 
+static void testLine58x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 0, 12, 12, (SkPath::Direction) 1);
+    path.addRect(0, 12, 9, 9, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine59() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -596,6 +1176,15 @@
     testSimplifyx(path);
 }
 
+static void testLine59x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(6, 6, 18, 18, (SkPath::Direction) 1);
+    path.addRect(4, 4, 13, 13, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine60() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -604,6 +1193,15 @@
     testSimplifyx(path);
 }
 
+static void testLine60x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(6, 12, 18, 18, (SkPath::Direction) 1);
+    path.addRect(4, 12, 13, 13, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine61() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -612,6 +1210,15 @@
     testSimplifyx(path);
 }
 
+static void testLine61x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(12, 0, 24, 24, (SkPath::Direction) 1);
+    path.addRect(12, 0, 21, 21, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine62() {
     SkPath path;
     path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
@@ -621,6 +1228,16 @@
     testSimplifyx(path);
 }
 
+static void testLine62x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
+    path.addRect(4, 12, 13, 13, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine63() {
     SkPath path;
     path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
@@ -630,6 +1247,16 @@
     testSimplifyx(path);
 }
 
+static void testLine63x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
+    path.addRect(0, 10, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 6, 12, 12, (SkPath::Direction) 1);
+    path.addRect(0, 32, 9, 36, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine64() {
     SkPath path;
     path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
@@ -638,6 +1265,15 @@
     testSimplifyx(path);
 }
 
+static void testLine64x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
+    path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
+    path.addRect(18, 6, 30, 30, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine65() {
     SkPath path;
     path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
@@ -647,6 +1283,16 @@
     testSimplifyx(path);
 }
 
+static void testLine65x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
+    path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
+    path.addRect(24, 0, 36, 36, (SkPath::Direction) 0);
+    path.addRect(32, 6, 36, 41, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine66() {
     SkPath path;
     path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
@@ -655,6 +1301,15 @@
     testSimplifyx(path);
 }
 
+static void testLine66x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
+    path.addRect(0, 30, 20, 20, (SkPath::Direction) 0);
+    path.addRect(12, 20, 24, 30, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine67() {
     SkPath path;
     path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
@@ -664,6 +1319,16 @@
     testSimplifyx(path);
 }
 
+static void testLine67x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
+    path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
+    path.addRect(24, 20, 36, 30, (SkPath::Direction) 0);
+    path.addRect(32, 0, 36, 41, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine68a() {
     SkPath path;
     path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
@@ -672,6 +1337,15 @@
     testSimplifyx(path);
 }
 
+static void testLine68ax() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 0);
+    path.addRect(1, 2, 4, 2, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine68b() {
     SkPath path;
     path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
@@ -680,6 +1354,15 @@
     testSimplifyx(path);
 }
 
+static void testLine68bx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(1, 2, 2, 2, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine68c() {
     SkPath path;
     path.addRect(0, 0, 8, 8, (SkPath::Direction) 1);
@@ -688,6 +1371,15 @@
     testSimplifyx(path);
 }
 
+static void testLine68cx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 1);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 0);
+    path.addRect(1, 2, 4, 2, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine68d() {
     SkPath path;
     path.addRect(0, 0, 8, 8, (SkPath::Direction) 1);
@@ -696,6 +1388,15 @@
     testSimplifyx(path);
 }
 
+static void testLine68dx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 1);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(1, 2, 4, 2, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine68e() {
     SkPath path;
     path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
@@ -705,6 +1406,16 @@
     testSimplifyx(path);
 }
 
+static void testLine68ex() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(1, 2, 2, 2, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine68f() {
     SkPath path;
     path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
@@ -714,6 +1425,16 @@
     testSimplifyx(path);
 }
 
+static void testLine68fx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(1, 2, 2, 2, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine68g() {
     SkPath path;
     path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
@@ -724,6 +1445,17 @@
     testSimplifyx(path);
 }
 
+static void testLine68gx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(1, 2, 2, 2, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine68h() {
     SkPath path;
     path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
@@ -734,6 +1466,17 @@
     testSimplifyx(path);
 }
 
+static void testLine68hx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
+    path.addRect(1, 2, 2, 2, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine69() {
     SkPath path;
     path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
@@ -742,6 +1485,15 @@
     testSimplifyx(path);
 }
 
+static void testLine69x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 20, 12, 30, (SkPath::Direction) 0);
+    path.addRect(12, 32, 21, 36, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine70() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -750,6 +1502,15 @@
     testSimplifyx(path);
 }
 
+static void testLine70x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 24, 12, 12, (SkPath::Direction) 0);
+    path.addRect(12, 32, 21, 36, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine71() {
     SkPath path;
     path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
@@ -758,6 +1519,15 @@
     testSimplifyx(path);
 }
 
+static void testLine71x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
+    path.addRect(12, 0, 24, 24, (SkPath::Direction) 0);
+    path.addRect(12, 32, 21, 36, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine72() {
     SkPath path;
     path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
@@ -766,6 +1536,15 @@
     testSimplifyx(path);
 }
 
+static void testLine72x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
+    path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
+    path.addRect(6, 20, 18, 30, (SkPath::Direction) 0);
+    testSimplifyx(path);
+}
+
 static void testLine73() {
     SkPath path;
     path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
@@ -775,6 +1554,16 @@
     testSimplifyx(path);
 }
 
+static void testLine73x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
+    path.addRect(0, 40, 20, 20, (SkPath::Direction) 0);
+    path.addRect(0, 20, 12, 30, (SkPath::Direction) 0);
+    path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine74() {
     SkPath path;
     path.addRect(20, 30, 40, 40, (SkPath::Direction) 0);
@@ -783,6 +1572,15 @@
     testSimplifyx(path);
 }
 
+static void testLine74x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(20, 30, 40, 40, (SkPath::Direction) 0);
+    path.addRect(24, 20, 36, 30, (SkPath::Direction) 1);
+    path.addRect(32, 24, 36, 41, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine75() {
     SkPath path;
     path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
@@ -792,6 +1590,16 @@
     testSimplifyx(path);
 }
 
+static void testLine75x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
+    path.addRect(10, 0, 30, 30, (SkPath::Direction) 1);
+    path.addRect(18, 0, 30, 30, (SkPath::Direction) 1);
+    path.addRect(12, 0, 21, 21, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine76() {
     SkPath path;
     path.addRect(36, 0, 66, 60, (SkPath::Direction) 0);
@@ -801,6 +1609,16 @@
     testSimplifyx(path);
 }
 
+static void testLine76x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(36, 0, 66, 60, (SkPath::Direction) 0);
+    path.addRect(10, 20, 40, 30, (SkPath::Direction) 0);
+    path.addRect(24, 20, 36, 30, (SkPath::Direction) 1);
+    path.addRect(32, 6, 36, 41, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine77() {
     SkPath path;
     path.addRect(20, 0, 40, 40, (SkPath::Direction) 0);
@@ -809,6 +1627,15 @@
     testSimplifyx(path);
 }
 
+static void testLine77x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(20, 0, 40, 40, (SkPath::Direction) 0);
+    path.addRect(24, 6, 36, 36, (SkPath::Direction) 1);
+    path.addRect(24, 32, 33, 36, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine78() {
     SkPath path;
     path.addRect(0, 0, 30, 60, (SkPath::Direction) 0);
@@ -818,6 +1645,16 @@
     testSimplifyx(path);
 }
 
+static void testLine78x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 0, 30, 60, (SkPath::Direction) 0);
+    path.addRect(10, 20, 30, 30, (SkPath::Direction) 1);
+    path.addRect(18, 20, 30, 30, (SkPath::Direction) 1);
+    path.addRect(32, 0, 36, 41, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testLine79() {
     SkPath path;
     path.addRect(0, 36, 60, 30, (SkPath::Direction) 0);
@@ -827,6 +1664,16 @@
     testSimplifyx(path);
 }
 
+static void testLine79x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.addRect(0, 36, 60, 30, (SkPath::Direction) 0);
+    path.addRect(10, 30, 40, 30, (SkPath::Direction) 0);
+    path.addRect(0, 20, 12, 30, (SkPath::Direction) 1);
+    path.addRect(0, 32, 9, 36, (SkPath::Direction) 1);
+    testSimplifyx(path);
+}
+
 static void testDegenerate1() {
     SkPath path;
     path.moveTo(0, 0);
@@ -840,6 +1687,20 @@
     testSimplifyx(path);
 }
 
+static void testDegenerate1x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.lineTo(2, 0);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(2, 0);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testDegenerate2() {
     SkPath path;
     path.moveTo(0, 0);
@@ -853,6 +1714,20 @@
     testSimplifyx(path);
 }
 
+static void testDegenerate2x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.lineTo(0, 0);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(0, 1);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testDegenerate3() {
     SkPath path;
     path.moveTo(0, 0);
@@ -866,6 +1741,20 @@
     testSimplifyx(path);
 }
 
+static void testDegenerate3x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(2, 0);
+    path.lineTo(1, 0);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.lineTo(3, 0);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testDegenerate4() {
     SkPath path;
     path.moveTo(0, 0);
@@ -879,6 +1768,20 @@
     testSimplifyx(path);
 }
 
+static void testDegenerate4x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(1, 3);
+    path.close();
+    path.moveTo(1, 0);
+    path.lineTo(1, 1);
+    path.lineTo(1, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testNondegenerate1() {
     SkPath path;
     path.moveTo(0, 0);
@@ -892,6 +1795,20 @@
     testSimplifyx(path);
 }
 
+static void testNondegenerate1x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(3, 0);
+    path.lineTo(1, 3);
+    path.close();
+    path.moveTo(1, 1);
+    path.lineTo(2, 1);
+    path.lineTo(1, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testNondegenerate2() {
     SkPath path;
     path.moveTo(1, 0);
@@ -905,6 +1822,20 @@
     testSimplifyx(path);
 }
 
+static void testNondegenerate2x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(1, 0);
+    path.lineTo(0, 1);
+    path.lineTo(1, 1);
+    path.close();
+    path.moveTo(0, 2);
+    path.lineTo(0, 3);
+    path.lineTo(1, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testNondegenerate3() {
     SkPath path;
     path.moveTo(0, 0);
@@ -918,6 +1849,20 @@
     testSimplifyx(path);
 }
 
+static void testNondegenerate3x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(2, 1);
+    path.close();
+    path.moveTo(0, 1);
+    path.lineTo(1, 1);
+    path.lineTo(0, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testNondegenerate4() {
     SkPath path;
     path.moveTo(1, 0);
@@ -931,6 +1876,20 @@
     testSimplifyx(path);
 }
 
+static void testNondegenerate4x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(1, 0);
+    path.lineTo(0, 1);
+    path.lineTo(1, 2);
+    path.close();
+    path.moveTo(0, 2);
+    path.lineTo(0, 3);
+    path.lineTo(1, 3);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testQuadralateral5() {
     SkPath path;
     path.moveTo(0, 0);
@@ -946,6 +1905,22 @@
     testSimplifyx(path);
 }
 
+static void testQuadralateral5x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(1, 1);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(2, 2);
+    path.lineTo(3, 2);
+    path.lineTo(3, 3);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testQuadralateral6() {
     SkPath path;
     path.moveTo(0, 0);
@@ -961,6 +1936,22 @@
     testSimplifyx(path);
 }
 
+static void testQuadralateral6x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(1, 1);
+    path.close();
+    path.moveTo(1, 0);
+    path.lineTo(2, 0);
+    path.lineTo(0, 2);
+    path.lineTo(2, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testFauxQuadralateral6() {
     SkPath path;
     path.moveTo(0, 0);
@@ -978,6 +1969,24 @@
     testSimplifyx(path);
 }
 
+static void testFauxQuadralateral6x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(1, 1);
+    path.close();
+    path.moveTo(1, 0);
+    path.lineTo(2, 0);
+    path.lineTo(1 + 1.0f/3, 2.0f/3);
+    path.close();
+    path.moveTo(1 + 1.0f/3, 2.0f/3);
+    path.lineTo(0, 2);
+    path.lineTo(2, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testFauxQuadralateral6a() {
     SkPath path;
     path.moveTo(0, 0);
@@ -995,6 +2004,24 @@
     testSimplifyx(path);
 }
 
+static void testFauxQuadralateral6ax() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(3, 0);
+    path.lineTo(3, 3);
+    path.close();
+    path.moveTo(3, 0);
+    path.lineTo(6, 0);
+    path.lineTo(4, 2);
+    path.close();
+    path.moveTo(4, 2);
+    path.lineTo(0, 6);
+    path.lineTo(6, 6);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testFauxQuadralateral6b() {
     SkPath path;
     path.moveTo(0, 0);
@@ -1012,6 +2039,24 @@
     testSimplifyx(path);
 }
 
+static void testFauxQuadralateral6bx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(3, 0);
+    path.lineTo(3, 3);
+    path.close();
+    path.moveTo(3, 0);
+    path.lineTo(6, 0);
+    path.lineTo(4, 2);
+    path.close();
+    path.moveTo(4, 2);
+    path.lineTo(6, 6);
+    path.lineTo(0, 6);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testFauxQuadralateral6c() {
     SkPath path;
     path.moveTo(0, 0);
@@ -1029,6 +2074,24 @@
     testSimplifyx(path);
 }
 
+static void testFauxQuadralateral6cx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(3, 3);
+    path.lineTo(3, 0);
+    path.close();
+    path.moveTo(3, 0);
+    path.lineTo(6, 0);
+    path.lineTo(4, 2);
+    path.close();
+    path.moveTo(4, 2);
+    path.lineTo(0, 6);
+    path.lineTo(6, 6);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testFauxQuadralateral6d() {
     SkPath path;
     path.moveTo(0, 0);
@@ -1046,6 +2109,24 @@
     testSimplifyx(path);
 }
 
+static void testFauxQuadralateral6dx() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(3, 3);
+    path.lineTo(3, 0);
+    path.close();
+    path.moveTo(3, 0);
+    path.lineTo(6, 0);
+    path.lineTo(4, 2);
+    path.close();
+    path.moveTo(4, 2);
+    path.lineTo(6, 6);
+    path.lineTo(0, 6);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testQuadralateral6a() {
     SkPath path;
     path.moveTo(0, 0);
@@ -1061,6 +2142,22 @@
     testSimplifyx(path);
 }
 
+static void testQuadralateral6ax() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.lineTo(3, 0);
+    path.lineTo(3, 3);
+    path.close();
+    path.moveTo(3, 0);
+    path.lineTo(6, 0);
+    path.lineTo(0, 6);
+    path.lineTo(6, 6);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testQuadralateral7() {
     SkPath path;
     path.moveTo(0, 0);
@@ -1076,6 +2173,22 @@
     testSimplifyx(path);
 }
 
+static void testQuadralateral7x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(2, 1);
+    path.close();
+    path.moveTo(1, 0);
+    path.lineTo(1, 1);
+    path.lineTo(2, 2);
+    path.lineTo(1, 3);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testQuadralateral8() {
     SkPath path;
     path.moveTo(0, 0);
@@ -1091,6 +2204,22 @@
     testSimplifyx(path);
 }
 
+static void testQuadralateral8x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(3, 1);
+    path.lineTo(1, 3);
+    path.lineTo(3, 3);
+    path.close();
+    path.moveTo(2, 1);
+    path.lineTo(0, 2);
+    path.lineTo(3, 2);
+    path.lineTo(2, 3);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testQuadralateral9() {
     SkPath path;
     path.moveTo(0, 0);
@@ -1106,7 +2235,23 @@
     testSimplifyx(path);
 }
 
-static void testLine1x() {
+static void testQuadralateral9x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(1, 2);
+    path.lineTo(2, 2);
+    path.close();
+    path.moveTo(1, 1);
+    path.lineTo(2, 1);
+    path.lineTo(1, 3);
+    path.lineTo(2, 3);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void testLine1ax() {
     SkPath path;
     path.setFillType(SkPath::kEvenOdd_FillType);
     path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
@@ -1114,7 +2259,7 @@
     testSimplifyx(path);
 }
 
-static void testLine2x() {
+static void testLine2ax() {
     SkPath path;
     path.setFillType(SkPath::kEvenOdd_FillType);
     path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
@@ -1123,7 +2268,7 @@
     testSimplifyx(path);
 }
 
-static void testLine3x() {
+static void testLine3aax() {
     SkPath path;
     path.setFillType(SkPath::kEvenOdd_FillType);
     path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
@@ -1132,7 +2277,7 @@
     testSimplifyx(path);
 }
 
-static void testLine4x() {
+static void testLine4ax() {
     SkPath path;
     path.setFillType(SkPath::kEvenOdd_FillType);
     path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
@@ -1154,6 +2299,20 @@
     testSimplifyx(path);
 }
 
+static void testQuadratic1x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 0, 0);
+    path.lineTo(1, 0);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(0, 0, 0, 0);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testQuadratic2() {
     SkPath path;
     path.moveTo(0, 0);
@@ -1167,6 +2326,20 @@
     testSimplifyx(path);
 }
 
+static void testQuadratic2x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 0, 0);
+    path.lineTo(3, 0);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(1, 0, 0, 1);
+    path.close();
+    testSimplifyx(path);
+}
+
 static void testQuadratic3() {
     SkPath path;
     path.moveTo(0, 0);
@@ -1180,38 +2353,278 @@
     testSimplifyx(path);
 }
 
-static void (*firstTest)() = testQuadratic3;
+static void testQuadratic3x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(0, 2);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(1, 0, 0, 1);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void testQuadratic4() {
+    SkPath path;
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(0, 2);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(1, 0, 0, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void testQuadratic4x() {
+    SkPath path;
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(0, 2);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(1, 0, 0, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void testQuadratic5() {
+    SkPath path;
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 0, 0);
+    path.lineTo(0, 1);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.quadTo(0, 1, 0, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void testQuadratic6() {
+    SkPath path;
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(2, 1);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(2, 0, 0, 1);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void testQuadratic7() {
+    SkPath path;
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(3, 1);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(3, 0, 1, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void testQuadratic8() {
+    SkPath path;
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(0, 2);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.quadTo(0, 1, 1, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void testQuadratic9() {
+    SkPath path;
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(3, 1);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.quadTo(1, 2, 3, 2);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void testQuadratic14() {
+    SkPath path;
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(3, 2);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.quadTo(3, 2, 3, 3);
+    path.close();
+    testSimplifyx(path);
+}
+
+static void (*firstTest)() = testQuadratic14;
 
 static struct {
     void (*fun)();
     const char* str;
 } tests[] = {
+    TEST(testQuadratic14),
+    TEST(testQuadratic9),
+    TEST(testQuadratic8),
+    TEST(testQuadratic7),
+    TEST(testQuadratic6),
+    TEST(testQuadratic5),
+    TEST(testQuadratic4x),
+    TEST(testQuadratic3x),
+    TEST(testQuadratic2x),
+    TEST(testQuadratic1x),
+    TEST(testQuadratic4),
     TEST(testQuadratic3),
     TEST(testQuadratic2),
     TEST(testQuadratic1),
-    TEST(testLine4x),
-    TEST(testLine3x),
-    TEST(testLine2x),
-    TEST(testLine1x),
+    TEST(testLine4ax),
+    TEST(testLine3aax),
+    TEST(testLine2ax),
+    TEST(testLine1ax),
+    TEST(testQuadralateral9x),
+    TEST(testQuadralateral8x),
+    TEST(testQuadralateral7x),
+    TEST(testQuadralateral6x),
+    TEST(testQuadralateral6ax),
     TEST(testQuadralateral9),
     TEST(testQuadralateral8),
     TEST(testQuadralateral7),
     TEST(testQuadralateral6),
     TEST(testQuadralateral6a),
+    TEST(testFauxQuadralateral6dx),
+    TEST(testFauxQuadralateral6cx),
+    TEST(testFauxQuadralateral6bx),
+    TEST(testFauxQuadralateral6ax),
+    TEST(testFauxQuadralateral6x),
     TEST(testFauxQuadralateral6d),
     TEST(testFauxQuadralateral6c),
     TEST(testFauxQuadralateral6b),
     TEST(testFauxQuadralateral6a),
     TEST(testFauxQuadralateral6),
+    TEST(testQuadralateral5x),
     TEST(testQuadralateral5),
+    TEST(testNondegenerate4x),
+    TEST(testNondegenerate3x),
+    TEST(testNondegenerate2x),
+    TEST(testNondegenerate1x),
     TEST(testNondegenerate4),
     TEST(testNondegenerate3),
     TEST(testNondegenerate2),
     TEST(testNondegenerate1),
+    TEST(testDegenerate4x),
+    TEST(testDegenerate3x),
+    TEST(testDegenerate2x),
+    TEST(testDegenerate1x),
     TEST(testDegenerate4),
     TEST(testDegenerate3),
     TEST(testDegenerate2),
     TEST(testDegenerate1),
+    TEST(testLine79x),
+    TEST(testLine78x),
+    TEST(testLine77x),
+    TEST(testLine76x),
+    TEST(testLine75x),
+    TEST(testLine74x),
+    TEST(testLine73x),
+    TEST(testLine72x),
+    TEST(testLine71x),
+    TEST(testLine70x),
+    TEST(testLine69x),
+    TEST(testLine68hx),
+    TEST(testLine68gx),
+    TEST(testLine68fx),
+    TEST(testLine68ex),
+    TEST(testLine68dx),
+    TEST(testLine68cx),
+    TEST(testLine68bx),
+    TEST(testLine68ax),
+    TEST(testLine67x),
+    TEST(testLine66x),
+    TEST(testLine65x),
+    TEST(testLine64x),
+    TEST(testLine63x),
+    TEST(testLine62x),
+    TEST(testLine61x),
+    TEST(testLine60x),
+    TEST(testLine59x),
+    TEST(testLine58x),
+    TEST(testLine57x),
+    TEST(testLine56x),
+    TEST(testLine55x),
+    TEST(testLine54x),
+    TEST(testLine53x),
+    TEST(testLine52x),
+    TEST(testLine51x),
+    TEST(testLine50x),
+    TEST(testLine49x),
+    TEST(testLine48x),
+    TEST(testLine47x),
+    TEST(testLine46x),
+    TEST(testLine45x),
+    TEST(testLine44x),
+    TEST(testLine43x),
+    TEST(testLine42x),
+    TEST(testLine41x),
+    TEST(testLine40x),
+    TEST(testLine38x),
+    TEST(testLine37x),
+    TEST(testLine36x),
+    TEST(testLine35x),
+    TEST(testLine34x),
+    TEST(testLine33x),
+    TEST(testLine32x),
+    TEST(testLine31x),
+    TEST(testLine30x),
+    TEST(testLine29x),
+    TEST(testLine28x),
+    TEST(testLine27x),
+    TEST(testLine26x),
+    TEST(testLine25x),
+    TEST(testLine24ax),
+    TEST(testLine24x),
+    TEST(testLine23x),
+    TEST(testLine22x),
+    TEST(testLine21x),
+    TEST(testLine20x),
+    TEST(testLine19x),
+    TEST(testLine18x),
+    TEST(testLine17x),
+    TEST(testLine16x),
+    TEST(testLine15x),
+    TEST(testLine14x),
+    TEST(testLine13x),
+    TEST(testLine12x),
+    TEST(testLine11x),
+    TEST(testLine10ax),
+    TEST(testLine10x),
+    TEST(testLine9x),
+    TEST(testLine8x),
+    TEST(testLine7bx),
+    TEST(testLine7ax),
+    TEST(testLine7x),
+    TEST(testLine6x),
+    TEST(testLine5x),
+    TEST(testLine4x),
+    TEST(testLine3bx),
+    TEST(testLine3ax),
+    TEST(testLine3x),
+    TEST(testLine2x),
+    TEST(testLine1x),
     TEST(testLine79),
     TEST(testLine78),
     TEST(testLine77),
diff --git a/experimental/Intersection/op.htm b/experimental/Intersection/op.htm
index b71ebbc..b11b8f3 100644
--- a/experimental/Intersection/op.htm
+++ b/experimental/Intersection/op.htm
@@ -1047,11 +1047,206 @@
     path.close();
 </div>
 
+<div id="testQuadratic4x">
+    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(0, 2);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(1, 0, 0, 2);
+    path.close();
+</div>
+
+<div id="testQuadratic5">
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 0, 0);
+    path.lineTo(0, 1);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.quadTo(0, 1, 0, 2);
+    path.close();
+</div>
+
+<div id="testQuadratic6">
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(2, 1);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(2, 0, 0, 1);
+    path.close();
+</div>
+
+<div id="testQuadratic7">
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(3, 1);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(0, 0);
+    path.quadTo(3, 0, 1, 2);
+    path.close();
+</div>
+
+<div id="testQuadratic8">
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(0, 2);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.quadTo(0, 1, 1, 2);
+    path.close();
+</div>
+
+<div id="testQuadratic9">
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(3, 1);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.quadTo(1, 2, 3, 2);
+    path.close();
+</div>
+
+<div id="testQuadratic9a">
+    path.moveTo(1.08000004, 0.720000029);
+    path.lineTo(0, 0);
+    path.lineTo(1, 0);
+    path.lineTo(3, 1);
+    path.lineTo(1.01568651, 0.338562161);
+    path.quadTo(1.03542483, 0.541699469, 1.08000004, 0.720000029);
+    path.close();
+    path.moveTo(1.08000004, 0.720000029);
+    path.lineTo(3, 2);
+    path.quadTo(1.39999998, 2, 1.08000004, 0.720000029);
+    path.close();
+
+</div>
+
+<div id="testQuadratic10a">
+path.moveTo(15.5, 15.5);
+path.lineTo(46.5, 15.5);
+path.quadTo(0, 31, 0, 46.5);
+path.lineTo(15.5, 15.5);
+path.close();
+</div>
+
+<div id="testQuadratic10b">
+path.moveTo(5.16666698, 36.1666641);
+path.lineTo(15.5, 15.5);
+path.lineTo(46.5, 15.5);
+path.quadTo(15.5, 25.8333321, 5.16666698, 36.1666641);
+path.close();
+path.moveTo(5.16666698, 36.1666641);
+path.lineTo(0, 46.5);
+path.quadTo(0, 41.3333359, 5.16666698, 36.1666641);
+path.close();
+</div>
+
+<div id="testQuadratic11a">
+path.moveTo(0, 0);
+path.lineTo(15.5, 31);
+path.lineTo(0, 0);
+path.close();
+path.moveTo(0, 15.5);
+path.lineTo(15.5, 15.5);
+path.quadTo(15.5, 15.5, 46.5, 31);
+path.lineTo(0, 15.5);
+path.close();
+</div>
+
+<div id="testQuadratic11b">
+path.moveTo(9.30000019, 18.6000004);
+path.lineTo(0, 15.5);
+path.lineTo(7.75, 15.5);
+path.lineTo(15.5, 15.5);
+path.lineTo(46.5, 31);
+path.lineTo(9.30000019, 18.6000004);
+path.close();
+</div>
+
+<div id="testQuadratic12">
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 0, 0);
+    path.lineTo(1, 3);
+    path.close();
+    path.moveTo(1, 0);
+    path.lineTo(0, 1);
+    path.quadTo(1, 1, 0, 3);
+    path.close();
+</div>
+
+<div id="testQuadratic13a">
+path.moveTo(0, 0);
+path.quadTo(0, 0, 15.5, 0);
+path.lineTo(15.5, 31);
+path.lineTo(0, 0);
+path.close();
+path.moveTo(0, 0);
+path.quadTo(15.5, 46.5, 46.5, 46.5);
+path.lineTo(0, 0);
+path.close();
+</div>
+
+<div id="testQuadratic13b">
+path.moveTo(14.8800001, 29.7600002);
+path.quadTo(6.20000029, 18.6000004, 0, 0);
+path.lineTo(14.8800001, 29.7600002);
+path.close();
+path.moveTo(15.5, 30.5437222);
+path.lineTo(15.5, 31);
+path.lineTo(14.8800001, 29.7600002);
+path.quadTo(15.1884346, 30.156559, 15.5, 30.5437222);
+path.close();
+path.moveTo(15.5, 15.5);
+path.lineTo(0, 0);
+path.lineTo(15.5, 0);
+path.lineTo(15.5, 15.5);
+path.close();
+path.moveTo(15.5, 30.5437222);
+path.lineTo(15.5, 15.5);
+path.lineTo(46.5, 46.5);
+path.quadTo(28.34062, 46.5, 15.5, 30.5437222);
+path.close();
+</div>
+
+<div id="testQuadratic14">
+    path.moveTo(0, 0);
+    path.quadTo(0, 0, 1, 0);
+    path.lineTo(3, 2);
+    path.close();
+    path.moveTo(0, 0);
+    path.lineTo(1, 0);
+    path.quadTo(3, 2, 3, 3);
+    path.close();
+</div>
+
 </div>
 
 <script type="text/javascript">
 
 var testDivs = [
+    testQuadratic14,
+    testQuadratic13b,
+    testQuadratic13a,
+    testQuadratic12,
+    testQuadratic11b,
+    testQuadratic11a,
+    testQuadratic10b,
+    testQuadratic10a,
+    testQuadratic9a,
+    testQuadratic9,
+    testQuadratic8,
+    testQuadratic7,
+    testQuadratic6,
+    testQuadratic5,
+    testQuadratic4x,
     testQuadratic3,
     testQuadratic2,
     testQuadratic1,