diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp
new file mode 100644
index 0000000..9efd4d6
--- /dev/null
+++ b/src/pathops/SkAddIntersections.cpp
@@ -0,0 +1,430 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkAddIntersections.h"
+#include "SkPathOpsBounds.h"
+
+#if DEBUG_ADD_INTERSECTING_TS
+
+static void debugShowLineIntersection(int pts, const SkIntersectionHelper& wt,
+                                      const SkIntersectionHelper& wn, const SkIntersections& i) {
+    SkASSERT(i.used() == pts);
+    if (!pts) {
+        SkDebugf("%s no intersect " LINE_DEBUG_STR " " LINE_DEBUG_STR "\n",
+                __FUNCTION__, LINE_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
+        return;
+    }
+    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " LINE_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
+            i[0][0], LINE_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
+    if (pts == 2) {
+        SkDebugf(" " T_DEBUG_STR(wtTs, 1) " " PT_DEBUG_STR, i[0][1], PT_DEBUG_DATA(i, 1));
+    }
+    SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
+    if (pts == 2) {
+        SkDebugf(" " T_DEBUG_STR(wnTs, 1), i[1][1]);
+    }
+    SkDebugf("\n");
+}
+
+static void debugShowQuadLineIntersection(int pts, const SkIntersectionHelper& wt,
+                                          const SkIntersectionHelper& wn,
+                                          const SkIntersections& i) {
+    SkASSERT(i.used() == pts);
+    if (!pts) {
+        SkDebugf("%s no intersect " QUAD_DEBUG_STR " " LINE_DEBUG_STR "\n",
+                __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
+        return;
+    }
+    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
+            i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
+    }
+    SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
+    }
+    SkDebugf("\n");
+}
+
+static void debugShowQuadIntersection(int pts, const SkIntersectionHelper& wt,
+        const SkIntersectionHelper& wn, const SkIntersections& i) {
+    SkASSERT(i.used() == pts);
+    if (!pts) {
+        SkDebugf("%s no intersect " QUAD_DEBUG_STR " " QUAD_DEBUG_STR "\n",
+                __FUNCTION__, QUAD_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts()));
+        return;
+    }
+    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " QUAD_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
+            i[0][0], QUAD_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
+    }
+    SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
+    }
+    SkDebugf("\n");
+}
+
+static void debugShowCubicLineIntersection(int pts, const SkIntersectionHelper& wt,
+        const SkIntersectionHelper& wn, const SkIntersections& i) {
+    SkASSERT(i.used() == pts);
+    if (!pts) {
+        SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " LINE_DEBUG_STR "\n",
+                __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), LINE_DEBUG_DATA(wn.pts()));
+        return;
+    }
+    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
+            i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
+    }
+    SkDebugf(" wnTs[0]=%g " LINE_DEBUG_STR, i[1][0], LINE_DEBUG_DATA(wn.pts()));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
+    }
+    SkDebugf("\n");
+}
+
+static void debugShowCubicQuadIntersection(int pts, const SkIntersectionHelper& wt,
+        const SkIntersectionHelper& wn, const SkIntersections& i) {
+    SkASSERT(i.used() == pts);
+    if (!pts) {
+        SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " QUAD_DEBUG_STR "\n",
+                __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), QUAD_DEBUG_DATA(wn.pts()));
+        return;
+    }
+    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
+            i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
+    }
+    SkDebugf(" wnTs[0]=%g " QUAD_DEBUG_STR, i[1][0], QUAD_DEBUG_DATA(wn.pts()));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
+    }
+    SkDebugf("\n");
+}
+
+static void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt,
+        const SkIntersectionHelper& wn, const SkIntersections& i) {
+    SkASSERT(i.used() == pts);
+    if (!pts) {
+        SkDebugf("%s no intersect " CUBIC_DEBUG_STR " " CUBIC_DEBUG_STR "\n",
+                __FUNCTION__, CUBIC_DEBUG_DATA(wt.pts()), CUBIC_DEBUG_DATA(wn.pts()));
+        return;
+    }
+    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
+            i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wtTs) " " PT_DEBUG_STR, n, i[0][n], PT_DEBUG_DATA(i, n));
+    }
+    SkDebugf(" wnTs[0]=%g " CUBIC_DEBUG_STR, i[1][0], CUBIC_DEBUG_DATA(wn.pts()));
+    for (int n = 1; n < pts; ++n) {
+        SkDebugf(" " TX_DEBUG_STR(wnTs), n, i[1][n]);
+    }
+    SkDebugf("\n");
+}
+
+static void debugShowCubicIntersection(int pts, const SkIntersectionHelper& wt,
+        const SkIntersections& i) {
+    SkASSERT(i.used() == pts);
+    if (!pts) {
+        SkDebugf("%s no self intersect " CUBIC_DEBUG_STR "\n", __FUNCTION__,
+                CUBIC_DEBUG_DATA(wt.pts()));
+        return;
+    }
+    SkDebugf("%s " T_DEBUG_STR(wtTs, 0) " " CUBIC_DEBUG_STR " " PT_DEBUG_STR, __FUNCTION__,
+            i[0][0], CUBIC_DEBUG_DATA(wt.pts()), PT_DEBUG_DATA(i, 0));
+    SkDebugf(" " T_DEBUG_STR(wtTs, 1), i[1][0]);
+    SkDebugf("\n");
+}
+
+#else
+static void debugShowLineIntersection(int , const SkIntersectionHelper& ,
+        const SkIntersectionHelper& , const SkIntersections& ) {
+}
+
+static void debugShowQuadLineIntersection(int , const SkIntersectionHelper& ,
+        const SkIntersectionHelper& , const SkIntersections& ) {
+}
+
+static void debugShowQuadIntersection(int , const SkIntersectionHelper& ,
+        const SkIntersectionHelper& , const SkIntersections& ) {
+}
+
+static void debugShowCubicLineIntersection(int , const SkIntersectionHelper& ,
+        const SkIntersectionHelper& , const SkIntersections& ) {
+}
+
+static void debugShowCubicQuadIntersection(int , const SkIntersectionHelper& ,
+        const SkIntersectionHelper& , const SkIntersections& ) {
+}
+
+static void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
+        const SkIntersectionHelper& , const SkIntersections& ) {
+}
+
+static void debugShowCubicIntersection(int , const SkIntersectionHelper& ,
+        const SkIntersections& ) {
+}
+#endif
+
+bool AddIntersectTs(SkOpContour* test, SkOpContour* next) {
+    if (test != next) {
+        if (test->bounds().fBottom < next->bounds().fTop) {
+            return false;
+        }
+        if (!SkPathOpsBounds::Intersects(test->bounds(), next->bounds())) {
+            return true;
+        }
+    }
+    SkIntersectionHelper wt;
+    wt.init(test);
+    bool foundCommonContour = test == next;
+    do {
+        SkIntersectionHelper wn;
+        wn.init(next);
+        if (test == next && !wn.startAfter(wt)) {
+            continue;
+        }
+        do {
+            if (!SkPathOpsBounds::Intersects(wt.bounds(), wn.bounds())) {
+                continue;
+            }
+            int pts = 0;
+            SkIntersections ts;
+            bool swap = false;
+            switch (wt.segmentType()) {
+                case SkIntersectionHelper::kHorizontalLine_Segment:
+                    swap = true;
+                    switch (wn.segmentType()) {
+                        case SkIntersectionHelper::kHorizontalLine_Segment:
+                        case SkIntersectionHelper::kVerticalLine_Segment:
+                        case SkIntersectionHelper::kLine_Segment: {
+                            pts = ts.lineHorizontal(wn.pts(), wt.left(),
+                                    wt.right(), wt.y(), wt.xFlipped());
+                            debugShowLineIntersection(pts, wt, wn, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kQuad_Segment: {
+                            pts = ts.quadHorizontal(wn.pts(), wt.left(),
+                                    wt.right(), wt.y(), wt.xFlipped());
+                            debugShowQuadLineIntersection(pts, wn, wt, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kCubic_Segment: {
+                            pts = ts.cubicHorizontal(wn.pts(), wt.left(),
+                                    wt.right(), wt.y(), wt.xFlipped());
+                            debugShowCubicLineIntersection(pts, wn, wt, ts);
+                            break;
+                        }
+                        default:
+                            SkASSERT(0);
+                    }
+                    break;
+                case SkIntersectionHelper::kVerticalLine_Segment:
+                    swap = true;
+                    switch (wn.segmentType()) {
+                        case SkIntersectionHelper::kHorizontalLine_Segment:
+                        case SkIntersectionHelper::kVerticalLine_Segment:
+                        case SkIntersectionHelper::kLine_Segment: {
+                            pts = ts.lineVertical(wn.pts(), wt.top(),
+                                    wt.bottom(), wt.x(), wt.yFlipped());
+                            debugShowLineIntersection(pts, wt, wn, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kQuad_Segment: {
+                            pts = ts.quadVertical(wn.pts(), wt.top(),
+                                    wt.bottom(), wt.x(), wt.yFlipped());
+                            debugShowQuadLineIntersection(pts, wn, wt, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kCubic_Segment: {
+                            pts = ts.cubicVertical(wn.pts(), wt.top(),
+                                    wt.bottom(), wt.x(), wt.yFlipped());
+                            debugShowCubicLineIntersection(pts, wn, wt, ts);
+                            break;
+                        }
+                        default:
+                            SkASSERT(0);
+                    }
+                    break;
+                case SkIntersectionHelper::kLine_Segment:
+                    switch (wn.segmentType()) {
+                        case SkIntersectionHelper::kHorizontalLine_Segment:
+                            pts = ts.lineHorizontal(wt.pts(), wn.left(),
+                                    wn.right(), wn.y(), wn.xFlipped());
+                            debugShowLineIntersection(pts, wt, wn, ts);
+                            break;
+                        case SkIntersectionHelper::kVerticalLine_Segment:
+                            pts = ts.lineVertical(wt.pts(), wn.top(),
+                                    wn.bottom(), wn.x(), wn.yFlipped());
+                            debugShowLineIntersection(pts, wt, wn, ts);
+                            break;
+                        case SkIntersectionHelper::kLine_Segment: {
+                            pts = ts.lineLine(wt.pts(), wn.pts());
+                            debugShowLineIntersection(pts, wt, wn, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kQuad_Segment: {
+                            swap = true;
+                            pts = ts.quadLine(wn.pts(), wt.pts());
+                            debugShowQuadLineIntersection(pts, wn, wt, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kCubic_Segment: {
+                            swap = true;
+                            pts = ts.cubicLine(wn.pts(), wt.pts());
+                            debugShowCubicLineIntersection(pts, wn, wt,  ts);
+                            break;
+                        }
+                        default:
+                            SkASSERT(0);
+                    }
+                    break;
+                case SkIntersectionHelper::kQuad_Segment:
+                    switch (wn.segmentType()) {
+                        case SkIntersectionHelper::kHorizontalLine_Segment:
+                            pts = ts.quadHorizontal(wt.pts(), wn.left(),
+                                    wn.right(), wn.y(), wn.xFlipped());
+                            debugShowQuadLineIntersection(pts, wt, wn, ts);
+                            break;
+                        case SkIntersectionHelper::kVerticalLine_Segment:
+                            pts = ts.quadVertical(wt.pts(), wn.top(),
+                                    wn.bottom(), wn.x(), wn.yFlipped());
+                            debugShowQuadLineIntersection(pts, wt, wn, ts);
+                            break;
+                        case SkIntersectionHelper::kLine_Segment: {
+                            pts = ts.quadLine(wt.pts(), wn.pts());
+                            debugShowQuadLineIntersection(pts, wt, wn, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kQuad_Segment: {
+                            pts = ts.quadQuad(wt.pts(), wn.pts());
+                            debugShowQuadIntersection(pts, wt, wn, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kCubic_Segment: {
+                            swap = true;
+                            pts = ts.cubicQuad(wn.pts(), wt.pts());
+                            debugShowCubicQuadIntersection(pts, wn, wt, ts);
+                            break;
+                        }
+                        default:
+                            SkASSERT(0);
+                    }
+                    break;
+                case SkIntersectionHelper::kCubic_Segment:
+                    switch (wn.segmentType()) {
+                        case SkIntersectionHelper::kHorizontalLine_Segment:
+                            pts = ts.cubicHorizontal(wt.pts(), wn.left(),
+                                    wn.right(), wn.y(), wn.xFlipped());
+                            debugShowCubicLineIntersection(pts, wt, wn, ts);
+                            break;
+                        case SkIntersectionHelper::kVerticalLine_Segment:
+                            pts = ts.cubicVertical(wt.pts(), wn.top(),
+                                    wn.bottom(), wn.x(), wn.yFlipped());
+                            debugShowCubicLineIntersection(pts, wt, wn, ts);
+                            break;
+                        case SkIntersectionHelper::kLine_Segment: {
+                            pts = ts.cubicLine(wt.pts(), wn.pts());
+                            debugShowCubicLineIntersection(pts, wt, wn, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kQuad_Segment: {
+                            pts = ts.cubicQuad(wt.pts(), wn.pts());
+                            debugShowCubicQuadIntersection(pts, wt, wn, ts);
+                            break;
+                        }
+                        case SkIntersectionHelper::kCubic_Segment: {
+                            pts = ts.cubicCubic(wt.pts(), wn.pts());
+                            debugShowCubicIntersection(pts, wt, wn, ts);
+                            break;
+                        }
+                        default:
+                            SkASSERT(0);
+                    }
+                    break;
+                default:
+                    SkASSERT(0);
+            }
+            if (!foundCommonContour && pts > 0) {
+                test->addCross(next);
+                next->addCross(test);
+                foundCommonContour = true;
+            }
+            // in addition to recording T values, record matching segment
+            if (pts == 2) {
+                if (wn.segmentType() <= SkIntersectionHelper::kLine_Segment
+                        && wt.segmentType() <= SkIntersectionHelper::kLine_Segment) {
+                    wt.addCoincident(wn, ts, swap);
+                    continue;
+                }
+                if (wn.segmentType() >= SkIntersectionHelper::kQuad_Segment
+                        && wt.segmentType() >= SkIntersectionHelper::kQuad_Segment
+                        && ts.isCoincident(0)) {
+                    SkASSERT(ts.coincidentUsed() == 2);
+                    wt.addCoincident(wn, ts, swap);
+                    continue;
+                }
+            }
+            for (int pt = 0; pt < pts; ++pt) {
+                SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1);
+                SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1);
+                SkPoint point = ts.pt(pt).asSkPoint();
+                int testTAt = wt.addT(wn, point, ts[swap][pt]);
+                int nextTAt = wn.addT(wt, point, ts[!swap][pt]);
+                wt.addOtherT(testTAt, ts[!swap][pt], nextTAt);
+                wn.addOtherT(nextTAt, ts[swap][pt], testTAt);
+            }
+        } while (wn.advance());
+    } while (wt.advance());
+    return true;
+}
+
+void AddSelfIntersectTs(SkOpContour* test) {
+    SkIntersectionHelper wt;
+    wt.init(test);
+    do {
+        if (wt.segmentType() != SkIntersectionHelper::kCubic_Segment) {
+            continue;
+        }
+        SkIntersections ts;
+        int pts = ts.cubic(wt.pts());
+        debugShowCubicIntersection(pts, wt, ts);
+        if (!pts) {
+            continue;
+        }
+        SkASSERT(pts == 1);
+        SkASSERT(ts[0][0] >= 0 && ts[0][0] <= 1);
+        SkASSERT(ts[1][0] >= 0 && ts[1][0] <= 1);
+        SkPoint point = ts.pt(0).asSkPoint();
+        int testTAt = wt.addSelfT(wt, point, ts[0][0]);
+        int nextTAt = wt.addT(wt, point, ts[1][0]);
+        wt.addOtherT(testTAt, ts[1][0], nextTAt);
+        wt.addOtherT(nextTAt, ts[0][0], testTAt);
+    } while (wt.advance());
+}
+
+// resolve any coincident pairs found while intersecting, and
+// see if coincidence is formed by clipping non-concident segments
+void CoincidenceCheck(SkTDArray<SkOpContour*>* contourList, int total) {
+    int contourCount = (*contourList).count();
+    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+        SkOpContour* contour = (*contourList)[cIndex];
+        contour->addCoincidentPoints();
+    }
+    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+        SkOpContour* contour = (*contourList)[cIndex];
+        contour->calcCoincidentWinding();
+    }
+    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+        SkOpContour* contour = (*contourList)[cIndex];
+        contour->findTooCloseToCall();
+    }
+}
diff --git a/src/pathops/SkAddIntersections.h b/src/pathops/SkAddIntersections.h
new file mode 100644
index 0000000..26cfa96
--- /dev/null
+++ b/src/pathops/SkAddIntersections.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkAddIntersections_DEFINED
+#define SkAddIntersections_DEFINED
+
+#include "SkIntersectionHelper.h"
+#include "SkIntersections.h"
+#include "SkTDArray.h"
+
+bool AddIntersectTs(SkOpContour* test, SkOpContour* next);
+void AddSelfIntersectTs(SkOpContour* test);
+void CoincidenceCheck(SkTDArray<SkOpContour*>* contourList, int total);
+
+#endif
+
diff --git a/src/pathops/SkDCubicIntersection.cpp b/src/pathops/SkDCubicIntersection.cpp
new file mode 100644
index 0000000..a31b1a4
--- /dev/null
+++ b/src/pathops/SkDCubicIntersection.cpp
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkIntersections.h"
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsPoint.h"
+#include "SkPathOpsQuad.h"
+#include "SkPathOpsRect.h"
+#include "SkReduceOrder.h"
+#include "SkTDArray.h"
+#include "TSearch.h"
+
+#if ONE_OFF_DEBUG
+static const double tLimits1[2][2] = {{0.36, 0.37}, {0.63, 0.64}};
+static const double tLimits2[2][2] = {{-0.865211397, -0.865215212}, {-0.865207696, -0.865208078}};
+#endif
+
+#define DEBUG_QUAD_PART 0
+#define SWAP_TOP_DEBUG 0
+
+static int quadPart(const SkDCubic& cubic, double tStart, double tEnd, SkReduceOrder* reducer) {
+    SkDCubic part = cubic.subDivide(tStart, tEnd);
+    SkDQuad quad = part.toQuad();
+    // FIXME: should reduceOrder be looser in this use case if quartic is going to blow up on an
+    // extremely shallow quadratic?
+    int order = reducer->reduce(quad, SkReduceOrder::kFill_Style);
+#if DEBUG_QUAD_PART
+    SkDebugf("%s cubic=(%1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g)"
+            " t=(%1.17g,%1.17g)\n", __FUNCTION__, cubic[0].fX, cubic[0].fY,
+            cubic[1].fX, cubic[1].fY, cubic[2].fX, cubic[2].fY,
+            cubic[3].fX, cubic[3].fY, tStart, tEnd);
+    SkDebugf("%s part=(%1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g)"
+            " quad=(%1.17g,%1.17g %1.17g,%1.17g %1.17g,%1.17g)\n", __FUNCTION__,
+            part[0].fX, part[0].fY, part[1].fX, part[1].fY, part[2].fX, part[2].fY,
+            part[3].fX, part[3].fY, quad[0].fX, quad[0].fY,
+            quad[1].fX, quad[1].fY, quad[2].fX, quad[2].fY);
+    SkDebugf("%s simple=(%1.17g,%1.17g", __FUNCTION__, reducer->fQuad[0].fX, reducer->fQuad[0].fY);
+    if (order > 1) {
+        SkDebugf(" %1.17g,%1.17g", reducer->fQuad[1].fX, reducer->fQuad[1].fY);
+    }
+    if (order > 2) {
+        SkDebugf(" %1.17g,%1.17g", reducer->fQuad[2].fX, reducer->fQuad[2].fY);
+    }
+    SkDebugf(")\n");
+    SkASSERT(order < 4 && order > 0);
+#endif
+    return order;
+}
+
+static void intersectWithOrder(const SkDQuad& simple1, int order1, const SkDQuad& simple2,
+        int order2, SkIntersections& i) {
+    if (order1 == 3 && order2 == 3) {
+        i.intersect(simple1, simple2);
+    } else if (order1 <= 2 && order2 <= 2) {
+        i.intersect((const SkDLine&) simple1, (const SkDLine&) simple2);
+    } else if (order1 == 3 && order2 <= 2) {
+        i.intersect(simple1, (const SkDLine&) simple2);
+    } else {
+        SkASSERT(order1 <= 2 && order2 == 3);
+        i.intersect(simple2, (const SkDLine&) simple1);
+        i.swapPts();
+    }
+}
+
+// this flavor centers potential intersections recursively. In contrast, '2' may inadvertently
+// chase intersections near quadratic ends, requiring odd hacks to find them.
+static void intersect(const SkDCubic& cubic1, double t1s, double t1e, const SkDCubic& cubic2,
+        double t2s, double t2e, double precisionScale, SkIntersections& i) {
+    i.upDepth();
+    SkDCubic c1 = cubic1.subDivide(t1s, t1e);
+    SkDCubic c2 = cubic2.subDivide(t2s, t2e);
+    SkTDArray<double> ts1;
+    // OPTIMIZE: if c1 == c2, call once (happens when detecting self-intersection)
+    c1.toQuadraticTs(c1.calcPrecision() * precisionScale, &ts1);
+    SkTDArray<double> ts2;
+    c2.toQuadraticTs(c2.calcPrecision() * precisionScale, &ts2);
+    double t1Start = t1s;
+    int ts1Count = ts1.count();
+    for (int i1 = 0; i1 <= ts1Count; ++i1) {
+        const double tEnd1 = i1 < ts1Count ? ts1[i1] : 1;
+        const double t1 = t1s + (t1e - t1s) * tEnd1;
+        SkReduceOrder s1;
+        int o1 = quadPart(cubic1, t1Start, t1, &s1);
+        double t2Start = t2s;
+        int ts2Count = ts2.count();
+        for (int i2 = 0; i2 <= ts2Count; ++i2) {
+            const double tEnd2 = i2 < ts2Count ? ts2[i2] : 1;
+            const double t2 = t2s + (t2e - t2s) * tEnd2;
+            if (&cubic1 == &cubic2 && t1Start >= t2Start) {
+                t2Start = t2;
+                continue;
+            }
+            SkReduceOrder s2;
+            int o2 = quadPart(cubic2, t2Start, t2, &s2);
+        #if ONE_OFF_DEBUG
+            char tab[] = "                  ";
+            if (tLimits1[0][0] >= t1Start && tLimits1[0][1] <= t1
+                    && tLimits1[1][0] >= t2Start && tLimits1[1][1] <= t2) {
+                SkDCubic cSub1 = cubic1.subDivide(t1Start, t1);
+                SkDCubic cSub2 = cubic2.subDivide(t2Start, t2);
+                SkDebugf("%.*s %s t1=(%1.9g,%1.9g) t2=(%1.9g,%1.9g)", i.depth()*2, tab,
+                        __FUNCTION__, t1Start, t1, t2Start, t2);
+                SkIntersections xlocals;
+                intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, xlocals);
+                SkDebugf(" xlocals.fUsed=%d\n", xlocals.used());
+            }
+        #endif
+            SkIntersections locals;
+            intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, locals);
+            double coStart[2] = { -1 };
+            SkDPoint coPoint;
+            int tCount = locals.used();
+            for (int tIdx = 0; tIdx < tCount; ++tIdx) {
+                double to1 = t1Start + (t1 - t1Start) * locals[0][tIdx];
+                double to2 = t2Start + (t2 - t2Start) * locals[1][tIdx];
+    // if the computed t is not sufficiently precise, iterate
+                SkDPoint p1 = cubic1.xyAtT(to1);
+                SkDPoint p2 = cubic2.xyAtT(to2);
+                if (p1.approximatelyEqual(p2)) {
+                    if (locals.isCoincident(tIdx)) {
+                        if (coStart[0] < 0) {
+                            coStart[0] = to1;
+                            coStart[1] = to2;
+                            coPoint = p1;
+                        } else {
+                            i.insertCoincidentPair(coStart[0], to1, coStart[1], to2, coPoint, p1);
+                            coStart[0] = -1;
+                        }
+                    } else if (&cubic1 != &cubic2 || !approximately_equal(to1, to2)) {
+                        if (i.swapped()) {  //  FIXME: insert should respect swap
+                            i.insert(to2, to1, p1);
+                        } else {
+                            i.insert(to1, to2, p1);
+                        }
+                    }
+                } else {
+                    double offset = precisionScale / 16;  // FIME: const is arbitrary: test, refine
+#if 1
+                    double c1Bottom = tIdx == 0 ? 0 :
+                            (t1Start + (t1 - t1Start) * locals[0][tIdx - 1] + to1) / 2;
+                    double c1Min = SkTMax<double>(c1Bottom, to1 - offset);
+                    double c1Top = tIdx == tCount - 1 ? 1 :
+                            (t1Start + (t1 - t1Start) * locals[0][tIdx + 1] + to1) / 2;
+                    double c1Max = SkTMin<double>(c1Top, to1 + offset);
+                    double c2Min = SkTMax<double>(0., to2 - offset);
+                    double c2Max = SkTMin<double>(1., to2 + offset);
+                #if ONE_OFF_DEBUG
+                    SkDebugf("%.*s %s 1 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab,
+                            __FUNCTION__,
+                            c1Min <= tLimits1[0][1] && tLimits1[0][0] <= c1Max
+                         && c2Min <= tLimits1[1][1] && tLimits1[1][0] <= c2Max,
+                            to1 - offset <= tLimits1[0][1] && tLimits1[0][0] <= to1 + offset
+                         && to2 - offset <= tLimits1[1][1] && tLimits1[1][0] <= to2 + offset,
+                            c1Min <= tLimits2[0][1] && tLimits2[0][0] <= c1Max
+                         && c2Min <= tLimits2[1][1] && tLimits2[1][0] <= c2Max,
+                            to1 - offset <= tLimits2[0][1] && tLimits2[0][0] <= to1 + offset
+                         && to2 - offset <= tLimits2[1][1] && tLimits2[1][0] <= to2 + offset);
+                    SkDebugf("%.*s %s 1 c1Bottom=%1.9g c1Top=%1.9g c2Bottom=%1.9g c2Top=%1.9g"
+                            " 1-o=%1.9g 1+o=%1.9g 2-o=%1.9g 2+o=%1.9g offset=%1.9g\n",
+                            i.depth()*2, tab, __FUNCTION__, c1Bottom, c1Top, 0., 1.,
+                            to1 - offset, to1 + offset, to2 - offset, to2 + offset, offset);
+                    SkDebugf("%.*s %s 1 to1=%1.9g to2=%1.9g c1Min=%1.9g c1Max=%1.9g c2Min=%1.9g"
+                            " c2Max=%1.9g\n", i.depth()*2, tab, __FUNCTION__, to1, to2, c1Min,
+                            c1Max, c2Min, c2Max);
+                #endif
+                    intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offset, i);
+                #if ONE_OFF_DEBUG
+                    SkDebugf("%.*s %s 1 i.used=%d t=%1.9g\n", i.depth()*2, tab, __FUNCTION__,
+                            i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1);
+                #endif
+                    if (tCount > 1) {
+                        c1Min = SkTMax<double>(0., to1 - offset);
+                        c1Max = SkTMin<double>(1., to1 + offset);
+                        double c2Bottom = tIdx == 0 ? to2 :
+                                (t2Start + (t2 - t2Start) * locals[1][tIdx - 1] + to2) / 2;
+                        double c2Top = tIdx == tCount - 1 ? to2 :
+                                (t2Start + (t2 - t2Start) * locals[1][tIdx + 1] + to2) / 2;
+                        if (c2Bottom > c2Top) {
+                            SkTSwap(c2Bottom, c2Top);
+                        }
+                        if (c2Bottom == to2) {
+                            c2Bottom = 0;
+                        }
+                        if (c2Top == to2) {
+                            c2Top = 1;
+                        }
+                        c2Min = SkTMax<double>(c2Bottom, to2 - offset);
+                        c2Max = SkTMin<double>(c2Top, to2 + offset);
+                    #if ONE_OFF_DEBUG
+                        SkDebugf("%.*s %s 2 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab,
+                            __FUNCTION__,
+                            c1Min <= tLimits1[0][1] && tLimits1[0][0] <= c1Max
+                         && c2Min <= tLimits1[1][1] && tLimits1[1][0] <= c2Max,
+                            to1 - offset <= tLimits1[0][1] && tLimits1[0][0] <= to1 + offset
+                         && to2 - offset <= tLimits1[1][1] && tLimits1[1][0] <= to2 + offset,
+                            c1Min <= tLimits2[0][1] && tLimits2[0][0] <= c1Max
+                         && c2Min <= tLimits2[1][1] && tLimits2[1][0] <= c2Max,
+                            to1 - offset <= tLimits2[0][1] && tLimits2[0][0] <= to1 + offset
+                         && to2 - offset <= tLimits2[1][1] && tLimits2[1][0] <= to2 + offset);
+                        SkDebugf("%.*s %s 2 c1Bottom=%1.9g c1Top=%1.9g c2Bottom=%1.9g c2Top=%1.9g"
+                                " 1-o=%1.9g 1+o=%1.9g 2-o=%1.9g 2+o=%1.9g offset=%1.9g\n",
+                                i.depth()*2, tab, __FUNCTION__, 0., 1., c2Bottom, c2Top,
+                                to1 - offset, to1 + offset, to2 - offset, to2 + offset, offset);
+                        SkDebugf("%.*s %s 2 to1=%1.9g to2=%1.9g c1Min=%1.9g c1Max=%1.9g c2Min=%1.9g"
+                                " c2Max=%1.9g\n", i.depth()*2, tab, __FUNCTION__, to1, to2, c1Min,
+                                c1Max, c2Min, c2Max);
+                    #endif
+                        intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offset, i);
+                #if ONE_OFF_DEBUG
+                    SkDebugf("%.*s %s 2 i.used=%d t=%1.9g\n", i.depth()*2, tab, __FUNCTION__,
+                            i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1);
+                #endif
+                        c1Min = SkTMax<double>(c1Bottom, to1 - offset);
+                        c1Max = SkTMin<double>(c1Top, to1 + offset);
+                    #if ONE_OFF_DEBUG
+                        SkDebugf("%.*s %s 3 contains1=%d/%d contains2=%d/%d\n", i.depth()*2, tab,
+                        __FUNCTION__,
+                            c1Min <= tLimits1[0][1] && tLimits1[0][0] <= c1Max
+                         && c2Min <= tLimits1[1][1] && tLimits1[1][0] <= c2Max,
+                            to1 - offset <= tLimits1[0][1] && tLimits1[0][0] <= to1 + offset
+                         && to2 - offset <= tLimits1[1][1] && tLimits1[1][0] <= to2 + offset,
+                            c1Min <= tLimits2[0][1] && tLimits2[0][0] <= c1Max
+                         && c2Min <= tLimits2[1][1] && tLimits2[1][0] <= c2Max,
+                            to1 - offset <= tLimits2[0][1] && tLimits2[0][0] <= to1 + offset
+                         && to2 - offset <= tLimits2[1][1] && tLimits2[1][0] <= to2 + offset);
+                        SkDebugf("%.*s %s 3 c1Bottom=%1.9g c1Top=%1.9g c2Bottom=%1.9g c2Top=%1.9g"
+                                " 1-o=%1.9g 1+o=%1.9g 2-o=%1.9g 2+o=%1.9g offset=%1.9g\n",
+                                i.depth()*2, tab, __FUNCTION__, 0., 1., c2Bottom, c2Top,
+                                to1 - offset, to1 + offset, to2 - offset, to2 + offset, offset);
+                        SkDebugf("%.*s %s 3 to1=%1.9g to2=%1.9g c1Min=%1.9g c1Max=%1.9g c2Min=%1.9g"
+                                " c2Max=%1.9g\n", i.depth()*2, tab, __FUNCTION__, to1, to2, c1Min,
+                                c1Max, c2Min, c2Max);
+                    #endif
+                        intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offset, i);
+                #if ONE_OFF_DEBUG
+                    SkDebugf("%.*s %s 3 i.used=%d t=%1.9g\n", i.depth()*2, tab, __FUNCTION__,
+                            i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1);
+                #endif
+                    }
+#else
+                    double c1Bottom = tIdx == 0 ? 0 :
+                            (t1Start + (t1 - t1Start) * locals.fT[0][tIdx - 1] + to1) / 2;
+                    double c1Min = SkTMax<double>(c1Bottom, to1 - offset);
+                    double c1Top = tIdx == tCount - 1 ? 1 :
+                            (t1Start + (t1 - t1Start) * locals.fT[0][tIdx + 1] + to1) / 2;
+                    double c1Max = SkTMin<double>(c1Top, to1 + offset);
+                    double c2Bottom = tIdx == 0 ? to2 :
+                            (t2Start + (t2 - t2Start) * locals.fT[1][tIdx - 1] + to2) / 2;
+                    double c2Top = tIdx == tCount - 1 ? to2 :
+                            (t2Start + (t2 - t2Start) * locals.fT[1][tIdx + 1] + to2) / 2;
+                    if (c2Bottom > c2Top) {
+                        SkTSwap(c2Bottom, c2Top);
+                    }
+                    if (c2Bottom == to2) {
+                        c2Bottom = 0;
+                    }
+                    if (c2Top == to2) {
+                        c2Top = 1;
+                    }
+                    double c2Min = SkTMax<double>(c2Bottom, to2 - offset);
+                    double c2Max = SkTMin<double>(c2Top, to2 + offset);
+                #if ONE_OFF_DEBUG
+                    SkDebugf("%s contains1=%d/%d contains2=%d/%d\n", __FUNCTION__,
+                            c1Min <= 0.210357794 && 0.210357794 <= c1Max
+                         && c2Min <= 0.223476406 && 0.223476406 <= c2Max,
+                            to1 - offset <= 0.210357794 && 0.210357794 <= to1 + offset
+                         && to2 - offset <= 0.223476406 && 0.223476406 <= to2 + offset,
+                            c1Min <= 0.211324707 && 0.211324707 <= c1Max
+                         && c2Min <= 0.211327209 && 0.211327209 <= c2Max,
+                            to1 - offset <= 0.211324707 && 0.211324707 <= to1 + offset
+                         && to2 - offset <= 0.211327209 && 0.211327209 <= to2 + offset);
+                    SkDebugf("%s c1Bottom=%1.9g c1Top=%1.9g c2Bottom=%1.9g c2Top=%1.9g"
+                            " 1-o=%1.9g 1+o=%1.9g 2-o=%1.9g 2+o=%1.9g offset=%1.9g\n",
+                            __FUNCTION__, c1Bottom, c1Top, c2Bottom, c2Top,
+                            to1 - offset, to1 + offset, to2 - offset, to2 + offset, offset);
+                    SkDebugf("%s to1=%1.9g to2=%1.9g c1Min=%1.9g c1Max=%1.9g c2Min=%1.9g"
+                            " c2Max=%1.9g\n", __FUNCTION__, to1, to2, c1Min, c1Max, c2Min, c2Max);
+                #endif
+#endif
+                    intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offset, i);
+                    // FIXME: if no intersection is found, either quadratics intersected where
+                    // cubics did not, or the intersection was missed. In the former case, expect
+                    // the quadratics to be nearly parallel at the point of intersection, and check
+                    // for that.
+                }
+            }
+            SkASSERT(coStart[0] == -1);
+            t2Start = t2;
+        }
+        t1Start = t1;
+    }
+    i.downDepth();
+}
+
+#define LINE_FRACTION 0.1
+
+// intersect the end of the cubic with the other. Try lines from the end to control and opposite
+// end to determine range of t on opposite cubic.
+static void intersectEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2,
+                         const SkDRect& bounds2, SkIntersections& i) {
+    SkDLine line;
+    int t1Index = start ? 0 : 3;
+    line[0] = cubic1[t1Index];
+    // don't bother if the two cubics are connnected
+    SkTDArray<double> tVals;  // OPTIMIZE: replace with hard-sized array
+    for (int index = 0; index < 4; ++index) {
+        if (index == t1Index) {
+            continue;
+        }
+        SkDVector dxy1 = cubic1[index] - line[0];
+        dxy1 /= SkDCubic::gPrecisionUnit;
+        line[1] = line[0] + dxy1;
+        SkDRect lineBounds;
+        lineBounds.setBounds(line);
+        if (!bounds2.intersects(&lineBounds)) {
+            continue;
+        }
+        SkIntersections local;
+        if (!local.intersect(cubic2, line)) {
+            continue;
+        }
+        for (int idx2 = 0; idx2 < local.used(); ++idx2) {
+            double foundT = local[0][idx2];
+            if (approximately_less_than_zero(foundT)
+                    || approximately_greater_than_one(foundT)) {
+                continue;
+            }
+            if (local.pt(idx2).approximatelyEqual(line[0])) {
+                if (i.swapped()) {  // FIXME: insert should respect swap
+                    i.insert(foundT, start ? 0 : 1, line[0]);
+                } else {
+                    i.insert(start ? 0 : 1, foundT, line[0]);
+                }
+            } else {
+                *tVals.append() = local[0][idx2];
+            }
+        }
+    }
+    if (tVals.count() == 0) {
+        return;
+    }
+    QSort<double>(tVals.begin(), tVals.end() - 1);
+    double tMin1 = start ? 0 : 1 - LINE_FRACTION;
+    double tMax1 = start ? LINE_FRACTION : 1;
+    int tIdx = 0;
+    do {
+        int tLast = tIdx;
+        while (tLast + 1 < tVals.count() && roughly_equal(tVals[tLast + 1], tVals[tIdx])) {
+            ++tLast;
+        }
+        double tMin2 = SkTMax<double>(tVals[tIdx] - LINE_FRACTION, 0.0);
+        double tMax2 = SkTMin<double>(tVals[tLast] + LINE_FRACTION, 1.0);
+        int lastUsed = i.used();
+        intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
+        if (lastUsed == i.used()) {
+            tMin2 = SkTMax<double>(tVals[tIdx] - (1.0 / SkDCubic::gPrecisionUnit), 0.0);
+            tMax2 = SkTMin<double>(tVals[tLast] + (1.0 / SkDCubic::gPrecisionUnit), 1.0);
+            intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
+        }
+        tIdx = tLast + 1;
+    } while (tIdx < tVals.count());
+    return;
+}
+
+const double CLOSE_ENOUGH = 0.001;
+
+static bool closeStart(const SkDCubic& cubic, int cubicIndex, SkIntersections& i, SkDPoint& pt) {
+    if (i[cubicIndex][0] != 0 || i[cubicIndex][1] > CLOSE_ENOUGH) {
+        return false;
+    }
+    pt = cubic.xyAtT((i[cubicIndex][0] + i[cubicIndex][1]) / 2);
+    return true;
+}
+
+static bool closeEnd(const SkDCubic& cubic, int cubicIndex, SkIntersections& i, SkDPoint& pt) {
+    int last = i.used() - 1;
+    if (i[cubicIndex][last] != 1 || i[cubicIndex][last - 1] < 1 - CLOSE_ENOUGH) {
+        return false;
+    }
+    pt = cubic.xyAtT((i[cubicIndex][last] + i[cubicIndex][last - 1]) / 2);
+    return true;
+}
+
+int SkIntersections::intersect(const SkDCubic& c1, const SkDCubic& c2) {
+    ::intersect(c1, 0, 1, c2, 0, 1, 1, *this);
+    // FIXME: pass in cached bounds from caller
+    SkDRect c1Bounds, c2Bounds;
+    c1Bounds.setBounds(c1);  // OPTIMIZE use setRawBounds ?
+    c2Bounds.setBounds(c2);
+    intersectEnd(c1, false, c2, c2Bounds, *this);
+    intersectEnd(c1, true, c2, c2Bounds, *this);
+    bool selfIntersect = &c1 == &c2;
+    if (!selfIntersect) {
+        swap();
+        intersectEnd(c2, false, c1, c1Bounds, *this);
+        intersectEnd(c2, true, c1, c1Bounds, *this);
+        swap();
+    }
+    // If an end point and a second point very close to the end is returned, the second
+    // point may have been detected because the approximate quads
+    // intersected at the end and close to it. Verify that the second point is valid.
+    if (fUsed <= 1 || coincidentUsed()) {
+        return fUsed;
+    }
+    SkDPoint pt[2];
+    if (closeStart(c1, 0, *this, pt[0]) && closeStart(c2, 1, *this, pt[1])
+            && pt[0].approximatelyEqual(pt[1])) {
+        removeOne(1);
+    }
+    if (closeEnd(c1, 0, *this, pt[0]) && closeEnd(c2, 1, *this, pt[1])
+            && pt[0].approximatelyEqual(pt[1])) {
+        removeOne(used() - 2);
+    }
+    return fUsed;
+}
+
+// Up promote the quad to a cubic.
+// OPTIMIZATION If this is a common use case, optimize by duplicating
+// the intersect 3 loop to avoid the promotion  / demotion code
+int SkIntersections::intersect(const SkDCubic& cubic, const SkDQuad& quad) {
+    SkDCubic up = quad.toCubic();
+    (void) intersect(cubic, up);
+    return used();
+}
+
+/* http://www.ag.jku.at/compass/compasssample.pdf
+( Self-Intersection Problems and Approximate Implicitization by Jan B. Thomassen
+Centre of Mathematics for Applications, University of Oslo http://www.cma.uio.no janbth@math.uio.no
+SINTEF Applied Mathematics http://www.sintef.no )
+describes a method to find the self intersection of a cubic by taking the gradient of the implicit
+form dotted with the normal, and solving for the roots. My math foo is too poor to implement this.*/
+
+int SkIntersections::intersect(const SkDCubic& c) {
+    // check to see if x or y end points are the extrema. Are other quick rejects possible?
+    if (c.endsAreExtremaInXOrY()) {
+        return false;
+    }
+    (void) intersect(c, c);
+    if (used() > 0) {
+        SkASSERT(used() == 1);
+        if (fT[0][0] > fT[1][0]) {
+            swapPts();
+        }
+    }
+    return used();
+}
diff --git a/src/pathops/SkDCubicLineIntersection.cpp b/src/pathops/SkDCubicLineIntersection.cpp
new file mode 100644
index 0000000..5df3aca
--- /dev/null
+++ b/src/pathops/SkDCubicLineIntersection.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkIntersections.h"
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+
+/*
+Find the interection of a line and cubic by solving for valid t values.
+
+Analogous to line-quadratic intersection, solve line-cubic intersection by
+representing the cubic as:
+  x = a(1-t)^3 + 2b(1-t)^2t + c(1-t)t^2 + dt^3
+  y = e(1-t)^3 + 2f(1-t)^2t + g(1-t)t^2 + ht^3
+and the line as:
+  y = i*x + j  (if the line is more horizontal)
+or:
+  x = i*y + j  (if the line is more vertical)
+
+Then using Mathematica, solve for the values of t where the cubic intersects the
+line:
+
+  (in) Resultant[
+        a*(1 - t)^3 + 3*b*(1 - t)^2*t + 3*c*(1 - t)*t^2 + d*t^3 - x,
+        e*(1 - t)^3 + 3*f*(1 - t)^2*t + 3*g*(1 - t)*t^2 + h*t^3 - i*x - j, x]
+  (out) -e     +   j     +
+       3 e t   - 3 f t   -
+       3 e t^2 + 6 f t^2 - 3 g t^2 +
+         e t^3 - 3 f t^3 + 3 g t^3 - h t^3 +
+     i ( a     -
+       3 a t + 3 b t +
+       3 a t^2 - 6 b t^2 + 3 c t^2 -
+         a t^3 + 3 b t^3 - 3 c t^3 + d t^3 )
+
+if i goes to infinity, we can rewrite the line in terms of x. Mathematica:
+
+  (in) Resultant[
+        a*(1 - t)^3 + 3*b*(1 - t)^2*t + 3*c*(1 - t)*t^2 + d*t^3 - i*y - j,
+        e*(1 - t)^3 + 3*f*(1 - t)^2*t + 3*g*(1 - t)*t^2 + h*t^3 - y,       y]
+  (out)  a     -   j     -
+       3 a t   + 3 b t   +
+       3 a t^2 - 6 b t^2 + 3 c t^2 -
+         a t^3 + 3 b t^3 - 3 c t^3 + d t^3 -
+     i ( e     -
+       3 e t   + 3 f t   +
+       3 e t^2 - 6 f t^2 + 3 g t^2 -
+         e t^3 + 3 f t^3 - 3 g t^3 + h t^3 )
+
+Solving this with Mathematica produces an expression with hundreds of terms;
+instead, use Numeric Solutions recipe to solve the cubic.
+
+The near-horizontal case, in terms of:  Ax^3 + Bx^2 + Cx + D == 0
+    A =   (-(-e + 3*f - 3*g + h) + i*(-a + 3*b - 3*c + d)     )
+    B = 3*(-( e - 2*f +   g    ) + i*( a - 2*b +   c    )     )
+    C = 3*(-(-e +   f          ) + i*(-a +   b          )     )
+    D =   (-( e                ) + i*( a                ) + j )
+
+The near-vertical case, in terms of:  Ax^3 + Bx^2 + Cx + D == 0
+    A =   ( (-a + 3*b - 3*c + d) - i*(-e + 3*f - 3*g + h)     )
+    B = 3*( ( a - 2*b +   c    ) - i*( e - 2*f +   g    )     )
+    C = 3*( (-a +   b          ) - i*(-e +   f          )     )
+    D =   ( ( a                ) - i*( e                ) - j )
+
+For horizontal lines:
+(in) Resultant[
+      a*(1 - t)^3 + 3*b*(1 - t)^2*t + 3*c*(1 - t)*t^2 + d*t^3 - j,
+      e*(1 - t)^3 + 3*f*(1 - t)^2*t + 3*g*(1 - t)*t^2 + h*t^3 - y, y]
+(out)  e     -   j     -
+     3 e t   + 3 f t   +
+     3 e t^2 - 6 f t^2 + 3 g t^2 -
+       e t^3 + 3 f t^3 - 3 g t^3 + h t^3
+ */
+
+class LineCubicIntersections {
+public:
+
+LineCubicIntersections(const SkDCubic& c, const SkDLine& l, SkIntersections& i)
+    : cubic(c)
+    , line(l)
+    , intersections(i) {
+}
+
+// see parallel routine in line quadratic intersections
+int intersectRay(double roots[3]) {
+    double adj = line[1].fX - line[0].fX;
+    double opp = line[1].fY - line[0].fY;
+    SkDCubic r;
+    for (int n = 0; n < 4; ++n) {
+        r[n].fX = (cubic[n].fY - line[0].fY) * adj - (cubic[n].fX - line[0].fX) * opp;
+    }
+    double A, B, C, D;
+    SkDCubic::Coefficients(&r[0].fX, &A, &B, &C, &D);
+    return SkDCubic::RootsValidT(A, B, C, D, roots);
+}
+
+int intersect() {
+    addEndPoints();
+    double rootVals[3];
+    int roots = intersectRay(rootVals);
+    for (int index = 0; index < roots; ++index) {
+        double cubicT = rootVals[index];
+        double lineT = findLineT(cubicT);
+        if (pinTs(&cubicT, &lineT)) {
+            SkDPoint pt = line.xyAtT(lineT);
+            intersections.insert(cubicT, lineT, pt);
+        }
+    }
+    return intersections.used();
+}
+
+int horizontalIntersect(double axisIntercept, double roots[3]) {
+    double A, B, C, D;
+    SkDCubic::Coefficients(&cubic[0].fY, &A, &B, &C, &D);
+    D -= axisIntercept;
+    return SkDCubic::RootsValidT(A, B, C, D, roots);
+}
+
+int horizontalIntersect(double axisIntercept, double left, double right, bool flipped) {
+    addHorizontalEndPoints(left, right, axisIntercept);
+    double rootVals[3];
+    int roots = horizontalIntersect(axisIntercept, rootVals);
+    for (int index = 0; index < roots; ++index) {
+        double cubicT = rootVals[index];
+        SkDPoint pt = cubic.xyAtT(cubicT);
+        double lineT = (pt.fX - left) / (right - left);
+        if (pinTs(&cubicT, &lineT)) {
+            intersections.insert(cubicT, lineT, pt);
+        }
+    }
+    if (flipped) {
+        intersections.flip();
+    }
+    return intersections.used();
+}
+
+int verticalIntersect(double axisIntercept, double roots[3]) {
+    double A, B, C, D;
+    SkDCubic::Coefficients(&cubic[0].fX, &A, &B, &C, &D);
+    D -= axisIntercept;
+    return SkDCubic::RootsValidT(A, B, C, D, roots);
+}
+
+int verticalIntersect(double axisIntercept, double top, double bottom, bool flipped) {
+    addVerticalEndPoints(top, bottom, axisIntercept);
+    double rootVals[3];
+    int roots = verticalIntersect(axisIntercept, rootVals);
+    for (int index = 0; index < roots; ++index) {
+        double cubicT = rootVals[index];
+        SkDPoint pt = cubic.xyAtT(cubicT);
+        double lineT = (pt.fY - top) / (bottom - top);
+        if (pinTs(&cubicT, &lineT)) {
+            intersections.insert(cubicT, lineT, pt);
+        }
+    }
+    if (flipped) {
+        intersections.flip();
+    }
+    return intersections.used();
+}
+
+protected:
+
+void addEndPoints() {
+    for (int cIndex = 0; cIndex < 4; cIndex += 3) {
+        for (int lIndex = 0; lIndex < 2; lIndex++) {
+            if (cubic[cIndex] == line[lIndex]) {
+                intersections.insert(cIndex >> 1, lIndex, line[lIndex]);
+            }
+        }
+    }
+}
+
+void addHorizontalEndPoints(double left, double right, double y) {
+    for (int cIndex = 0; cIndex < 4; cIndex += 3) {
+        if (cubic[cIndex].fY != y) {
+            continue;
+        }
+        if (cubic[cIndex].fX == left) {
+            intersections.insert(cIndex >> 1, 0, cubic[cIndex]);
+        }
+        if (cubic[cIndex].fX == right) {
+            intersections.insert(cIndex >> 1, 1, cubic[cIndex]);
+        }
+    }
+}
+
+void addVerticalEndPoints(double top, double bottom, double x) {
+    for (int cIndex = 0; cIndex < 4; cIndex += 3) {
+        if (cubic[cIndex].fX != x) {
+            continue;
+        }
+        if (cubic[cIndex].fY == top) {
+            intersections.insert(cIndex >> 1, 0, cubic[cIndex]);
+        }
+        if (cubic[cIndex].fY == bottom) {
+            intersections.insert(cIndex >> 1, 1, cubic[cIndex]);
+        }
+    }
+}
+
+double findLineT(double t) {
+    SkDPoint xy = cubic.xyAtT(t);
+    double dx = line[1].fX - line[0].fX;
+    double dy = line[1].fY - line[0].fY;
+    if (fabs(dx) > fabs(dy)) {
+        return (xy.fX - line[0].fX) / dx;
+    }
+    return (xy.fY - line[0].fY) / dy;
+}
+
+static bool pinTs(double* cubicT, double* lineT) {
+    if (!approximately_one_or_less(*lineT)) {
+        return false;
+    }
+    if (!approximately_zero_or_more(*lineT)) {
+        return false;
+    }
+    if (precisely_less_than_zero(*cubicT)) {
+        *cubicT = 0;
+    } else if (precisely_greater_than_one(*cubicT)) {
+        *cubicT = 1;
+    }
+    if (precisely_less_than_zero(*lineT)) {
+        *lineT = 0;
+    } else if (precisely_greater_than_one(*lineT)) {
+        *lineT = 1;
+    }
+    return true;
+}
+
+private:
+
+const SkDCubic& cubic;
+const SkDLine& line;
+SkIntersections& intersections;
+};
+
+int SkIntersections::horizontal(const SkDCubic& cubic, double left, double right, double y,
+        bool flipped) {
+    LineCubicIntersections c(cubic, *(static_cast<SkDLine*>(0)), *this);
+    return c.horizontalIntersect(y, left, right, flipped);
+}
+
+int SkIntersections::vertical(const SkDCubic& cubic, double top, double bottom, double x,
+        bool flipped) {
+    LineCubicIntersections c(cubic, *(static_cast<SkDLine*>(0)), *this);
+    return c.verticalIntersect(x, top, bottom, flipped);
+}
+
+int SkIntersections::intersect(const SkDCubic& cubic, const SkDLine& line) {
+    LineCubicIntersections c(cubic, line, *this);
+    return c.intersect();
+}
+
+int SkIntersections::intersectRay(const SkDCubic& cubic, const SkDLine& line) {
+    LineCubicIntersections c(cubic, line, *this);
+    return c.intersectRay(fT[0]);
+}
diff --git a/src/pathops/SkDCubicToQuads.cpp b/src/pathops/SkDCubicToQuads.cpp
new file mode 100644
index 0000000..b8a02c4
--- /dev/null
+++ b/src/pathops/SkDCubicToQuads.cpp
@@ -0,0 +1,190 @@
+/*
+http://stackoverflow.com/questions/2009160/how-do-i-convert-the-2-control-points-of-a-cubic-curve-to-the-single-control-poi
+*/
+
+/*
+Let's call the control points of the cubic Q0..Q3 and the control points of the quadratic P0..P2.
+Then for degree elevation, the equations are:
+
+Q0 = P0
+Q1 = 1/3 P0 + 2/3 P1
+Q2 = 2/3 P1 + 1/3 P2
+Q3 = P2
+In your case you have Q0..Q3 and you're solving for P0..P2. There are two ways to compute P1 from
+ the equations above:
+
+P1 = 3/2 Q1 - 1/2 Q0
+P1 = 3/2 Q2 - 1/2 Q3
+If this is a degree-elevated cubic, then both equations will give the same answer for P1. Since
+ it's likely not, your best bet is to average them. So,
+
+P1 = -1/4 Q0 + 3/4 Q1 + 3/4 Q2 - 1/4 Q3
+
+
+SkDCubic defined by: P1/2 - anchor points, C1/C2 control points
+|x| is the euclidean norm of x
+mid-point approx of cubic: a quad that shares the same anchors with the cubic and has the
+ control point at C = (3·C2 - P2 + 3·C1 - P1)/4
+
+Algorithm
+
+pick an absolute precision (prec)
+Compute the Tdiv as the root of (cubic) equation
+sqrt(3)/18 · |P2 - 3·C2 + 3·C1 - P1|/2 · Tdiv ^ 3 = prec
+if Tdiv < 0.5 divide the cubic at Tdiv. First segment [0..Tdiv] can be approximated with by a
+ quadratic, with a defect less than prec, by the mid-point approximation.
+ Repeat from step 2 with the second resulted segment (corresponding to 1-Tdiv)
+0.5<=Tdiv<1 - simply divide the cubic in two. The two halves can be approximated by the mid-point
+ approximation
+Tdiv>=1 - the entire cubic can be approximated by the mid-point approximation
+
+confirmed by (maybe stolen from)
+http://www.caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html
+// maybe in turn derived from  http://www.cccg.ca/proceedings/2004/36.pdf
+// also stored at http://www.cis.usouthal.edu/~hain/general/Publications/Bezier/bezier%20cccg04%20paper.pdf
+
+*/
+
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsQuad.h"
+#include "SkReduceOrder.h"
+#include "SkTDArray.h"
+#include "TSearch.h"
+
+#define USE_CUBIC_END_POINTS 1
+
+static double calc_t_div(const SkDCubic& cubic, double precision, double start) {
+    const double adjust = sqrt(3.) / 36;
+    SkDCubic sub;
+    const SkDCubic* cPtr;
+    if (start == 0) {
+        cPtr = &cubic;
+    } else {
+        // OPTIMIZE: special-case half-split ?
+        sub = cubic.subDivide(start, 1);
+        cPtr = &sub;
+    }
+    const SkDCubic& c = *cPtr;
+    double dx = c[3].fX - 3 * (c[2].fX - c[1].fX) - c[0].fX;
+    double dy = c[3].fY - 3 * (c[2].fY - c[1].fY) - c[0].fY;
+    double dist = sqrt(dx * dx + dy * dy);
+    double tDiv3 = precision / (adjust * dist);
+    double t = SkDCubeRoot(tDiv3);
+    if (start > 0) {
+        t = start + (1 - start) * t;
+    }
+    return t;
+}
+
+SkDQuad SkDCubic::toQuad() const {
+    SkDQuad quad;
+    quad[0] = fPts[0];
+    const SkDPoint fromC1 = {(3 * fPts[1].fX - fPts[0].fX) / 2, (3 * fPts[1].fY - fPts[0].fY) / 2};
+    const SkDPoint fromC2 = {(3 * fPts[2].fX - fPts[3].fX) / 2, (3 * fPts[2].fY - fPts[3].fY) / 2};
+    quad[1].fX = (fromC1.fX + fromC2.fX) / 2;
+    quad[1].fY = (fromC1.fY + fromC2.fY) / 2;
+    quad[2] = fPts[3];
+    return quad;
+}
+
+static bool add_simple_ts(const SkDCubic& cubic, double precision, SkTDArray<double>* ts) {
+    double tDiv = calc_t_div(cubic, precision, 0);
+    if (tDiv >= 1) {
+        return true;
+    }
+    if (tDiv >= 0.5) {
+        *ts->append() = 0.5;
+        return true;
+    }
+    return false;
+}
+
+static void addTs(const SkDCubic& cubic, double precision, double start, double end,
+        SkTDArray<double>* ts) {
+    double tDiv = calc_t_div(cubic, precision, 0);
+    double parts = ceil(1.0 / tDiv);
+    for (double index = 0; index < parts; ++index) {
+        double newT = start + (index / parts) * (end - start);
+        if (newT > 0 && newT < 1) {
+            *ts->append() = newT;
+        }
+    }
+}
+
+// flavor that returns T values only, deferring computing the quads until they are needed
+// FIXME: when called from recursive intersect 2, this could take the original cubic
+// and do a more precise job when calling chop at and sub divide by computing the fractional ts.
+// it would still take the prechopped cubic for reduce order and find cubic inflections
+void SkDCubic::toQuadraticTs(double precision, SkTDArray<double>* ts) const {
+    SkReduceOrder reducer;
+    int order = reducer.reduce(*this, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style);
+    if (order < 3) {
+        return;
+    }
+    double inflectT[5];
+    int inflections = findInflections(inflectT);
+    SkASSERT(inflections <= 2);
+    if (!endsAreExtremaInXOrY()) {
+        inflections += findMaxCurvature(&inflectT[inflections]);
+        SkASSERT(inflections <= 5);
+    }
+    QSort<double>(inflectT, &inflectT[inflections - 1]);
+    // OPTIMIZATION: is this filtering common enough that it needs to be pulled out into its
+    // own subroutine?
+    while (inflections && approximately_less_than_zero(inflectT[0])) {
+        memmove(inflectT, &inflectT[1], sizeof(inflectT[0]) * --inflections);
+    }
+    int start = 0;
+    do {
+        int next = start + 1;
+        if (next >= inflections) {
+            break;
+        }
+        if (!approximately_equal(inflectT[start], inflectT[next])) {
+            ++start;
+            continue;
+        }
+        memmove(&inflectT[start], &inflectT[next], sizeof(inflectT[0]) * (--inflections - start));
+    } while (true);
+    while (inflections && approximately_greater_than_one(inflectT[inflections - 1])) {
+        --inflections;
+    }
+    SkDCubicPair pair;
+    if (inflections == 1) {
+        pair = chopAt(inflectT[0]);
+        int orderP1 = reducer.reduce(pair.first(), SkReduceOrder::kNo_Quadratics,
+                SkReduceOrder::kFill_Style);
+        if (orderP1 < 2) {
+            --inflections;
+        } else {
+            int orderP2 = reducer.reduce(pair.second(), SkReduceOrder::kNo_Quadratics,
+                    SkReduceOrder::kFill_Style);
+            if (orderP2 < 2) {
+                --inflections;
+            }
+        }
+    }
+    if (inflections == 0 && add_simple_ts(*this, precision, ts)) {
+        return;
+    }
+    if (inflections == 1) {
+        pair = chopAt(inflectT[0]);
+        addTs(pair.first(), precision, 0, inflectT[0], ts);
+        addTs(pair.second(), precision, inflectT[0], 1, ts);
+        return;
+    }
+    if (inflections > 1) {
+        SkDCubic part = subDivide(0, inflectT[0]);
+        addTs(part, precision, 0, inflectT[0], ts);
+        int last = inflections - 1;
+        for (int idx = 0; idx < last; ++idx) {
+            part = subDivide(inflectT[idx], inflectT[idx + 1]);
+            addTs(part, precision, inflectT[idx], inflectT[idx + 1], ts);
+        }
+        part = subDivide(inflectT[last], 1);
+        addTs(part, precision, inflectT[last], 1, ts);
+        return;
+    }
+    addTs(*this, precision, 0, 1, ts);
+}
diff --git a/src/pathops/SkDLineIntersection.cpp b/src/pathops/SkDLineIntersection.cpp
new file mode 100644
index 0000000..8b02030
--- /dev/null
+++ b/src/pathops/SkDLineIntersection.cpp
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkIntersections.h"
+#include "SkPathOpsLine.h"
+
+/* Determine the intersection point of two lines. This assumes the lines are not parallel,
+   and that that the lines are infinite.
+   From http://en.wikipedia.org/wiki/Line-line_intersection
+ */
+SkDPoint SkIntersections::Line(const SkDLine& a, const SkDLine& b) {
+    double axLen = a[1].fX - a[0].fX;
+    double ayLen = a[1].fY - a[0].fY;
+    double bxLen = b[1].fX - b[0].fX;
+    double byLen = b[1].fY - b[0].fY;
+    double denom = byLen * axLen - ayLen * bxLen;
+    SkASSERT(denom);
+    double term1 = a[1].fX * a[0].fY - a[1].fY * a[0].fX;
+    double term2 = b[1].fX * b[0].fY - b[1].fY * b[0].fX;
+    SkDPoint p;
+    p.fX = (term1 * bxLen - axLen * term2) / denom;
+    p.fY = (term1 * byLen - ayLen * term2) / denom;
+    return p;
+}
+
+int SkIntersections::computePoints(const SkDLine& line, int used) {
+    fPt[0] = line.xyAtT(fT[0][0]);
+    if ((fUsed = used) == 2) {
+        fPt[1] = line.xyAtT(fT[0][1]);
+    }
+    return fUsed;
+}
+
+/*
+   Determine the intersection point of two line segments
+   Return FALSE if the lines don't intersect
+   from: http://paulbourke.net/geometry/lineline2d/
+ */
+
+int SkIntersections::intersect(const SkDLine& a, const SkDLine& b) {
+    double axLen = a[1].fX - a[0].fX;
+    double ayLen = a[1].fY - a[0].fY;
+    double bxLen = b[1].fX - b[0].fX;
+    double byLen = b[1].fY - b[0].fY;
+    /* Slopes match when denom goes to zero:
+                      axLen / ayLen ==                   bxLen / byLen
+    (ayLen * byLen) * axLen / ayLen == (ayLen * byLen) * bxLen / byLen
+             byLen  * axLen         ==  ayLen          * bxLen
+             byLen  * axLen         -   ayLen          * bxLen == 0 ( == denom )
+     */
+    double denom = byLen * axLen - ayLen * bxLen;
+    double ab0y = a[0].fY - b[0].fY;
+    double ab0x = a[0].fX - b[0].fX;
+    double numerA = ab0y * bxLen - byLen * ab0x;
+    double numerB = ab0y * axLen - ayLen * ab0x;
+    bool mayNotOverlap = (numerA < 0 && denom > numerA) || (numerA > 0 && denom < numerA)
+            || (numerB < 0 && denom > numerB) || (numerB > 0 && denom < numerB);
+    numerA /= denom;
+    numerB /= denom;
+    if ((!approximately_zero(denom) || (!approximately_zero_inverse(numerA)
+            && !approximately_zero_inverse(numerB))) && !sk_double_isnan(numerA)
+            && !sk_double_isnan(numerB)) {
+        if (mayNotOverlap) {
+            return fUsed = 0;
+        }
+        fT[0][0] = numerA;
+        fT[1][0] = numerB;
+        fPt[0] = a.xyAtT(numerA);
+        return computePoints(a, 1);
+    }
+   /* See if the axis intercepts match:
+              ay - ax * ayLen / axLen  ==          by - bx * ayLen / axLen
+     axLen * (ay - ax * ayLen / axLen) == axLen * (by - bx * ayLen / axLen)
+     axLen *  ay - ax * ayLen          == axLen *  by - bx * ayLen
+    */
+    // FIXME: need to use AlmostEqualUlps variant instead
+    if (!approximately_equal_squared(axLen * a[0].fY - ayLen * a[0].fX,
+            axLen * b[0].fY - ayLen * b[0].fX)) {
+        return fUsed = 0;
+    }
+    const double* aPtr;
+    const double* bPtr;
+    if (fabs(axLen) > fabs(ayLen) || fabs(bxLen) > fabs(byLen)) {
+        aPtr = &a[0].fX;
+        bPtr = &b[0].fX;
+    } else {
+        aPtr = &a[0].fY;
+        bPtr = &b[0].fY;
+    }
+    double a0 = aPtr[0];
+    double a1 = aPtr[2];
+    double b0 = bPtr[0];
+    double b1 = bPtr[2];
+    // OPTIMIZATION: restructure to reject before the divide
+    // e.g., if ((a0 - b0) * (a0 - a1) < 0 || abs(a0 - b0) > abs(a0 - a1))
+    // (except efficient)
+    double aDenom = a0 - a1;
+    if (approximately_zero(aDenom)) {
+        if (!between(b0, a0, b1)) {
+            return fUsed = 0;
+        }
+        fT[0][0] = fT[0][1] = 0;
+    } else {
+        double at0 = (a0 - b0) / aDenom;
+        double at1 = (a0 - b1) / aDenom;
+        if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
+            return fUsed = 0;
+        }
+        fT[0][0] = SkTMax<double>(SkTMin<double>(at0, 1.0), 0.0);
+        fT[0][1] = SkTMax<double>(SkTMin<double>(at1, 1.0), 0.0);
+    }
+    double bDenom = b0 - b1;
+    if (approximately_zero(bDenom)) {
+        fT[1][0] = fT[1][1] = 0;
+    } else {
+        int bIn = aDenom * bDenom < 0;
+        fT[1][bIn] = SkTMax<double>(SkTMin<double>((b0 - a0) / bDenom, 1.0), 0.0);
+        fT[1][!bIn] = SkTMax<double>(SkTMin<double>((b0 - a1) / bDenom, 1.0), 0.0);
+    }
+    bool second = fabs(fT[0][0] - fT[0][1]) > FLT_EPSILON;
+    SkASSERT((fabs(fT[1][0] - fT[1][1]) <= FLT_EPSILON) ^ second);
+    return computePoints(a, 1 + second);
+}
+
+int SkIntersections::horizontal(const SkDLine& line, double y) {
+    double min = line[0].fY;
+    double max = line[1].fY;
+    if (min > max) {
+        SkTSwap(min, max);
+    }
+    if (min > y || max < y) {
+        return fUsed = 0;
+    }
+    if (AlmostEqualUlps(min, max)) {
+        fT[0][0] = 0;
+        fT[0][1] = 1;
+        return fUsed = 2;
+    }
+    fT[0][0] = (y - line[0].fY) / (line[1].fY - line[0].fY);
+    return fUsed = 1;
+}
+
+// OPTIMIZATION  Given: dy = line[1].fY - line[0].fY
+// and: xIntercept / (y - line[0].fY) == (line[1].fX - line[0].fX) / dy
+// then: xIntercept * dy == (line[1].fX - line[0].fX) * (y - line[0].fY)
+// Assuming that dy is always > 0, the line segment intercepts if:
+//   left * dy <= xIntercept * dy <= right * dy
+// thus: left * dy <= (line[1].fX - line[0].fX) * (y - line[0].fY) <= right * dy
+// (clever as this is, it does not give us the t value, so may be useful only
+// as a quick reject -- and maybe not then; it takes 3 muls, 3 adds, 2 cmps)
+int SkIntersections::horizontal(const SkDLine& line, double left, double right, double y) {
+    int result = horizontal(line, y);
+    if (result != 1) {
+        SkASSERT(result == 0);  // FIXME: this is incorrect if result == 2
+        return result;
+    }
+    double xIntercept = line[0].fX + fT[0][0] * (line[1].fX - line[0].fX);
+    if (xIntercept > right || xIntercept < left) {
+        return fUsed = 0;
+    }
+    return result;
+}
+
+int SkIntersections::horizontal(const SkDLine& line, double left, double right,
+                                double y, bool flipped) {
+    int result = horizontal(line, y);
+    switch (result) {
+        case 0:
+            break;
+        case 1: {
+            double xIntercept = line[0].fX + fT[0][0] * (line[1].fX - line[0].fX);
+            if (xIntercept > right || xIntercept < left) {
+                return fUsed = 0;
+            }
+            fT[1][0] = (xIntercept - left) / (right - left);
+            break;
+        }
+        case 2:
+            double a0 = line[0].fX;
+            double a1 = line[1].fX;
+            double b0 = flipped ? right : left;
+            double b1 = flipped ? left : right;
+            // FIXME: share common code below
+            double at0 = (a0 - b0) / (a0 - a1);
+            double at1 = (a0 - b1) / (a0 - a1);
+            if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
+                return fUsed = 0;
+            }
+            fT[0][0] = SkTMax<double>(SkTMin<double>(at0, 1.0), 0.0);
+            fT[0][1] = SkTMax<double>(SkTMin<double>(at1, 1.0), 0.0);
+            int bIn = (a0 - a1) * (b0 - b1) < 0;
+            fT[1][bIn] = SkTMax<double>(SkTMin<double>((b0 - a0) / (b0 - b1), 1.0), 0.0);
+            fT[1][!bIn] = SkTMax<double>(SkTMin<double>((b0 - a1) / (b0 - b1), 1.0), 0.0);
+            bool second = fabs(fT[0][0] - fT[0][1]) > FLT_EPSILON;
+            SkASSERT((fabs(fT[1][0] - fT[1][1]) <= FLT_EPSILON) ^ second);
+            return computePoints(line, 1 + second);
+    }
+    if (flipped) {
+        // OPTIMIZATION: instead of swapping, pass original line, use [1].fX - [0].fX
+        for (int index = 0; index < result; ++index) {
+            fT[1][index] = 1 - fT[1][index];
+        }
+    }
+    return computePoints(line, result);
+}
+
+int SkIntersections::vertical(const SkDLine& line, double x) {
+    double min = line[0].fX;
+    double max = line[1].fX;
+    if (min > max) {
+        SkTSwap(min, max);
+    }
+    if (min > x || max < x) {
+        return fUsed = 0;
+    }
+    if (AlmostEqualUlps(min, max)) {
+        fT[0][0] = 0;
+        fT[0][1] = 1;
+        return fUsed = 2;
+    }
+    fT[0][0] = (x - line[0].fX) / (line[1].fX - line[0].fX);
+    return fUsed = 1;
+}
+
+int SkIntersections::vertical(const SkDLine& line, double top, double bottom,
+                              double x, bool flipped) {
+    int result = vertical(line, x);
+    switch (result) {
+        case 0:
+            break;
+        case 1: {
+            double yIntercept = line[0].fY + fT[0][0] * (line[1].fY - line[0].fY);
+            if (yIntercept > bottom || yIntercept < top) {
+                return fUsed = 0;
+            }
+            fT[1][0] = (yIntercept - top) / (bottom - top);
+            break;
+        }
+        case 2:
+            double a0 = line[0].fY;
+            double a1 = line[1].fY;
+            double b0 = flipped ? bottom : top;
+            double b1 = flipped ? top : bottom;
+            // FIXME: share common code above
+            double at0 = (a0 - b0) / (a0 - a1);
+            double at1 = (a0 - b1) / (a0 - a1);
+            if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
+                return fUsed = 0;
+            }
+            fT[0][0] = SkTMax<double>(SkTMin<double>(at0, 1.0), 0.0);
+            fT[0][1] = SkTMax<double>(SkTMin<double>(at1, 1.0), 0.0);
+            int bIn = (a0 - a1) * (b0 - b1) < 0;
+            fT[1][bIn] = SkTMax<double>(SkTMin<double>((b0 - a0) / (b0 - b1), 1.0), 0.0);
+            fT[1][!bIn] = SkTMax<double>(SkTMin<double>((b0 - a1) / (b0 - b1), 1.0), 0.0);
+            bool second = fabs(fT[0][0] - fT[0][1]) > FLT_EPSILON;
+            SkASSERT((fabs(fT[1][0] - fT[1][1]) <= FLT_EPSILON) ^ second);
+            return computePoints(line, 1 + second);
+            break;
+    }
+    if (flipped) {
+        // OPTIMIZATION: instead of swapping, pass original line, use [1].fY - [0].fY
+        for (int index = 0; index < result; ++index) {
+            fT[1][index] = 1 - fT[1][index];
+        }
+    }
+    return computePoints(line, result);
+}
+
+// from http://www.bryceboe.com/wordpress/wp-content/uploads/2006/10/intersect.py
+// 4 subs, 2 muls, 1 cmp
+static bool ccw(const SkDPoint& A, const SkDPoint& B, const SkDPoint& C) {
+    return (C.fY - A.fY) * (B.fX - A.fX) > (B.fY - A.fY) * (C.fX - A.fX);
+}
+
+// 16 subs, 8 muls, 6 cmps
+bool SkIntersections::Test(const SkDLine& a, const SkDLine& b) {
+    return ccw(a[0], b[0], b[1]) != ccw(a[1], b[0], b[1])
+            && ccw(a[0], a[1], b[0]) != ccw(a[0], a[1], b[1]);
+}
diff --git a/src/pathops/SkDQuadImplicit.cpp b/src/pathops/SkDQuadImplicit.cpp
new file mode 100644
index 0000000..9f1e882
--- /dev/null
+++ b/src/pathops/SkDQuadImplicit.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkDQuadImplicit.h"
+
+/* from http://tom.cs.byu.edu/~tom/papers/cvgip84.pdf 4.1
+ *
+ * This paper proves that Syvester's method can compute the implicit form of
+ * the quadratic from the parameterized form.
+ *
+ * Given x = a*t*t + b*t + c  (the parameterized form)
+ *       y = d*t*t + e*t + f
+ *
+ * we want to find an equation of the implicit form:
+ *
+ * A*x*x + B*x*y + C*y*y + D*x + E*y + F = 0
+ *
+ * The implicit form can be expressed as a 4x4 determinant, as shown.
+ *
+ * The resultant obtained by Syvester's method is
+ *
+ * |   a   b   (c - x)     0     |
+ * |   0   a      b     (c - x)  |
+ * |   d   e   (f - y)     0     |
+ * |   0   d      e     (f - y)  |
+ *
+ * which expands to
+ *
+ * d*d*x*x + -2*a*d*x*y + a*a*y*y
+ *         + (-2*c*d*d + b*e*d - a*e*e + 2*a*f*d)*x
+ *         + (-2*f*a*a + e*b*a - d*b*b + 2*d*c*a)*y
+ *         +
+ * |   a   b   c   0   |
+ * |   0   a   b   c   | == 0.
+ * |   d   e   f   0   |
+ * |   0   d   e   f   |
+ *
+ * Expanding the constant determinant results in
+ *
+ *   | a b c |     | b c 0 |
+ * a*| e f 0 | + d*| a b c | ==
+ *   | d e f |     | d e f |
+ *
+ * a*(a*f*f + c*e*e - c*f*d - b*e*f) + d*(b*b*f + c*c*d - c*a*f - c*e*b)
+ *
+ */
+
+// OPTIMIZATION: test, verify tricky arithmetic
+static bool straight_forward = true;
+
+SkDQuadImplicit::SkDQuadImplicit(const SkDQuad& q) {
+    double a, b, c;
+    SkDQuad::SetABC(&q[0].fX, &a, &b, &c);
+    double d, e, f;
+    SkDQuad::SetABC(&q[0].fY, &d, &e, &f);
+    // compute the implicit coefficients
+    if (straight_forward) {  // 42 muls, 13 adds
+        fP[kXx_Coeff] = d * d;
+        fP[kXy_Coeff] = -2 * a * d;
+        fP[kYy_Coeff] = a * a;
+        fP[kX_Coeff] = -2*c*d*d + b*e*d - a*e*e + 2*a*f*d;
+        fP[kY_Coeff] = -2*f*a*a + e*b*a - d*b*b + 2*d*c*a;
+        fP[kC_Coeff] = a*(a*f*f + c*e*e - c*f*d - b*e*f)
+                   + d*(b*b*f + c*c*d - c*a*f - c*e*b);
+    } else {  // 26 muls, 11 adds
+        double aa = a * a;
+        double ad = a * d;
+        double dd = d * d;
+        fP[kXx_Coeff] = dd;
+        fP[kXy_Coeff] = -2 * ad;
+        fP[kYy_Coeff] = aa;
+        double be = b * e;
+        double bde = be * d;
+        double cdd = c * dd;
+        double ee = e * e;
+        fP[kX_Coeff] =  -2*cdd + bde - a*ee + 2*ad*f;
+        double aaf = aa * f;
+        double abe = a * be;
+        double ac = a * c;
+        double bb_2ac = b*b - 2*ac;
+        fP[kY_Coeff] = -2*aaf + abe - d*bb_2ac;
+        fP[kC_Coeff] = aaf*f + ac*ee + d*f*bb_2ac - abe*f + c*cdd - c*bde;
+    }
+}
+
+ /* Given a pair of quadratics, determine their parametric coefficients.
+  * If the scaled coefficients are nearly equal, then the part of the quadratics
+  * may be coincident.
+  * FIXME: optimization -- since comparison short-circuits on no match,
+  * lazily compute the coefficients, comparing the easiest to compute first.
+  * xx and yy first; then xy; and so on.
+  */
+bool SkDQuadImplicit::match(const SkDQuadImplicit& p2) const {
+    int first = 0;
+    for (int index = 0; index <= kC_Coeff; ++index) {
+        if (approximately_zero(fP[index]) && approximately_zero(p2.fP[index])) {
+            first += first == index;
+            continue;
+        }
+        if (first == index) {
+            continue;
+        }
+        if (!AlmostEqualUlps(fP[index] * p2.fP[first], fP[first] * p2.fP[index])) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool SkDQuadImplicit::Match(const SkDQuad& quad1, const SkDQuad& quad2) {
+    SkDQuadImplicit i1(quad1);  // a'xx , b'xy , c'yy , d'x , e'y , f
+    SkDQuadImplicit i2(quad2);
+    return i1.match(i2);
+}
diff --git a/src/pathops/SkDQuadImplicit.h b/src/pathops/SkDQuadImplicit.h
new file mode 100644
index 0000000..24f1aac
--- /dev/null
+++ b/src/pathops/SkDQuadImplicit.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkDQuadImplicit_DEFINED
+#define SkDQuadImplicit_DEFINED
+
+#include "SkPathOpsQuad.h"
+
+class SkDQuadImplicit {
+public:
+    explicit SkDQuadImplicit(const SkDQuad& q);
+
+    bool match(const SkDQuadImplicit& two) const;
+    static bool Match(const SkDQuad& quad1, const SkDQuad& quad2);
+
+    double x2() const { return fP[kXx_Coeff]; }
+    double xy() const { return fP[kXy_Coeff]; }
+    double y2() const { return fP[kYy_Coeff]; }
+    double x() const { return fP[kX_Coeff]; }
+    double y() const { return fP[kY_Coeff]; }
+    double c() const { return fP[kC_Coeff]; }
+
+private:
+    enum Coeffs {
+        kXx_Coeff,
+        kXy_Coeff,
+        kYy_Coeff,
+        kX_Coeff,
+        kY_Coeff,
+        kC_Coeff,
+    };
+
+    double fP[kC_Coeff + 1];
+};
+
+#endif
diff --git a/src/pathops/SkDQuadIntersection.cpp b/src/pathops/SkDQuadIntersection.cpp
new file mode 100644
index 0000000..d8e3f20
--- /dev/null
+++ b/src/pathops/SkDQuadIntersection.cpp
@@ -0,0 +1,496 @@
+// Another approach is to start with the implicit form of one curve and solve
+// (seek implicit coefficients in QuadraticParameter.cpp
+// by substituting in the parametric form of the other.
+// The downside of this approach is that early rejects are difficult to come by.
+// http://planetmath.org/encyclopedia/GaloisTheoreticDerivationOfTheQuarticFormula.html#step
+
+
+#include "SkDQuadImplicit.h"
+#include "SkIntersections.h"
+#include "SkPathOpsLine.h"
+#include "SkQuarticRoot.h"
+#include "SkTDArray.h"
+#include "TSearch.h"
+
+/* given the implicit form 0 = Ax^2 + Bxy + Cy^2 + Dx + Ey + F
+ * and given x = at^2 + bt + c  (the parameterized form)
+ *           y = dt^2 + et + f
+ * then
+ * 0 = A(at^2+bt+c)(at^2+bt+c)+B(at^2+bt+c)(dt^2+et+f)+C(dt^2+et+f)(dt^2+et+f)+D(at^2+bt+c)+E(dt^2+et+f)+F
+ */
+
+static int findRoots(const SkDQuadImplicit& i, const SkDQuad& q2, double roots[4],
+        bool oneHint, int firstCubicRoot) {
+    double a, b, c;
+    SkDQuad::SetABC(&q2[0].fX, &a, &b, &c);
+    double d, e, f;
+    SkDQuad::SetABC(&q2[0].fY, &d, &e, &f);
+    const double t4 =     i.x2() *  a * a
+                    +     i.xy() *  a * d
+                    +     i.y2() *  d * d;
+    const double t3 = 2 * i.x2() *  a * b
+                    +     i.xy() * (a * e +     b * d)
+                    + 2 * i.y2() *  d * e;
+    const double t2 =     i.x2() * (b * b + 2 * a * c)
+                    +     i.xy() * (c * d +     b * e + a * f)
+                    +     i.y2() * (e * e + 2 * d * f)
+                    +     i.x()  *  a
+                    +     i.y()  *  d;
+    const double t1 = 2 * i.x2() *  b * c
+                    +     i.xy() * (c * e + b * f)
+                    + 2 * i.y2() *  e * f
+                    +     i.x()  *  b
+                    +     i.y()  *  e;
+    const double t0 =     i.x2() *  c * c
+                    +     i.xy() *  c * f
+                    +     i.y2() *  f * f
+                    +     i.x()  *  c
+                    +     i.y()  *  f
+                    +     i.c();
+    int rootCount = SkReducedQuarticRoots(t4, t3, t2, t1, t0, oneHint, roots);
+    if (rootCount >= 0) {
+        return rootCount;
+    }
+    return SkQuarticRootsReal(firstCubicRoot, t4, t3, t2, t1, t0, roots);
+}
+
+static int addValidRoots(const double roots[4], const int count, double valid[4]) {
+    int result = 0;
+    int index;
+    for (index = 0; index < count; ++index) {
+        if (!approximately_zero_or_more(roots[index]) || !approximately_one_or_less(roots[index])) {
+            continue;
+        }
+        double t = 1 - roots[index];
+        if (approximately_less_than_zero(t)) {
+            t = 0;
+        } else if (approximately_greater_than_one(t)) {
+            t = 1;
+        }
+        valid[result++] = t;
+    }
+    return result;
+}
+
+static bool only_end_pts_in_common(const SkDQuad& q1, const SkDQuad& q2, SkIntersections* i) {
+// the idea here is to see at minimum do a quick reject by rotating all points
+// to either side of the line formed by connecting the endpoints
+// if the opposite curves points are on the line or on the other side, the
+// curves at most intersect at the endpoints
+    for (int oddMan = 0; oddMan < 3; ++oddMan) {
+        const SkDPoint* endPt[2];
+        for (int opp = 1; opp < 3; ++opp) {
+            int end = oddMan ^ opp;
+            if (end == 3) {
+                end = opp;
+            }
+            endPt[opp - 1] = &q1[end];
+        }
+        double origX = endPt[0]->fX;
+        double origY = endPt[0]->fY;
+        double adj = endPt[1]->fX - origX;
+        double opp = endPt[1]->fY - origY;
+        double sign = (q1[oddMan].fY - origY) * adj - (q1[oddMan].fX - origX) * opp;
+        if (approximately_zero(sign)) {
+            goto tryNextHalfPlane;
+        }
+        for (int n = 0; n < 3; ++n) {
+            double test = (q2[n].fY - origY) * adj - (q2[n].fX - origX) * opp;
+            if (test * sign > 0) {
+                goto tryNextHalfPlane;
+            }
+        }
+        for (int i1 = 0; i1 < 3; i1 += 2) {
+            for (int i2 = 0; i2 < 3; i2 += 2) {
+                if (q1[i1] == q2[i2]) {
+                    i->insert(i1 >> 1, i2 >> 1, q1[i1]);
+                }
+            }
+        }
+        SkASSERT(i->used() < 3);
+        return true;
+tryNextHalfPlane:
+        ;
+    }
+    return false;
+}
+
+// returns false if there's more than one intercept or the intercept doesn't match the point
+// returns true if the intercept was successfully added or if the
+// original quads need to be subdivided
+static bool add_intercept(const SkDQuad& q1, const SkDQuad& q2, double tMin, double tMax,
+                          SkIntersections* i, bool* subDivide) {
+    double tMid = (tMin + tMax) / 2;
+    SkDPoint mid = q2.xyAtT(tMid);
+    SkDLine line;
+    line[0] = line[1] = mid;
+    SkDVector dxdy = q2.dxdyAtT(tMid);
+    line[0] -= dxdy;
+    line[1] += dxdy;
+    SkIntersections rootTs;
+    int roots = rootTs.intersect(q1, line);
+    if (roots == 0) {
+        if (subDivide) {
+            *subDivide = true;
+        }
+        return true;
+    }
+    if (roots == 2) {
+        return false;
+    }
+    SkDPoint pt2 = q1.xyAtT(rootTs[0][0]);
+    if (!pt2.approximatelyEqualHalf(mid)) {
+        return false;
+    }
+    i->insertSwap(rootTs[0][0], tMid, pt2);
+    return true;
+}
+
+static bool is_linear_inner(const SkDQuad& q1, double t1s, double t1e, const SkDQuad& q2,
+                            double t2s, double t2e, SkIntersections* i, bool* subDivide) {
+    SkDQuad hull = q1.subDivide(t1s, t1e);
+    SkDLine line = {{hull[2], hull[0]}};
+    const SkDLine* testLines[] = { &line, (const SkDLine*) &hull[0], (const SkDLine*) &hull[1] };
+    size_t testCount = sizeof(testLines) / sizeof(testLines[0]);
+    SkTDArray<double> tsFound;
+    for (size_t index = 0; index < testCount; ++index) {
+        SkIntersections rootTs;
+        int roots = rootTs.intersect(q2, *testLines[index]);
+        for (int idx2 = 0; idx2 < roots; ++idx2) {
+            double t = rootTs[0][idx2];
+#ifdef SK_DEBUG
+            SkDPoint qPt = q2.xyAtT(t);
+            SkDPoint lPt = testLines[index]->xyAtT(rootTs[1][idx2]);
+            SkASSERT(qPt.approximatelyEqual(lPt));
+#endif
+            if (approximately_negative(t - t2s) || approximately_positive(t - t2e)) {
+                continue;
+            }
+            *tsFound.append() = rootTs[0][idx2];
+        }
+    }
+    int tCount = tsFound.count();
+    if (tCount <= 0) {
+        return true;
+    }
+    double tMin, tMax;
+    if (tCount == 1) {
+        tMin = tMax = tsFound[0];
+    } else if (tCount > 1) {
+        QSort<double>(tsFound.begin(), tsFound.end() - 1);
+        tMin = tsFound[0];
+        tMax = tsFound[tsFound.count() - 1];
+    }
+    SkDPoint end = q2.xyAtT(t2s);
+    bool startInTriangle = hull.pointInHull(end);
+    if (startInTriangle) {
+        tMin = t2s;
+    }
+    end = q2.xyAtT(t2e);
+    bool endInTriangle = hull.pointInHull(end);
+    if (endInTriangle) {
+        tMax = t2e;
+    }
+    int split = 0;
+    SkDVector dxy1, dxy2;
+    if (tMin != tMax || tCount > 2) {
+        dxy2 = q2.dxdyAtT(tMin);
+        for (int index = 1; index < tCount; ++index) {
+            dxy1 = dxy2;
+            dxy2 = q2.dxdyAtT(tsFound[index]);
+            double dot = dxy1.dot(dxy2);
+            if (dot < 0) {
+                split = index - 1;
+                break;
+            }
+        }
+    }
+    if (split == 0) {  // there's one point
+        if (add_intercept(q1, q2, tMin, tMax, i, subDivide)) {
+            return true;
+        }
+        i->swap();
+        return is_linear_inner(q2, tMin, tMax, q1, t1s, t1e, i, subDivide);
+    }
+    // At this point, we have two ranges of t values -- treat each separately at the split
+    bool result;
+    if (add_intercept(q1, q2, tMin, tsFound[split - 1], i, subDivide)) {
+        result = true;
+    } else {
+        i->swap();
+        result = is_linear_inner(q2, tMin, tsFound[split - 1], q1, t1s, t1e, i, subDivide);
+    }
+    if (add_intercept(q1, q2, tsFound[split], tMax, i, subDivide)) {
+        result = true;
+    } else {
+        i->swap();
+        result |= is_linear_inner(q2, tsFound[split], tMax, q1, t1s, t1e, i, subDivide);
+    }
+    return result;
+}
+
+static double flat_measure(const SkDQuad& q) {
+    SkDVector mid = q[1] - q[0];
+    SkDVector dxy = q[2] - q[0];
+    double length = dxy.length();  // OPTIMIZE: get rid of sqrt
+    return fabs(mid.cross(dxy) / length);
+}
+
+// FIXME ? should this measure both and then use the quad that is the flattest as the line?
+static bool is_linear(const SkDQuad& q1, const SkDQuad& q2, SkIntersections* i) {
+    double measure = flat_measure(q1);
+    // OPTIMIZE: (get rid of sqrt) use approximately_zero
+    if (!approximately_zero_sqrt(measure)) {
+        return false;
+    }
+    return is_linear_inner(q1, 0, 1, q2, 0, 1, i, NULL);
+}
+
+// FIXME: if flat measure is sufficiently large, then probably the quartic solution failed
+static void relaxed_is_linear(const SkDQuad& q1, const SkDQuad& q2, SkIntersections* i) {
+    double m1 = flat_measure(q1);
+    double m2 = flat_measure(q2);
+#if DEBUG_FLAT_QUADS
+    double min = SkTMin<double>(m1, m2);
+    if (min > 5) {
+        SkDebugf("%s maybe not flat enough.. %1.9g\n", __FUNCTION__, min);
+    }
+#endif
+    i->reset();
+    const SkDQuad& rounder = m2 < m1 ? q1 : q2;
+    const SkDQuad& flatter = m2 < m1 ? q2 : q1;
+    bool subDivide = false;
+    is_linear_inner(flatter, 0, 1, rounder, 0, 1, i, &subDivide);
+    if (subDivide) {
+        SkDQuadPair pair = flatter.chopAt(0.5);
+        SkIntersections firstI, secondI;
+        relaxed_is_linear(pair.first(), rounder, &firstI);
+        for (int index = 0; index < firstI.used(); ++index) {
+            i->insert(firstI[0][index] * 0.5, firstI[1][index], firstI.pt(index));
+        }
+        relaxed_is_linear(pair.second(), rounder, &secondI);
+        for (int index = 0; index < secondI.used(); ++index) {
+            i->insert(0.5 + secondI[0][index] * 0.5, secondI[1][index], secondI.pt(index));
+        }
+    }
+    if (m2 < m1) {
+        i->swapPts();
+    }
+}
+
+// each time through the loop, this computes values it had from the last loop
+// if i == j == 1, the center values are still good
+// otherwise, for i != 1 or j != 1, four of the values are still good
+// and if i == 1 ^ j == 1, an additional value is good
+static bool binary_search(const SkDQuad& quad1, const SkDQuad& quad2, double* t1Seed,
+                          double* t2Seed, SkDPoint* pt) {
+    double tStep = ROUGH_EPSILON;
+    SkDPoint t1[3], t2[3];
+    int calcMask = ~0;
+    do {
+        if (calcMask & (1 << 1)) t1[1] = quad1.xyAtT(*t1Seed);
+        if (calcMask & (1 << 4)) t2[1] = quad2.xyAtT(*t2Seed);
+        if (t1[1].approximatelyEqual(t2[1])) {
+            *pt = t1[1];
+    #if ONE_OFF_DEBUG
+            SkDebugf("%s t1=%1.9g t2=%1.9g (%1.9g,%1.9g) == (%1.9g,%1.9g)\n", __FUNCTION__,
+                    t1Seed, t2Seed, t1[1].fX, t1[1].fY, t1[2].fX, t1[2].fY);
+    #endif
+            return true;
+        }
+        if (calcMask & (1 << 0)) t1[0] = quad1.xyAtT(*t1Seed - tStep);
+        if (calcMask & (1 << 2)) t1[2] = quad1.xyAtT(*t1Seed + tStep);
+        if (calcMask & (1 << 3)) t2[0] = quad2.xyAtT(*t2Seed - tStep);
+        if (calcMask & (1 << 5)) t2[2] = quad2.xyAtT(*t2Seed + tStep);
+        double dist[3][3];
+        // OPTIMIZE: using calcMask value permits skipping some distance calcuations
+        //   if prior loop's results are moved to correct slot for reuse
+        dist[1][1] = t1[1].distanceSquared(t2[1]);
+        int best_i = 1, best_j = 1;
+        for (int i = 0; i < 3; ++i) {
+            for (int j = 0; j < 3; ++j) {
+                if (i == 1 && j == 1) {
+                    continue;
+                }
+                dist[i][j] = t1[i].distanceSquared(t2[j]);
+                if (dist[best_i][best_j] > dist[i][j]) {
+                    best_i = i;
+                    best_j = j;
+                }
+            }
+        }
+        if (best_i == 1 && best_j == 1) {
+            tStep /= 2;
+            if (tStep < FLT_EPSILON_HALF) {
+                break;
+            }
+            calcMask = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 5);
+            continue;
+        }
+        if (best_i == 0) {
+            *t1Seed -= tStep;
+            t1[2] = t1[1];
+            t1[1] = t1[0];
+            calcMask = 1 << 0;
+        } else if (best_i == 2) {
+            *t1Seed += tStep;
+            t1[0] = t1[1];
+            t1[1] = t1[2];
+            calcMask = 1 << 2;
+        } else {
+            calcMask = 0;
+        }
+        if (best_j == 0) {
+            *t2Seed -= tStep;
+            t2[2] = t2[1];
+            t2[1] = t2[0];
+            calcMask |= 1 << 3;
+        } else if (best_j == 2) {
+            *t2Seed += tStep;
+            t2[0] = t2[1];
+            t2[1] = t2[2];
+            calcMask |= 1 << 5;
+        }
+    } while (true);
+#if ONE_OFF_DEBUG
+    SkDebugf("%s t1=%1.9g t2=%1.9g (%1.9g,%1.9g) != (%1.9g,%1.9g) %s\n", __FUNCTION__,
+        t1Seed, t2Seed, t1[1].fX, t1[1].fY, t1[2].fX, t1[2].fY);
+#endif
+    return false;
+}
+
+int SkIntersections::intersect(const SkDQuad& q1, const SkDQuad& q2) {
+    // if the quads share an end point, check to see if they overlap
+
+    if (only_end_pts_in_common(q1, q2, this)) {
+        return fUsed;
+    }
+    if (only_end_pts_in_common(q2, q1, this)) {
+        swapPts();
+        return fUsed;
+    }
+    // see if either quad is really a line
+    if (is_linear(q1, q2, this)) {
+        return fUsed;
+    }
+    if (is_linear(q2, q1, this)) {
+        swapPts();
+        return fUsed;
+    }
+    SkDQuadImplicit i1(q1);
+    SkDQuadImplicit i2(q2);
+    if (i1.match(i2)) {
+        // FIXME: compute T values
+        // compute the intersections of the ends to find the coincident span
+        bool useVertical = fabs(q1[0].fX - q1[2].fX) < fabs(q1[0].fY - q1[2].fY);
+        double t;
+        if ((t = SkIntersections::Axial(q1, q2[0], useVertical)) >= 0) {
+            insertCoincident(t, 0, q2[0]);
+        }
+        if ((t = SkIntersections::Axial(q1, q2[2], useVertical)) >= 0) {
+            insertCoincident(t, 1, q2[2]);
+        }
+        useVertical = fabs(q2[0].fX - q2[2].fX) < fabs(q2[0].fY - q2[2].fY);
+        if ((t = SkIntersections::Axial(q2, q1[0], useVertical)) >= 0) {
+            insertCoincident(0, t, q1[0]);
+        }
+        if ((t = SkIntersections::Axial(q2, q1[2], useVertical)) >= 0) {
+            insertCoincident(1, t, q1[2]);
+        }
+        SkASSERT(coincidentUsed() <= 2);
+        return fUsed;
+    }
+    int index;
+    bool useCubic = q1[0] == q2[0] || q1[0] == q2[2] || q1[2] == q2[0];
+    double roots1[4];
+    int rootCount = findRoots(i2, q1, roots1, useCubic, 0);
+    // OPTIMIZATION: could short circuit here if all roots are < 0 or > 1
+    double roots1Copy[4];
+    int r1Count = addValidRoots(roots1, rootCount, roots1Copy);
+    SkDPoint pts1[4];
+    for (index = 0; index < r1Count; ++index) {
+        pts1[index] = q1.xyAtT(roots1Copy[index]);
+    }
+    double roots2[4];
+    int rootCount2 = findRoots(i1, q2, roots2, useCubic, 0);
+    double roots2Copy[4];
+    int r2Count = addValidRoots(roots2, rootCount2, roots2Copy);
+    SkDPoint pts2[4];
+    for (index = 0; index < r2Count; ++index) {
+        pts2[index] = q2.xyAtT(roots2Copy[index]);
+    }
+    if (r1Count == r2Count && r1Count <= 1) {
+        if (r1Count == 1) {
+            if (pts1[0].approximatelyEqualHalf(pts2[0])) {
+                insert(roots1Copy[0], roots2Copy[0], pts1[0]);
+            } else if (pts1[0].moreRoughlyEqual(pts2[0])) {
+                // experiment: try to find intersection by chasing t
+                rootCount = findRoots(i2, q1, roots1, useCubic, 0);
+                (void) addValidRoots(roots1, rootCount, roots1Copy);
+                rootCount2 = findRoots(i1, q2, roots2, useCubic, 0);
+                (void) addValidRoots(roots2, rootCount2, roots2Copy);
+                if (binary_search(q1, q2, roots1Copy, roots2Copy, pts1)) {
+                    insert(roots1Copy[0], roots2Copy[0], pts1[0]);
+                }
+            }
+        }
+        return fUsed;
+    }
+    int closest[4];
+    double dist[4];
+    bool foundSomething = false;
+    for (index = 0; index < r1Count; ++index) {
+        dist[index] = DBL_MAX;
+        closest[index] = -1;
+        for (int ndex2 = 0; ndex2 < r2Count; ++ndex2) {
+            if (!pts2[ndex2].approximatelyEqualHalf(pts1[index])) {
+                continue;
+            }
+            double dx = pts2[ndex2].fX - pts1[index].fX;
+            double dy = pts2[ndex2].fY - pts1[index].fY;
+            double distance = dx * dx + dy * dy;
+            if (dist[index] <= distance) {
+                continue;
+            }
+            for (int outer = 0; outer < index; ++outer) {
+                if (closest[outer] != ndex2) {
+                    continue;
+                }
+                if (dist[outer] < distance) {
+                    goto next;
+                }
+                closest[outer] = -1;
+            }
+            dist[index] = distance;
+            closest[index] = ndex2;
+            foundSomething = true;
+        next:
+            ;
+        }
+    }
+    if (r1Count && r2Count && !foundSomething) {
+        relaxed_is_linear(q1, q2, this);
+        return fUsed;
+    }
+    int used = 0;
+    do {
+        double lowest = DBL_MAX;
+        int lowestIndex = -1;
+        for (index = 0; index < r1Count; ++index) {
+            if (closest[index] < 0) {
+                continue;
+            }
+            if (roots1Copy[index] < lowest) {
+                lowestIndex = index;
+                lowest = roots1Copy[index];
+            }
+        }
+        if (lowestIndex < 0) {
+            break;
+        }
+        insert(roots1Copy[lowestIndex], roots2Copy[closest[lowestIndex]],
+                pts1[lowestIndex]);
+        closest[lowestIndex] = -1;
+    } while (++used < r1Count);
+    return fUsed;
+}
diff --git a/src/pathops/SkDQuadLineIntersection.cpp b/src/pathops/SkDQuadLineIntersection.cpp
new file mode 100644
index 0000000..e7e77e6
--- /dev/null
+++ b/src/pathops/SkDQuadLineIntersection.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkIntersections.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsQuad.h"
+
+/*
+Find the interection of a line and quadratic by solving for valid t values.
+
+From http://stackoverflow.com/questions/1853637/how-to-find-the-mathematical-function-defining-a-bezier-curve
+
+"A Bezier curve is a parametric function. A quadratic Bezier curve (i.e. three
+control points) can be expressed as: F(t) = A(1 - t)^2 + B(1 - t)t + Ct^2 where
+A, B and C are points and t goes from zero to one.
+
+This will give you two equations:
+
+  x = a(1 - t)^2 + b(1 - t)t + ct^2
+  y = d(1 - t)^2 + e(1 - t)t + ft^2
+
+If you add for instance the line equation (y = kx + m) to that, you'll end up
+with three equations and three unknowns (x, y and t)."
+
+Similar to above, the quadratic is represented as
+  x = a(1-t)^2 + 2b(1-t)t + ct^2
+  y = d(1-t)^2 + 2e(1-t)t + ft^2
+and the line as
+  y = g*x + h
+
+Using Mathematica, solve for the values of t where the quadratic intersects the
+line:
+
+  (in)  t1 = Resultant[a*(1 - t)^2 + 2*b*(1 - t)*t + c*t^2 - x,
+                       d*(1 - t)^2 + 2*e*(1 - t)*t  + f*t^2 - g*x - h, x]
+  (out) -d + h + 2 d t - 2 e t - d t^2 + 2 e t^2 - f t^2 +
+         g  (a - 2 a t + 2 b t + a t^2 - 2 b t^2 + c t^2)
+  (in)  Solve[t1 == 0, t]
+  (out) {
+    {t -> (-2 d + 2 e +   2 a g - 2 b g    -
+      Sqrt[(2 d - 2 e -   2 a g + 2 b g)^2 -
+          4 (-d + 2 e - f + a g - 2 b g    + c g) (-d + a g + h)]) /
+         (2 (-d + 2 e - f + a g - 2 b g    + c g))
+         },
+    {t -> (-2 d + 2 e +   2 a g - 2 b g    +
+      Sqrt[(2 d - 2 e -   2 a g + 2 b g)^2 -
+          4 (-d + 2 e - f + a g - 2 b g    + c g) (-d + a g + h)]) /
+         (2 (-d + 2 e - f + a g - 2 b g    + c g))
+         }
+        }
+
+Using the results above (when the line tends towards horizontal)
+       A =   (-(d - 2*e + f) + g*(a - 2*b + c)     )
+       B = 2*( (d -   e    ) - g*(a -   b    )     )
+       C =   (-(d          ) + g*(a          ) + h )
+
+If g goes to infinity, we can rewrite the line in terms of x.
+  x = g'*y + h'
+
+And solve accordingly in Mathematica:
+
+  (in)  t2 = Resultant[a*(1 - t)^2 + 2*b*(1 - t)*t + c*t^2 - g'*y - h',
+                       d*(1 - t)^2 + 2*e*(1 - t)*t  + f*t^2 - y, y]
+  (out)  a - h' - 2 a t + 2 b t + a t^2 - 2 b t^2 + c t^2 -
+         g'  (d - 2 d t + 2 e t + d t^2 - 2 e t^2 + f t^2)
+  (in)  Solve[t2 == 0, t]
+  (out) {
+    {t -> (2 a - 2 b -   2 d g' + 2 e g'    -
+    Sqrt[(-2 a + 2 b +   2 d g' - 2 e g')^2 -
+          4 (a - 2 b + c - d g' + 2 e g' - f g') (a - d g' - h')]) /
+         (2 (a - 2 b + c - d g' + 2 e g' - f g'))
+         },
+    {t -> (2 a - 2 b -   2 d g' + 2 e g'    +
+    Sqrt[(-2 a + 2 b +   2 d g' - 2 e g')^2 -
+          4 (a - 2 b + c - d g' + 2 e g' - f g') (a - d g' - h')])/
+         (2 (a - 2 b + c - d g' + 2 e g' - f g'))
+         }
+        }
+
+Thus, if the slope of the line tends towards vertical, we use:
+       A =   ( (a - 2*b + c) - g'*(d  - 2*e + f)      )
+       B = 2*(-(a -   b    ) + g'*(d  -   e    )      )
+       C =   ( (a          ) - g'*(d           ) - h' )
+ */
+
+
+class LineQuadraticIntersections {
+public:
+    LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersections* i)
+        : quad(q)
+        , line(l)
+        , intersections(i) {
+    }
+
+    int intersectRay(double roots[2]) {
+    /*
+        solve by rotating line+quad so line is horizontal, then finding the roots
+        set up matrix to rotate quad to x-axis
+        |cos(a) -sin(a)|
+        |sin(a)  cos(a)|
+        note that cos(a) = A(djacent) / Hypoteneuse
+                  sin(a) = O(pposite) / Hypoteneuse
+        since we are computing Ts, we can ignore hypoteneuse, the scale factor:
+        |  A     -O    |
+        |  O      A    |
+        A = line[1].fX - line[0].fX (adjacent side of the right triangle)
+        O = line[1].fY - line[0].fY (opposite side of the right triangle)
+        for each of the three points (e.g. n = 0 to 2)
+        quad[n].fY' = (quad[n].fY - line[0].fY) * A - (quad[n].fX - line[0].fX) * O
+    */
+        double adj = line[1].fX - line[0].fX;
+        double opp = line[1].fY - line[0].fY;
+        double r[3];
+        for (int n = 0; n < 3; ++n) {
+            r[n] = (quad[n].fY - line[0].fY) * adj - (quad[n].fX - line[0].fX) * opp;
+        }
+        double A = r[2];
+        double B = r[1];
+        double C = r[0];
+        A += C - 2 * B;  // A = a - 2*b + c
+        B -= C;  // B = -(b - c)
+        return SkDQuad::RootsValidT(A, 2 * B, C, roots);
+    }
+
+    int intersect() {
+        addEndPoints();
+        double rootVals[2];
+        int roots = intersectRay(rootVals);
+        for (int index = 0; index < roots; ++index) {
+            double quadT = rootVals[index];
+            double lineT = findLineT(quadT);
+            if (PinTs(&quadT, &lineT)) {
+                SkDPoint pt = line.xyAtT(lineT);
+                intersections->insert(quadT, lineT, pt);
+            }
+        }
+        return intersections->used();
+    }
+
+    int horizontalIntersect(double axisIntercept, double roots[2]) {
+        double D = quad[2].fY;  // f
+        double E = quad[1].fY;  // e
+        double F = quad[0].fY;  // d
+        D += F - 2 * E;         // D = d - 2*e + f
+        E -= F;                 // E = -(d - e)
+        F -= axisIntercept;
+        return SkDQuad::RootsValidT(D, 2 * E, F, roots);
+    }
+
+    int horizontalIntersect(double axisIntercept, double left, double right, bool flipped) {
+        addHorizontalEndPoints(left, right, axisIntercept);
+        double rootVals[2];
+        int roots = horizontalIntersect(axisIntercept, rootVals);
+        for (int index = 0; index < roots; ++index) {
+            double quadT = rootVals[index];
+            SkDPoint pt = quad.xyAtT(quadT);
+            double lineT = (pt.fX - left) / (right - left);
+            if (PinTs(&quadT, &lineT)) {
+                intersections->insert(quadT, lineT, pt);
+            }
+        }
+        if (flipped) {
+            intersections->flip();
+        }
+        return intersections->used();
+    }
+
+    int verticalIntersect(double axisIntercept, double roots[2]) {
+        double D = quad[2].fX;  // f
+        double E = quad[1].fX;  // e
+        double F = quad[0].fX;  // d
+        D += F - 2 * E;         // D = d - 2*e + f
+        E -= F;                 // E = -(d - e)
+        F -= axisIntercept;
+        return SkDQuad::RootsValidT(D, 2 * E, F, roots);
+    }
+
+    int verticalIntersect(double axisIntercept, double top, double bottom, bool flipped) {
+        addVerticalEndPoints(top, bottom, axisIntercept);
+        double rootVals[2];
+        int roots = verticalIntersect(axisIntercept, rootVals);
+        for (int index = 0; index < roots; ++index) {
+            double quadT = rootVals[index];
+            SkDPoint pt = quad.xyAtT(quadT);
+            double lineT = (pt.fY - top) / (bottom - top);
+            if (PinTs(&quadT, &lineT)) {
+                intersections->insert(quadT, lineT, pt);
+            }
+        }
+        if (flipped) {
+            intersections->flip();
+        }
+        return intersections->used();
+    }
+
+protected:
+    // add endpoints first to get zero and one t values exactly
+    void addEndPoints() {
+        for (int qIndex = 0; qIndex < 3; qIndex += 2) {
+            for (int lIndex = 0; lIndex < 2; lIndex++) {
+                if (quad[qIndex] == line[lIndex]) {
+                    intersections->insert(qIndex >> 1, lIndex, line[lIndex]);
+                }
+            }
+        }
+    }
+
+    void addHorizontalEndPoints(double left, double right, double y) {
+        for (int qIndex = 0; qIndex < 3; qIndex += 2) {
+            if (quad[qIndex].fY != y) {
+                continue;
+            }
+            if (quad[qIndex].fX == left) {
+                intersections->insert(qIndex >> 1, 0, quad[qIndex]);
+            }
+            if (quad[qIndex].fX == right) {
+                intersections->insert(qIndex >> 1, 1, quad[qIndex]);
+            }
+        }
+    }
+
+    void addVerticalEndPoints(double top, double bottom, double x) {
+        for (int qIndex = 0; qIndex < 3; qIndex += 2) {
+            if (quad[qIndex].fX != x) {
+                continue;
+            }
+            if (quad[qIndex].fY == top) {
+                intersections->insert(qIndex >> 1, 0, quad[qIndex]);
+            }
+            if (quad[qIndex].fY == bottom) {
+                intersections->insert(qIndex >> 1, 1, quad[qIndex]);
+            }
+        }
+    }
+
+    double findLineT(double t) {
+        SkDPoint xy = quad.xyAtT(t);
+        double dx = line[1].fX - line[0].fX;
+        double dy = line[1].fY - line[0].fY;
+        if (fabs(dx) > fabs(dy)) {
+            return (xy.fX - line[0].fX) / dx;
+        }
+        return (xy.fY - line[0].fY) / dy;
+    }
+
+    static bool PinTs(double* quadT, double* lineT) {
+        if (!approximately_one_or_less(*lineT)) {
+            return false;
+        }
+        if (!approximately_zero_or_more(*lineT)) {
+            return false;
+        }
+        if (precisely_less_than_zero(*quadT)) {
+            *quadT = 0;
+        } else if (precisely_greater_than_one(*quadT)) {
+            *quadT = 1;
+        }
+        if (precisely_less_than_zero(*lineT)) {
+            *lineT = 0;
+        } else if (precisely_greater_than_one(*lineT)) {
+            *lineT = 1;
+        }
+        return true;
+    }
+
+private:
+    const SkDQuad& quad;
+    const SkDLine& line;
+    SkIntersections* intersections;
+};
+
+// utility for pairs of coincident quads
+static double horizontalIntersect(const SkDQuad& quad, const SkDPoint& pt) {
+    LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)),
+            static_cast<SkIntersections*>(0));
+    double rootVals[2];
+    int roots = q.horizontalIntersect(pt.fY, rootVals);
+    for (int index = 0; index < roots; ++index) {
+        double t = rootVals[index];
+        SkDPoint qPt = quad.xyAtT(t);
+        if (AlmostEqualUlps(qPt.fX, pt.fX)) {
+            return t;
+        }
+    }
+    return -1;
+}
+
+static double verticalIntersect(const SkDQuad& quad, const SkDPoint& pt) {
+    LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)),
+            static_cast<SkIntersections*>(0));
+    double rootVals[2];
+    int roots = q.verticalIntersect(pt.fX, rootVals);
+    for (int index = 0; index < roots; ++index) {
+        double t = rootVals[index];
+        SkDPoint qPt = quad.xyAtT(t);
+        if (AlmostEqualUlps(qPt.fY, pt.fY)) {
+            return t;
+        }
+    }
+    return -1;
+}
+
+double SkIntersections::Axial(const SkDQuad& q1, const SkDPoint& p, bool vertical) {
+    if (vertical) {
+        return verticalIntersect(q1, p);
+    }
+    return horizontalIntersect(q1, p);
+}
+
+int SkIntersections::horizontal(const SkDQuad& quad, double left, double right, double y,
+                                bool flipped) {
+    LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), this);
+    return q.horizontalIntersect(y, left, right, flipped);
+}
+
+int SkIntersections::vertical(const SkDQuad& quad, double top, double bottom, double x,
+                              bool flipped) {
+    LineQuadraticIntersections q(quad, *(static_cast<SkDLine*>(0)), this);
+    return q.verticalIntersect(x, top, bottom, flipped);
+}
+
+int SkIntersections::intersect(const SkDQuad& quad, const SkDLine& line) {
+    LineQuadraticIntersections q(quad, line, this);
+    return q.intersect();
+}
+
+int SkIntersections::intersectRay(const SkDQuad& quad, const SkDLine& line) {
+    LineQuadraticIntersections q(quad, line, this);
+    return q.intersectRay(fT[0]);
+}
diff --git a/src/pathops/SkIntersectionHelper.h b/src/pathops/SkIntersectionHelper.h
new file mode 100644
index 0000000..5d8ebcd
--- /dev/null
+++ b/src/pathops/SkIntersectionHelper.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkOpContour.h"
+#include "SkPath.h"
+
+class SkIntersectionHelper {
+public:
+    enum SegmentType {
+        kHorizontalLine_Segment = -1,
+        kVerticalLine_Segment = 0,
+        kLine_Segment = SkPath::kLine_Verb,
+        kQuad_Segment = SkPath::kQuad_Verb,
+        kCubic_Segment = SkPath::kCubic_Verb,
+    };
+
+    void addCoincident(SkIntersectionHelper& other, const SkIntersections& ts, bool swap) {
+        fContour->addCoincident(fIndex, other.fContour, other.fIndex, ts, swap);
+    }
+
+    // FIXME: does it make sense to write otherIndex now if we're going to
+    // fix it up later?
+    void addOtherT(int index, double otherT, int otherIndex) {
+        fContour->addOtherT(fIndex, index, otherT, otherIndex);
+    }
+
+    // Avoid collapsing t values that are close to the same since
+    // we walk ts to describe consecutive intersections. Since a pair of ts can
+    // be nearly equal, any problems caused by this should be taken care
+    // of later.
+    // On the edge or out of range values are negative; add 2 to get end
+    int addT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) {
+        return fContour->addT(fIndex, other.fContour, other.fIndex, pt, newT);
+    }
+
+    int addSelfT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) {
+        return fContour->addSelfT(fIndex, other.fContour, other.fIndex, pt, newT);
+    }
+
+    int addUnsortableT(const SkIntersectionHelper& other, bool start, const SkPoint& pt,
+                       double newT) {
+        return fContour->addUnsortableT(fIndex, other.fContour, other.fIndex, start, pt, newT);
+    }
+
+    bool advance() {
+        return ++fIndex < fLast;
+    }
+
+    SkScalar bottom() const {
+        return bounds().fBottom;
+    }
+
+    const SkPathOpsBounds& bounds() const {
+        return fContour->segments()[fIndex].bounds();
+    }
+
+    void init(SkOpContour* contour) {
+        fContour = contour;
+        fIndex = 0;
+        fLast = contour->segments().count();
+    }
+
+    bool isAdjacent(const SkIntersectionHelper& next) {
+        return fContour == next.fContour && fIndex + 1 == next.fIndex;
+    }
+
+    bool isFirstLast(const SkIntersectionHelper& next) {
+        return fContour == next.fContour && fIndex == 0
+                && next.fIndex == fLast - 1;
+    }
+
+    SkScalar left() const {
+        return bounds().fLeft;
+    }
+
+    const SkPoint* pts() const {
+        return fContour->segments()[fIndex].pts();
+    }
+
+    SkScalar right() const {
+        return bounds().fRight;
+    }
+
+    SegmentType segmentType() const {
+        const SkOpSegment& segment = fContour->segments()[fIndex];
+        SegmentType type = (SegmentType) segment.verb();
+        if (type != kLine_Segment) {
+            return type;
+        }
+        if (segment.isHorizontal()) {
+            return kHorizontalLine_Segment;
+        }
+        if (segment.isVertical()) {
+            return kVerticalLine_Segment;
+        }
+        return kLine_Segment;
+    }
+
+    bool startAfter(const SkIntersectionHelper& after) {
+        fIndex = after.fIndex;
+        return advance();
+    }
+
+    SkScalar top() const {
+        return bounds().fTop;
+    }
+
+    SkPath::Verb verb() const {
+        return fContour->segments()[fIndex].verb();
+    }
+
+    SkScalar x() const {
+        return bounds().fLeft;
+    }
+
+    bool xFlipped() const {
+        return x() != pts()[0].fX;
+    }
+
+    SkScalar y() const {
+        return bounds().fTop;
+    }
+
+    bool yFlipped() const {
+        return y() != pts()[0].fY;
+    }
+
+private:
+    SkOpContour* fContour;
+    int fIndex;
+    int fLast;
+};
diff --git a/src/pathops/SkIntersections.cpp b/src/pathops/SkIntersections.cpp
new file mode 100644
index 0000000..205308f
--- /dev/null
+++ b/src/pathops/SkIntersections.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkIntersections.h"
+
+int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar, SkScalar, SkScalar, bool) = {
+    NULL,
+    &SkIntersections::verticalLine,
+    &SkIntersections::verticalQuad,
+    &SkIntersections::verticalCubic
+};
+
+int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine&) = {
+    NULL,
+    NULL,
+    &SkIntersections::quadRay,
+    &SkIntersections::cubicRay
+};
+
+int SkIntersections::coincidentUsed() const {
+    if (!fIsCoincident[0]) {
+        SkASSERT(!fIsCoincident[0]);
+        return 0;
+    }
+    int count = 0;
+    SkDEBUGCODE(int count2 = 0;)
+    for (int index = 0; index < fUsed; ++index) {
+        if (fIsCoincident[0] & (1 << index)) {
+            ++count;
+        }
+#ifdef SK_DEBUG
+        if (fIsCoincident[1] & (1 << index)) {
+            ++count2;
+        }
+#endif
+    }
+    SkASSERT(count == count2);
+    return count;
+}
+
+int SkIntersections::cubicRay(const SkPoint pts[4], const SkDLine& line) {
+    SkDCubic cubic;
+    cubic.set(pts);
+    return intersectRay(cubic, line);
+}
+
+void SkIntersections::flip() {
+    for (int index = 0; index < fUsed; ++index) {
+        fT[1][index] = 1 - fT[1][index];
+    }
+}
+
+void SkIntersections::insertCoincidentPair(double s1, double e1, double s2, double e2,
+        const SkDPoint& startPt, const SkDPoint& endPt) {
+    if (fSwap) {
+        remove(s2, e2, startPt, endPt);
+    } else {
+        remove(s1, e1, startPt, endPt);
+    }
+    SkASSERT(coincidentUsed() == fUsed);
+    SkASSERT((coincidentUsed() & 1) != 1);
+    int i1 = 0;
+    int i2 = 0;
+    do {
+        while (i1 < fUsed && !(fIsCoincident[fSwap] & (1 << i1))) {
+            ++i1;
+        }
+        if (i1 == fUsed) {
+            break;
+        }
+        SkASSERT(i1 < fUsed);
+        int iEnd1 = i1 + 1;
+        while (!(fIsCoincident[fSwap] & (1 << iEnd1))) {
+            ++iEnd1;
+        }
+        SkASSERT(iEnd1 < fUsed);
+        double cs1 = fT[fSwap][i1];
+        double ce1 = fT[fSwap][iEnd1];
+        bool s1in = between(cs1, s1, ce1) || startPt.approximatelyEqual(fPt[i1])
+                || startPt.approximatelyEqual(fPt[iEnd1]);
+        bool e1in = between(cs1, e1, ce1) || endPt.approximatelyEqual(fPt[i1])
+                || endPt.approximatelyEqual(fPt[iEnd1]);
+        while (i2 < fUsed && !(fIsCoincident[fSwap ^ 1] & (1 << i2))) {
+            ++i2;
+        }
+        int iEnd2 = i2 + 1;
+        while (!(fIsCoincident[fSwap ^ 1] & (1 << iEnd2))) {
+            ++iEnd2;
+        }
+        SkASSERT(iEnd2 < fUsed);
+        double cs2 = fT[fSwap ^ 1][i2];
+        double ce2 = fT[fSwap ^ 1][iEnd2];
+        bool s2in = between(cs2, s2, ce2) || startPt.approximatelyEqual(fPt[i2])
+                || startPt.approximatelyEqual(fPt[iEnd2]);
+        bool e2in = between(cs2, e2, ce2) || endPt.approximatelyEqual(fPt[i2])
+                || endPt.approximatelyEqual(fPt[iEnd2]);
+        if ((s1in | e1in) & (s2in | e2in)) {
+            if (s1 < cs1) {
+                fT[fSwap][i1] = s1;
+                fPt[i1] = startPt;
+            } else if (e1 < cs1) {
+                fT[fSwap][i1] = e1;
+                fPt[i1] = endPt;
+            }
+            if (s1 > ce1) {
+                fT[fSwap][iEnd1] = s1;
+                fPt[iEnd1] = startPt;
+            } else if (e1 > ce1) {
+                fT[fSwap][iEnd1] = e1;
+                fPt[iEnd1] = endPt;
+            }
+            if (s2 > e2) {
+                SkTSwap(cs2, ce2);
+                SkTSwap(i2, iEnd2);
+            }
+            if (s2 < cs2) {
+                fT[fSwap ^ 1][i2] = s2;
+            } else if (e2 < cs2) {
+                fT[fSwap ^ 1][i2] = e2;
+            }
+            if (s2 > ce2) {
+                fT[fSwap ^ 1][iEnd2] = s2;
+            } else if (e2 > ce2) {
+                fT[fSwap ^ 1][iEnd2] = e2;
+            }
+            return;
+        }
+    } while (true);
+    SkASSERT(fUsed < 9);
+    insertCoincident(s1, s2, startPt);
+    insertCoincident(e1, e2, endPt);
+}
+
+int SkIntersections::insert(double one, double two, const SkDPoint& pt) {
+    SkASSERT(fUsed <= 1 || fT[0][0] <= fT[0][1]);
+    int index;
+    for (index = 0; index < fUsed; ++index) {
+        double oldOne = fT[0][index];
+        double oldTwo = fT[1][index];
+        if (roughly_equal(oldOne, one) && roughly_equal(oldTwo, two)) {
+            if ((precisely_zero(one) && !precisely_zero(oldOne))
+                    || (precisely_equal(one, 1) && !precisely_equal(oldOne, 1))
+                    || (precisely_zero(two) && !precisely_zero(oldTwo))
+                    || (precisely_equal(two, 1) && !precisely_equal(oldTwo, 1))) {
+                fT[0][index] = one;
+                fT[1][index] = two;
+                fPt[index] = pt;
+            }
+            return -1;
+        }
+    #if ONE_OFF_DEBUG
+        if (pt.roughlyEqual(fPt[index])) {
+            SkDebugf("%s t=%1.9g pts roughly equal\n", __FUNCTION__, one);
+        }
+    #endif
+        if (fT[0][index] > one) {
+            break;
+        }
+    }
+    SkASSERT(fUsed < 9);
+    int remaining = fUsed - index;
+    if (remaining > 0) {
+        memmove(&fPt[index + 1], &fPt[index], sizeof(fPt[0]) * remaining);
+        memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining);
+        memmove(&fT[1][index + 1], &fT[1][index], sizeof(fT[1][0]) * remaining);
+        fIsCoincident[0] += fIsCoincident[0] & ~((1 << index) - 1);
+        fIsCoincident[1] += fIsCoincident[1] & ~((1 << index) - 1);
+    }
+    fPt[index] = pt;
+    fT[0][index] = one;
+    fT[1][index] = two;
+    ++fUsed;
+    return index;
+}
+
+void SkIntersections::insertCoincident(double one, double two, const SkDPoint& pt) {
+    int index = insertSwap(one, two, pt);
+    int bit = 1 << index;
+    fIsCoincident[0] |= bit;
+    fIsCoincident[1] |= bit;
+}
+
+void SkIntersections::offset(int base, double start, double end) {
+    for (int index = base; index < fUsed; ++index) {
+        double val = fT[fSwap][index];
+        val *= end - start;
+        val += start;
+        fT[fSwap][index] = val;
+    }
+}
+
+int SkIntersections::quadRay(const SkPoint pts[3], const SkDLine& line) {
+    SkDQuad quad;
+    quad.set(pts);
+    return intersectRay(quad, line);
+}
+
+void SkIntersections::quickRemoveOne(int index, int replace) {
+    if (index < replace) {
+        fT[0][index] = fT[0][replace];
+    }
+}
+
+void SkIntersections::remove(double one, double two, const SkDPoint& startPt,
+        const SkDPoint& endPt) {
+    for (int index = fUsed - 1; index >= 0; --index) {
+        if (!(fIsCoincident[0] & (1 << index)) && (between(one, fT[fSwap][index], two)
+                || startPt.approximatelyEqual(fPt[index])
+                || endPt.approximatelyEqual(fPt[index]))) {
+            SkASSERT(fUsed > 0);
+            removeOne(index);
+        }
+    }
+}
+
+void SkIntersections::removeOne(int index) {
+    int remaining = --fUsed - index;
+    if (remaining <= 0) {
+        return;
+    }
+    memmove(&fPt[index], &fPt[index + 1], sizeof(fPt[0]) * remaining);
+    memmove(&fT[0][index], &fT[0][index + 1], sizeof(fT[0][0]) * remaining);
+    memmove(&fT[1][index], &fT[1][index + 1], sizeof(fT[1][0]) * remaining);
+    SkASSERT(fIsCoincident[0] == 0);
+    int coBit = fIsCoincident[0] & (1 << index);
+    fIsCoincident[0] -= ((fIsCoincident[0] >> 1) & ~((1 << index) - 1)) + coBit;
+    SkASSERT(!(coBit ^ (fIsCoincident[1] & (1 << index))));
+    fIsCoincident[1] -= ((fIsCoincident[1] >> 1) & ~((1 << index) - 1)) + coBit;
+}
+
+void SkIntersections::swapPts() {
+    int index;
+    for (index = 0; index < fUsed; ++index) {
+        SkTSwap(fT[0][index], fT[1][index]);
+    }
+}
+
+int SkIntersections::verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom,
+        SkScalar x, bool flipped) {
+    SkDLine line;
+    line.set(a);
+    return vertical(line, top, bottom, x, flipped);
+}
+
+int SkIntersections::verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bottom,
+        SkScalar x, bool flipped) {
+    SkDQuad quad;
+    quad.set(a);
+    return vertical(quad, top, bottom, x, flipped);
+}
+
+int SkIntersections::verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bottom,
+        SkScalar x, bool flipped) {
+    SkDCubic cubic;
+    cubic.set(a);
+    return vertical(cubic, top, bottom, x, flipped);
+}
diff --git a/src/pathops/SkIntersections.h b/src/pathops/SkIntersections.h
new file mode 100644
index 0000000..c2f05fe
--- /dev/null
+++ b/src/pathops/SkIntersections.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkIntersections_DEFINE
+#define SkIntersections_DEFINE
+
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsPoint.h"
+#include "SkPathOpsQuad.h"
+
+class SkIntersections {
+public:
+    SkIntersections()
+        : fSwap(0)
+#ifdef SK_DEBUG
+        , fDepth(0)
+#endif
+    {
+        sk_bzero(fPt, sizeof(fPt));
+        sk_bzero(fT, sizeof(fT));
+        sk_bzero(fIsCoincident, sizeof(fIsCoincident));
+        reset();
+    }
+
+    class TArray {
+    public:
+        explicit TArray(const double ts[9]) : fTArray(ts) {}
+        double operator[](int n) const {
+            return fTArray[n];
+        }
+        const double* fTArray;
+    };
+    TArray operator[](int n) const { return TArray(fT[n]); }
+
+    int cubic(const SkPoint a[4]) {
+        SkDCubic cubic;
+        cubic.set(a);
+        return intersect(cubic);
+    }
+
+    int cubicCubic(const SkPoint a[4], const SkPoint b[4]) {
+        SkDCubic aCubic;
+        aCubic.set(a);
+        SkDCubic bCubic;
+        bCubic.set(b);
+        return intersect(aCubic, bCubic);
+    }
+
+    int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkScalar y,
+                        bool flipped) {
+        SkDCubic cubic;
+        cubic.set(a);
+        return horizontal(cubic, left, right, y, flipped);
+    }
+
+    int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
+        SkDCubic cubic;
+        cubic.set(a);
+        return vertical(cubic, top, bottom, x, flipped);
+    }
+
+    int cubicLine(const SkPoint a[4], const SkPoint b[2]) {
+        SkDCubic cubic;
+        cubic.set(a);
+        SkDLine line;
+        line.set(b);
+        return intersect(cubic, line);
+    }
+
+    int cubicQuad(const SkPoint a[4], const SkPoint b[3]) {
+        SkDCubic cubic;
+        cubic.set(a);
+        SkDQuad quad;
+        quad.set(b);
+        return intersect(cubic, quad);
+    }
+
+    int insertSwap(double one, double two, const SkDPoint& pt) {
+        if (fSwap) {
+            return insert(two, one, pt);
+        } else {
+            return insert(one, two, pt);
+        }
+    }
+
+    bool isCoincident(int index) {
+        return (fIsCoincident[0] & 1 << index) != 0;
+    }
+
+    int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScalar y,
+                       bool flipped) {
+        SkDLine line;
+        line.set(a);
+        return horizontal(line, left, right, y, flipped);
+    }
+
+    int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
+        SkDLine line;
+        line.set(a);
+        return vertical(line, top, bottom, x, flipped);
+    }
+
+    int lineLine(const SkPoint a[2], const SkPoint b[2]) {
+        SkDLine aLine, bLine;
+        aLine.set(a);
+        bLine.set(b);
+        return intersect(aLine, bLine);
+    }
+
+    const SkDPoint& pt(int index) const {
+        return fPt[index];
+    }
+
+    int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScalar y,
+                       bool flipped) {
+        SkDQuad quad;
+        quad.set(a);
+        return horizontal(quad, left, right, y, flipped);
+    }
+
+    int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
+        SkDQuad quad;
+        quad.set(a);
+        return vertical(quad, top, bottom, x, flipped);
+    }
+
+    int quadLine(const SkPoint a[3], const SkPoint b[2]) {
+        SkDQuad quad;
+        quad.set(a);
+        SkDLine line;
+        line.set(b);
+        return intersect(quad, line);
+    }
+
+    int quadQuad(const SkPoint a[3], const SkPoint b[3]) {
+        SkDQuad aQuad;
+        aQuad.set(a);
+        SkDQuad bQuad;
+        bQuad.set(b);
+        return intersect(aQuad, bQuad);
+    }
+
+    int quadRay(const SkPoint pts[3], const SkDLine& line);
+    void removeOne(int index);
+
+    // leaves flip, swap alone
+    void reset() {
+        fUsed = 0;
+    }
+
+    void swap() {
+        fSwap ^= true;
+    }
+
+    void swapPts();
+
+    bool swapped() const {
+        return fSwap;
+    }
+
+    int used() const {
+        return fUsed;
+    }
+
+    void downDepth() {
+        SkASSERT(--fDepth >= 0);
+    }
+
+    void upDepth() {
+        SkASSERT(++fDepth < 16);
+    }
+
+    static double Axial(const SkDQuad& , const SkDPoint& , bool vertical);
+    int coincidentUsed() const;
+    int cubicRay(const SkPoint pts[4], const SkDLine& line);
+    void flip();
+    int horizontal(const SkDLine&, double y);
+    int horizontal(const SkDLine&, double left, double right, double y);
+    int horizontal(const SkDLine&, double left, double right, double y, bool flipped);
+    int horizontal(const SkDQuad&, double left, double right, double y, bool flipped);
+    int horizontal(const SkDQuad&, double left, double right, double y, double tRange[2]);
+    int horizontal(const SkDCubic&, double y, double tRange[3]);
+    int horizontal(const SkDCubic&, double left, double right, double y, bool flipped);
+    int horizontal(const SkDCubic&, double left, double right, double y, double tRange[3]);
+    // FIXME : does not respect swap
+    int insert(double one, double two, const SkDPoint& pt);
+    // start if index == 0 : end if index == 1
+    void insertCoincident(double one, double two, const SkDPoint& pt);
+    void insertCoincidentPair(double s1, double e1, double s2, double e2,
+            const SkDPoint& startPt, const SkDPoint& endPt);
+    int intersect(const SkDLine&, const SkDLine&);
+    int intersect(const SkDQuad&, const SkDLine&);
+    int intersect(const SkDQuad&, const SkDQuad&);
+    int intersect(const SkDCubic&);  // return true if cubic self-intersects
+    int intersect(const SkDCubic&, const SkDLine&);
+    int intersect(const SkDCubic&, const SkDQuad&);
+    int intersect(const SkDCubic&, const SkDCubic&);
+    int intersectRay(const SkDCubic& , const SkDLine&);
+    int intersectRay(const SkDQuad& , const SkDLine&);
+    static SkDPoint Line(const SkDLine& , const SkDLine&);
+    void offset(int base, double start, double end);
+    void quickRemoveOne(int index, int replace);
+    static bool Test(const SkDLine& , const SkDLine&);
+    int vertical(const SkDLine&, double x);
+    int vertical(const SkDLine&, double top, double bottom, double x, bool flipped);
+    int vertical(const SkDQuad&, double top, double bottom, double x, bool flipped);
+    int vertical(const SkDCubic&, double top, double bottom, double x, bool flipped);
+    int verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
+    int verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
+    int verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
+
+    int depth() const {
+#ifdef SK_DEBUG
+        return fDepth;
+#else
+        return 0;
+#endif
+    }
+
+private:
+    int computePoints(const SkDLine& line, int used);
+    // used by addCoincident to remove ordinary intersections in range
+    void remove(double one, double two, const SkDPoint& startPt, const SkDPoint& endPt);
+
+    SkDPoint fPt[9];
+    double fT[2][9];
+    uint16_t fIsCoincident[2];  // bit arrays, one bit set for each coincident T
+    unsigned char fUsed;
+    bool fSwap;
+#ifdef SK_DEBUG
+    int fDepth;
+#endif
+};
+
+extern int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine& );
+extern int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar top, SkScalar bottom,
+            SkScalar x, bool flipped);
+
+#endif
diff --git a/src/pathops/SkLineParameters.h b/src/pathops/SkLineParameters.h
new file mode 100644
index 0000000..5139c6c
--- /dev/null
+++ b/src/pathops/SkLineParameters.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsQuad.h"
+
+// Sources
+// computer-aided design - volume 22 number 9 november 1990 pp 538 - 549
+// online at http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf
+
+// This turns a line segment into a parameterized line, of the form
+// ax + by + c = 0
+// When a^2 + b^2 == 1, the line is normalized.
+// The distance to the line for (x, y) is d(x,y) = ax + by + c
+//
+// Note that the distances below are not necessarily normalized. To get the true
+// distance, it's necessary to either call normalize() after xxxEndPoints(), or
+// divide the result of xxxDistance() by sqrt(normalSquared())
+
+class SkLineParameters {
+public:
+    void cubicEndPoints(const SkDCubic& pts) {
+        cubicEndPoints(pts, 0, 3);
+    }
+
+    void cubicEndPoints(const SkDCubic& pts, int s, int e) {
+        a = approximately_pin(pts[s].fY - pts[e].fY);
+        b = approximately_pin(pts[e].fX - pts[s].fX);
+        c = pts[s].fX * pts[e].fY - pts[e].fX * pts[s].fY;
+    }
+
+    void lineEndPoints(const SkDLine& pts) {
+        a = approximately_pin(pts[0].fY - pts[1].fY);
+        b = approximately_pin(pts[1].fX - pts[0].fX);
+        c = pts[0].fX * pts[1].fY - pts[1].fX * pts[0].fY;
+    }
+
+    void quadEndPoints(const SkDQuad& pts) {
+        quadEndPoints(pts, 0, 2);
+    }
+
+    void quadEndPoints(const SkDQuad& pts, int s, int e) {
+        a = approximately_pin(pts[s].fY - pts[e].fY);
+        b = approximately_pin(pts[e].fX - pts[s].fX);
+        c = pts[s].fX * pts[e].fY - pts[e].fX * pts[s].fY;
+    }
+
+    double normalSquared() const {
+        return a * a + b * b;
+    }
+
+    bool normalize() {
+        double normal = sqrt(normalSquared());
+        if (approximately_zero(normal)) {
+            a = b = c = 0;
+            return false;
+        }
+        double reciprocal = 1 / normal;
+        a *= reciprocal;
+        b *= reciprocal;
+        c *= reciprocal;
+        return true;
+    }
+
+    void cubicDistanceY(const SkDCubic& pts, SkDCubic& distance) const {
+        double oneThird = 1 / 3.0;
+        for (int index = 0; index < 4; ++index) {
+            distance[index].fX = index * oneThird;
+            distance[index].fY = a * pts[index].fX + b * pts[index].fY + c;
+        }
+    }
+
+    void quadDistanceY(const SkDQuad& pts, SkDQuad& distance) const {
+        double oneHalf = 1 / 2.0;
+        for (int index = 0; index < 3; ++index) {
+            distance[index].fX = index * oneHalf;
+            distance[index].fY = a * pts[index].fX + b * pts[index].fY + c;
+        }
+    }
+
+    double controlPtDistance(const SkDCubic& pts, int index) const {
+        SkASSERT(index == 1 || index == 2);
+        return a * pts[index].fX + b * pts[index].fY + c;
+    }
+
+    double controlPtDistance(const SkDQuad& pts) const {
+        return a * pts[1].fX + b * pts[1].fY + c;
+    }
+
+    double pointDistance(const SkDPoint& pt) const {
+        return a * pt.fX + b * pt.fY + c;
+    }
+
+    double dx() const {
+        return b;
+    }
+
+    double dy() const {
+        return -a;
+    }
+
+private:
+    double a;
+    double b;
+    double c;
+};
diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp
new file mode 100644
index 0000000..fd1e0f4
--- /dev/null
+++ b/src/pathops/SkOpAngle.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkIntersections.h"
+#include "SkOpAngle.h"
+#include "SkPathOpsCurve.h"
+
+// FIXME: this is bogus for quads and cubics
+// if the quads and cubics' line from end pt to ctrl pt are coincident,
+// there's no obvious way to determine the curve ordering from the
+// derivatives alone. In particular, if one quadratic's coincident tangent
+// is longer than the other curve, the final control point can place the
+// longer curve on either side of the shorter one.
+// Using Bezier curve focus http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf
+// may provide some help, but nothing has been figured out yet.
+
+/*(
+for quads and cubics, set up a parameterized line (e.g. LineParameters )
+for points [0] to [1]. See if point [2] is on that line, or on one side
+or the other. If it both quads' end points are on the same side, choose
+the shorter tangent. If the tangents are equal, choose the better second
+tangent angle
+
+maybe I could set up LineParameters lazily
+*/
+bool SkOpAngle::operator<(const SkOpAngle& rh) const {
+    double y = dy();
+    double ry = rh.dy();
+    if ((y < 0) ^ (ry < 0)) {  // OPTIMIZATION: better to use y * ry < 0 ?
+        return y < 0;
+    }
+    double x = dx();
+    double rx = rh.dx();
+    if (y == 0 && ry == 0 && x * rx < 0) {
+        return x < rx;
+    }
+    double x_ry = x * ry;
+    double rx_y = rx * y;
+    double cmp = x_ry - rx_y;
+    if (!approximately_zero(cmp)) {
+        return cmp < 0;
+    }
+    if (approximately_zero(x_ry) && approximately_zero(rx_y)
+            && !approximately_zero_squared(cmp)) {
+        return cmp < 0;
+    }
+    // at this point, the initial tangent line is coincident
+    // see if edges curl away from each other
+    if (fSide * rh.fSide <= 0 && (!approximately_zero(fSide)
+            || !approximately_zero(rh.fSide))) {
+        // FIXME: running demo will trigger this assertion
+        // (don't know if commenting out will trigger further assertion or not)
+        // commenting it out allows demo to run in release, though
+        return fSide < rh.fSide;
+    }
+    // see if either curve can be lengthened and try the tangent compare again
+    if (cmp && (*fSpans)[fEnd].fOther != rh.fSegment  // tangents not absolutely identical
+            && (*rh.fSpans)[rh.fEnd].fOther != fSegment) {  // and not intersecting
+        SkOpAngle longer = *this;
+        SkOpAngle rhLonger = rh;
+        if (longer.lengthen() | rhLonger.lengthen()) {
+            return longer < rhLonger;
+        }
+    }
+    if ((fVerb == SkPath::kLine_Verb && approximately_zero(x) && approximately_zero(y))
+            || (rh.fVerb == SkPath::kLine_Verb
+            && approximately_zero(rx) && approximately_zero(ry))) {
+        // See general unsortable comment below. This case can happen when
+        // one line has a non-zero change in t but no change in x and y.
+        fUnsortable = true;
+        rh.fUnsortable = true;
+        return this < &rh;  // even with no solution, return a stable sort
+    }
+    if ((*rh.fSpans)[SkMin32(rh.fStart, rh.fEnd)].fTiny
+            || (*fSpans)[SkMin32(fStart, fEnd)].fTiny) {
+        fUnsortable = true;
+        rh.fUnsortable = true;
+        return this < &rh;  // even with no solution, return a stable sort
+    }
+    SkASSERT(fVerb >= SkPath::kQuad_Verb);
+    SkASSERT(rh.fVerb >= SkPath::kQuad_Verb);
+    // FIXME: until I can think of something better, project a ray from the
+    // end of the shorter tangent to midway between the end points
+    // through both curves and use the resulting angle to sort
+    // FIXME: some of this setup can be moved to set() if it works, or cached if it's expensive
+    double len = fTangent1.normalSquared();
+    double rlen = rh.fTangent1.normalSquared();
+    SkDLine ray;
+    SkIntersections i, ri;
+    int roots, rroots;
+    bool flip = false;
+    do {
+        bool useThis = (len < rlen) ^ flip;
+        const SkDCubic& part = useThis ? fCurvePart : rh.fCurvePart;
+        SkPath::Verb partVerb = useThis ? fVerb : rh.fVerb;
+        ray[0] = partVerb == SkPath::kCubic_Verb && part[0].approximatelyEqual(part[1]) ?
+            part[2] : part[1];
+        ray[1].fX = (part[0].fX + part[partVerb].fX) / 2;
+        ray[1].fY = (part[0].fY + part[partVerb].fY) / 2;
+        SkASSERT(ray[0] != ray[1]);
+        roots = (i.*CurveRay[fVerb])(fPts, ray);
+        rroots = (ri.*CurveRay[rh.fVerb])(rh.fPts, ray);
+    } while ((roots == 0 || rroots == 0) && (flip ^= true));
+    if (roots == 0 || rroots == 0) {
+        // FIXME: we don't have a solution in this case. The interim solution
+        // is to mark the edges as unsortable, exclude them from this and
+        // future computations, and allow the returned path to be fragmented
+        fUnsortable = true;
+        rh.fUnsortable = true;
+        return this < &rh;  // even with no solution, return a stable sort
+    }
+    SkDPoint loc;
+    double best = SK_ScalarInfinity;
+    SkDVector dxy;
+    double dist;
+    int index;
+    for (index = 0; index < roots; ++index) {
+        loc = (*CurveDPointAtT[fVerb])(fPts, i[0][index]);
+        dxy = loc - ray[0];
+        dist = dxy.lengthSquared();
+        if (best > dist) {
+            best = dist;
+        }
+    }
+    for (index = 0; index < rroots; ++index) {
+        loc = (*CurveDPointAtT[rh.fVerb])(rh.fPts, ri[0][index]);
+        dxy = loc - ray[0];
+        dist = dxy.lengthSquared();
+        if (best > dist) {
+            return fSide < 0;
+        }
+    }
+    return fSide > 0;
+}
+
+bool SkOpAngle::lengthen() {
+    int newEnd = fEnd;
+    if (fStart < fEnd ? ++newEnd < fSpans->count() : --newEnd >= 0) {
+        fEnd = newEnd;
+        setSpans();
+        return true;
+    }
+    return false;
+}
+
+bool SkOpAngle::reverseLengthen() {
+    if (fReversed) {
+        return false;
+    }
+    int newEnd = fStart;
+    if (fStart > fEnd ? ++newEnd < fSpans->count() : --newEnd >= 0) {
+        fEnd = newEnd;
+        fReversed = true;
+        setSpans();
+        return true;
+    }
+    return false;
+}
+
+void SkOpAngle::set(const SkPoint* orig, SkPath::Verb verb, const SkOpSegment* segment,
+        int start, int end, const SkTDArray<SkOpSpan>& spans) {
+    fSegment = segment;
+    fStart = start;
+    fEnd = end;
+    fPts = orig;
+    fVerb = verb;
+    fSpans = &spans;
+    fReversed = false;
+    fUnsortable = false;
+    setSpans();
+}
+
+
+void SkOpAngle::setSpans() {
+    double startT = (*fSpans)[fStart].fT;
+    double endT = (*fSpans)[fEnd].fT;
+    switch (fVerb) {
+    case SkPath::kLine_Verb: {
+        SkDLine l = SkDLine::SubDivide(fPts, startT, endT);
+        // OPTIMIZATION: for pure line compares, we never need fTangent1.c
+        fTangent1.lineEndPoints(l);
+        fSide = 0;
+        } break;
+    case SkPath::kQuad_Verb: {
+        SkDQuad& quad = *SkTCast<SkDQuad*>(&fCurvePart);
+        quad = SkDQuad::SubDivide(fPts, startT, endT);
+        fTangent1.quadEndPoints(quad, 0, 1);
+        if (dx() == 0 && dy() == 0) {
+            fTangent1.quadEndPoints(quad);
+        }
+        fSide = -fTangent1.pointDistance(fCurvePart[2]);  // not normalized -- compare sign only
+        } break;
+    case SkPath::kCubic_Verb: {
+        int nextC = 2;
+        fCurvePart = SkDCubic::SubDivide(fPts, startT, endT);
+        fTangent1.cubicEndPoints(fCurvePart, 0, 1);
+        if (dx() == 0 && dy() == 0) {
+            fTangent1.cubicEndPoints(fCurvePart, 0, 2);
+            nextC = 3;
+            if (dx() == 0 && dy() == 0) {
+                fTangent1.cubicEndPoints(fCurvePart, 0, 3);
+            }
+        }
+        fSide = -fTangent1.pointDistance(fCurvePart[nextC]);  // compare sign only
+        if (nextC == 2 && approximately_zero(fSide)) {
+            fSide = -fTangent1.pointDistance(fCurvePart[3]);
+        }
+        } break;
+    default:
+        SkASSERT(0);
+    }
+    fUnsortable = dx() == 0 && dy() == 0;
+    if (fUnsortable) {
+        return;
+    }
+    SkASSERT(fStart != fEnd);
+    int step = fStart < fEnd ? 1 : -1;  // OPTIMIZE: worth fStart - fEnd >> 31 type macro?
+    for (int index = fStart; index != fEnd; index += step) {
+#if 1
+        const SkOpSpan& thisSpan = (*fSpans)[index];
+        const SkOpSpan& nextSpan = (*fSpans)[index + step];
+        if (thisSpan.fTiny || precisely_equal(thisSpan.fT, nextSpan.fT)) {
+            continue;
+        }
+        fUnsortable = step > 0 ? thisSpan.fUnsortableStart : nextSpan.fUnsortableEnd;
+#if DEBUG_UNSORTABLE
+        if (fUnsortable) {
+            SkPoint iPt = (*CurvePointAtT[fVerb])(fPts, thisSpan.fT);
+            SkPoint ePt = (*CurvePointAtT[fVerb])(fPts, nextSpan.fT);
+            SkDebugf("%s unsortable [%d] (%1.9g,%1.9g) [%d] (%1.9g,%1.9g)\n", __FUNCTION__,
+                    index, iPt.fX, iPt.fY, fEnd, ePt.fX, ePt.fY);
+        }
+#endif
+        return;
+#else
+        if ((*fSpans)[index].fUnsortableStart) {
+            fUnsortable = true;
+            return;
+        }
+#endif
+    }
+#if 1
+#if DEBUG_UNSORTABLE
+    SkPoint iPt = (*CurvePointAtT[fVerb])(fPts, startT);
+    SkPoint ePt = (*CurvePointAtT[fVerb])(fPts, endT);
+    SkDebugf("%s all tiny unsortable [%d] (%1.9g,%1.9g) [%d] (%1.9g,%1.9g)\n", __FUNCTION__,
+        fStart, iPt.fX, iPt.fY, fEnd, ePt.fX, ePt.fY);
+#endif
+    fUnsortable = true;
+#endif
+}
+
diff --git a/src/pathops/SkOpAngle.h b/src/pathops/SkOpAngle.h
new file mode 100644
index 0000000..d599dea
--- /dev/null
+++ b/src/pathops/SkOpAngle.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkOpAngle_DEFINED
+#define SkOpAngle_DEFINED
+
+#include "SkLineParameters.h"
+#include "SkOpSpan.h"
+#include "SkPath.h"
+#include "SkPathOpsCubic.h"
+#include "SkTDArray.h"
+
+// sorting angles
+// given angles of {dx dy ddx ddy dddx dddy} sort them
+class SkOpAngle {
+public:
+    bool operator<(const SkOpAngle& rh) const;
+    double dx() const {
+        return fTangent1.dx();
+    }
+
+    double dy() const {
+        return fTangent1.dy();
+    }
+
+    int end() const {
+        return fEnd;
+    }
+
+    bool isHorizontal() const {
+        return dy() == 0 && fVerb == SkPath::kLine_Verb;
+    }
+
+    bool lengthen();
+    bool reverseLengthen();
+    void set(const SkPoint* orig, SkPath::Verb verb, const SkOpSegment* segment,
+            int start, int end, const SkTDArray<SkOpSpan>& spans);
+
+    void setSpans();
+    SkOpSegment* segment() const {
+        return const_cast<SkOpSegment*>(fSegment);
+    }
+
+    int sign() const {
+        return SkSign32(fStart - fEnd);
+    }
+
+    const SkTDArray<SkOpSpan>* spans() const {
+        return fSpans;
+    }
+
+    int start() const {
+        return fStart;
+    }
+
+    bool unsortable() const {
+        return fUnsortable;
+    }
+
+#if DEBUG_ANGLE
+    const SkPoint* pts() const {
+        return fPts;
+    }
+
+    SkPath::Verb verb() const {
+        return fVerb;
+    }
+
+    void debugShow(const SkPoint& a) const {
+        SkDebugf("    d=(%1.9g,%1.9g) side=%1.9g\n", dx(), dy(), fSide);
+    }
+#endif
+
+private:
+    const SkPoint* fPts;
+    SkDCubic fCurvePart;
+    SkPath::Verb fVerb;
+    double fSide;
+    SkLineParameters fTangent1;
+    const SkTDArray<SkOpSpan>* fSpans;
+    const SkOpSegment* fSegment;
+    int fStart;
+    int fEnd;
+    bool fReversed;
+    mutable bool fUnsortable;  // this alone is editable by the less than operator
+};
+
+#endif
diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp
new file mode 100644
index 0000000..e68341c
--- /dev/null
+++ b/src/pathops/SkOpContour.cpp
@@ -0,0 +1,265 @@
+/*
+* Copyright 2013 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+#include "SkIntersections.h"
+#include "SkOpContour.h"
+#include "SkPathWriter.h"
+#include "TSearch.h"
+
+void SkOpContour::addCoincident(int index, SkOpContour* other, int otherIndex,
+        const SkIntersections& ts, bool swap) {
+    SkCoincidence& coincidence = *fCoincidences.append();
+    coincidence.fContours[0] = this;  // FIXME: no need to store
+    coincidence.fContours[1] = other;
+    coincidence.fSegments[0] = index;
+    coincidence.fSegments[1] = otherIndex;
+    coincidence.fTs[swap][0] = ts[0][0];
+    coincidence.fTs[swap][1] = ts[0][1];
+    coincidence.fTs[!swap][0] = ts[1][0];
+    coincidence.fTs[!swap][1] = ts[1][1];
+    coincidence.fPts[0] = ts.pt(0).asSkPoint();
+    coincidence.fPts[1] = ts.pt(1).asSkPoint();
+}
+
+SkOpSegment* SkOpContour::nonVerticalSegment(int* start, int* end) {
+    int segmentCount = fSortedSegments.count();
+    SkASSERT(segmentCount > 0);
+    for (int sortedIndex = fFirstSorted; sortedIndex < segmentCount; ++sortedIndex) {
+        SkOpSegment* testSegment = fSortedSegments[sortedIndex];
+        if (testSegment->done()) {
+            continue;
+        }
+        *start = *end = 0;
+        while (testSegment->nextCandidate(start, end)) {
+            if (!testSegment->isVertical(*start, *end)) {
+                return testSegment;
+            }
+        }
+    }
+    return NULL;
+}
+
+// first pass, add missing T values
+// second pass, determine winding values of overlaps
+void SkOpContour::addCoincidentPoints() {
+    int count = fCoincidences.count();
+    for (int index = 0; index < count; ++index) {
+        SkCoincidence& coincidence = fCoincidences[index];
+        SkASSERT(coincidence.fContours[0] == this);
+        int thisIndex = coincidence.fSegments[0];
+        SkOpSegment& thisOne = fSegments[thisIndex];
+        SkOpContour* otherContour = coincidence.fContours[1];
+        int otherIndex = coincidence.fSegments[1];
+        SkOpSegment& other = otherContour->fSegments[otherIndex];
+        if ((thisOne.done() || other.done()) && thisOne.complete() && other.complete()) {
+            // OPTIMIZATION: remove from array
+            continue;
+        }
+    #if DEBUG_CONCIDENT
+        thisOne.debugShowTs();
+        other.debugShowTs();
+    #endif
+        double startT = coincidence.fTs[0][0];
+        double endT = coincidence.fTs[0][1];
+        bool cancelers;
+        if ((cancelers = startT > endT)) {
+            SkTSwap(startT, endT);
+            SkTSwap(coincidence.fPts[0], coincidence.fPts[1]);
+        }
+        SkASSERT(!approximately_negative(endT - startT));
+        double oStartT = coincidence.fTs[1][0];
+        double oEndT = coincidence.fTs[1][1];
+        if (oStartT > oEndT) {
+            SkTSwap<double>(oStartT, oEndT);
+            cancelers ^= true;
+        }
+        SkASSERT(!approximately_negative(oEndT - oStartT));
+        bool opp = fOperand ^ otherContour->fOperand;
+        if (cancelers && !opp) {
+            // make sure startT and endT have t entries
+            if (startT > 0 || oEndT < 1
+                    || thisOne.isMissing(startT) || other.isMissing(oEndT)) {
+                thisOne.addTPair(startT, &other, oEndT, true, coincidence.fPts[0]);
+            }
+            if (oStartT > 0 || endT < 1
+                    || thisOne.isMissing(endT) || other.isMissing(oStartT)) {
+                other.addTPair(oStartT, &thisOne, endT, true, coincidence.fPts[1]);
+            }
+        } else {
+            if (startT > 0 || oStartT > 0
+                    || thisOne.isMissing(startT) || other.isMissing(oStartT)) {
+                thisOne.addTPair(startT, &other, oStartT, true, coincidence.fPts[0]);
+            }
+            if (endT < 1 || oEndT < 1
+                    || thisOne.isMissing(endT) || other.isMissing(oEndT)) {
+                other.addTPair(oEndT, &thisOne, endT, true, coincidence.fPts[1]);
+            }
+        }
+    #if DEBUG_CONCIDENT
+        thisOne.debugShowTs();
+        other.debugShowTs();
+    #endif
+    }
+}
+
+void SkOpContour::calcCoincidentWinding() {
+    int count = fCoincidences.count();
+    for (int index = 0; index < count; ++index) {
+        SkCoincidence& coincidence = fCoincidences[index];
+        SkASSERT(coincidence.fContours[0] == this);
+        int thisIndex = coincidence.fSegments[0];
+        SkOpSegment& thisOne = fSegments[thisIndex];
+        if (thisOne.done()) {
+            continue;
+        }
+        SkOpContour* otherContour = coincidence.fContours[1];
+        int otherIndex = coincidence.fSegments[1];
+        SkOpSegment& other = otherContour->fSegments[otherIndex];
+        if (other.done()) {
+            continue;
+        }
+        double startT = coincidence.fTs[0][0];
+        double endT = coincidence.fTs[0][1];
+        bool cancelers;
+        if ((cancelers = startT > endT)) {
+            SkTSwap<double>(startT, endT);
+        }
+        SkASSERT(!approximately_negative(endT - startT));
+        double oStartT = coincidence.fTs[1][0];
+        double oEndT = coincidence.fTs[1][1];
+        if (oStartT > oEndT) {
+            SkTSwap<double>(oStartT, oEndT);
+            cancelers ^= true;
+        }
+        SkASSERT(!approximately_negative(oEndT - oStartT));
+        bool opp = fOperand ^ otherContour->fOperand;
+        if (cancelers && !opp) {
+            // make sure startT and endT have t entries
+            if (!thisOne.done() && !other.done()) {
+                thisOne.addTCancel(startT, endT, &other, oStartT, oEndT);
+            }
+        } else {
+            if (!thisOne.done() && !other.done()) {
+                thisOne.addTCoincident(startT, endT, &other, oStartT, oEndT);
+            }
+        }
+    #if DEBUG_CONCIDENT
+        thisOne.debugShowTs();
+        other.debugShowTs();
+    #endif
+    }
+}
+
+void SkOpContour::sortSegments() {
+    int segmentCount = fSegments.count();
+    fSortedSegments.setReserve(segmentCount);
+    for (int test = 0; test < segmentCount; ++test) {
+        *fSortedSegments.append() = &fSegments[test];
+    }
+    QSort<SkOpSegment>(fSortedSegments.begin(), fSortedSegments.end() - 1);
+    fFirstSorted = 0;
+}
+
+void SkOpContour::toPath(SkPathWriter* path) const {
+    int segmentCount = fSegments.count();
+    const SkPoint& pt = fSegments.front().pts()[0];
+    path->deferredMove(pt);
+    for (int test = 0; test < segmentCount; ++test) {
+        fSegments[test].addCurveTo(0, 1, path, true);
+    }
+    path->close();
+}
+
+void SkOpContour::topSortableSegment(const SkPoint& topLeft, SkPoint* bestXY,
+        SkOpSegment** topStart) {
+    int segmentCount = fSortedSegments.count();
+    SkASSERT(segmentCount > 0);
+    int sortedIndex = fFirstSorted;
+    fDone = true;  // may be cleared below
+    for ( ; sortedIndex < segmentCount; ++sortedIndex) {
+        SkOpSegment* testSegment = fSortedSegments[sortedIndex];
+        if (testSegment->done()) {
+            if (sortedIndex == fFirstSorted) {
+                ++fFirstSorted;
+            }
+            continue;
+        }
+        fDone = false;
+        SkPoint testXY = testSegment->activeLeftTop(true, NULL);
+        if (*topStart) {
+            if (testXY.fY < topLeft.fY) {
+                continue;
+            }
+            if (testXY.fY == topLeft.fY && testXY.fX < topLeft.fX) {
+                continue;
+            }
+            if (bestXY->fY < testXY.fY) {
+                continue;
+            }
+            if (bestXY->fY == testXY.fY && bestXY->fX < testXY.fX) {
+                continue;
+            }
+        }
+        *topStart = testSegment;
+        *bestXY = testXY;
+    }
+}
+
+SkOpSegment* SkOpContour::undoneSegment(int* start, int* end) {
+    int segmentCount = fSegments.count();
+    for (int test = 0; test < segmentCount; ++test) {
+        SkOpSegment* testSegment = &fSegments[test];
+        if (testSegment->done()) {
+            continue;
+        }
+        testSegment->undoneSpan(start, end);
+        return testSegment;
+    }
+    return NULL;
+}
+
+#if DEBUG_SHOW_WINDING
+int SkOpContour::debugShowWindingValues(int totalSegments, int ofInterest) {
+    int count = fSegments.count();
+    int sum = 0;
+    for (int index = 0; index < count; ++index) {
+        sum += fSegments[index].debugShowWindingValues(totalSegments, ofInterest);
+    }
+//      SkDebugf("%s sum=%d\n", __FUNCTION__, sum);
+    return sum;
+}
+
+static void SkOpContour::debugShowWindingValues(const SkTDArray<SkOpContour*>& contourList) {
+//     int ofInterest = 1 << 1 | 1 << 5 | 1 << 9 | 1 << 13;
+//    int ofInterest = 1 << 4 | 1 << 8 | 1 << 12 | 1 << 16;
+    int ofInterest = 1 << 5 | 1 << 8;
+    int total = 0;
+    int index;
+    for (index = 0; index < contourList.count(); ++index) {
+        total += contourList[index]->segments().count();
+    }
+    int sum = 0;
+    for (index = 0; index < contourList.count(); ++index) {
+        sum += contourList[index]->debugShowWindingValues(total, ofInterest);
+    }
+//       SkDebugf("%s total=%d\n", __FUNCTION__, sum);
+}
+#endif
+
+void SkOpContour::setBounds() {
+    int count = fSegments.count();
+    if (count == 0) {
+        SkDebugf("%s empty contour\n", __FUNCTION__);
+        SkASSERT(0);
+        // FIXME: delete empty contour?
+        return;
+    }
+    fBounds = fSegments.front().bounds();
+    for (int index = 1; index < count; ++index) {
+        fBounds.add(fSegments[index].bounds());
+    }
+}
+
diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h
new file mode 100644
index 0000000..2f1c481
--- /dev/null
+++ b/src/pathops/SkOpContour.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkOpContour_DEFINED
+#define SkOpContour_DEFINED
+
+#include "SkOpSegment.h"
+#include "SkTArray.h"
+
+class SkIntersections;
+class SkOpContour;
+class SkPathWriter;
+
+struct SkCoincidence {
+    SkOpContour* fContours[2];
+    int fSegments[2];
+    double fTs[2][2];
+    SkPoint fPts[2];
+};
+
+class SkOpContour {
+public:
+    SkOpContour() {
+        reset();
+#if DEBUG_DUMP
+        fID = ++gContourID;
+#endif
+    }
+
+    bool operator<(const SkOpContour& rh) const {
+        return fBounds.fTop == rh.fBounds.fTop
+                ? fBounds.fLeft < rh.fBounds.fLeft
+                : fBounds.fTop < rh.fBounds.fTop;
+    }
+
+    void addCoincident(int index, SkOpContour* other, int otherIndex,
+                       const SkIntersections& ts, bool swap);
+    void addCoincidentPoints();
+
+    void addCross(const SkOpContour* crosser) {
+#ifdef DEBUG_CROSS
+        for (int index = 0; index < fCrosses.count(); ++index) {
+            SkASSERT(fCrosses[index] != crosser);
+        }
+#endif
+        *fCrosses.append() = crosser;
+    }
+
+    void addCubic(const SkPoint pts[4]) {
+        fSegments.push_back().addCubic(pts, fOperand, fXor);
+        fContainsCurves = fContainsCubics = true;
+    }
+
+    int addLine(const SkPoint pts[2]) {
+        fSegments.push_back().addLine(pts, fOperand, fXor);
+        return fSegments.count();
+    }
+
+    void addOtherT(int segIndex, int tIndex, double otherT, int otherIndex) {
+        fSegments[segIndex].addOtherT(tIndex, otherT, otherIndex);
+    }
+
+    int addQuad(const SkPoint pts[3]) {
+        fSegments.push_back().addQuad(pts, fOperand, fXor);
+        fContainsCurves = true;
+        return fSegments.count();
+    }
+
+    int addT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) {
+        setContainsIntercepts();
+        return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT);
+    }
+
+    int addSelfT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) {
+        setContainsIntercepts();
+        return fSegments[segIndex].addSelfT(&other->fSegments[otherIndex], pt, newT);
+    }
+
+    int addUnsortableT(int segIndex, SkOpContour* other, int otherIndex, bool start,
+                       const SkPoint& pt, double newT) {
+        return fSegments[segIndex].addUnsortableT(&other->fSegments[otherIndex], start, pt, newT);
+    }
+
+    const SkPathOpsBounds& bounds() const {
+        return fBounds;
+    }
+
+    void calcCoincidentWinding();
+
+    void complete() {
+        setBounds();
+        fContainsIntercepts = false;
+    }
+
+    bool containsCubics() const {
+        return fContainsCubics;
+    }
+
+    bool crosses(const SkOpContour* crosser) const {
+        for (int index = 0; index < fCrosses.count(); ++index) {
+            if (fCrosses[index] == crosser) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    bool done() const {
+        return fDone;
+    }
+
+    const SkPoint& end() const {
+        const SkOpSegment& segment = fSegments.back();
+        return segment.pts()[segment.verb()];
+    }
+
+    void findTooCloseToCall() {
+        int segmentCount = fSegments.count();
+        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
+            fSegments[sIndex].findTooCloseToCall();
+        }
+    }
+
+    void fixOtherTIndex() {
+        int segmentCount = fSegments.count();
+        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
+            fSegments[sIndex].fixOtherTIndex();
+        }
+    }
+
+    SkOpSegment* nonVerticalSegment(int* start, int* end);
+    
+    bool operand() const {
+        return fOperand;
+    }
+
+    void reset() {
+        fSegments.reset();
+        fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax);
+        fContainsCurves = fContainsCubics = fContainsIntercepts = fDone = false;
+    }
+
+    SkTArray<SkOpSegment>& segments() {
+        return fSegments;
+    }
+
+    void setContainsIntercepts() {
+        fContainsIntercepts = true;
+    }
+
+    void setOperand(bool isOp) {
+        fOperand = isOp;
+    }
+
+    void setOppXor(bool isOppXor) {
+        fOppXor = isOppXor;
+        int segmentCount = fSegments.count();
+        for (int test = 0; test < segmentCount; ++test) {
+            fSegments[test].setOppXor(isOppXor);
+        }
+    }
+
+    void setXor(bool isXor) {
+        fXor = isXor;
+    }
+
+    void sortSegments();
+    
+    const SkPoint& start() const {
+        return fSegments.front().pts()[0];
+    }
+    
+    void toPath(SkPathWriter* path) const;
+    
+    void toPartialBackward(SkPathWriter* path) const {
+        int segmentCount = fSegments.count();
+        for (int test = segmentCount - 1; test >= 0; --test) {
+            fSegments[test].addCurveTo(1, 0, path, true);
+        }
+    }
+
+    void toPartialForward(SkPathWriter* path) const {
+        int segmentCount = fSegments.count();
+        for (int test = 0; test < segmentCount; ++test) {
+            fSegments[test].addCurveTo(0, 1, path, true);
+        }
+    }
+
+    void topSortableSegment(const SkPoint& topLeft, SkPoint* bestXY, SkOpSegment** topStart);
+    SkOpSegment* undoneSegment(int* start, int* end);
+
+    int updateSegment(int index, const SkPoint* pts) {
+        SkOpSegment& segment = fSegments[index];
+        segment.updatePts(pts);
+        return segment.verb() + 1;
+    }
+
+#if DEBUG_TEST
+    SkTArray<SkOpSegment>& debugSegments() {
+        return fSegments;
+    }
+#endif
+
+#if DEBUG_ACTIVE_SPANS
+    void debugShowActiveSpans() {
+        for (int index = 0; index < fSegments.count(); ++index) {
+            fSegments[index].debugShowActiveSpans();
+        }
+    }
+#endif
+
+#if DEBUG_SHOW_WINDING
+    int debugShowWindingValues(int totalSegments, int ofInterest);
+    static void debugShowWindingValues(const SkTDArray<SkOpContour*>& contourList);
+#endif
+
+private:
+    void setBounds();
+
+    SkTArray<SkOpSegment> fSegments;
+    SkTDArray<SkOpSegment*> fSortedSegments;
+    int fFirstSorted;
+    SkTDArray<SkCoincidence> fCoincidences;
+    SkTDArray<const SkOpContour*> fCrosses;
+    SkPathOpsBounds fBounds;
+    bool fContainsIntercepts;  // FIXME: is this used by anybody?
+    bool fContainsCubics;
+    bool fContainsCurves;
+    bool fDone;
+    bool fOperand;  // true for the second argument to a binary operator
+    bool fXor;
+    bool fOppXor;
+#if DEBUG_DUMP
+    int fID;
+#endif
+};
+
+#endif
diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp
new file mode 100644
index 0000000..56e7c20
--- /dev/null
+++ b/src/pathops/SkOpEdgeBuilder.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkOpEdgeBuilder.h"
+#include "SkReduceOrder.h"
+
+void SkOpEdgeBuilder::init() {
+    fCurrentContour = NULL;
+    fOperand = false;
+    fXorMask[0] = fXorMask[1] = (fPath->getFillType() & 1) ? kEvenOdd_PathOpsMask
+            : kWinding_PathOpsMask;
+#if DEBUG_DUMP
+    gContourID = 0;
+    gSegmentID = 0;
+#endif
+    fSecondHalf = preFetch();
+}
+
+void SkOpEdgeBuilder::addOperand(const SkPath& path) {
+    SkASSERT(fPathVerbs.count() > 0 && fPathVerbs.end()[-1] == SkPath::kDone_Verb);
+    fPathVerbs.pop();
+    fPath = &path;
+    fXorMask[1] = (fPath->getFillType() & 1) ? kEvenOdd_PathOpsMask
+            : kWinding_PathOpsMask;
+    preFetch();
+}
+
+void SkOpEdgeBuilder::finish() {
+    walk();
+    complete();
+    if (fCurrentContour && !fCurrentContour->segments().count()) {
+        fContours.pop_back();
+    }
+    // correct pointers in contours since fReducePts may have moved as it grew
+    int cIndex = 0;
+    int extraCount = fExtra.count();
+    SkASSERT(extraCount == 0 || fExtra[0] == -1);
+    int eIndex = 0;
+    int rIndex = 0;
+    while (++eIndex < extraCount) {
+        int offset = fExtra[eIndex];
+        if (offset < 0) {
+            ++cIndex;
+            continue;
+        }
+        fCurrentContour = &fContours[cIndex];
+        rIndex += fCurrentContour->updateSegment(offset - 1,
+                &fReducePts[rIndex]);
+    }
+    fExtra.reset();  // we're done with this
+}
+
+// FIXME:remove once we can access path pts directly
+int SkOpEdgeBuilder::preFetch() {
+    SkPath::RawIter iter(*fPath);  // FIXME: access path directly when allowed
+    SkPoint pts[4];
+    SkPath::Verb verb;
+    do {
+        verb = iter.next(pts);
+        *fPathVerbs.append() = verb;
+        if (verb == SkPath::kMove_Verb) {
+            *fPathPts.append() = pts[0];
+        } else if (verb >= SkPath::kLine_Verb && verb <= SkPath::kCubic_Verb) {
+            fPathPts.append(verb, &pts[1]);
+        }
+    } while (verb != SkPath::kDone_Verb);
+    return fPathVerbs.count() - 1;
+}
+
+void SkOpEdgeBuilder::walk() {
+    SkPath::Verb reducedVerb;
+    uint8_t* verbPtr = fPathVerbs.begin();
+    uint8_t* endOfFirstHalf = &verbPtr[fSecondHalf];
+    const SkPoint* pointsPtr = fPathPts.begin();
+    const SkPoint* finalCurveStart = NULL;
+    const SkPoint* finalCurveEnd = NULL;
+    SkPath::Verb verb;
+    while ((verb = (SkPath::Verb) *verbPtr++) != SkPath::kDone_Verb) {
+        switch (verb) {
+            case SkPath::kMove_Verb:
+                complete();
+                if (!fCurrentContour) {
+                    fCurrentContour = fContours.push_back_n(1);
+                    fCurrentContour->setOperand(fOperand);
+                    fCurrentContour->setXor(fXorMask[fOperand] == kEvenOdd_PathOpsMask);
+                    *fExtra.append() = -1;  // start new contour
+                }
+                finalCurveEnd = pointsPtr++;
+                goto nextVerb;
+            case SkPath::kLine_Verb:
+                // skip degenerate points
+                if (pointsPtr[-1].fX != pointsPtr[0].fX || pointsPtr[-1].fY != pointsPtr[0].fY) {
+                    fCurrentContour->addLine(&pointsPtr[-1]);
+                }
+                break;
+            case SkPath::kQuad_Verb:
+                reducedVerb = SkReduceOrder::Quad(&pointsPtr[-1], &fReducePts);
+                if (reducedVerb == 0) {
+                    break;  // skip degenerate points
+                }
+                if (reducedVerb == 1) {
+                    *fExtra.append() =
+                            fCurrentContour->addLine(fReducePts.end() - 2);
+                    break;
+                }
+                fCurrentContour->addQuad(&pointsPtr[-1]);
+                break;
+            case SkPath::kCubic_Verb:
+                reducedVerb = SkReduceOrder::Cubic(&pointsPtr[-1], &fReducePts);
+                if (reducedVerb == 0) {
+                    break;  // skip degenerate points
+                }
+                if (reducedVerb == 1) {
+                    *fExtra.append() = fCurrentContour->addLine(fReducePts.end() - 2);
+                    break;
+                }
+                if (reducedVerb == 2) {
+                    *fExtra.append() = fCurrentContour->addQuad(fReducePts.end() - 3);
+                    break;
+                }
+                fCurrentContour->addCubic(&pointsPtr[-1]);
+                break;
+            case SkPath::kClose_Verb:
+                SkASSERT(fCurrentContour);
+                if (finalCurveStart && finalCurveEnd
+                        && *finalCurveStart != *finalCurveEnd) {
+                    *fReducePts.append() = *finalCurveStart;
+                    *fReducePts.append() = *finalCurveEnd;
+                    *fExtra.append() = fCurrentContour->addLine(fReducePts.end() - 2);
+                }
+                complete();
+                goto nextVerb;
+            default:
+                SkDEBUGFAIL("bad verb");
+                return;
+        }
+        finalCurveStart = &pointsPtr[verb - 1];
+        pointsPtr += verb;
+        SkASSERT(fCurrentContour);
+    nextVerb:
+        if (verbPtr == endOfFirstHalf) {
+            fOperand = true;
+        }
+    }
+}
diff --git a/src/pathops/SkOpEdgeBuilder.h b/src/pathops/SkOpEdgeBuilder.h
new file mode 100644
index 0000000..68afc93
--- /dev/null
+++ b/src/pathops/SkOpEdgeBuilder.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkOpEdgeBuilder_DEFINED
+#define SkOpEdgeBuilder_DEFINED
+
+#include "SkOpContour.h"
+#include "SkPathWriter.h"
+#include "SkTArray.h"
+#include "SkTDArray.h"
+
+class SkOpEdgeBuilder {
+public:
+    SkOpEdgeBuilder(const SkPathWriter& path, SkTArray<SkOpContour>& contours)
+        : fPath(path.nativePath())
+        , fContours(contours) {
+        init();
+    }
+
+    SkOpEdgeBuilder(const SkPath& path, SkTArray<SkOpContour>& contours)
+        : fPath(&path)
+        , fContours(contours) {
+        init();
+    }
+
+    void complete() {
+        if (fCurrentContour && fCurrentContour->segments().count()) {
+            fCurrentContour->complete();
+            fCurrentContour = NULL;
+        }
+    }
+
+    SkPathOpsMask xorMask() const {
+        return fXorMask[fOperand];
+    }
+
+    void addOperand(const SkPath& path);
+    void finish();
+    void init();
+
+private:
+    int preFetch();
+    void walk();
+
+    const SkPath* fPath;
+    SkTDArray<SkPoint> fPathPts;  // FIXME: point directly to path pts instead
+    SkTDArray<uint8_t> fPathVerbs;  // FIXME: remove
+    SkOpContour* fCurrentContour;
+    SkTArray<SkOpContour>& fContours;
+    SkTDArray<SkPoint> fReducePts;  // segments created on the fly
+    SkTDArray<int> fExtra;  // -1 marks new contour, > 0 offsets into contour
+    SkPathOpsMask fXorMask[2];
+    int fSecondHalf;
+    bool fOperand;
+};
+
+#endif
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
new file mode 100644
index 0000000..627b0af
--- /dev/null
+++ b/src/pathops/SkOpSegment.cpp
@@ -0,0 +1,2795 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkIntersections.h"
+#include "SkOpSegment.h"
+#include "SkPathWriter.h"
+#include "TSearch.h"
+
+#define F (false)      // discard the edge
+#define T (true)       // keep the edge
+
+static const bool gUnaryActiveEdge[2][2] = {
+//  from=0  from=1
+//  to=0,1  to=0,1
+    {F, T}, {T, F},
+};
+
+// FIXME: add support for kReverseDifference_Op
+static const bool gActiveEdge[kXOR_PathOp + 1][2][2][2][2] = {
+//                 miFrom=0                              miFrom=1
+//         miTo=0            miTo=1              miTo=0             miTo=1
+//    suFrom=0    1     suFrom=0     1      suFrom=0    1      suFrom=0    1
+//   suTo=0,1 suTo=0,1  suTo=0,1 suTo=0,1  suTo=0,1 suTo=0,1  suTo=0,1 suTo=0,1
+    {{{{F, F}, {F, F}}, {{T, F}, {T, F}}}, {{{T, T}, {F, F}}, {{F, T}, {T, F}}}},  // mi - su
+    {{{{F, F}, {F, F}}, {{F, T}, {F, T}}}, {{{F, F}, {T, T}}, {{F, T}, {T, F}}}},  // mi & su
+    {{{{F, T}, {T, F}}, {{T, T}, {F, F}}}, {{{T, F}, {T, F}}, {{F, F}, {F, F}}}},  // mi | su
+    {{{{F, T}, {T, F}}, {{T, F}, {F, T}}}, {{{T, F}, {F, T}}, {{F, T}, {T, F}}}},  // mi ^ su
+};
+
+#undef F
+#undef T
+
+// OPTIMIZATION: does the following also work, and is it any faster?
+// return outerWinding * innerWinding > 0
+//      || ((outerWinding + innerWinding < 0) ^ ((outerWinding - innerWinding) < 0)))
+bool SkOpSegment::UseInnerWinding(int outerWinding, int innerWinding) {
+    SkASSERT(outerWinding != SK_MaxS32);
+    SkASSERT(innerWinding != SK_MaxS32);
+    int absOut = abs(outerWinding);
+    int absIn = abs(innerWinding);
+    bool result = absOut == absIn ? outerWinding < 0 : absOut < absIn;
+    return result;
+}
+
+bool SkOpSegment::activeAngle(int index, int* done, SkTDArray<SkOpAngle>* angles) {
+    if (activeAngleInner(index, done, angles)) {
+        return true;
+    }
+    int lesser = index;
+    while (--lesser >= 0 && equalPoints(index, lesser)) {
+        if (activeAngleOther(lesser, done, angles)) {
+            return true;
+        }
+    }
+    lesser = index;
+    do {
+        if (activeAngleOther(index, done, angles)) {
+            return true;
+        }
+    } while (++index < fTs.count() && equalPoints(index, lesser));
+    return false;
+}
+
+bool SkOpSegment::activeAngleOther(int index, int* done, SkTDArray<SkOpAngle>* angles) {
+    SkOpSpan* span = &fTs[index];
+    SkOpSegment* other = span->fOther;
+    int oIndex = span->fOtherIndex;
+    return other->activeAngleInner(oIndex, done, angles);
+}
+
+bool SkOpSegment::activeAngleInner(int index, int* done, SkTDArray<SkOpAngle>* angles) {
+    int next = nextExactSpan(index, 1);
+    if (next > 0) {
+        SkOpSpan& upSpan = fTs[index];
+        if (upSpan.fWindValue || upSpan.fOppValue) {
+            addAngle(angles, index, next);
+            if (upSpan.fDone || upSpan.fUnsortableEnd) {
+                (*done)++;
+            } else if (upSpan.fWindSum != SK_MinS32) {
+                return true;
+            }
+        } else if (!upSpan.fDone) {
+            upSpan.fDone = true;
+            fDoneSpans++;
+        }
+    }
+    int prev = nextExactSpan(index, -1);
+    // edge leading into junction
+    if (prev >= 0) {
+        SkOpSpan& downSpan = fTs[prev];
+        if (downSpan.fWindValue || downSpan.fOppValue) {
+            addAngle(angles, index, prev);
+            if (downSpan.fDone) {
+                (*done)++;
+             } else if (downSpan.fWindSum != SK_MinS32) {
+                return true;
+            }
+        } else if (!downSpan.fDone) {
+            downSpan.fDone = true;
+            fDoneSpans++;
+        }
+    }
+    return false;
+}
+
+SkPoint SkOpSegment::activeLeftTop(bool onlySortable, int* firstT) const {
+    SkASSERT(!done());
+    SkPoint topPt = {SK_ScalarMax, SK_ScalarMax};
+    int count = fTs.count();
+    // see if either end is not done since we want smaller Y of the pair
+    bool lastDone = true;
+    bool lastUnsortable = false;
+    double lastT = -1;
+    for (int index = 0; index < count; ++index) {
+        const SkOpSpan& span = fTs[index];
+        if (onlySortable && (span.fUnsortableStart || lastUnsortable)) {
+            goto next;
+        }
+        if (span.fDone && lastDone) {
+            goto next;
+        }
+        if (approximately_negative(span.fT - lastT)) {
+            goto next;
+        }
+        {
+            const SkPoint& xy = xyAtT(&span);
+            if (topPt.fY > xy.fY || (topPt.fY == xy.fY && topPt.fX > xy.fX)) {
+                topPt = xy;
+                if (firstT) {
+                    *firstT = index;
+                }
+            }
+            if (fVerb != SkPath::kLine_Verb && !lastDone) {
+                SkPoint curveTop = (*CurveTop[fVerb])(fPts, lastT, span.fT);
+                if (topPt.fY > curveTop.fY || (topPt.fY == curveTop.fY
+                        && topPt.fX > curveTop.fX)) {
+                    topPt = curveTop;
+                    if (firstT) {
+                        *firstT = index;
+                    }
+                }
+            }
+            lastT = span.fT;
+        }
+next:
+        lastDone = span.fDone;
+        lastUnsortable = span.fUnsortableEnd;
+    }
+    return topPt;
+}
+
+bool SkOpSegment::activeOp(int index, int endIndex, int xorMiMask, int xorSuMask, SkPathOp op) {
+    int sumMiWinding = updateWinding(endIndex, index);
+    int sumSuWinding = updateOppWinding(endIndex, index);
+    if (fOperand) {
+        SkTSwap<int>(sumMiWinding, sumSuWinding);
+    }
+    int maxWinding, sumWinding, oppMaxWinding, oppSumWinding;
+    return activeOp(xorMiMask, xorSuMask, index, endIndex, op, &sumMiWinding, &sumSuWinding,
+            &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
+}
+
+bool SkOpSegment::activeOp(int xorMiMask, int xorSuMask, int index, int endIndex, SkPathOp op,
+        int* sumMiWinding, int* sumSuWinding,
+        int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding) {
+    setUpWindings(index, endIndex, sumMiWinding, sumSuWinding,
+            maxWinding, sumWinding, oppMaxWinding, oppSumWinding);
+    bool miFrom;
+    bool miTo;
+    bool suFrom;
+    bool suTo;
+    if (operand()) {
+        miFrom = (*oppMaxWinding & xorMiMask) != 0;
+        miTo = (*oppSumWinding & xorMiMask) != 0;
+        suFrom = (*maxWinding & xorSuMask) != 0;
+        suTo = (*sumWinding & xorSuMask) != 0;
+    } else {
+        miFrom = (*maxWinding & xorMiMask) != 0;
+        miTo = (*sumWinding & xorMiMask) != 0;
+        suFrom = (*oppMaxWinding & xorSuMask) != 0;
+        suTo = (*oppSumWinding & xorSuMask) != 0;
+    }
+    bool result = gActiveEdge[op][miFrom][miTo][suFrom][suTo];
+#if DEBUG_ACTIVE_OP
+    SkDebugf("%s op=%s miFrom=%d miTo=%d suFrom=%d suTo=%d result=%d\n", __FUNCTION__,
+            kPathOpStr[op], miFrom, miTo, suFrom, suTo, result);
+#endif
+    return result;
+}
+
+bool SkOpSegment::activeWinding(int index, int endIndex) {
+    int sumWinding = updateWinding(endIndex, index);
+    int maxWinding;
+    return activeWinding(index, endIndex, &maxWinding, &sumWinding);
+}
+
+bool SkOpSegment::activeWinding(int index, int endIndex, int* maxWinding, int* sumWinding) {
+    setUpWinding(index, endIndex, maxWinding, sumWinding);
+    bool from = *maxWinding != 0;
+    bool to = *sumWinding  != 0;
+    bool result = gUnaryActiveEdge[from][to];
+    return result;
+}
+
+void SkOpSegment::addAngle(SkTDArray<SkOpAngle>* anglesPtr, int start, int end) const {
+    SkASSERT(start != end);
+    SkOpAngle* angle = anglesPtr->append();
+#if DEBUG_ANGLE
+    SkTDArray<SkOpAngle>& angles = *anglesPtr;
+    if (angles.count() > 1 && !fTs[start].fTiny) {
+        SkPoint angle0Pt = (*CurvePointAtT[angles[0].verb()])(angles[0].pts(),
+                (*angles[0].spans())[angles[0].start()].fT);
+        SkPoint newPt = (*CurvePointAtT[fVerb])(fPts, fTs[start].fT);
+        SkASSERT(AlmostEqualUlps(angle0Pt.fX, newPt.fX));
+        SkASSERT(AlmostEqualUlps(angle0Pt.fY, newPt.fY));
+    }
+#endif
+    angle->set(fPts, fVerb, this, start, end, fTs);
+}
+
+void SkOpSegment::addCancelOutsides(double tStart, double oStart, SkOpSegment* other, double oEnd) {
+    int tIndex = -1;
+    int tCount = fTs.count();
+    int oIndex = -1;
+    int oCount = other->fTs.count();
+    do {
+        ++tIndex;
+    } while (!approximately_negative(tStart - fTs[tIndex].fT) && tIndex < tCount);
+    int tIndexStart = tIndex;
+    do {
+        ++oIndex;
+    } while (!approximately_negative(oStart - other->fTs[oIndex].fT) && oIndex < oCount);
+    int oIndexStart = oIndex;
+    double nextT;
+    do {
+        nextT = fTs[++tIndex].fT;
+    } while (nextT < 1 && approximately_negative(nextT - tStart));
+    double oNextT;
+    do {
+        oNextT = other->fTs[++oIndex].fT;
+    } while (oNextT < 1 && approximately_negative(oNextT - oStart));
+    // at this point, spans before and after are at:
+    //  fTs[tIndexStart - 1], fTs[tIndexStart], fTs[tIndex]
+    // if tIndexStart == 0, no prior span
+    // if nextT == 1, no following span
+
+    // advance the span with zero winding
+    // if the following span exists (not past the end, non-zero winding)
+    // connect the two edges
+    if (!fTs[tIndexStart].fWindValue) {
+        if (tIndexStart > 0 && fTs[tIndexStart - 1].fWindValue) {
+#if DEBUG_CONCIDENT
+            SkDebugf("%s 1 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
+                    __FUNCTION__, fID, other->fID, tIndexStart - 1,
+                    fTs[tIndexStart].fT, xyAtT(tIndexStart).fX,
+                    xyAtT(tIndexStart).fY);
+#endif
+            addTPair(fTs[tIndexStart].fT, other, other->fTs[oIndex].fT, false,
+                    fTs[tIndexStart].fPt);
+        }
+        if (nextT < 1 && fTs[tIndex].fWindValue) {
+#if DEBUG_CONCIDENT
+            SkDebugf("%s 2 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
+                    __FUNCTION__, fID, other->fID, tIndex,
+                    fTs[tIndex].fT, xyAtT(tIndex).fX,
+                    xyAtT(tIndex).fY);
+#endif
+            addTPair(fTs[tIndex].fT, other, other->fTs[oIndexStart].fT, false, fTs[tIndex].fPt);
+        }
+    } else {
+        SkASSERT(!other->fTs[oIndexStart].fWindValue);
+        if (oIndexStart > 0 && other->fTs[oIndexStart - 1].fWindValue) {
+#if DEBUG_CONCIDENT
+            SkDebugf("%s 3 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
+                    __FUNCTION__, fID, other->fID, oIndexStart - 1,
+                    other->fTs[oIndexStart].fT, other->xyAtT(oIndexStart).fX,
+                    other->xyAtT(oIndexStart).fY);
+            other->debugAddTPair(other->fTs[oIndexStart].fT, *this, fTs[tIndex].fT);
+#endif
+        }
+        if (oNextT < 1 && other->fTs[oIndex].fWindValue) {
+#if DEBUG_CONCIDENT
+            SkDebugf("%s 4 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n",
+                    __FUNCTION__, fID, other->fID, oIndex,
+                    other->fTs[oIndex].fT, other->xyAtT(oIndex).fX,
+                    other->xyAtT(oIndex).fY);
+            other->debugAddTPair(other->fTs[oIndex].fT, *this, fTs[tIndexStart].fT);
+#endif
+        }
+    }
+}
+
+void SkOpSegment::addCoinOutsides(const SkTDArray<double>& outsideTs, SkOpSegment* other,
+                                  double oEnd) {
+    // walk this to outsideTs[0]
+    // walk other to outsideTs[1]
+    // if either is > 0, add a pointer to the other, copying adjacent winding
+    int tIndex = -1;
+    int oIndex = -1;
+    double tStart = outsideTs[0];
+    double oStart = outsideTs[1];
+    do {
+        ++tIndex;
+    } while (!approximately_negative(tStart - fTs[tIndex].fT));
+    SkPoint ptStart = fTs[tIndex].fPt;
+    do {
+        ++oIndex;
+    } while (!approximately_negative(oStart - other->fTs[oIndex].fT));
+    if (tIndex > 0 || oIndex > 0 || fOperand != other->fOperand) {
+        addTPair(tStart, other, oStart, false, ptStart);
+    }
+    tStart = fTs[tIndex].fT;
+    oStart = other->fTs[oIndex].fT;
+    do {
+        double nextT;
+        do {
+            nextT = fTs[++tIndex].fT;
+        } while (approximately_negative(nextT - tStart));
+        tStart = nextT;
+        ptStart = fTs[tIndex].fPt;
+        do {
+            nextT = other->fTs[++oIndex].fT;
+        } while (approximately_negative(nextT - oStart));
+        oStart = nextT;
+        if (tStart == 1 && oStart == 1 && fOperand == other->fOperand) {
+            break;
+        }
+        addTPair(tStart, other, oStart, false, ptStart);
+    } while (tStart < 1 && oStart < 1 && !approximately_negative(oEnd - oStart));
+}
+
+void SkOpSegment::addCubic(const SkPoint pts[4], bool operand, bool evenOdd) {
+    init(pts, SkPath::kCubic_Verb, operand, evenOdd);
+    fBounds.setCubicBounds(pts);
+}
+
+void SkOpSegment::addCurveTo(int start, int end, SkPathWriter* path, bool active) const {
+    SkPoint edge[4];
+    const SkPoint* ePtr;
+    int lastT = fTs.count() - 1;
+    if (lastT < 0 || (start == 0 && end == lastT) || (start == lastT && end == 0)) {
+        ePtr = fPts;
+    } else {
+    // OPTIMIZE? if not active, skip remainder and return xyAtT(end)
+        subDivide(start, end, edge);
+        ePtr = edge;
+    }
+    if (active) {
+        bool reverse = ePtr == fPts && start != 0;
+        if (reverse) {
+            path->deferredMoveLine(ePtr[fVerb]);
+            switch (fVerb) {
+                case SkPath::kLine_Verb:
+                    path->deferredLine(ePtr[0]);
+                    break;
+                case SkPath::kQuad_Verb:
+                    path->quadTo(ePtr[1], ePtr[0]);
+                    break;
+                case SkPath::kCubic_Verb:
+                    path->cubicTo(ePtr[2], ePtr[1], ePtr[0]);
+                    break;
+                default:
+                    SkASSERT(0);
+            }
+   //         return ePtr[0];
+       } else {
+            path->deferredMoveLine(ePtr[0]);
+            switch (fVerb) {
+                case SkPath::kLine_Verb:
+                    path->deferredLine(ePtr[1]);
+                    break;
+                case SkPath::kQuad_Verb:
+                    path->quadTo(ePtr[1], ePtr[2]);
+                    break;
+                case SkPath::kCubic_Verb:
+                    path->cubicTo(ePtr[1], ePtr[2], ePtr[3]);
+                    break;
+                default:
+                    SkASSERT(0);
+            }
+        }
+    }
+  //  return ePtr[fVerb];
+}
+
+void SkOpSegment::addLine(const SkPoint pts[2], bool operand, bool evenOdd) {
+    init(pts, SkPath::kLine_Verb, operand, evenOdd);
+    fBounds.set(pts, 2);
+}
+
+// add 2 to edge or out of range values to get T extremes
+void SkOpSegment::addOtherT(int index, double otherT, int otherIndex) {
+    SkOpSpan& span = fTs[index];
+#if PIN_ADD_T
+    if (precisely_less_than_zero(otherT)) {
+        otherT = 0;
+    } else if (precisely_greater_than_one(otherT)) {
+        otherT = 1;
+    }
+#endif
+    span.fOtherT = otherT;
+    span.fOtherIndex = otherIndex;
+}
+
+void SkOpSegment::addQuad(const SkPoint pts[3], bool operand, bool evenOdd) {
+    init(pts, SkPath::kQuad_Verb, operand, evenOdd);
+    fBounds.setQuadBounds(pts);
+}
+
+    // Defer all coincident edge processing until
+    // after normal intersections have been computed
+
+// no need to be tricky; insert in normal T order
+// resolve overlapping ts when considering coincidence later
+
+    // add non-coincident intersection. Resulting edges are sorted in T.
+int SkOpSegment::addT(SkOpSegment* other, const SkPoint& pt, double newT) {
+    // FIXME: in the pathological case where there is a ton of intercepts,
+    //  binary search?
+    int insertedAt = -1;
+    size_t tCount = fTs.count();
+    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
+        // that all the edges are clockwise or counterclockwise.
+        // This could later limit segment tests to the two adjacent
+        // neighbors, although it doesn't help with determining which
+        // circular direction to go in.
+        if (newT < fTs[index].fT) {
+            insertedAt = index;
+            break;
+        }
+    }
+    SkOpSpan* span;
+    if (insertedAt >= 0) {
+        span = fTs.insert(insertedAt);
+    } else {
+        insertedAt = tCount;
+        span = fTs.append();
+    }
+    span->fT = newT;
+    span->fOther = other;
+    span->fPt = pt;
+    span->fWindSum = SK_MinS32;
+    span->fOppSum = SK_MinS32;
+    span->fWindValue = 1;
+    span->fOppValue = 0;
+    span->fTiny = false;
+    span->fLoop = false;
+    if ((span->fDone = newT == 1)) {
+        ++fDoneSpans;
+    }
+    span->fUnsortableStart = false;
+    span->fUnsortableEnd = false;
+    int less = -1;
+    while (&span[less + 1] - fTs.begin() > 0 && xyAtT(&span[less]) == xyAtT(span)) {
+        if (span[less].fDone) {
+            break;
+        }
+        double tInterval = newT - span[less].fT;
+        if (precisely_negative(tInterval)) {
+            break;
+        }
+        if (fVerb == SkPath::kCubic_Verb) {
+            double tMid = newT - tInterval / 2;
+            SkDPoint midPt = dcubic_xy_at_t(fPts, tMid);
+            if (!midPt.approximatelyEqual(xyAtT(span))) {
+                break;
+            }
+        }
+        span[less].fTiny = true;
+        span[less].fDone = true;
+        if (approximately_negative(newT - span[less].fT)) {
+            if (approximately_greater_than_one(newT)) {
+                SkASSERT(&span[less] - fTs.begin() < fTs.count());
+                span[less].fUnsortableStart = true;
+                if (&span[less - 1] - fTs.begin() >= 0) {
+                    span[less - 1].fUnsortableEnd = true;
+                }
+            }
+            if (approximately_less_than_zero(span[less].fT)) {
+                SkASSERT(&span[less + 1] - fTs.begin() < fTs.count());
+                SkASSERT(&span[less] - fTs.begin() >= 0);
+                span[less + 1].fUnsortableStart = true;
+                span[less].fUnsortableEnd = true;
+            }
+        }
+        ++fDoneSpans;
+        --less;
+    }
+    int more = 1;
+    while (fTs.end() - &span[more - 1] > 1 && xyAtT(&span[more]) == xyAtT(span)) {
+        if (span[more - 1].fDone) {
+            break;
+        }
+        double tEndInterval = span[more].fT - newT;
+        if (precisely_negative(tEndInterval)) {
+            break;
+        }
+        if (fVerb == SkPath::kCubic_Verb) {
+            double tMid = newT - tEndInterval / 2;
+            SkDPoint midEndPt = dcubic_xy_at_t(fPts, tMid);
+            if (!midEndPt.approximatelyEqual(xyAtT(span))) {
+                break;
+            }
+        }
+        span[more - 1].fTiny = true;
+        span[more - 1].fDone = true;
+        if (approximately_negative(span[more].fT - newT)) {
+            if (approximately_greater_than_one(span[more].fT)) {
+                span[more + 1].fUnsortableStart = true;
+                span[more].fUnsortableEnd = true;
+            }
+            if (approximately_less_than_zero(newT)) {
+                span[more].fUnsortableStart = true;
+                span[more - 1].fUnsortableEnd = true;
+            }
+        }
+        ++fDoneSpans;
+        ++more;
+    }
+    return insertedAt;
+}
+
+// set spans from start to end to decrement by one
+// note this walks other backwards
+// FIMXE: there's probably an edge case that can be constructed where
+// two span in one segment are separated by float epsilon on one span but
+// not the other, if one segment is very small. For this
+// case the counts asserted below may or may not be enough to separate the
+// spans. Even if the counts work out, what if the spans aren't correctly
+// sorted? It feels better in such a case to match the span's other span
+// pointer since both coincident segments must contain the same spans.
+void SkOpSegment::addTCancel(double startT, double endT, SkOpSegment* other,
+        double oStartT, double oEndT) {
+    SkASSERT(!approximately_negative(endT - startT));
+    SkASSERT(!approximately_negative(oEndT - oStartT));
+    bool binary = fOperand != other->fOperand;
+    int index = 0;
+    while (!approximately_negative(startT - fTs[index].fT)) {
+        ++index;
+    }
+    int oIndex = other->fTs.count();
+    while (approximately_positive(other->fTs[--oIndex].fT - oEndT))
+        ;
+    double tRatio = (oEndT - oStartT) / (endT - startT);
+    SkOpSpan* test = &fTs[index];
+    SkOpSpan* oTest = &other->fTs[oIndex];
+    SkTDArray<double> outsideTs;
+    SkTDArray<double> oOutsideTs;
+    do {
+        bool decrement = test->fWindValue && oTest->fWindValue && !binary;
+        bool track = test->fWindValue || oTest->fWindValue;
+        double testT = test->fT;
+        double oTestT = oTest->fT;
+        SkOpSpan* span = test;
+        do {
+            if (decrement) {
+                decrementSpan(span);
+            } else if (track && span->fT < 1 && oTestT < 1) {
+                TrackOutside(&outsideTs, span->fT, oTestT);
+            }
+            span = &fTs[++index];
+        } while (approximately_negative(span->fT - testT));
+        SkOpSpan* oSpan = oTest;
+        double otherTMatchStart = oEndT - (span->fT - startT) * tRatio;
+        double otherTMatchEnd = oEndT - (test->fT - startT) * tRatio;
+        SkDEBUGCODE(int originalWindValue = oSpan->fWindValue);
+        while (approximately_negative(otherTMatchStart - oSpan->fT)
+                && !approximately_negative(otherTMatchEnd - oSpan->fT)) {
+    #ifdef SK_DEBUG
+            SkASSERT(originalWindValue == oSpan->fWindValue);
+    #endif
+            if (decrement) {
+                other->decrementSpan(oSpan);
+            } else if (track && oSpan->fT < 1 && testT < 1) {
+                TrackOutside(&oOutsideTs, oSpan->fT, testT);
+            }
+            if (!oIndex) {
+                break;
+            }
+            oSpan = &other->fTs[--oIndex];
+        }
+        test = span;
+        oTest = oSpan;
+    } while (!approximately_negative(endT - test->fT));
+    SkASSERT(!oIndex || approximately_negative(oTest->fT - oStartT));
+    // FIXME: determine if canceled edges need outside ts added
+    if (!done() && outsideTs.count()) {
+        double tStart = outsideTs[0];
+        double oStart = outsideTs[1];
+        addCancelOutsides(tStart, oStart, other, oEndT);
+        int count = outsideTs.count();
+        if (count > 2) {
+            double tStart = outsideTs[count - 2];
+            double oStart = outsideTs[count - 1];
+            addCancelOutsides(tStart, oStart, other, oEndT);
+        }
+    }
+    if (!other->done() && oOutsideTs.count()) {
+        double tStart = oOutsideTs[0];
+        double oStart = oOutsideTs[1];
+        other->addCancelOutsides(tStart, oStart, this, endT);
+    }
+}
+
+int SkOpSegment::addSelfT(SkOpSegment* other, const SkPoint& pt, double newT) {
+    int result = addT(other, pt, newT);
+    SkOpSpan* span = &fTs[result];
+    span->fLoop = true;
+    return result;
+}
+
+int SkOpSegment::addUnsortableT(SkOpSegment* other, bool start, const SkPoint& pt, double newT) {
+    int result = addT(other, pt, newT);
+    SkOpSpan* span = &fTs[result];
+    if (start) {
+        if (result > 0) {
+            span[result - 1].fUnsortableEnd = true;
+        }
+        span[result].fUnsortableStart = true;
+    } else {
+        span[result].fUnsortableEnd = true;
+        if (result + 1 < fTs.count()) {
+            span[result + 1].fUnsortableStart = true;
+        }
+    }
+    return result;
+}
+
+int SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index,
+        SkTDArray<double>* outsideTs) {
+    int oWindValue = oTest.fWindValue;
+    int oOppValue = oTest.fOppValue;
+    if (opp) {
+        SkTSwap<int>(oWindValue, oOppValue);
+    }
+    SkOpSpan* const test = &fTs[index];
+    SkOpSpan* end = test;
+    const double oStartT = oTest.fT;
+    do {
+        if (bumpSpan(end, oWindValue, oOppValue)) {
+            TrackOutside(outsideTs, end->fT, oStartT);
+        }
+        end = &fTs[++index];
+    } while (approximately_negative(end->fT - test->fT));
+    return index;
+}
+
+// because of the order in which coincidences are resolved, this and other
+// may not have the same intermediate points. Compute the corresponding
+// intermediate T values (using this as the master, other as the follower)
+// and walk other conditionally -- hoping that it catches up in the end
+int SkOpSegment::bumpCoincidentOther(const SkOpSpan& test, double oEndT, int& oIndex,
+        SkTDArray<double>* oOutsideTs) {
+    SkOpSpan* const oTest = &fTs[oIndex];
+    SkOpSpan* oEnd = oTest;
+    const double startT = test.fT;
+    const double oStartT = oTest->fT;
+    while (!approximately_negative(oEndT - oEnd->fT)
+            && approximately_negative(oEnd->fT - oStartT)) {
+        zeroSpan(oEnd);
+        TrackOutside(oOutsideTs, oEnd->fT, startT);
+        oEnd = &fTs[++oIndex];
+    }
+    return oIndex;
+}
+
+// FIXME: need to test this case:
+// contourA has two segments that are coincident
+// contourB has two segments that are coincident in the same place
+// each ends up with +2/0 pairs for winding count
+// since logic below doesn't transfer count (only increments/decrements) can this be
+// resolved to +4/0 ?
+
+// set spans from start to end to increment the greater by one and decrement
+// the lesser
+void SkOpSegment::addTCoincident(double startT, double endT, SkOpSegment* other, double oStartT,
+                                 double oEndT) {
+    SkASSERT(!approximately_negative(endT - startT));
+    SkASSERT(!approximately_negative(oEndT - oStartT));
+    bool opp = fOperand ^ other->fOperand;
+    int index = 0;
+    while (!approximately_negative(startT - fTs[index].fT)) {
+        ++index;
+    }
+    int oIndex = 0;
+    while (!approximately_negative(oStartT - other->fTs[oIndex].fT)) {
+        ++oIndex;
+    }
+    SkOpSpan* test = &fTs[index];
+    SkOpSpan* oTest = &other->fTs[oIndex];
+    SkTDArray<double> outsideTs;
+    SkTDArray<double> oOutsideTs;
+    do {
+        // if either span has an opposite value and the operands don't match, resolve first
+ //       SkASSERT(!test->fDone || !oTest->fDone);
+        if (test->fDone || oTest->fDone) {
+            index = advanceCoincidentThis(oTest, opp, index);
+            oIndex = other->advanceCoincidentOther(test, oEndT, oIndex);
+        } else {
+            index = bumpCoincidentThis(*oTest, opp, index, &outsideTs);
+            oIndex = other->bumpCoincidentOther(*test, oEndT, oIndex, &oOutsideTs);
+        }
+        test = &fTs[index];
+        oTest = &other->fTs[oIndex];
+    } while (!approximately_negative(endT - test->fT));
+    SkASSERT(approximately_negative(oTest->fT - oEndT));
+    SkASSERT(approximately_negative(oEndT - oTest->fT));
+    if (!done() && outsideTs.count()) {
+        addCoinOutsides(outsideTs, other, oEndT);
+    }
+    if (!other->done() && oOutsideTs.count()) {
+        other->addCoinOutsides(oOutsideTs, this, endT);
+    }
+}
+
+// FIXME: this doesn't prevent the same span from being added twice
+// fix in caller, SkASSERT here?
+void SkOpSegment::addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
+                           const SkPoint& pt) {
+    int tCount = fTs.count();
+    for (int tIndex = 0; tIndex < tCount; ++tIndex) {
+        const SkOpSpan& span = fTs[tIndex];
+        if (!approximately_negative(span.fT - t)) {
+            break;
+        }
+        if (approximately_negative(span.fT - t) && span.fOther == other
+                && approximately_equal(span.fOtherT, otherT)) {
+#if DEBUG_ADD_T_PAIR
+            SkDebugf("%s addTPair duplicate this=%d %1.9g other=%d %1.9g\n",
+                    __FUNCTION__, fID, t, other->fID, otherT);
+#endif
+            return;
+        }
+    }
+#if DEBUG_ADD_T_PAIR
+    SkDebugf("%s addTPair this=%d %1.9g other=%d %1.9g\n",
+            __FUNCTION__, fID, t, other->fID, otherT);
+#endif
+    int insertedAt = addT(other, pt, t);
+    int otherInsertedAt = other->addT(this, pt, otherT);
+    addOtherT(insertedAt, otherT, otherInsertedAt);
+    other->addOtherT(otherInsertedAt, t, insertedAt);
+    matchWindingValue(insertedAt, t, borrowWind);
+    other->matchWindingValue(otherInsertedAt, otherT, borrowWind);
+}
+
+void SkOpSegment::addTwoAngles(int start, int end, SkTDArray<SkOpAngle>* angles) const {
+    // add edge leading into junction
+    int min = SkMin32(end, start);
+    if (fTs[min].fWindValue > 0 || fTs[min].fOppValue > 0) {
+        addAngle(angles, end, start);
+    }
+    // add edge leading away from junction
+    int step = SkSign32(end - start);
+    int tIndex = nextExactSpan(end, step);
+    min = SkMin32(end, tIndex);
+    if (tIndex >= 0 && (fTs[min].fWindValue > 0 || fTs[min].fOppValue > 0)) {
+        addAngle(angles, end, tIndex);
+    }
+}
+
+int SkOpSegment::advanceCoincidentThis(const SkOpSpan* oTest, bool opp, int index) {
+    SkOpSpan* const test = &fTs[index];
+    SkOpSpan* end;
+    do {
+        end = &fTs[++index];
+    } while (approximately_negative(end->fT - test->fT));
+    return index;
+}
+
+int SkOpSegment::advanceCoincidentOther(const SkOpSpan* test, double oEndT, int oIndex) {
+    SkOpSpan* const oTest = &fTs[oIndex];
+    SkOpSpan* oEnd = oTest;
+    const double oStartT = oTest->fT;
+    while (!approximately_negative(oEndT - oEnd->fT)
+            && approximately_negative(oEnd->fT - oStartT)) {
+        oEnd = &fTs[++oIndex];
+    }
+    return oIndex;
+}
+
+bool SkOpSegment::betweenTs(int lesser, double testT, int greater) const {
+    if (lesser > greater) {
+        SkTSwap<int>(lesser, greater);
+    }
+    return approximately_between(fTs[lesser].fT, testT, fTs[greater].fT);
+}
+
+void SkOpSegment::buildAngles(int index, SkTDArray<SkOpAngle>* angles, bool includeOpp) const {
+    double referenceT = fTs[index].fT;
+    int lesser = index;
+    while (--lesser >= 0 && (includeOpp || fTs[lesser].fOther->fOperand == fOperand)
+            && precisely_negative(referenceT - fTs[lesser].fT)) {
+        buildAnglesInner(lesser, angles);
+    }
+    do {
+        buildAnglesInner(index, angles);
+    } while (++index < fTs.count() && (includeOpp || fTs[index].fOther->fOperand == fOperand)
+            && precisely_negative(fTs[index].fT - referenceT));
+}
+
+void SkOpSegment::buildAnglesInner(int index, SkTDArray<SkOpAngle>* angles) const {
+    const SkOpSpan* span = &fTs[index];
+    SkOpSegment* other = span->fOther;
+// if there is only one live crossing, and no coincidence, continue
+// in the same direction
+// if there is coincidence, the only choice may be to reverse direction
+    // find edge on either side of intersection
+    int oIndex = span->fOtherIndex;
+    // if done == -1, prior span has already been processed
+    int step = 1;
+    int next = other->nextExactSpan(oIndex, step);
+   if (next < 0) {
+        step = -step;
+        next = other->nextExactSpan(oIndex, step);
+    }
+    // add candidate into and away from junction
+    other->addTwoAngles(next, oIndex, angles);
+}
+
+int SkOpSegment::computeSum(int startIndex, int endIndex, bool binary) {
+    SkTDArray<SkOpAngle> angles;
+    addTwoAngles(startIndex, endIndex, &angles);
+    buildAngles(endIndex, &angles, false);
+    // OPTIMIZATION: check all angles to see if any have computed wind sum
+    // before sorting (early exit if none)
+    SkTDArray<SkOpAngle*> sorted;
+    bool sortable = SortAngles(angles, &sorted);
+#if DEBUG_SORT
+    sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0, 0, 0);
+#endif
+    if (!sortable) {
+        return SK_MinS32;
+    }
+    int angleCount = angles.count();
+    const SkOpAngle* angle;
+    const SkOpSegment* base;
+    int winding;
+    int oWinding;
+    int firstIndex = 0;
+    do {
+        angle = sorted[firstIndex];
+        base = angle->segment();
+        winding = base->windSum(angle);
+        if (winding != SK_MinS32) {
+            oWinding = base->oppSum(angle);
+            break;
+        }
+        if (++firstIndex == angleCount) {
+            return SK_MinS32;
+        }
+    } while (true);
+    // turn winding into contourWinding
+    int spanWinding = base->spanSign(angle);
+    bool inner = UseInnerWinding(winding + spanWinding, winding);
+#if DEBUG_WINDING
+    SkDebugf("%s spanWinding=%d winding=%d sign=%d inner=%d result=%d\n", __FUNCTION__,
+        spanWinding, winding, angle->sign(), inner,
+        inner ? winding + spanWinding : winding);
+#endif
+    if (inner) {
+        winding += spanWinding;
+    }
+#if DEBUG_SORT
+    base->debugShowSort(__FUNCTION__, sorted, firstIndex, winding, oWinding);
+#endif
+    int nextIndex = firstIndex + 1;
+    int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
+    winding -= base->spanSign(angle);
+    oWinding -= base->oppSign(angle);
+    do {
+        if (nextIndex == angleCount) {
+            nextIndex = 0;
+        }
+        angle = sorted[nextIndex];
+        SkOpSegment* segment = angle->segment();
+        bool opp = base->fOperand ^ segment->fOperand;
+        int maxWinding, oMaxWinding;
+        int spanSign = segment->spanSign(angle);
+        int oppoSign = segment->oppSign(angle);
+        if (opp) {
+            oMaxWinding = oWinding;
+            oWinding -= spanSign;
+            maxWinding = winding;
+            if (oppoSign) {
+                winding -= oppoSign;
+            }
+        } else {
+            maxWinding = winding;
+            winding -= spanSign;
+            oMaxWinding = oWinding;
+            if (oppoSign) {
+                oWinding -= oppoSign;
+            }
+        }
+        if (segment->windSum(angle) == SK_MinS32) {
+            if (opp) {
+                if (UseInnerWinding(oMaxWinding, oWinding)) {
+                    oMaxWinding = oWinding;
+                }
+                if (oppoSign && UseInnerWinding(maxWinding, winding)) {
+                    maxWinding = winding;
+                }
+                (void) segment->markAndChaseWinding(angle, oMaxWinding, maxWinding);
+            } else {
+                if (UseInnerWinding(maxWinding, winding)) {
+                    maxWinding = winding;
+                }
+                if (oppoSign && UseInnerWinding(oMaxWinding, oWinding)) {
+                    oMaxWinding = oWinding;
+                }
+                (void) segment->markAndChaseWinding(angle, maxWinding,
+                        binary ? oMaxWinding : 0);
+            }
+        }
+    } while (++nextIndex != lastIndex);
+    int minIndex = SkMin32(startIndex, endIndex);
+    return windSum(minIndex);
+}
+
+int SkOpSegment::crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hitT,
+                              bool* hitSomething, double mid, bool opp, bool current) const {
+    SkScalar bottom = fBounds.fBottom;
+    int bestTIndex = -1;
+    if (bottom <= *bestY) {
+        return bestTIndex;
+    }
+    SkScalar top = fBounds.fTop;
+    if (top >= basePt.fY) {
+        return bestTIndex;
+    }
+    if (fBounds.fLeft > basePt.fX) {
+        return bestTIndex;
+    }
+    if (fBounds.fRight < basePt.fX) {
+        return bestTIndex;
+    }
+    if (fBounds.fLeft == fBounds.fRight) {
+        // if vertical, and directly above test point, wait for another one
+        return AlmostEqualUlps(basePt.fX, fBounds.fLeft) ? SK_MinS32 : bestTIndex;
+    }
+    // intersect ray starting at basePt with edge
+    SkIntersections intersections;
+    // OPTIMIZE: use specialty function that intersects ray with curve,
+    // returning t values only for curve (we don't care about t on ray)
+    int pts = (intersections.*CurveVertical[fVerb])(fPts, top, bottom, basePt.fX, false);
+    if (pts == 0 || (current && pts == 1)) {
+        return bestTIndex;
+    }
+    if (current) {
+        SkASSERT(pts > 1);
+        int closestIdx = 0;
+        double closest = fabs(intersections[0][0] - mid);
+        for (int idx = 1; idx < pts; ++idx) {
+            double test = fabs(intersections[0][idx] - mid);
+            if (closest > test) {
+                closestIdx = idx;
+                closest = test;
+            }
+        }
+        intersections.quickRemoveOne(closestIdx, --pts);
+    }
+    double bestT = -1;
+    for (int index = 0; index < pts; ++index) {
+        double foundT = intersections[0][index];
+        if (approximately_less_than_zero(foundT)
+                    || approximately_greater_than_one(foundT)) {
+            continue;
+        }
+        SkScalar testY = (*CurvePointAtT[fVerb])(fPts, foundT).fY;
+        if (approximately_negative(testY - *bestY)
+                || approximately_negative(basePt.fY - testY)) {
+            continue;
+        }
+        if (pts > 1 && fVerb == SkPath::kLine_Verb) {
+            return SK_MinS32;  // if the intersection is edge on, wait for another one
+        }
+        if (fVerb > SkPath::kLine_Verb) {
+            SkScalar dx = (*CurveSlopeAtT[fVerb])(fPts, foundT).fX;
+            if (approximately_zero(dx)) {
+                return SK_MinS32;  // hit vertical, wait for another one
+            }
+        }
+        *bestY = testY;
+        bestT = foundT;
+    }
+    if (bestT < 0) {
+        return bestTIndex;
+    }
+    SkASSERT(bestT >= 0);
+    SkASSERT(bestT <= 1);
+    int start;
+    int end = 0;
+    do {
+        start = end;
+        end = nextSpan(start, 1);
+    } while (fTs[end].fT < bestT);
+    // FIXME: see next candidate for a better pattern to find the next start/end pair
+    while (start + 1 < end && fTs[start].fDone) {
+        ++start;
+    }
+    if (!isCanceled(start)) {
+        *hitT = bestT;
+        bestTIndex = start;
+        *hitSomething = true;
+    }
+    return bestTIndex;
+}
+
+void SkOpSegment::decrementSpan(SkOpSpan* span) {
+    SkASSERT(span->fWindValue > 0);
+    if (--(span->fWindValue) == 0) {
+        if (!span->fOppValue && !span->fDone) {
+            span->fDone = true;
+            ++fDoneSpans;
+        }
+    }
+}
+
+bool SkOpSegment::bumpSpan(SkOpSpan* span, int windDelta, int oppDelta) {
+    SkASSERT(!span->fDone);
+    span->fWindValue += windDelta;
+    SkASSERT(span->fWindValue >= 0);
+    span->fOppValue += oppDelta;
+    SkASSERT(span->fOppValue >= 0);
+    if (fXor) {
+        span->fWindValue &= 1;
+    }
+    if (fOppXor) {
+        span->fOppValue &= 1;
+    }
+    if (!span->fWindValue && !span->fOppValue) {
+        span->fDone = true;
+        ++fDoneSpans;
+        return true;
+    }
+    return false;
+}
+
+bool SkOpSegment::equalPoints(int greaterTIndex, int lesserTIndex) {
+    SkASSERT(greaterTIndex >= lesserTIndex);
+    double greaterT = fTs[greaterTIndex].fT;
+    double lesserT = fTs[lesserTIndex].fT;
+    if (greaterT == lesserT) {
+        return true;
+    }
+    if (!approximately_negative(greaterT - lesserT)) {
+        return false;
+    }
+    return xyAtT(greaterTIndex) == xyAtT(lesserTIndex);
+}
+
+/*
+ The M and S variable name parts stand for the operators.
+   Mi stands for Minuend (see wiki subtraction, analogous to difference)
+   Su stands for Subtrahend
+ The Opp variable name part designates that the value is for the Opposite operator.
+ Opposite values result from combining coincident spans.
+ */
+SkOpSegment* SkOpSegment::findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* nextEnd,
+                                     bool* unsortable, SkPathOp op, const int xorMiMask,
+                                     const int xorSuMask) {
+    const int startIndex = *nextStart;
+    const int endIndex = *nextEnd;
+    SkASSERT(startIndex != endIndex);
+    SkDEBUGCODE(const int count = fTs.count());
+    SkASSERT(startIndex < endIndex ? startIndex < count - 1 : startIndex > 0);
+    const int step = SkSign32(endIndex - startIndex);
+    const int end = nextExactSpan(startIndex, step);
+    SkASSERT(end >= 0);
+    SkOpSpan* endSpan = &fTs[end];
+    SkOpSegment* other;
+    if (isSimple(end)) {
+    // mark the smaller of startIndex, endIndex done, and all adjacent
+    // spans with the same T value (but not 'other' spans)
+#if DEBUG_WINDING
+        SkDebugf("%s simple\n", __FUNCTION__);
+#endif
+        int min = SkMin32(startIndex, endIndex);
+        if (fTs[min].fDone) {
+            return NULL;
+        }
+        markDoneBinary(min);
+        other = endSpan->fOther;
+        *nextStart = endSpan->fOtherIndex;
+        double startT = other->fTs[*nextStart].fT;
+        *nextEnd = *nextStart;
+        do {
+            *nextEnd += step;
+        }
+        while (precisely_zero(startT - other->fTs[*nextEnd].fT));
+        SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count());
+        return other;
+    }
+    // more than one viable candidate -- measure angles to find best
+    SkTDArray<SkOpAngle> angles;
+    SkASSERT(startIndex - endIndex != 0);
+    SkASSERT((startIndex - endIndex < 0) ^ (step < 0));
+    addTwoAngles(startIndex, end, &angles);
+    buildAngles(end, &angles, true);
+    SkTDArray<SkOpAngle*> sorted;
+    bool sortable = SortAngles(angles, &sorted);
+    int angleCount = angles.count();
+    int firstIndex = findStartingEdge(sorted, startIndex, end);
+    SkASSERT(firstIndex >= 0);
+#if DEBUG_SORT
+    debugShowSort(__FUNCTION__, sorted, firstIndex);
+#endif
+    if (!sortable) {
+        *unsortable = true;
+        return NULL;
+    }
+    SkASSERT(sorted[firstIndex]->segment() == this);
+#if DEBUG_WINDING
+    SkDebugf("%s firstIndex=[%d] sign=%d\n", __FUNCTION__, firstIndex,
+            sorted[firstIndex]->sign());
+#endif
+    int sumMiWinding = updateWinding(endIndex, startIndex);
+    int sumSuWinding = updateOppWinding(endIndex, startIndex);
+    if (operand()) {
+        SkTSwap<int>(sumMiWinding, sumSuWinding);
+    }
+    int nextIndex = firstIndex + 1;
+    int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
+    const SkOpAngle* foundAngle = NULL;
+    bool foundDone = false;
+    // iterate through the angle, and compute everyone's winding
+    SkOpSegment* nextSegment;
+    int activeCount = 0;
+    do {
+        SkASSERT(nextIndex != firstIndex);
+        if (nextIndex == angleCount) {
+            nextIndex = 0;
+        }
+        const SkOpAngle* nextAngle = sorted[nextIndex];
+        nextSegment = nextAngle->segment();
+        int maxWinding, sumWinding, oppMaxWinding, oppSumWinding;
+        bool activeAngle = nextSegment->activeOp(xorMiMask, xorSuMask, nextAngle->start(),
+                nextAngle->end(), op, &sumMiWinding, &sumSuWinding,
+                &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
+        if (activeAngle) {
+            ++activeCount;
+            if (!foundAngle || (foundDone && activeCount & 1)) {
+                if (nextSegment->tiny(nextAngle)) {
+                    *unsortable = true;
+                    return NULL;
+                }
+                foundAngle = nextAngle;
+                foundDone = nextSegment->done(nextAngle) && !nextSegment->tiny(nextAngle);
+            }
+        }
+        if (nextSegment->done()) {
+            continue;
+        }
+        if (nextSegment->windSum(nextAngle) != SK_MinS32) {
+            continue;
+        }
+        SkOpSpan* last = nextSegment->markAngle(maxWinding, sumWinding, oppMaxWinding,
+                oppSumWinding, activeAngle, nextAngle);
+        if (last) {
+            *chase->append() = last;
+#if DEBUG_WINDING
+            SkDebugf("%s chase.append id=%d\n", __FUNCTION__,
+                    last->fOther->fTs[last->fOtherIndex].fOther->debugID());
+#endif
+        }
+    } while (++nextIndex != lastIndex);
+    markDoneBinary(SkMin32(startIndex, endIndex));
+    if (!foundAngle) {
+        return NULL;
+    }
+    *nextStart = foundAngle->start();
+    *nextEnd = foundAngle->end();
+    nextSegment = foundAngle->segment();
+
+#if DEBUG_WINDING
+    SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n",
+            __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEnd);
+ #endif
+    return nextSegment;
+}
+
+SkOpSegment* SkOpSegment::findNextWinding(SkTDArray<SkOpSpan*>* chase, int* nextStart,
+                                          int* nextEnd, bool* unsortable) {
+    const int startIndex = *nextStart;
+    const int endIndex = *nextEnd;
+    SkASSERT(startIndex != endIndex);
+    SkDEBUGCODE(const int count = fTs.count());
+    SkASSERT(startIndex < endIndex ? startIndex < count - 1 : startIndex > 0);
+    const int step = SkSign32(endIndex - startIndex);
+    const int end = nextExactSpan(startIndex, step);
+    SkASSERT(end >= 0);
+    SkOpSpan* endSpan = &fTs[end];
+    SkOpSegment* other;
+    if (isSimple(end)) {
+    // mark the smaller of startIndex, endIndex done, and all adjacent
+    // spans with the same T value (but not 'other' spans)
+#if DEBUG_WINDING
+        SkDebugf("%s simple\n", __FUNCTION__);
+#endif
+        int min = SkMin32(startIndex, endIndex);
+        if (fTs[min].fDone) {
+            return NULL;
+        }
+        markDoneUnary(min);
+        other = endSpan->fOther;
+        *nextStart = endSpan->fOtherIndex;
+        double startT = other->fTs[*nextStart].fT;
+        *nextEnd = *nextStart;
+        do {
+            *nextEnd += step;
+        }
+        while (precisely_zero(startT - other->fTs[*nextEnd].fT));
+        SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count());
+        return other;
+    }
+    // more than one viable candidate -- measure angles to find best
+    SkTDArray<SkOpAngle> angles;
+    SkASSERT(startIndex - endIndex != 0);
+    SkASSERT((startIndex - endIndex < 0) ^ (step < 0));
+    addTwoAngles(startIndex, end, &angles);
+    buildAngles(end, &angles, true);
+    SkTDArray<SkOpAngle*> sorted;
+    bool sortable = SortAngles(angles, &sorted);
+    int angleCount = angles.count();
+    int firstIndex = findStartingEdge(sorted, startIndex, end);
+    SkASSERT(firstIndex >= 0);
+#if DEBUG_SORT
+    debugShowSort(__FUNCTION__, sorted, firstIndex);
+#endif
+    if (!sortable) {
+        *unsortable = true;
+        return NULL;
+    }
+    SkASSERT(sorted[firstIndex]->segment() == this);
+#if DEBUG_WINDING
+    SkDebugf("%s firstIndex=[%d] sign=%d\n", __FUNCTION__, firstIndex,
+            sorted[firstIndex]->sign());
+#endif
+    int sumWinding = updateWinding(endIndex, startIndex);
+    int nextIndex = firstIndex + 1;
+    int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
+    const SkOpAngle* foundAngle = NULL;
+    bool foundDone = false;
+    // iterate through the angle, and compute everyone's winding
+    SkOpSegment* nextSegment;
+    int activeCount = 0;
+    do {
+        SkASSERT(nextIndex != firstIndex);
+        if (nextIndex == angleCount) {
+            nextIndex = 0;
+        }
+        const SkOpAngle* nextAngle = sorted[nextIndex];
+        nextSegment = nextAngle->segment();
+        int maxWinding;
+        bool activeAngle = nextSegment->activeWinding(nextAngle->start(), nextAngle->end(),
+                &maxWinding, &sumWinding);
+        if (activeAngle) {
+            ++activeCount;
+            if (!foundAngle || (foundDone && activeCount & 1)) {
+                if (nextSegment->tiny(nextAngle)) {
+                    *unsortable = true;
+                    return NULL;
+                }
+                foundAngle = nextAngle;
+                foundDone = nextSegment->done(nextAngle);
+            }
+        }
+        if (nextSegment->done()) {
+            continue;
+        }
+        if (nextSegment->windSum(nextAngle) != SK_MinS32) {
+            continue;
+        }
+        SkOpSpan* last = nextSegment->markAngle(maxWinding, sumWinding, activeAngle, nextAngle);
+        if (last) {
+            *chase->append() = last;
+#if DEBUG_WINDING
+            SkDebugf("%s chase.append id=%d\n", __FUNCTION__,
+                    last->fOther->fTs[last->fOtherIndex].fOther->debugID());
+#endif
+        }
+    } while (++nextIndex != lastIndex);
+    markDoneUnary(SkMin32(startIndex, endIndex));
+    if (!foundAngle) {
+        return NULL;
+    }
+    *nextStart = foundAngle->start();
+    *nextEnd = foundAngle->end();
+    nextSegment = foundAngle->segment();
+#if DEBUG_WINDING
+    SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n",
+            __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEnd);
+ #endif
+    return nextSegment;
+}
+
+SkOpSegment* SkOpSegment::findNextXor(int* nextStart, int* nextEnd, bool* unsortable) {
+    const int startIndex = *nextStart;
+    const int endIndex = *nextEnd;
+    SkASSERT(startIndex != endIndex);
+    SkDEBUGCODE(int count = fTs.count());
+    SkASSERT(startIndex < endIndex ? startIndex < count - 1
+            : startIndex > 0);
+    int step = SkSign32(endIndex - startIndex);
+    int end = nextExactSpan(startIndex, step);
+    SkASSERT(end >= 0);
+    SkOpSpan* endSpan = &fTs[end];
+    SkOpSegment* other;
+    if (isSimple(end)) {
+#if DEBUG_WINDING
+        SkDebugf("%s simple\n", __FUNCTION__);
+#endif
+        int min = SkMin32(startIndex, endIndex);
+        if (fTs[min].fDone) {
+            return NULL;
+        }
+        markDone(min, 1);
+        other = endSpan->fOther;
+        *nextStart = endSpan->fOtherIndex;
+        double startT = other->fTs[*nextStart].fT;
+        // FIXME: I don't know why the logic here is difference from the winding case
+        SkDEBUGCODE(bool firstLoop = true;)
+        if ((approximately_less_than_zero(startT) && step < 0)
+                || (approximately_greater_than_one(startT) && step > 0)) {
+            step = -step;
+            SkDEBUGCODE(firstLoop = false;)
+        }
+        do {
+            *nextEnd = *nextStart;
+            do {
+                *nextEnd += step;
+            }
+             while (precisely_zero(startT - other->fTs[*nextEnd].fT));
+            if (other->fTs[SkMin32(*nextStart, *nextEnd)].fWindValue) {
+                break;
+            }
+#ifdef SK_DEBUG
+            SkASSERT(firstLoop);
+#endif
+            SkDEBUGCODE(firstLoop = false;)
+            step = -step;
+        } while (true);
+        SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count());
+        return other;
+    }
+    SkTDArray<SkOpAngle> angles;
+    SkASSERT(startIndex - endIndex != 0);
+    SkASSERT((startIndex - endIndex < 0) ^ (step < 0));
+    addTwoAngles(startIndex, end, &angles);
+    buildAngles(end, &angles, false);
+    SkTDArray<SkOpAngle*> sorted;
+    bool sortable = SortAngles(angles, &sorted);
+    if (!sortable) {
+        *unsortable = true;
+#if DEBUG_SORT
+        debugShowSort(__FUNCTION__, sorted, findStartingEdge(sorted, startIndex, end), 0, 0);
+#endif
+        return NULL;
+    }
+    int angleCount = angles.count();
+    int firstIndex = findStartingEdge(sorted, startIndex, end);
+    SkASSERT(firstIndex >= 0);
+#if DEBUG_SORT
+    debugShowSort(__FUNCTION__, sorted, firstIndex, 0, 0);
+#endif
+    SkASSERT(sorted[firstIndex]->segment() == this);
+    int nextIndex = firstIndex + 1;
+    int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
+    const SkOpAngle* foundAngle = NULL;
+    bool foundDone = false;
+    SkOpSegment* nextSegment;
+    int activeCount = 0;
+    do {
+        SkASSERT(nextIndex != firstIndex);
+        if (nextIndex == angleCount) {
+            nextIndex = 0;
+        }
+        const SkOpAngle* nextAngle = sorted[nextIndex];
+        nextSegment = nextAngle->segment();
+        ++activeCount;
+        if (!foundAngle || (foundDone && activeCount & 1)) {
+            if (nextSegment->tiny(nextAngle)) {
+                *unsortable = true;
+                return NULL;
+            }
+            foundAngle = nextAngle;
+            foundDone = nextSegment->done(nextAngle);
+        }
+        if (nextSegment->done()) {
+            continue;
+        }
+    } while (++nextIndex != lastIndex);
+    markDone(SkMin32(startIndex, endIndex), 1);
+    if (!foundAngle) {
+        return NULL;
+    }
+    *nextStart = foundAngle->start();
+    *nextEnd = foundAngle->end();
+    nextSegment = foundAngle->segment();
+#if DEBUG_WINDING
+    SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n",
+            __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEnd);
+ #endif
+    return nextSegment;
+}
+
+int SkOpSegment::findStartingEdge(const SkTDArray<SkOpAngle*>& sorted, int start, int end) {
+    int angleCount = sorted.count();
+    int firstIndex = -1;
+    for (int angleIndex = 0; angleIndex < angleCount; ++angleIndex) {
+        const SkOpAngle* angle = sorted[angleIndex];
+        if (angle->segment() == this && angle->start() == end &&
+                angle->end() == start) {
+            firstIndex = angleIndex;
+            break;
+        }
+    }
+    return firstIndex;
+}
+
+// FIXME: this is tricky code; needs its own unit test
+// note that fOtherIndex isn't computed yet, so it can't be used here
+void SkOpSegment::findTooCloseToCall() {
+    int count = fTs.count();
+    if (count < 3) {  // require t=0, x, 1 at minimum
+        return;
+    }
+    int matchIndex = 0;
+    int moCount;
+    SkOpSpan* match;
+    SkOpSegment* mOther;
+    do {
+        match = &fTs[matchIndex];
+        mOther = match->fOther;
+        // 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;
+        }
+    } while (true);  // require t=0, x, 1 at minimum
+    // OPTIMIZATION: defer matchPt until qualifying toCount is found?
+    const SkPoint* matchPt = &xyAtT(match);
+    // look for a pair of nearby T values that map to the same (x,y) value
+    // if found, see if the pair of other segments share a common point. If
+    // so, the span from here to there is coincident.
+    for (int index = matchIndex + 1; index < count; ++index) {
+        SkOpSpan* test = &fTs[index];
+        if (test->fDone) {
+            continue;
+        }
+        SkOpSegment* 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;
+        }
+        const SkPoint* testPt = &xyAtT(test);
+        if (*matchPt != *testPt) {
+            matchIndex = index;
+            moCount = toCount;
+            match = test;
+            mOther = tOther;
+            matchPt = testPt;
+            continue;
+        }
+        int moStart = -1;
+        int moEnd = -1;
+        double moStartT = 0;
+        double moEndT = 0;
+        for (int moIndex = 0; moIndex < moCount; ++moIndex) {
+            SkOpSpan& moSpan = mOther->fTs[moIndex];
+            if (moSpan.fDone) {
+                continue;
+            }
+            if (moSpan.fOther == this) {
+                if (moSpan.fOtherT == match->fT) {
+                    moStart = moIndex;
+                    moStartT = moSpan.fT;
+                }
+                continue;
+            }
+            if (moSpan.fOther == tOther) {
+                if (tOther->windValueAt(moSpan.fOtherT) == 0) {
+                    moStart = -1;
+                    break;
+                }
+                SkASSERT(moEnd == -1);
+                moEnd = moIndex;
+                moEndT = moSpan.fT;
+            }
+        }
+        if (moStart < 0 || moEnd < 0) {
+            continue;
+        }
+        // FIXME: if moStartT, moEndT are initialized to NaN, can skip this test
+        if (approximately_equal(moStartT, moEndT)) {
+            continue;
+        }
+        int toStart = -1;
+        int toEnd = -1;
+        double toStartT = 0;
+        double toEndT = 0;
+        for (int toIndex = 0; toIndex < toCount; ++toIndex) {
+            SkOpSpan& toSpan = tOther->fTs[toIndex];
+            if (toSpan.fDone) {
+                continue;
+            }
+            if (toSpan.fOther == this) {
+                if (toSpan.fOtherT == test->fT) {
+                    toStart = toIndex;
+                    toStartT = toSpan.fT;
+                }
+                continue;
+            }
+            if (toSpan.fOther == mOther && toSpan.fOtherT == moEndT) {
+                if (mOther->windValueAt(toSpan.fOtherT) == 0) {
+                    moStart = -1;
+                    break;
+                }
+                SkASSERT(toEnd == -1);
+                toEnd = toIndex;
+                toEndT = toSpan.fT;
+            }
+        }
+        // FIXME: if toStartT, toEndT are initialized to NaN, can skip this test
+        if (toStart <= 0 || toEnd <= 0) {
+            continue;
+        }
+        if (approximately_equal(toStartT, toEndT)) {
+            continue;
+        }
+        // test to see if the segment between there and here is linear
+        if (!mOther->isLinear(moStart, moEnd)
+                || !tOther->isLinear(toStart, toEnd)) {
+            continue;
+        }
+        bool flipped = (moStart - moEnd) * (toStart - toEnd) < 1;
+        if (flipped) {
+            mOther->addTCancel(moStartT, moEndT, tOther, toEndT, toStartT);
+        } else {
+            mOther->addTCoincident(moStartT, moEndT, tOther, toStartT, toEndT);
+        }
+    }
+}
+
+// FIXME: either:
+// a) mark spans with either end unsortable as done, or
+// b) rewrite findTop / findTopSegment / findTopContour to iterate further
+//    when encountering an unsortable span
+
+// OPTIMIZATION : for a pair of lines, can we compute points at T (cached)
+// and use more concise logic like the old edge walker code?
+// FIXME: this needs to deal with coincident edges
+SkOpSegment* SkOpSegment::findTop(int* tIndexPtr, int* endIndexPtr, bool* unsortable,
+                                  bool onlySortable) {
+    // iterate through T intersections and return topmost
+    // topmost tangent from y-min to first pt is closer to horizontal
+    SkASSERT(!done());
+    int firstT = -1;
+    /* SkPoint topPt = */ activeLeftTop(onlySortable, &firstT);
+    if (firstT < 0) {
+        *unsortable = true;
+        firstT = 0;
+        while (fTs[firstT].fDone) {
+            SkASSERT(firstT < fTs.count());
+            ++firstT;
+        }
+        *tIndexPtr = firstT;
+        *endIndexPtr = nextExactSpan(firstT, 1);
+        return this;
+    }
+    // sort the edges to find the leftmost
+    int step = 1;
+    int end = nextSpan(firstT, step);
+    if (end == -1) {
+        step = -1;
+        end = nextSpan(firstT, step);
+        SkASSERT(end != -1);
+    }
+    // if the topmost T is not on end, or is three-way or more, find left
+    // look for left-ness from tLeft to firstT (matching y of other)
+    SkTDArray<SkOpAngle> angles;
+    SkASSERT(firstT - end != 0);
+    addTwoAngles(end, firstT, &angles);
+    buildAngles(firstT, &angles, true);
+    SkTDArray<SkOpAngle*> sorted;
+    bool sortable = SortAngles(angles, &sorted);
+    int first = SK_MaxS32;
+    SkScalar top = SK_ScalarMax;
+    int count = sorted.count();
+    for (int index = 0; index < count; ++index) {
+        const SkOpAngle* angle = sorted[index];
+        SkOpSegment* next = angle->segment();
+        SkPathOpsBounds bounds;
+        next->subDivideBounds(angle->end(), angle->start(), &bounds);
+        if (approximately_greater(top, bounds.fTop)) {
+            top = bounds.fTop;
+            first = index;
+        }
+    }
+    SkASSERT(first < SK_MaxS32);
+#if DEBUG_SORT  // || DEBUG_SWAP_TOP
+    sorted[first]->segment()->debugShowSort(__FUNCTION__, sorted, first, 0, 0);
+#endif
+    if (onlySortable && !sortable) {
+        *unsortable = true;
+        return NULL;
+    }
+    // skip edges that have already been processed
+    firstT = first - 1;
+    SkOpSegment* leftSegment;
+    do {
+        if (++firstT == count) {
+            firstT = 0;
+        }
+        const SkOpAngle* angle = sorted[firstT];
+        SkASSERT(!onlySortable || !angle->unsortable());
+        leftSegment = angle->segment();
+        *tIndexPtr = angle->end();
+        *endIndexPtr = angle->start();
+    } while (leftSegment->fTs[SkMin32(*tIndexPtr, *endIndexPtr)].fDone);
+    if (leftSegment->verb() >= SkPath::kQuad_Verb) {
+        const int tIndex = *tIndexPtr;
+        const int endIndex = *endIndexPtr;
+        if (!leftSegment->clockwise(tIndex, endIndex)) {
+            bool swap = !leftSegment->monotonicInY(tIndex, endIndex)
+                    && !leftSegment->serpentine(tIndex, endIndex);
+    #if DEBUG_SWAP_TOP
+            SkDebugf("%s swap=%d serpentine=%d containedByEnds=%d monotonic=%d\n", __FUNCTION__,
+                    swap,
+                    leftSegment->serpentine(tIndex, endIndex),
+                    leftSegment->controlsContainedByEnds(tIndex, endIndex),
+                    leftSegment->monotonicInY(tIndex, endIndex));
+    #endif
+            if (swap) {
+    // FIXME: I doubt it makes sense to (necessarily) swap if the edge was not the first
+    // sorted but merely the first not already processed (i.e., not done)
+                SkTSwap(*tIndexPtr, *endIndexPtr);
+            }
+        }
+    }
+    SkASSERT(!leftSegment->fTs[SkMin32(*tIndexPtr, *endIndexPtr)].fTiny);
+    return leftSegment;
+}
+
+// FIXME: not crazy about this
+// when the intersections are performed, the other index is into an
+// incomplete array. As the array grows, the indices become incorrect
+// while the following fixes the indices up again, it isn't smart about
+// skipping segments whose indices are already correct
+// assuming we leave the code that wrote the index in the first place
+void SkOpSegment::fixOtherTIndex() {
+    int iCount = fTs.count();
+    for (int i = 0; i < iCount; ++i) {
+        SkOpSpan& iSpan = fTs[i];
+        double oT = iSpan.fOtherT;
+        SkOpSegment* other = iSpan.fOther;
+        int oCount = other->fTs.count();
+        for (int o = 0; o < oCount; ++o) {
+            SkOpSpan& oSpan = other->fTs[o];
+            if (oT == oSpan.fT && this == oSpan.fOther && oSpan.fOtherT == iSpan.fT) {
+                iSpan.fOtherIndex = o;
+                break;
+            }
+        }
+    }
+}
+
+void SkOpSegment::init(const SkPoint pts[], SkPath::Verb verb, bool operand, bool evenOdd) {
+    fDoneSpans = 0;
+    fOperand = operand;
+    fXor = evenOdd;
+    fPts = pts;
+    fVerb = verb;
+}
+
+void SkOpSegment::initWinding(int start, int end) {
+    int local = spanSign(start, end);
+    int oppLocal = oppSign(start, end);
+    (void) markAndChaseWinding(start, end, local, oppLocal);
+    // OPTIMIZATION: the reverse mark and chase could skip the first marking
+    (void) markAndChaseWinding(end, start, local, oppLocal);
+}
+
+/*
+when we start with a vertical intersect, we try to use the dx to determine if the edge is to
+the left or the right of vertical. This determines if we need to add the span's
+sign or not. However, this isn't enough.
+If the supplied sign (winding) is zero, then we didn't hit another vertical span, so dx is needed.
+If there was a winding, then it may or may not need adjusting. If the span the winding was borrowed
+from has the same x direction as this span, the winding should change. If the dx is opposite, then
+the same winding is shared by both.
+*/
+void SkOpSegment::initWinding(int start, int end, double tHit, int winding, SkScalar hitDx,
+                              int oppWind, SkScalar hitOppDx) {
+    SkASSERT(hitDx || !winding);
+    SkScalar dx = (*CurveSlopeAtT[fVerb])(fPts, tHit).fX;
+    SkASSERT(dx);
+    int windVal = windValue(SkMin32(start, end));
+#if DEBUG_WINDING_AT_T
+    SkDebugf("%s oldWinding=%d hitDx=%c dx=%c windVal=%d", __FUNCTION__, winding,
+            hitDx ? hitDx > 0 ? '+' : '-' : '0', dx > 0 ? '+' : '-', windVal);
+#endif
+    if (!winding) {
+        winding = dx < 0 ? windVal : -windVal;
+    } else if (winding * dx < 0) {
+        int sideWind = winding + (dx < 0 ? windVal : -windVal);
+        if (abs(winding) < abs(sideWind)) {
+            winding = sideWind;
+        }
+    }
+#if DEBUG_WINDING_AT_T
+    SkDebugf(" winding=%d\n", winding);
+#endif
+    SkDEBUGCODE(int oppLocal = oppSign(start, end));
+    SkASSERT(hitOppDx || !oppWind || !oppLocal);
+    int oppWindVal = oppValue(SkMin32(start, end));
+    if (!oppWind) {
+        oppWind = dx < 0 ? oppWindVal : -oppWindVal;
+    } else if (hitOppDx * dx >= 0) {
+        int oppSideWind = oppWind + (dx < 0 ? oppWindVal : -oppWindVal);
+        if (abs(oppWind) < abs(oppSideWind)) {
+            oppWind = oppSideWind;
+        }
+    }
+    (void) markAndChaseWinding(start, end, winding, oppWind);
+}
+
+bool SkOpSegment::isLinear(int start, int end) const {
+    if (fVerb == SkPath::kLine_Verb) {
+        return true;
+    }
+    if (fVerb == SkPath::kQuad_Verb) {
+        SkDQuad qPart = SkDQuad::SubDivide(fPts, fTs[start].fT, fTs[end].fT);
+        return qPart.isLinear(0, 2);
+    } else {
+        SkASSERT(fVerb == SkPath::kCubic_Verb);
+        SkDCubic cPart = SkDCubic::SubDivide(fPts, fTs[start].fT, fTs[end].fT);
+        return cPart.isLinear(0, 3);
+    }
+}
+
+// OPTIMIZE: successive calls could start were the last leaves off
+// or calls could specialize to walk forwards or backwards
+bool SkOpSegment::isMissing(double startT) const {
+    size_t tCount = fTs.count();
+    for (size_t index = 0; index < tCount; ++index) {
+        if (approximately_zero(startT - fTs[index].fT)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool SkOpSegment::isSimple(int end) const {
+    int count = fTs.count();
+    if (count == 2) {
+        return true;
+    }
+    double t = fTs[end].fT;
+    if (approximately_less_than_zero(t)) {
+        return !approximately_less_than_zero(fTs[1].fT);
+    }
+    if (approximately_greater_than_one(t)) {
+        return !approximately_greater_than_one(fTs[count - 2].fT);
+    }
+    return false;
+}
+
+// this span is excluded by the winding rule -- chase the ends
+// as long as they are unambiguous to mark connections as done
+// and give them the same winding value
+SkOpSpan* SkOpSegment::markAndChaseDone(int index, int endIndex, int winding) {
+    int step = SkSign32(endIndex - index);
+    int min = SkMin32(index, endIndex);
+    markDone(min, winding);
+    SkOpSpan* last;
+    SkOpSegment* other = this;
+    while ((other = other->nextChase(&index, step, &min, &last))) {
+        other->markDone(min, winding);
+    }
+    return last;
+}
+
+SkOpSpan* SkOpSegment::markAndChaseDoneBinary(const SkOpAngle* angle, int winding, int oppWinding) {
+    int index = angle->start();
+    int endIndex = angle->end();
+    int step = SkSign32(endIndex - index);
+    int min = SkMin32(index, endIndex);
+    markDoneBinary(min, winding, oppWinding);
+    SkOpSpan* last;
+    SkOpSegment* other = this;
+    while ((other = other->nextChase(&index, step, &min, &last))) {
+        other->markDoneBinary(min, winding, oppWinding);
+    }
+    return last;
+}
+
+SkOpSpan* SkOpSegment::markAndChaseDoneBinary(int index, int endIndex) {
+    int step = SkSign32(endIndex - index);
+    int min = SkMin32(index, endIndex);
+    markDoneBinary(min);
+    SkOpSpan* last;
+    SkOpSegment* other = this;
+    while ((other = other->nextChase(&index, step, &min, &last))) {
+        if (other->done()) {
+            return NULL;
+        }
+        other->markDoneBinary(min);
+    }
+    return last;
+}
+
+SkOpSpan* SkOpSegment::markAndChaseDoneUnary(int index, int endIndex) {
+    int step = SkSign32(endIndex - index);
+    int min = SkMin32(index, endIndex);
+    markDoneUnary(min);
+    SkOpSpan* last;
+    SkOpSegment* other = this;
+    while ((other = other->nextChase(&index, step, &min, &last))) {
+        if (other->done()) {
+            return NULL;
+        }
+        other->markDoneUnary(min);
+    }
+    return last;
+}
+
+SkOpSpan* SkOpSegment::markAndChaseDoneUnary(const SkOpAngle* angle, int winding) {
+    int index = angle->start();
+    int endIndex = angle->end();
+    return markAndChaseDone(index, endIndex, winding);
+}
+
+SkOpSpan* SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, const int winding) {
+    int index = angle->start();
+    int endIndex = angle->end();
+    int step = SkSign32(endIndex - index);
+    int min = SkMin32(index, endIndex);
+    markWinding(min, winding);
+    SkOpSpan* last;
+    SkOpSegment* other = this;
+    while ((other = other->nextChase(&index, step, &min, &last))) {
+        if (other->fTs[min].fWindSum != SK_MinS32) {
+            SkASSERT(other->fTs[min].fWindSum == winding);
+            return NULL;
+        }
+        other->markWinding(min, winding);
+    }
+    return last;
+}
+
+SkOpSpan* SkOpSegment::markAndChaseWinding(int index, int endIndex, int winding, int oppWinding) {
+    int min = SkMin32(index, endIndex);
+    int step = SkSign32(endIndex - index);
+    markWinding(min, winding, oppWinding);
+    SkOpSpan* last;
+    SkOpSegment* other = this;
+    while ((other = other->nextChase(&index, step, &min, &last))) {
+        if (other->fTs[min].fWindSum != SK_MinS32) {
+            SkASSERT(other->fTs[min].fWindSum == winding || other->fTs[min].fLoop);
+            return NULL;
+        }
+        other->markWinding(min, winding, oppWinding);
+    }
+    return last;
+}
+
+SkOpSpan* SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding, int oppWinding) {
+    int start = angle->start();
+    int end = angle->end();
+    return markAndChaseWinding(start, end, winding, oppWinding);
+}
+
+SkOpSpan* SkOpSegment::markAngle(int maxWinding, int sumWinding, bool activeAngle,
+                                const SkOpAngle* angle) {
+    SkASSERT(angle->segment() == this);
+    if (UseInnerWinding(maxWinding, sumWinding)) {
+        maxWinding = sumWinding;
+    }
+    SkOpSpan* last;
+    if (activeAngle) {
+        last = markAndChaseWinding(angle, maxWinding);
+    } else {
+        last = markAndChaseDoneUnary(angle, maxWinding);
+    }
+    return last;
+}
+
+SkOpSpan* SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxWinding,
+                                 int oppSumWinding, bool activeAngle, const SkOpAngle* angle) {
+    SkASSERT(angle->segment() == this);
+    if (UseInnerWinding(maxWinding, sumWinding)) {
+        maxWinding = sumWinding;
+    }
+    if (oppMaxWinding != oppSumWinding && UseInnerWinding(oppMaxWinding, oppSumWinding)) {
+        oppMaxWinding = oppSumWinding;
+    }
+    SkOpSpan* last;
+    if (activeAngle) {
+        last = markAndChaseWinding(angle, maxWinding, oppMaxWinding);
+    } else {
+        last = markAndChaseDoneBinary(angle, maxWinding, oppMaxWinding);
+    }
+    return last;
+}
+
+// FIXME: this should also mark spans with equal (x,y)
+// This may be called when the segment is already marked done. While this
+// wastes time, it shouldn't do any more than spin through the T spans.
+// OPTIMIZATION: abort on first done found (assuming that this code is
+// always called to mark segments done).
+void SkOpSegment::markDone(int index, int winding) {
+  //  SkASSERT(!done());
+    SkASSERT(winding);
+    double referenceT = fTs[index].fT;
+    int lesser = index;
+    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
+        markOneDone(__FUNCTION__, lesser, winding);
+    }
+    do {
+        markOneDone(__FUNCTION__, index, winding);
+    } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
+}
+
+void SkOpSegment::markDoneBinary(int index, int winding, int oppWinding) {
+  //  SkASSERT(!done());
+    SkASSERT(winding || oppWinding);
+    double referenceT = fTs[index].fT;
+    int lesser = index;
+    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
+        markOneDoneBinary(__FUNCTION__, lesser, winding, oppWinding);
+    }
+    do {
+        markOneDoneBinary(__FUNCTION__, index, winding, oppWinding);
+    } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
+}
+
+void SkOpSegment::markDoneBinary(int index) {
+    double referenceT = fTs[index].fT;
+    int lesser = index;
+    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
+        markOneDoneBinary(__FUNCTION__, lesser);
+    }
+    do {
+        markOneDoneBinary(__FUNCTION__, index);
+    } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
+}
+
+void SkOpSegment::markDoneUnary(int index) {
+    double referenceT = fTs[index].fT;
+    int lesser = index;
+    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
+        markOneDoneUnary(__FUNCTION__, lesser);
+    }
+    do {
+        markOneDoneUnary(__FUNCTION__, index);
+    } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
+}
+
+void SkOpSegment::markOneDone(const char* funName, int tIndex, int winding) {
+    SkOpSpan* span = markOneWinding(funName, tIndex, winding);
+    if (!span) {
+        return;
+    }
+    span->fDone = true;
+    fDoneSpans++;
+}
+
+void SkOpSegment::markOneDoneBinary(const char* funName, int tIndex) {
+    SkOpSpan* span = verifyOneWinding(funName, tIndex);
+    if (!span) {
+        return;
+    }
+    span->fDone = true;
+    fDoneSpans++;
+}
+
+void SkOpSegment::markOneDoneBinary(const char* funName, int tIndex, int winding, int oppWinding) {
+    SkOpSpan* span = markOneWinding(funName, tIndex, winding, oppWinding);
+    if (!span) {
+        return;
+    }
+    span->fDone = true;
+    fDoneSpans++;
+}
+
+void SkOpSegment::markOneDoneUnary(const char* funName, int tIndex) {
+    SkOpSpan* span = verifyOneWindingU(funName, tIndex);
+    if (!span) {
+        return;
+    }
+    span->fDone = true;
+    fDoneSpans++;
+}
+
+SkOpSpan* SkOpSegment::markOneWinding(const char* funName, int tIndex, int winding) {
+    SkOpSpan& span = fTs[tIndex];
+    if (span.fDone) {
+        return NULL;
+    }
+#if DEBUG_MARK_DONE
+    debugShowNewWinding(funName, span, winding);
+#endif
+    SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
+#ifdef SK_DEBUG
+    SkASSERT(abs(winding) <= gDebugMaxWindSum);
+#endif
+    span.fWindSum = winding;
+    return &span;
+}
+
+SkOpSpan* SkOpSegment::markOneWinding(const char* funName, int tIndex, int winding,
+                                      int oppWinding) {
+    SkOpSpan& span = fTs[tIndex];
+    if (span.fDone) {
+        return NULL;
+    }
+#if DEBUG_MARK_DONE
+    debugShowNewWinding(funName, span, winding, oppWinding);
+#endif
+    SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
+#ifdef SK_DEBUG
+    SkASSERT(abs(winding) <= gDebugMaxWindSum);
+#endif
+    span.fWindSum = winding;
+    SkASSERT(span.fOppSum == SK_MinS32 || span.fOppSum == oppWinding);
+#ifdef SK_DEBUG
+    SkASSERT(abs(oppWinding) <= gDebugMaxWindSum);
+#endif
+    span.fOppSum = oppWinding;
+    return &span;
+}
+
+// from http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
+bool SkOpSegment::clockwise(int tStart, int tEnd) const {
+    SkASSERT(fVerb != SkPath::kLine_Verb);
+    SkPoint edge[4];
+    subDivide(tStart, tEnd, edge);
+    double sum = (edge[0].fX - edge[fVerb].fX) * (edge[0].fY + edge[fVerb].fY);
+    if (fVerb == SkPath::kCubic_Verb) {
+        SkScalar lesser = SkTMin<SkScalar>(edge[0].fY, edge[3].fY);
+        if (edge[1].fY < lesser && edge[2].fY < lesser) {
+            SkDLine tangent1 = {{ {edge[0].fX, edge[0].fY}, {edge[1].fX, edge[1].fY} }};
+            SkDLine tangent2 = {{ {edge[2].fX, edge[2].fY}, {edge[3].fX, edge[3].fY} }};
+            if (SkIntersections::Test(tangent1, tangent2)) {
+                SkPoint topPt = cubic_top(fPts, fTs[tStart].fT, fTs[tEnd].fT);
+                sum += (topPt.fX - edge[0].fX) * (topPt.fY + edge[0].fY);
+                sum += (edge[3].fX - topPt.fX) * (edge[3].fY + topPt.fY);
+                return sum <= 0;
+            }
+        }
+    }
+    for (int idx = 0; idx < fVerb; ++idx){
+        sum += (edge[idx + 1].fX - edge[idx].fX) * (edge[idx + 1].fY + edge[idx].fY);
+    }
+    return sum <= 0;
+}
+
+bool SkOpSegment::monotonicInY(int tStart, int tEnd) const {
+    if (fVerb == SkPath::kLine_Verb) {
+        return false;
+    }
+    if (fVerb == SkPath::kQuad_Verb) {
+        SkDQuad dst = SkDQuad::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
+        return dst.monotonicInY();
+    }
+    SkASSERT(fVerb == SkPath::kCubic_Verb);
+    SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
+    return dst.monotonicInY();
+}
+
+bool SkOpSegment::serpentine(int tStart, int tEnd) const {
+    if (fVerb != SkPath::kCubic_Verb) {
+        return false;
+    }
+    SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
+    return dst.serpentine();
+}
+
+SkOpSpan* SkOpSegment::verifyOneWinding(const char* funName, int tIndex) {
+    SkOpSpan& span = fTs[tIndex];
+    if (span.fDone) {
+        return NULL;
+    }
+#if DEBUG_MARK_DONE
+    debugShowNewWinding(funName, span, span.fWindSum, span.fOppSum);
+#endif
+    SkASSERT(span.fWindSum != SK_MinS32);
+    SkASSERT(span.fOppSum != SK_MinS32);
+    return &span;
+}
+
+SkOpSpan* SkOpSegment::verifyOneWindingU(const char* funName, int tIndex) {
+    SkOpSpan& span = fTs[tIndex];
+    if (span.fDone) {
+        return NULL;
+    }
+#if DEBUG_MARK_DONE
+    debugShowNewWinding(funName, span, span.fWindSum);
+#endif
+    SkASSERT(span.fWindSum != SK_MinS32);
+    return &span;
+}
+
+// note that just because a span has one end that is unsortable, that's
+// not enough to mark it done. The other end may be sortable, allowing the
+// span to be added.
+// FIXME: if abs(start - end) > 1, mark intermediates as unsortable on both ends
+void SkOpSegment::markUnsortable(int start, int end) {
+    SkOpSpan* span = &fTs[start];
+    if (start < end) {
+#if DEBUG_UNSORTABLE
+        debugShowNewWinding(__FUNCTION__, *span, 0);
+#endif
+        span->fUnsortableStart = true;
+    } else {
+        --span;
+#if DEBUG_UNSORTABLE
+        debugShowNewWinding(__FUNCTION__, *span, 0);
+#endif
+        span->fUnsortableEnd = true;
+    }
+    if (!span->fUnsortableStart || !span->fUnsortableEnd || span->fDone) {
+        return;
+    }
+    span->fDone = true;
+    fDoneSpans++;
+}
+
+void SkOpSegment::markWinding(int index, int winding) {
+//    SkASSERT(!done());
+    SkASSERT(winding);
+    double referenceT = fTs[index].fT;
+    int lesser = index;
+    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
+        markOneWinding(__FUNCTION__, lesser, winding);
+    }
+    do {
+        markOneWinding(__FUNCTION__, index, winding);
+   } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
+}
+
+void SkOpSegment::markWinding(int index, int winding, int oppWinding) {
+//    SkASSERT(!done());
+    SkASSERT(winding || oppWinding);
+    double referenceT = fTs[index].fT;
+    int lesser = index;
+    while (--lesser >= 0 && precisely_negative(referenceT - fTs[lesser].fT)) {
+        markOneWinding(__FUNCTION__, lesser, winding, oppWinding);
+    }
+    do {
+        markOneWinding(__FUNCTION__, index, winding, oppWinding);
+   } while (++index < fTs.count() && precisely_negative(fTs[index].fT - referenceT));
+}
+
+void SkOpSegment::matchWindingValue(int tIndex, double t, bool borrowWind) {
+    int nextDoorWind = SK_MaxS32;
+    int nextOppWind = SK_MaxS32;
+    if (tIndex > 0) {
+        const SkOpSpan& below = fTs[tIndex - 1];
+        if (approximately_negative(t - below.fT)) {
+            nextDoorWind = below.fWindValue;
+            nextOppWind = below.fOppValue;
+        }
+    }
+    if (nextDoorWind == SK_MaxS32 && tIndex + 1 < fTs.count()) {
+        const SkOpSpan& above = fTs[tIndex + 1];
+        if (approximately_negative(above.fT - t)) {
+            nextDoorWind = above.fWindValue;
+            nextOppWind = above.fOppValue;
+        }
+    }
+    if (nextDoorWind == SK_MaxS32 && borrowWind && tIndex > 0 && t < 1) {
+        const SkOpSpan& below = fTs[tIndex - 1];
+        nextDoorWind = below.fWindValue;
+        nextOppWind = below.fOppValue;
+    }
+    if (nextDoorWind != SK_MaxS32) {
+        SkOpSpan& newSpan = fTs[tIndex];
+        newSpan.fWindValue = nextDoorWind;
+        newSpan.fOppValue = nextOppWind;
+        if (!nextDoorWind && !nextOppWind && !newSpan.fDone) {
+            newSpan.fDone = true;
+            ++fDoneSpans;
+        }
+    }
+}
+
+// return span if when chasing, two or more radiating spans are not done
+// OPTIMIZATION: ? multiple spans is detected when there is only one valid
+// candidate and the remaining spans have windValue == 0 (canceled by
+// coincidence). The coincident edges could either be removed altogether,
+// or this code could be more complicated in detecting this case. Worth it?
+bool SkOpSegment::multipleSpans(int end) const {
+    return end > 0 && end < fTs.count() - 1;
+}
+
+bool SkOpSegment::nextCandidate(int* start, int* end) const {
+    while (fTs[*end].fDone) {
+        if (fTs[*end].fT == 1) {
+            return false;
+        }
+        ++(*end);
+    }
+    *start = *end;
+    *end = nextExactSpan(*start, 1);
+    return true;
+}
+
+SkOpSegment* SkOpSegment::nextChase(int* index, const int step, int* min, SkOpSpan** last) {
+    int end = nextExactSpan(*index, step);
+    SkASSERT(end >= 0);
+    if (multipleSpans(end)) {
+        *last = &fTs[end];
+        return NULL;
+    }
+    const SkOpSpan& endSpan = fTs[end];
+    SkOpSegment* other = endSpan.fOther;
+    *index = endSpan.fOtherIndex;
+    SkASSERT(index >= 0);
+    int otherEnd = other->nextExactSpan(*index, step);
+    SkASSERT(otherEnd >= 0);
+    *min = SkMin32(*index, otherEnd);
+    return other;
+}
+
+// This has callers for two different situations: one establishes the end
+// of the current span, and one establishes the beginning of the next span
+// (thus the name). When this is looking for the end of the current span,
+// coincidence is found when the beginning Ts contain -step and the end
+// contains step. When it is looking for the beginning of the next, the
+// first Ts found can be ignored and the last Ts should contain -step.
+// OPTIMIZATION: probably should split into two functions
+int SkOpSegment::nextSpan(int from, int step) const {
+    const SkOpSpan& fromSpan = fTs[from];
+    int count = fTs.count();
+    int to = from;
+    while (step > 0 ? ++to < count : --to >= 0) {
+        const SkOpSpan& span = fTs[to];
+        if (approximately_zero(span.fT - fromSpan.fT)) {
+            continue;
+        }
+        return to;
+    }
+    return -1;
+}
+
+// FIXME
+// this returns at any difference in T, vs. a preset minimum. It may be
+// that all callers to nextSpan should use this instead.
+// OPTIMIZATION splitting this into separate loops for up/down steps
+// would allow using precisely_negative instead of precisely_zero
+int SkOpSegment::nextExactSpan(int from, int step) const {
+    const SkOpSpan& fromSpan = fTs[from];
+    int count = fTs.count();
+    int to = from;
+    while (step > 0 ? ++to < count : --to >= 0) {
+        const SkOpSpan& span = fTs[to];
+        if (precisely_zero(span.fT - fromSpan.fT)) {
+            continue;
+        }
+        return to;
+    }
+    return -1;
+}
+
+void SkOpSegment::setUpWindings(int index, int endIndex, int* sumMiWinding, int* sumSuWinding,
+        int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding) {
+    int deltaSum = spanSign(index, endIndex);
+    int oppDeltaSum = oppSign(index, endIndex);
+    if (operand()) {
+        *maxWinding = *sumSuWinding;
+        *sumWinding = *sumSuWinding -= deltaSum;
+        *oppMaxWinding = *sumMiWinding;
+        *oppSumWinding = *sumMiWinding -= oppDeltaSum;
+    } else {
+        *maxWinding = *sumMiWinding;
+        *sumWinding = *sumMiWinding -= deltaSum;
+        *oppMaxWinding = *sumSuWinding;
+        *oppSumWinding = *sumSuWinding -= oppDeltaSum;
+    }
+}
+
+// This marks all spans unsortable so that this info is available for early
+// exclusion in find top and others. This could be optimized to only mark
+// adjacent spans that unsortable. However, this makes it difficult to later
+// determine starting points for edge detection in find top and the like.
+bool SkOpSegment::SortAngles(const SkTDArray<SkOpAngle>& angles,
+                             SkTDArray<SkOpAngle*>* angleList) {
+    bool sortable = true;
+    int angleCount = angles.count();
+    int angleIndex;
+    angleList->setReserve(angleCount);
+    for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) {
+        const SkOpAngle& angle = angles[angleIndex];
+        *angleList->append() = const_cast<SkOpAngle*>(&angle);
+        sortable &= !angle.unsortable();
+    }
+    if (sortable) {
+        QSort<SkOpAngle>(angleList->begin(), angleList->end() - 1);
+        for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) {
+            if (angles[angleIndex].unsortable()) {
+                sortable = false;
+                break;
+            }
+        }
+    }
+    if (!sortable) {
+        for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) {
+            const SkOpAngle& angle = angles[angleIndex];
+            angle.segment()->markUnsortable(angle.start(), angle.end());
+        }
+    }
+    return sortable;
+}
+
+void SkOpSegment::subDivide(int start, int end, SkPoint edge[4]) const {
+    edge[0] = fTs[start].fPt;
+    edge[fVerb] = fTs[end].fPt;
+    if (fVerb == SkPath::kQuad_Verb || fVerb == SkPath::kCubic_Verb) {
+        SkDPoint sub[2] = {{ edge[0].fX, edge[0].fY}, {edge[fVerb].fX, edge[fVerb].fY }};
+        if (fVerb == SkPath::kQuad_Verb) {
+            edge[1] = SkDQuad::SubDivide(fPts, sub[0], sub[1], fTs[start].fT,
+                    fTs[end].fT).asSkPoint();
+        } else {
+            SkDCubic::SubDivide(fPts, sub[0], sub[1], fTs[start].fT, fTs[end].fT, sub);
+            edge[1] = sub[0].asSkPoint();
+            edge[2] = sub[1].asSkPoint();
+        }
+    }
+}
+
+void SkOpSegment::subDivideBounds(int start, int end, SkPathOpsBounds* bounds) const {
+    SkPoint edge[4];
+    subDivide(start, end, edge);
+    (bounds->*SetCurveBounds[fVerb])(edge);
+}
+
+bool SkOpSegment::tiny(const SkOpAngle* angle) const {
+    int start = angle->start();
+    int end = angle->end();
+    const SkOpSpan& mSpan = fTs[SkMin32(start, end)];
+    return mSpan.fTiny;
+}
+
+void SkOpSegment::TrackOutside(SkTDArray<double>* outsideTs, double end, double start) {
+    int outCount = outsideTs->count();
+    if (outCount == 0 || !approximately_negative(end - (*outsideTs)[outCount - 2])) {
+        *outsideTs->append() = end;
+        *outsideTs->append() = start;
+    }
+}
+
+void SkOpSegment::undoneSpan(int* start, int* end) {
+    size_t tCount = fTs.count();
+    size_t index;
+    for (index = 0; index < tCount; ++index) {
+        if (!fTs[index].fDone) {
+            break;
+        }
+    }
+    SkASSERT(index < tCount - 1);
+    *start = index;
+    double startT = fTs[index].fT;
+    while (approximately_negative(fTs[++index].fT - startT))
+        SkASSERT(index < tCount);
+    SkASSERT(index < tCount);
+    *end = index;
+}
+
+int SkOpSegment::updateOppWinding(int index, int endIndex) const {
+    int lesser = SkMin32(index, endIndex);
+    int oppWinding = oppSum(lesser);
+    int oppSpanWinding = oppSign(index, endIndex);
+    if (oppSpanWinding && UseInnerWinding(oppWinding - oppSpanWinding, oppWinding)
+            && oppWinding != SK_MaxS32) {
+        oppWinding -= oppSpanWinding;
+    }
+    return oppWinding;
+}
+
+int SkOpSegment::updateOppWinding(const SkOpAngle* angle) const {
+    int startIndex = angle->start();
+    int endIndex = angle->end();
+    return updateOppWinding(endIndex, startIndex);
+}
+
+int SkOpSegment::updateOppWindingReverse(const SkOpAngle* angle) const {
+    int startIndex = angle->start();
+    int endIndex = angle->end();
+    return updateOppWinding(startIndex, endIndex);
+}
+
+int SkOpSegment::updateWinding(int index, int endIndex) const {
+    int lesser = SkMin32(index, endIndex);
+    int winding = windSum(lesser);
+    int spanWinding = spanSign(index, endIndex);
+    if (winding && UseInnerWinding(winding - spanWinding, winding) && winding != SK_MaxS32) {
+        winding -= spanWinding;
+    }
+    return winding;
+}
+
+int SkOpSegment::updateWinding(const SkOpAngle* angle) const {
+    int startIndex = angle->start();
+    int endIndex = angle->end();
+    return updateWinding(endIndex, startIndex);
+}
+
+int SkOpSegment::updateWindingReverse(const SkOpAngle* angle) const {
+    int startIndex = angle->start();
+    int endIndex = angle->end();
+    return updateWinding(startIndex, endIndex);
+}
+
+int SkOpSegment::windingAtT(double tHit, int tIndex, bool crossOpp, SkScalar* dx) const {
+    if (approximately_zero(tHit - t(tIndex))) {  // if we hit the end of a span, disregard
+        return SK_MinS32;
+    }
+    int winding = crossOpp ? oppSum(tIndex) : windSum(tIndex);
+    SkASSERT(winding != SK_MinS32);
+    int windVal = crossOpp ? oppValue(tIndex) : windValue(tIndex);
+#if DEBUG_WINDING_AT_T
+    SkDebugf("%s oldWinding=%d windValue=%d", __FUNCTION__, winding, windVal);
+#endif
+    // see if a + change in T results in a +/- change in X (compute x'(T))
+    *dx = (*CurveSlopeAtT[fVerb])(fPts, tHit).fX;
+    if (fVerb > SkPath::kLine_Verb && approximately_zero(*dx)) {
+        *dx = fPts[2].fX - fPts[1].fX - *dx;
+    }
+    if (*dx == 0) {
+#if DEBUG_WINDING_AT_T
+        SkDebugf(" dx=0 winding=SK_MinS32\n");
+#endif
+        return SK_MinS32;
+    }
+    if (winding * *dx > 0) {  // if same signs, result is negative
+        winding += *dx > 0 ? -windVal : windVal;
+    }
+#if DEBUG_WINDING_AT_T
+    SkDebugf(" dx=%c winding=%d\n", *dx > 0 ? '+' : '-', winding);
+#endif
+    return winding;
+}
+
+int SkOpSegment::windSum(const SkOpAngle* angle) const {
+    int start = angle->start();
+    int end = angle->end();
+    int index = SkMin32(start, end);
+    return windSum(index);
+}
+
+int SkOpSegment::windValue(const SkOpAngle* angle) const {
+    int start = angle->start();
+    int end = angle->end();
+    int index = SkMin32(start, end);
+    return windValue(index);
+}
+
+int SkOpSegment::windValueAt(double t) const {
+    int count = fTs.count();
+    for (int index = 0; index < count; ++index) {
+        if (fTs[index].fT == t) {
+            return fTs[index].fWindValue;
+        }
+    }
+    SkASSERT(0);
+    return 0;
+}
+
+void SkOpSegment::zeroSpan(SkOpSpan* span) {
+    SkASSERT(span->fWindValue > 0 || span->fOppValue > 0);
+    span->fWindValue = 0;
+    span->fOppValue = 0;
+    SkASSERT(!span->fDone);
+    span->fDone = true;
+    ++fDoneSpans;
+}
+    
+#if DEBUG_SWAP_TOP
+bool SkOpSegment::controlsContainedByEnds(int tStart, int tEnd) const {
+    if (fVerb != SkPath::kCubic_Verb) {
+        return false;
+    }
+    SkDCubic dst = SkDCubic::SubDivide(fPts, fTs[tStart].fT, fTs[tEnd].fT);
+    return dst.controlsContainedByEnds();
+}
+#endif
+
+#if DEBUG_CONCIDENT
+// SkASSERT if pair has not already been added
+void SkOpSegment::debugAddTPair(double t, const SkOpSegment& other, double otherT) const {
+    for (int i = 0; i < fTs.count(); ++i) {
+        if (fTs[i].fT == t && fTs[i].fOther == &other && fTs[i].fOtherT == otherT) {
+            return;
+        }
+    }
+    SkASSERT(0);
+}
+#endif
+
+#if DEBUG_CONCIDENT
+void SkOpSegment::debugShowTs() const {
+    SkDebugf("%s id=%d", __FUNCTION__, fID);
+    int lastWind = -1;
+    int lastOpp = -1;
+    double lastT = -1;
+    int i;
+    for (i = 0; i < fTs.count(); ++i) {
+        bool change = lastT != fTs[i].fT || lastWind != fTs[i].fWindValue
+                || lastOpp != fTs[i].fOppValue;
+        if (change && lastWind >= 0) {
+            SkDebugf(" t=%1.3g %1.9g,%1.9g w=%d o=%d]",
+                    lastT, xyAtT(i - 1).fX, xyAtT(i - 1).fY, lastWind, lastOpp);
+        }
+        if (change) {
+            SkDebugf(" [o=%d", fTs[i].fOther->fID);
+            lastWind = fTs[i].fWindValue;
+            lastOpp = fTs[i].fOppValue;
+            lastT = fTs[i].fT;
+        } else {
+            SkDebugf(",%d", fTs[i].fOther->fID);
+        }
+    }
+    if (i <= 0) {
+        return;
+    }
+    SkDebugf(" t=%1.3g %1.9g,%1.9g w=%d o=%d]",
+            lastT, xyAtT(i - 1).fX, xyAtT(i - 1).fY, lastWind, lastOpp);
+    if (fOperand) {
+        SkDebugf(" operand");
+    }
+    if (done()) {
+        SkDebugf(" done");
+    }
+    SkDebugf("\n");
+}
+#endif
+
+#if DEBUG_ACTIVE_SPANS
+void SkOpSegment::debugShowActiveSpans() const {
+    if (done()) {
+        return;
+    }
+#if DEBUG_ACTIVE_SPANS_SHORT_FORM
+    int lastId = -1;
+    double lastT = -1;
+#endif
+    for (int i = 0; i < fTs.count(); ++i) {
+        SkASSERT(&fTs[i] == &fTs[i].fOther->fTs[fTs[i].fOtherIndex].fOther->
+                fTs[fTs[i].fOther->fTs[fTs[i].fOtherIndex].fOtherIndex]);
+        if (fTs[i].fDone) {
+            continue;
+        }
+#if DEBUG_ACTIVE_SPANS_SHORT_FORM
+        if (lastId == fID && lastT == fTs[i].fT) {
+            continue;
+        }
+        lastId = fID;
+        lastT = fTs[i].fT;
+#endif
+        SkDebugf("%s id=%d", __FUNCTION__, fID);
+        SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+        for (int vIndex = 1; vIndex <= fVerb; ++vIndex) {
+            SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+        }
+        const SkOpSpan* span = &fTs[i];
+        SkDebugf(") t=%1.9g (%1.9g,%1.9g)", span->fT, xAtT(span), yAtT(span));
+        int iEnd = i + 1;
+        while (fTs[iEnd].fT < 1 && approximately_equal(fTs[i].fT, fTs[iEnd].fT)) {
+            ++iEnd;
+        }
+        SkDebugf(" tEnd=%1.9g", fTs[iEnd].fT);
+        const SkOpSegment* other = fTs[i].fOther;
+        SkDebugf(" other=%d otherT=%1.9g otherIndex=%d windSum=",
+                other->fID, fTs[i].fOtherT, fTs[i].fOtherIndex);
+        if (fTs[i].fWindSum == SK_MinS32) {
+            SkDebugf("?");
+        } else {
+            SkDebugf("%d", fTs[i].fWindSum);
+        }
+        SkDebugf(" windValue=%d oppValue=%d\n", fTs[i].fWindValue, fTs[i].fOppValue);
+    }
+}
+#endif
+
+
+#if DEBUG_MARK_DONE || DEBUG_UNSORTABLE
+void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding) {
+    const SkPoint& pt = xyAtT(&span);
+    SkDebugf("%s id=%d", fun, fID);
+    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+    for (int vIndex = 1; vIndex <= fVerb; ++vIndex) {
+        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+    }
+    SkASSERT(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
+            fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]);
+    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d windSum=",
+            span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.fY,
+            (&span)[1].fT, winding);
+    if (span.fWindSum == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", span.fWindSum);
+    }
+    SkDebugf(" windValue=%d\n", span.fWindValue);
+}
+
+void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding,
+                                      int oppWinding) {
+    const SkPoint& pt = xyAtT(&span);
+    SkDebugf("%s id=%d", fun, fID);
+    SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
+    for (int vIndex = 1; vIndex <= fVerb; ++vIndex) {
+        SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
+    }
+    SkASSERT(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
+            fTs[span.fOther->fTs[span.fOtherIndex].fOtherIndex]);
+    SkDebugf(") t=%1.9g [%d] (%1.9g,%1.9g) tEnd=%1.9g newWindSum=%d newOppSum=%d oppSum=",
+            span.fT, span.fOther->fTs[span.fOtherIndex].fOtherIndex, pt.fX, pt.fY,
+            (&span)[1].fT, winding, oppWinding);
+    if (span.fOppSum == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", span.fOppSum);
+    }
+    SkDebugf(" windSum=");
+    if (span.fWindSum == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", span.fWindSum);
+    }
+    SkDebugf(" windValue=%d\n", span.fWindValue);
+}
+#endif
+
+#if DEBUG_SORT || DEBUG_SWAP_TOP
+void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first,
+        const int contourWinding, const int oppContourWinding) const {
+    if (--gDebugSortCount < 0) {
+        return;
+    }
+    SkASSERT(angles[first]->segment() == this);
+    SkASSERT(angles.count() > 1);
+    int lastSum = contourWinding;
+    int oppLastSum = oppContourWinding;
+    const SkOpAngle* firstAngle = angles[first];
+    int windSum = lastSum - spanSign(firstAngle);
+    int oppoSign = oppSign(firstAngle);
+    int oppWindSum = oppLastSum - oppoSign;
+    #define WIND_AS_STRING(x) char x##Str[12]; if (!valid_wind(x)) strcpy(x##Str, "?"); \
+        else snprintf(x##Str, sizeof(x##Str), "%d", x)
+    WIND_AS_STRING(contourWinding);
+    WIND_AS_STRING(oppContourWinding);
+    SkDebugf("%s %s contourWinding=%s oppContourWinding=%s sign=%d\n", fun, __FUNCTION__,
+            contourWindingStr, oppContourWindingStr, spanSign(angles[first]));
+    int index = first;
+    bool firstTime = true;
+    do {
+        const SkOpAngle& angle = *angles[index];
+        const SkOpSegment& segment = *angle.segment();
+        int start = angle.start();
+        int end = angle.end();
+        const SkOpSpan& sSpan = segment.fTs[start];
+        const SkOpSpan& eSpan = segment.fTs[end];
+        const SkOpSpan& mSpan = segment.fTs[SkMin32(start, end)];
+        bool opp = segment.fOperand ^ fOperand;
+        if (!firstTime) {
+            oppoSign = segment.oppSign(&angle);
+            if (opp) {
+                oppLastSum = oppWindSum;
+                oppWindSum -= segment.spanSign(&angle);
+                if (oppoSign) {
+                    lastSum = windSum;
+                    windSum -= oppoSign;
+                }
+            } else {
+                lastSum = windSum;
+                windSum -= segment.spanSign(&angle);
+                if (oppoSign) {
+                    oppLastSum = oppWindSum;
+                    oppWindSum -= oppoSign;
+                }
+            }
+        }
+        SkDebugf("%s [%d] %s", __FUNCTION__, index,
+                angle.unsortable() ? "*** UNSORTABLE *** " : "");
+    #if COMPACT_DEBUG_SORT
+        SkDebugf("id=%d %s start=%d (%1.9g,%,1.9g) end=%d (%1.9g,%,1.9g)",
+                segment.fID, kLVerbStr[segment.fVerb],
+                start, segment.xAtT(&sSpan), segment.yAtT(&sSpan), end,
+                segment.xAtT(&eSpan), segment.yAtT(&eSpan));
+    #else
+        switch (segment.fVerb) {
+            case SkPath::kLine_Verb:
+                SkDebugf(LINE_DEBUG_STR, LINE_DEBUG_DATA(segment.fPts));
+                break;
+            case SkPath::kQuad_Verb:
+                SkDebugf(QUAD_DEBUG_STR, QUAD_DEBUG_DATA(segment.fPts));
+                break;
+            case SkPath::kCubic_Verb:
+                SkDebugf(CUBIC_DEBUG_STR, CUBIC_DEBUG_DATA(segment.fPts));
+                break;
+            default:
+                SkASSERT(0);
+        }
+        SkDebugf(" tStart=%1.9g tEnd=%1.9g", sSpan.fT, eSpan.fT);
+    #endif
+        SkDebugf(" sign=%d windValue=%d windSum=", angle.sign(), mSpan.fWindValue);
+        #ifdef SK_DEBUG
+            winding_printf(mSpan.fWindSum);
+        #endif
+        int last, wind;
+        if (opp) {
+            last = oppLastSum;
+            wind = oppWindSum;
+        } else {
+            last = lastSum;
+            wind = windSum;
+        }
+        bool useInner = valid_wind(last) && valid_wind(wind) && UseInnerWinding(last, wind);
+        WIND_AS_STRING(last);
+        WIND_AS_STRING(wind);
+        WIND_AS_STRING(lastSum);
+        WIND_AS_STRING(oppLastSum);
+        WIND_AS_STRING(windSum);
+        WIND_AS_STRING(oppWindSum);
+        #undef WIND_AS_STRING
+        if (!oppoSign) {
+            SkDebugf(" %s->%s (max=%s)", lastStr, windStr, useInner ? windStr : lastStr);
+        } else {
+            SkDebugf(" %s->%s (%s->%s)", lastStr, windStr, opp ? lastSumStr : oppLastSumStr,
+                    opp ? windSumStr : oppWindSumStr);
+        }
+        SkDebugf(" done=%d tiny=%d opp=%d\n", mSpan.fDone, mSpan.fTiny, opp);
+#if false && DEBUG_ANGLE
+        angle.debugShow(segment.xyAtT(&sSpan));
+#endif
+        ++index;
+        if (index == angles.count()) {
+            index = 0;
+        }
+        if (firstTime) {
+            firstTime = false;
+        }
+    } while (index != first);
+}
+
+void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first) {
+    const SkOpAngle* firstAngle = angles[first];
+    const SkOpSegment* segment = firstAngle->segment();
+    int winding = segment->updateWinding(firstAngle);
+    int oppWinding = segment->updateOppWinding(firstAngle);
+    debugShowSort(fun, angles, first, winding, oppWinding);
+}
+
+#endif
+
+#if DEBUG_SHOW_WINDING
+int SkOpSegment::debugShowWindingValues(int slotCount, int ofInterest) const {
+    if (!(1 << fID & ofInterest)) {
+        return 0;
+    }
+    int sum = 0;
+    SkTDArray<char> slots;
+    slots.setCount(slotCount * 2);
+    memset(slots.begin(), ' ', slotCount * 2);
+    for (int i = 0; i < fTs.count(); ++i) {
+   //     if (!(1 << fTs[i].fOther->fID & ofInterest)) {
+   //         continue;
+   //     }
+        sum += fTs[i].fWindValue;
+        slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue);
+        sum += fTs[i].fOppValue;
+        slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue);
+    }
+    SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begin(), slotCount,
+            slots.begin() + slotCount);
+    return sum;
+}
+#endif
diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
new file mode 100644
index 0000000..1e9eb4b
--- /dev/null
+++ b/src/pathops/SkOpSegment.h
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkOpSegment_DEFINE
+#define SkOpSegment_DEFINE
+
+#include "SkOpAngle.h"
+#include "SkPathOpsBounds.h"
+#include "SkPathOpsCurve.h"
+#include "SkTDArray.h"
+
+class SkPathWriter;
+
+class SkOpSegment {
+public:
+    SkOpSegment() {
+#if DEBUG_DUMP
+        fID = ++gSegmentID;
+#endif
+    }
+
+    bool operator<(const SkOpSegment& rh) const {
+        return fBounds.fTop < rh.fBounds.fTop;
+    }
+
+    const SkPathOpsBounds& bounds() const {
+        return fBounds;
+    }
+
+    // OPTIMIZE
+    // when the edges are initially walked, they don't automatically get the prior and next
+    // edges assigned to positions t=0 and t=1. Doing that would remove the need for this check,
+    // and would additionally remove the need for similar checks in condition edges. It would
+    // also allow intersection code to assume end of segment intersections (maybe?)
+    bool complete() const {
+        int count = fTs.count();
+        return count > 1 && fTs[0].fT == 0 && fTs[--count].fT == 1;
+    }
+
+    bool done() const {
+        SkASSERT(fDoneSpans <= fTs.count());
+        return fDoneSpans == fTs.count();
+    }
+
+    bool done(int min) const {
+        return fTs[min].fDone;
+    }
+
+    bool done(const SkOpAngle* angle) const {
+        return done(SkMin32(angle->start(), angle->end()));
+    }
+
+    SkVector dxdy(int index) const {
+        return (*CurveSlopeAtT[fVerb])(fPts, fTs[index].fT);
+    }
+
+    SkScalar dy(int index) const {
+        return dxdy(index).fY;
+    }
+
+    bool intersected() const {
+        return fTs.count() > 0;
+    }
+
+    bool isCanceled(int tIndex) const {
+        return fTs[tIndex].fWindValue == 0 && fTs[tIndex].fOppValue == 0;
+    }
+
+    bool isConnected(int startIndex, int endIndex) const {
+        return fTs[startIndex].fWindSum != SK_MinS32 || fTs[endIndex].fWindSum != SK_MinS32;
+    }
+
+    bool isHorizontal() const {
+        return fBounds.fTop == fBounds.fBottom;
+    }
+
+    bool isVertical() const {
+        return fBounds.fLeft == fBounds.fRight;
+    }
+
+    bool isVertical(int start, int end) const {
+        return (*CurveIsVertical[fVerb])(fPts, start, end);
+    }
+
+    bool operand() const {
+        return fOperand;
+    }
+
+    int oppSign(const SkOpAngle* angle) const {
+        SkASSERT(angle->segment() == this);
+        return oppSign(angle->start(), angle->end());
+    }
+
+    int oppSign(int startIndex, int endIndex) const {
+        int result = startIndex < endIndex ? -fTs[startIndex].fOppValue : fTs[endIndex].fOppValue;
+#if DEBUG_WIND_BUMP
+        SkDebugf("%s oppSign=%d\n", __FUNCTION__, result);
+#endif
+        return result;
+    }
+
+    int oppSum(int tIndex) const {
+        return fTs[tIndex].fOppSum;
+    }
+
+    int oppSum(const SkOpAngle* angle) const {
+        int lesser = SkMin32(angle->start(), angle->end());
+        return fTs[lesser].fOppSum;
+    }
+
+    int oppValue(int tIndex) const {
+        return fTs[tIndex].fOppValue;
+    }
+
+    int oppValue(const SkOpAngle* angle) const {
+        int lesser = SkMin32(angle->start(), angle->end());
+        return fTs[lesser].fOppValue;
+    }
+
+    const SkPoint* pts() const {
+        return fPts;
+    }
+
+    void reset() {
+        init(NULL, (SkPath::Verb) -1, false, false);
+        fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax);
+        fTs.reset();
+    }
+
+    void setOppXor(bool isOppXor) {
+        fOppXor = isOppXor;
+    }
+
+    void setSpanT(int index, double t) {
+        SkOpSpan& span = fTs[index];
+        span.fT = t;
+        span.fOther->fTs[span.fOtherIndex].fOtherT = t;
+    }
+
+    void setUpWinding(int index, int endIndex, int* maxWinding, int* sumWinding) {
+        int deltaSum = spanSign(index, endIndex);
+        *maxWinding = *sumWinding;
+        *sumWinding -= deltaSum;
+    }
+
+    // OPTIMIZATION: mark as debugging only if used solely by tests
+    const SkOpSpan& span(int tIndex) const {
+        return fTs[tIndex];
+    }
+
+    int spanSign(const SkOpAngle* angle) const {
+        SkASSERT(angle->segment() == this);
+        return spanSign(angle->start(), angle->end());
+    }
+
+    int spanSign(int startIndex, int endIndex) const {
+        int result = startIndex < endIndex ? -fTs[startIndex].fWindValue : fTs[endIndex].fWindValue;
+#if DEBUG_WIND_BUMP
+        SkDebugf("%s spanSign=%d\n", __FUNCTION__, result);
+#endif
+        return result;
+    }
+
+    // OPTIMIZATION: mark as debugging only if used solely by tests
+    double t(int tIndex) const {
+        return fTs[tIndex].fT;
+    }
+
+    double tAtMid(int start, int end, double mid) const {
+        return fTs[start].fT * (1 - mid) + fTs[end].fT * mid;
+    }
+
+    bool unsortable(int index) const {
+        return fTs[index].fUnsortableStart || fTs[index].fUnsortableEnd;
+    }
+
+    void updatePts(const SkPoint pts[]) {
+        fPts = pts;
+    }
+    
+    SkPath::Verb verb() const {
+        return fVerb;
+    }
+
+    int windSum(int tIndex) const {
+        return fTs[tIndex].fWindSum;
+    }
+
+    int windValue(int tIndex) const {
+        return fTs[tIndex].fWindValue;
+    }
+
+    SkScalar xAtT(int index) const {
+        return xAtT(&fTs[index]);
+    }
+
+    SkScalar xAtT(const SkOpSpan* span) const {
+        return xyAtT(span).fX;
+    }
+
+    const SkPoint& xyAtT(const SkOpSpan* span) const {
+        return span->fPt;
+    }
+
+    // used only by right angle winding finding
+    SkPoint xyAtT(double mid) const {
+        return (*CurvePointAtT[fVerb])(fPts, mid);
+    }
+
+    const SkPoint& xyAtT(int index) const {
+        return xyAtT(&fTs[index]);
+    }
+    
+    SkScalar yAtT(int index) const {
+        return yAtT(&fTs[index]);
+    }
+
+    SkScalar yAtT(const SkOpSpan* span) const {
+        return xyAtT(span).fY;
+    }
+
+    bool activeAngle(int index, int* done, SkTDArray<SkOpAngle>* angles);
+    SkPoint activeLeftTop(bool onlySortable, int* firstT) const;
+    bool activeOp(int index, int endIndex, int xorMiMask, int xorSuMask, SkPathOp op);
+    bool activeOp(int xorMiMask, int xorSuMask, int index, int endIndex, SkPathOp op,
+                  int* sumMiWinding, int* sumSuWinding, int* maxWinding, int* sumWinding,
+                  int* oppMaxWinding, int* oppSumWinding);
+    bool activeWinding(int index, int endIndex);
+    bool activeWinding(int index, int endIndex, int* maxWinding, int* sumWinding);
+    void addCubic(const SkPoint pts[4], bool operand, bool evenOdd);
+    void addCurveTo(int start, int end, SkPathWriter* path, bool active) const;
+    void addLine(const SkPoint pts[2], bool operand, bool evenOdd);
+    void addOtherT(int index, double otherT, int otherIndex);
+    void addQuad(const SkPoint pts[3], bool operand, bool evenOdd);
+    int addSelfT(SkOpSegment* other, const SkPoint& pt, double newT);
+    int addT(SkOpSegment* other, const SkPoint& pt, double newT);
+    void addTCancel(double startT, double endT, SkOpSegment* other, double oStartT, double oEndT);
+    void addTCoincident(double startT, double endT, SkOpSegment* other, double oStartT,
+                        double oEndT);
+    void addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind, const SkPoint& pt);
+    int addUnsortableT(SkOpSegment* other, bool start, const SkPoint& pt, double newT);
+    bool betweenTs(int lesser, double testT, int greater) const;
+    int computeSum(int startIndex, int endIndex, bool binary);
+    int crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hitT, bool* hitSomething,
+                     double mid, bool opp, bool current) const;
+    SkOpSegment* findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* nextEnd,
+                            bool* unsortable, SkPathOp op, const int xorMiMask,
+                            const int xorSuMask);
+    SkOpSegment* findNextWinding(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* nextEnd,
+                                 bool* unsortable);
+    SkOpSegment* findNextXor(int* nextStart, int* nextEnd, bool* unsortable);
+    void findTooCloseToCall();
+    SkOpSegment* findTop(int* tIndex, int* endIndex, bool* unsortable, bool onlySortable);
+    void fixOtherTIndex();
+    void initWinding(int start, int end);
+    void initWinding(int start, int end, double tHit, int winding, SkScalar hitDx, int oppWind,
+            SkScalar hitOppDx);
+    bool isLinear(int start, int end) const;
+    bool isMissing(double startT) const;
+    bool isSimple(int end) const;
+    SkOpSpan* markAndChaseDoneBinary(int index, int endIndex);
+    SkOpSpan* markAndChaseDoneUnary(int index, int endIndex);
+    SkOpSpan* markAndChaseWinding(const SkOpAngle* angle, int winding, int oppWinding);
+    SkOpSpan* markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int oppSumWinding,
+                        bool activeAngle, const SkOpAngle* angle);
+    void markDone(int index, int winding);
+    void markDoneBinary(int index);
+    void markDoneUnary(int index);
+    SkOpSpan* markOneWinding(const char* funName, int tIndex, int winding);
+    SkOpSpan* markOneWinding(const char* funName, int tIndex, int winding, int oppWinding);
+    void markWinding(int index, int winding);
+    void markWinding(int index, int winding, int oppWinding);
+    bool nextCandidate(int* start, int* end) const;
+    int nextExactSpan(int from, int step) const;
+    int nextSpan(int from, int step) const;
+    void setUpWindings(int index, int endIndex, int* sumMiWinding, int* sumSuWinding,
+            int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding);
+    static bool SortAngles(const SkTDArray<SkOpAngle>& angles, SkTDArray<SkOpAngle*>* angleList);
+    void subDivide(int start, int end, SkPoint edge[4]) const;
+    void undoneSpan(int* start, int* end);
+    int updateOppWindingReverse(const SkOpAngle* angle) const;
+    int updateWindingReverse(const SkOpAngle* angle) const;
+    static bool UseInnerWinding(int outerWinding, int innerWinding);
+    int windingAtT(double tHit, int tIndex, bool crossOpp, SkScalar* dx) const;
+    int windSum(const SkOpAngle* angle) const;
+    int windValue(const SkOpAngle* angle) const;
+
+#if DEBUG_DUMP
+    int debugID() const {
+        return fID;
+    }
+#endif
+#if DEBUG_ACTIVE_SPANS
+    void debugShowActiveSpans() const;
+#endif
+#if DEBUG_SORT || DEBUG_SWAP_TOP
+    void debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first,
+            const int contourWinding, const int oppContourWinding) const;
+    void debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first);
+#endif
+#if DEBUG_CONCIDENT
+    void debugShowTs() const;
+#endif
+#if DEBUG_SHOW_WINDING
+    int debugShowWindingValues(int slotCount, int ofInterest) const;
+#endif
+
+private:
+    bool activeAngleOther(int index, int* done, SkTDArray<SkOpAngle>* angles);
+    bool activeAngleInner(int index, int* done, SkTDArray<SkOpAngle>* angles);
+    void addAngle(SkTDArray<SkOpAngle>* angles, int start, int end) const;
+    void addCancelOutsides(double tStart, double oStart, SkOpSegment* other, double oEnd);
+    void addCoinOutsides(const SkTDArray<double>& outsideTs, SkOpSegment* other, double oEnd);
+    void addTwoAngles(int start, int end, SkTDArray<SkOpAngle>* angles) const;
+    int advanceCoincidentOther(const SkOpSpan* test, double oEndT, int oIndex);
+    int advanceCoincidentThis(const SkOpSpan* oTest, bool opp, int index);
+    void buildAngles(int index, SkTDArray<SkOpAngle>* angles, bool includeOpp) const;
+    void buildAnglesInner(int index, SkTDArray<SkOpAngle>* angles) const;
+    int bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index,
+                           SkTDArray<double>* outsideTs);
+    int bumpCoincidentOther(const SkOpSpan& test, double oEndT, int& oIndex,
+                            SkTDArray<double>* oOutsideTs);
+    bool bumpSpan(SkOpSpan* span, int windDelta, int oppDelta);
+    bool clockwise(int tStart, int tEnd) const;
+    void decrementSpan(SkOpSpan* span);
+    bool equalPoints(int greaterTIndex, int lesserTIndex);
+    int findStartingEdge(const SkTDArray<SkOpAngle*>& sorted, int start, int end);
+    void init(const SkPoint pts[], SkPath::Verb verb, bool operand, bool evenOdd);
+    void matchWindingValue(int tIndex, double t, bool borrowWind);
+    SkOpSpan* markAndChaseDone(int index, int endIndex, int winding);
+    SkOpSpan* markAndChaseDoneBinary(const SkOpAngle* angle, int winding, int oppWinding);
+    SkOpSpan* markAndChaseWinding(const SkOpAngle* angle, const int winding);
+    SkOpSpan* markAndChaseWinding(int index, int endIndex, int winding, int oppWinding);
+    SkOpSpan* markAngle(int maxWinding, int sumWinding, bool activeAngle, const SkOpAngle* angle);
+    void markDoneBinary(int index, int winding, int oppWinding);
+    SkOpSpan* markAndChaseDoneUnary(const SkOpAngle* angle, int winding);
+    void markOneDone(const char* funName, int tIndex, int winding);
+    void markOneDoneBinary(const char* funName, int tIndex);
+    void markOneDoneBinary(const char* funName, int tIndex, int winding, int oppWinding);
+    void markOneDoneUnary(const char* funName, int tIndex);
+    void markUnsortable(int start, int end);
+    bool monotonicInY(int tStart, int tEnd) const;
+    bool multipleSpans(int end) const;
+    SkOpSegment* nextChase(int* index, const int step, int* min, SkOpSpan** last);
+    bool serpentine(int tStart, int tEnd) const;
+    void subDivideBounds(int start, int end, SkPathOpsBounds* bounds) const;
+    bool tiny(const SkOpAngle* angle) const;
+    static void TrackOutside(SkTDArray<double>* outsideTs, double end, double start);
+    int updateOppWinding(int index, int endIndex) const;
+    int updateOppWinding(const SkOpAngle* angle) const;
+    int updateWinding(int index, int endIndex) const;
+    int updateWinding(const SkOpAngle* angle) const;
+    SkOpSpan* verifyOneWinding(const char* funName, int tIndex);
+    SkOpSpan* verifyOneWindingU(const char* funName, int tIndex);
+    int windValueAt(double t) const;
+    void zeroSpan(SkOpSpan* span);
+
+#if DEBUG_SWAP_TOP
+    bool controlsContainedByEnds(int tStart, int tEnd) const;
+#endif
+#if DEBUG_CONCIDENT
+     void debugAddTPair(double t, const SkOpSegment& other, double otherT) const;
+#endif
+#if DEBUG_MARK_DONE || DEBUG_UNSORTABLE
+    void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding);
+    void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding, int oppWinding);
+#endif
+#if DEBUG_WINDING
+    static char as_digit(int value) {
+        return value < 0 ? '?' : value <= 9 ? '0' + value : '+';
+    }
+#endif
+
+    const SkPoint* fPts;
+    SkPathOpsBounds fBounds;
+    SkTDArray<SkOpSpan> fTs;  // two or more (always includes t=0 t=1)
+    // OPTIMIZATION: could pack donespans, verb, operand, xor into 1 int-sized value
+    int fDoneSpans;  // quick check that segment is finished
+    // OPTIMIZATION: force the following to be byte-sized
+    SkPath::Verb fVerb;
+    bool fOperand;
+    bool fXor;  // set if original contour had even-odd fill
+    bool fOppXor;  // set if opposite operand had even-odd fill
+#if DEBUG_DUMP
+    int fID;
+#endif
+};
+
+#endif
diff --git a/src/pathops/SkOpSpan.h b/src/pathops/SkOpSpan.h
new file mode 100644
index 0000000..3666623
--- /dev/null
+++ b/src/pathops/SkOpSpan.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkOpSpan_DEFINED
+#define SkOpSpan_DEFINED
+
+#include "SkPoint.h"
+
+class SkOpSegment;
+
+struct SkOpSpan {
+    SkOpSegment* fOther;
+    SkPoint fPt;  // computed when the curves are intersected
+    double fT;
+    double fOtherT;  // value at fOther[fOtherIndex].fT
+    int fOtherIndex;  // can't be used during intersection
+    int fWindSum;  // accumulated from contours surrounding this one.
+    int fOppSum;  // for binary operators: the opposite winding sum
+    int fWindValue;  // 0 == canceled; 1 == normal; >1 == coincident
+    int fOppValue;  // normally 0 -- when binary coincident edges combine, opp value goes here
+    bool fDone;  // if set, this span to next higher T has been processed
+    bool fUnsortableStart;  // set when start is part of an unsortable pair
+    bool fUnsortableEnd;  // set when end is part of an unsortable pair
+    bool fTiny;  // if set, span may still be considered once for edge following
+    bool fLoop;  // set when a cubic loops back to this point
+};
+
+#endif
diff --git a/src/pathops/SkPathOpsBounds.cpp b/src/pathops/SkPathOpsBounds.cpp
new file mode 100644
index 0000000..106cd30
--- /dev/null
+++ b/src/pathops/SkPathOpsBounds.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkPathOpsBounds.h"
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsQuad.h"
+
+void SkPathOpsBounds::setCubicBounds(const SkPoint a[4]) {
+    SkDCubic cubic;
+    cubic.set(a);
+    SkDRect dRect;
+    dRect.setBounds(cubic);
+    set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop),
+            SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom));
+}
+
+void SkPathOpsBounds::setLineBounds(const SkPoint a[2]) {
+    setPointBounds(a[0]);
+    add(a[1]);
+}
+
+void SkPathOpsBounds::setQuadBounds(const SkPoint a[3]) {
+    SkDQuad quad;
+    quad.set(a);
+    SkDRect dRect;
+    dRect.setBounds(quad);
+    set(SkDoubleToScalar(dRect.fLeft), SkDoubleToScalar(dRect.fTop),
+            SkDoubleToScalar(dRect.fRight), SkDoubleToScalar(dRect.fBottom));
+}
+
+void (SkPathOpsBounds::*SetCurveBounds[])(const SkPoint[]) = {
+    NULL,
+    &SkPathOpsBounds::setLineBounds,
+    &SkPathOpsBounds::setQuadBounds,
+    &SkPathOpsBounds::setCubicBounds
+};
diff --git a/src/pathops/SkPathOpsBounds.h b/src/pathops/SkPathOpsBounds.h
new file mode 100644
index 0000000..8102032
--- /dev/null
+++ b/src/pathops/SkPathOpsBounds.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOpBounds_DEFINED
+#define SkPathOpBounds_DEFINED
+
+#include "SkPathOpsRect.h"
+#include "SkRect.h"
+
+// SkPathOpsBounds, unlike SkRect, does not consider a line to be empty.
+struct SkPathOpsBounds : public SkRect {
+    static bool Intersects(const SkPathOpsBounds& a, const SkPathOpsBounds& b) {
+        return a.fLeft <= b.fRight && b.fLeft <= a.fRight &&
+                a.fTop <= b.fBottom && b.fTop <= a.fBottom;
+    }
+
+    // FIXME: add() is generically useful and could be added directly to SkRect
+    void add(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
+        if (left < fLeft) fLeft = left;
+        if (top < fTop) fTop = top;
+        if (right > fRight) fRight = right;
+        if (bottom > fBottom) fBottom = bottom;
+    }
+
+    void add(const SkPathOpsBounds& toAdd) {
+        add(toAdd.fLeft, toAdd.fTop, toAdd.fRight, toAdd.fBottom);
+    }
+
+    void add(const SkPoint& pt) {
+        if (pt.fX < fLeft) fLeft = pt.fX;
+        if (pt.fY < fTop) fTop = pt.fY;
+        if (pt.fX > fRight) fRight = pt.fX;
+        if (pt.fY > fBottom) fBottom = pt.fY;
+    }
+
+    // unlike isEmpty(), this permits lines, but not points
+    // FIXME: unused for now
+    bool isReallyEmpty() const {
+        // use !<= instead of > to detect NaN values
+        return !(fLeft <= fRight) || !(fTop <= fBottom)
+                || (fLeft == fRight && fTop == fBottom);
+    }
+
+    void setCubicBounds(const SkPoint a[4]);
+    void setLineBounds(const SkPoint a[2]);
+    void setQuadBounds(const SkPoint a[3]);
+
+    void setPointBounds(const SkPoint& pt) {
+        fLeft = fRight = pt.fX;
+        fTop = fBottom = pt.fY;
+    }
+    
+    typedef SkRect INHERITED;
+};
+
+extern void (SkPathOpsBounds::*SetCurveBounds[])(const SkPoint[]);
+
+#endif
diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp
new file mode 100644
index 0000000..0a65bc9
--- /dev/null
+++ b/src/pathops/SkPathOpsCommon.cpp
@@ -0,0 +1,578 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkOpEdgeBuilder.h"
+#include "SkPathOpsCommon.h"
+#include "SkPathWriter.h"
+#include "TSearch.h"
+
+static int contourRangeCheckY(const SkTDArray<SkOpContour*>& contourList, SkOpSegment** currentPtr,
+                              int* indexPtr, int* endIndexPtr, double* bestHit, SkScalar* bestDx,
+                              bool* tryAgain, double* midPtr, bool opp) {
+    const int index = *indexPtr;
+    const int endIndex = *endIndexPtr;
+    const double mid = *midPtr;
+    const SkOpSegment* current = *currentPtr;
+    double tAtMid = current->tAtMid(index, endIndex, mid);
+    SkPoint basePt = current->xyAtT(tAtMid);
+    int contourCount = contourList.count();
+    SkScalar bestY = SK_ScalarMin;
+    SkOpSegment* bestSeg = NULL;
+    int bestTIndex;
+    bool bestOpp;
+    bool hitSomething = false;
+    for (int cTest = 0; cTest < contourCount; ++cTest) {
+        SkOpContour* contour = contourList[cTest];
+        bool testOpp = contour->operand() ^ current->operand() ^ opp;
+        if (basePt.fY < contour->bounds().fTop) {
+            continue;
+        }
+        if (bestY > contour->bounds().fBottom) {
+            continue;
+        }
+        int segmentCount = contour->segments().count();
+        for (int test = 0; test < segmentCount; ++test) {
+            SkOpSegment* testSeg = &contour->segments()[test];
+            SkScalar testY = bestY;
+            double testHit;
+            int testTIndex = testSeg->crossedSpanY(basePt, &testY, &testHit, &hitSomething, tAtMid,
+                    testOpp, testSeg == current);
+            if (testTIndex < 0) {
+                if (testTIndex == SK_MinS32) {
+                    hitSomething = true;
+                    bestSeg = NULL;
+                    goto abortContours;  // vertical encountered, return and try different point
+                }
+                continue;
+            }
+            if (testSeg == current && current->betweenTs(index, testHit, endIndex)) {
+                double baseT = current->t(index);
+                double endT = current->t(endIndex);
+                double newMid = (testHit - baseT) / (endT - baseT);
+#if DEBUG_WINDING
+                double midT = current->tAtMid(index, endIndex, mid);
+                SkPoint midXY = current->xyAtT(midT);
+                double newMidT = current->tAtMid(index, endIndex, newMid);
+                SkPoint newXY = current->xyAtT(newMidT);
+                SkDebugf("%s [%d] mid=%1.9g->%1.9g s=%1.9g (%1.9g,%1.9g) m=%1.9g (%1.9g,%1.9g)"
+                        " n=%1.9g (%1.9g,%1.9g) e=%1.9g (%1.9g,%1.9g)\n", __FUNCTION__,
+                        current->debugID(), mid, newMid,
+                        baseT, current->xAtT(index), current->yAtT(index),
+                        baseT + mid * (endT - baseT), midXY.fX, midXY.fY,
+                        baseT + newMid * (endT - baseT), newXY.fX, newXY.fY,
+                        endT, current->xAtT(endIndex), current->yAtT(endIndex));
+#endif
+                *midPtr = newMid * 2;  // calling loop with divide by 2 before continuing
+                return SK_MinS32;
+            }
+            bestSeg = testSeg;
+            *bestHit = testHit;
+            bestOpp = testOpp;
+            bestTIndex = testTIndex;
+            bestY = testY;
+        }
+    }
+abortContours:
+    int result;
+    if (!bestSeg) {
+        result = hitSomething ? SK_MinS32 : 0;
+    } else {
+        if (bestSeg->windSum(bestTIndex) == SK_MinS32) {
+            *currentPtr = bestSeg;
+            *indexPtr = bestTIndex;
+            *endIndexPtr = bestSeg->nextSpan(bestTIndex, 1);
+            SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
+            *tryAgain = true;
+            return 0;
+        }
+        result = bestSeg->windingAtT(*bestHit, bestTIndex, bestOpp, bestDx);
+        SkASSERT(*bestDx);
+    }
+    double baseT = current->t(index);
+    double endT = current->t(endIndex);
+    *bestHit = baseT + mid * (endT - baseT);
+    return result;
+}
+
+SkOpSegment* FindUndone(SkTDArray<SkOpContour*>& contourList, int* start, int* end) {
+    int contourCount = contourList.count();
+    SkOpSegment* result;
+    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+        SkOpContour* contour = contourList[cIndex];
+        result = contour->undoneSegment(start, end);
+        if (result) {
+            return result;
+        }
+    }
+    return NULL;
+}
+
+SkOpSegment* FindChase(SkTDArray<SkOpSpan*>& chase, int& tIndex, int& endIndex) {
+    while (chase.count()) {
+        SkOpSpan* span;
+        chase.pop(&span);
+        const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex);
+        SkOpSegment* segment = backPtr.fOther;
+        tIndex = backPtr.fOtherIndex;
+        SkTDArray<SkOpAngle> angles;
+        int done = 0;
+        if (segment->activeAngle(tIndex, &done, &angles)) {
+            SkOpAngle* last = angles.end() - 1;
+            tIndex = last->start();
+            endIndex = last->end();
+   #if TRY_ROTATE
+            *chase.insert(0) = span;
+   #else
+            *chase.append() = span;
+   #endif
+            return last->segment();
+        }
+        if (done == angles.count()) {
+            continue;
+        }
+        SkTDArray<SkOpAngle*> sorted;
+        bool sortable = SkOpSegment::SortAngles(angles, &sorted);
+        int angleCount = sorted.count();
+#if DEBUG_SORT
+        sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0, 0, 0);
+#endif
+        if (!sortable) {
+            continue;
+        }
+        // find first angle, initialize winding to computed fWindSum
+        int firstIndex = -1;
+        const SkOpAngle* angle;
+        int winding;
+        do {
+            angle = sorted[++firstIndex];
+            segment = angle->segment();
+            winding = segment->windSum(angle);
+        } while (winding == SK_MinS32);
+        int spanWinding = segment->spanSign(angle->start(), angle->end());
+    #if DEBUG_WINDING
+        SkDebugf("%s winding=%d spanWinding=%d\n",
+                __FUNCTION__, winding, spanWinding);
+    #endif
+        // turn span winding into contour winding
+        if (spanWinding * winding < 0) {
+            winding += spanWinding;
+        }
+    #if DEBUG_SORT
+        segment->debugShowSort(__FUNCTION__, sorted, firstIndex, winding, 0);
+    #endif
+        // we care about first sign and whether wind sum indicates this
+        // edge is inside or outside. Maybe need to pass span winding
+        // or first winding or something into this function?
+        // advance to first undone angle, then return it and winding
+        // (to set whether edges are active or not)
+        int nextIndex = firstIndex + 1;
+        int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
+        angle = sorted[firstIndex];
+        winding -= angle->segment()->spanSign(angle);
+        do {
+            SkASSERT(nextIndex != firstIndex);
+            if (nextIndex == angleCount) {
+                nextIndex = 0;
+            }
+            angle = sorted[nextIndex];
+            segment = angle->segment();
+            int maxWinding = winding;
+            winding -= segment->spanSign(angle);
+    #if DEBUG_SORT
+            SkDebugf("%s id=%d maxWinding=%d winding=%d sign=%d\n", __FUNCTION__,
+                    segment->debugID(), maxWinding, winding, angle->sign());
+    #endif
+            tIndex = angle->start();
+            endIndex = angle->end();
+            int lesser = SkMin32(tIndex, endIndex);
+            const SkOpSpan& nextSpan = segment->span(lesser);
+            if (!nextSpan.fDone) {
+            // FIXME: this be wrong? assign startWinding if edge is in
+            // same direction. If the direction is opposite, winding to
+            // assign is flipped sign or +/- 1?
+                if (SkOpSegment::UseInnerWinding(maxWinding, winding)) {
+                    maxWinding = winding;
+                }
+                segment->markAndChaseWinding(angle, maxWinding, 0);
+                break;
+            }
+        } while (++nextIndex != lastIndex);
+        *chase.insert(0) = span;
+        return segment;
+    }
+    return NULL;
+}
+
+#if DEBUG_ACTIVE_SPANS
+void DebugShowActiveSpans(SkTDArray<SkOpContour*>& contourList) {
+    int index;
+    for (index = 0; index < contourList.count(); ++ index) {
+        contourList[index]->debugShowActiveSpans();
+    }
+}
+#endif
+
+static SkOpSegment* findSortableTop(const SkTDArray<SkOpContour*>& contourList,
+                                    int* index, int* endIndex, SkPoint* topLeft, bool* unsortable,
+                                    bool* done, bool onlySortable) {
+    SkOpSegment* result;
+    do {
+        SkPoint bestXY = {SK_ScalarMax, SK_ScalarMax};
+        int contourCount = contourList.count();
+        SkOpSegment* topStart = NULL;
+        *done = true;
+        for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+            SkOpContour* contour = contourList[cIndex];
+            if (contour->done()) {
+                continue;
+            }
+            const SkPathOpsBounds& bounds = contour->bounds();
+            if (bounds.fBottom < topLeft->fY) {
+                *done = false;
+                continue;
+            }
+            if (bounds.fBottom == topLeft->fY && bounds.fRight < topLeft->fX) {
+                *done = false;
+                continue;
+            }
+            contour->topSortableSegment(*topLeft, &bestXY, &topStart);
+            if (!contour->done()) {
+                *done = false;
+            }
+        }
+        if (!topStart) {
+            return NULL;
+        }
+        *topLeft = bestXY;
+        result = topStart->findTop(index, endIndex, unsortable, onlySortable);
+    } while (!result);
+    return result;
+}
+
+static int rightAngleWinding(const SkTDArray<SkOpContour*>& contourList,
+                             SkOpSegment** current, int* index, int* endIndex, double* tHit,
+                             SkScalar* hitDx, bool* tryAgain, bool opp) {
+    double test = 0.9;
+    int contourWinding;
+    do {
+        contourWinding = contourRangeCheckY(contourList, current, index, endIndex, tHit, hitDx,
+                tryAgain, &test, opp);
+        if (contourWinding != SK_MinS32 || *tryAgain) {
+            return contourWinding;
+        }
+        test /= 2;
+    } while (!approximately_negative(test));
+    SkASSERT(0);  // should be OK to comment out, but interested when this hits
+    return contourWinding;
+}
+
+static void skipVertical(const SkTDArray<SkOpContour*>& contourList,
+        SkOpSegment** current, int* index, int* endIndex) {
+    if (!(*current)->isVertical(*index, *endIndex)) {
+        return;
+    }
+    int contourCount = contourList.count();
+    for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
+        SkOpContour* contour = contourList[cIndex];
+        if (contour->done()) {
+            continue;
+        }
+        *current = contour->nonVerticalSegment(index, endIndex);
+        if (*current) {
+            return;
+        }
+    }
+}
+
+SkOpSegment* FindSortableTop(const SkTDArray<SkOpContour*>& contourList, bool* firstContour,
+                             int* indexPtr, int* endIndexPtr, SkPoint* topLeft, bool* unsortable,
+                             bool* done,  bool binary) {
+    SkOpSegment* current = findSortableTop(contourList, indexPtr, endIndexPtr, topLeft, unsortable,
+            done, true);
+    if (!current) {
+        return NULL;
+    }
+    const int index = *indexPtr;
+    const int endIndex = *endIndexPtr;
+    if (*firstContour) {
+        current->initWinding(index, endIndex);
+        *firstContour = false;
+        return current;
+    }
+    int minIndex = SkMin32(index, endIndex);
+    int sumWinding = current->windSum(minIndex);
+    if (sumWinding != SK_MinS32) {
+        return current;
+    }
+    sumWinding = current->computeSum(index, endIndex, binary);
+    if (sumWinding != SK_MinS32) {
+        return current;
+    }
+    int contourWinding;
+    int oppContourWinding = 0;
+    // the simple upward projection of the unresolved points hit unsortable angles
+    // shoot rays at right angles to the segment to find its winding, ignoring angle cases
+    bool tryAgain;
+    double tHit;
+    SkScalar hitDx = 0;
+    SkScalar hitOppDx = 0;
+    do {
+        // if current is vertical, find another candidate which is not
+        // if only remaining candidates are vertical, then they can be marked done
+        SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
+        skipVertical(contourList, &current, indexPtr, endIndexPtr);
+        
+        SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
+        tryAgain = false;
+        contourWinding = rightAngleWinding(contourList, &current, indexPtr, endIndexPtr, &tHit,
+                &hitDx, &tryAgain, false);
+        if (tryAgain) {
+            continue;
+        }
+        if (!binary) {
+            break;
+        }
+        oppContourWinding = rightAngleWinding(contourList, &current, indexPtr, endIndexPtr, &tHit,
+                &hitOppDx, &tryAgain, true);
+    } while (tryAgain);
+    current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWinding, hitDx, oppContourWinding,
+            hitOppDx);
+    return current;
+}
+
+void FixOtherTIndex(SkTDArray<SkOpContour*>* contourList) {
+    int contourCount = (*contourList).count();
+    for (int cTest = 0; cTest < contourCount; ++cTest) {
+        SkOpContour* contour = (*contourList)[cTest];
+        contour->fixOtherTIndex();
+    }
+}
+
+void SortSegments(SkTDArray<SkOpContour*>* contourList) {
+    int contourCount = (*contourList).count();
+    for (int cTest = 0; cTest < contourCount; ++cTest) {
+        SkOpContour* contour = (*contourList)[cTest];
+        contour->sortSegments();
+    }
+}
+
+void MakeContourList(SkTArray<SkOpContour>& contours, SkTDArray<SkOpContour*>& list,
+                     bool evenOdd, bool oppEvenOdd) {
+    int count = contours.count();
+    if (count == 0) {
+        return;
+    }
+    for (int index = 0; index < count; ++index) {
+        SkOpContour& contour = contours[index];
+        contour.setOppXor(contour.operand() ? evenOdd : oppEvenOdd);
+        *list.append() = &contour;
+    }
+    QSort<SkOpContour>(list.begin(), list.end() - 1);
+}
+
+static bool approximatelyEqual(const SkPoint& a, const SkPoint& b) {
+    return AlmostEqualUlps(a.fX, b.fX) && AlmostEqualUlps(a.fY, b.fY);
+}
+
+static bool lessThan(SkTDArray<double>& distances, const int one, const int two) {
+    return distances[one] < distances[two];
+}
+    /*
+        check start and end of each contour
+        if not the same, record them
+        match them up
+        connect closest
+        reassemble contour pieces into new path
+    */
+void Assemble(const SkPathWriter& path, SkPathWriter* simple) {
+#if DEBUG_PATH_CONSTRUCTION
+    SkDebugf("%s\n", __FUNCTION__);
+#endif
+    SkTArray<SkOpContour> contours;
+    SkOpEdgeBuilder builder(path, contours);
+    builder.finish();
+    int count = contours.count();
+    int outer;
+    SkTDArray<int> runs;  // indices of partial contours
+    for (outer = 0; outer < count; ++outer) {
+        const SkOpContour& eContour = contours[outer];
+        const SkPoint& eStart = eContour.start();
+        const SkPoint& eEnd = eContour.end();
+#if DEBUG_ASSEMBLE
+        SkDebugf("%s contour", __FUNCTION__);
+        if (!approximatelyEqual(eStart, eEnd)) {
+            SkDebugf("[%d]", runs.count());
+        } else {
+            SkDebugf("   ");
+        }
+        SkDebugf(" start=(%1.9g,%1.9g) end=(%1.9g,%1.9g)\n",
+                eStart.fX, eStart.fY, eEnd.fX, eEnd.fY);
+#endif
+        if (approximatelyEqual(eStart, eEnd)) {
+            eContour.toPath(simple);
+            continue;
+        }
+        *runs.append() = outer;
+    }
+    count = runs.count();
+    if (count == 0) {
+        return;
+    }
+    SkTDArray<int> sLink, eLink;
+    sLink.setCount(count);
+    eLink.setCount(count);
+    int rIndex, iIndex;
+    for (rIndex = 0; rIndex < count; ++rIndex) {
+        sLink[rIndex] = eLink[rIndex] = SK_MaxS32;
+    }
+    SkTDArray<double> distances;
+    const int ends = count * 2;  // all starts and ends
+    const int entries = (ends - 1) * count;  // folded triangle : n * (n - 1) / 2
+    distances.setCount(entries);
+    for (rIndex = 0; rIndex < ends - 1; ++rIndex) {
+        outer = runs[rIndex >> 1];
+        const SkOpContour& oContour = contours[outer];
+        const SkPoint& oPt = rIndex & 1 ? oContour.end() : oContour.start();
+        const int row = rIndex < count - 1 ? rIndex * ends : (ends - rIndex - 2)
+                * ends - rIndex - 1;
+        for (iIndex = rIndex + 1; iIndex < ends; ++iIndex) {
+            int inner = runs[iIndex >> 1];
+            const SkOpContour& iContour = contours[inner];
+            const SkPoint& iPt = iIndex & 1 ? iContour.end() : iContour.start();
+            double dx = iPt.fX - oPt.fX;
+            double dy = iPt.fY - oPt.fY;
+            double dist = dx * dx + dy * dy;
+            distances[row + iIndex] = dist;  // oStart distance from iStart
+        }
+    }
+    SkTDArray<int> sortedDist;
+    sortedDist.setCount(entries);
+    for (rIndex = 0; rIndex < entries; ++rIndex) {
+        sortedDist[rIndex] = rIndex;
+    }
+    QSort<SkTDArray<double>, int>(distances, sortedDist.begin(), sortedDist.end() - 1, lessThan);
+    int remaining = count;  // number of start/end pairs
+    for (rIndex = 0; rIndex < entries; ++rIndex) {
+        int pair = sortedDist[rIndex];
+        int row = pair / ends;
+        int col = pair - row * ends;
+        int thingOne = row < col ? row : ends - row - 2;
+        int ndxOne = thingOne >> 1;
+        bool endOne = thingOne & 1;
+        int* linkOne = endOne ? eLink.begin() : sLink.begin();
+        if (linkOne[ndxOne] != SK_MaxS32) {
+            continue;
+        }
+        int thingTwo = row < col ? col : ends - row + col - 1;
+        int ndxTwo = thingTwo >> 1;
+        bool endTwo = thingTwo & 1;
+        int* linkTwo = endTwo ? eLink.begin() : sLink.begin();
+        if (linkTwo[ndxTwo] != SK_MaxS32) {
+            continue;
+        }
+        SkASSERT(&linkOne[ndxOne] != &linkTwo[ndxTwo]);
+        bool flip = endOne == endTwo;
+        linkOne[ndxOne] = flip ? ~ndxTwo : ndxTwo;
+        linkTwo[ndxTwo] = flip ? ~ndxOne : ndxOne;
+        if (!--remaining) {
+            break;
+        }
+    }
+    SkASSERT(!remaining);
+#if DEBUG_ASSEMBLE
+    for (rIndex = 0; rIndex < count; ++rIndex) {
+        int s = sLink[rIndex];
+        int e = eLink[rIndex];
+        SkDebugf("%s %c%d <- s%d - e%d -> %c%d\n", __FUNCTION__, s < 0 ? 's' : 'e',
+                s < 0 ? ~s : s, rIndex, rIndex, e < 0 ? 'e' : 's', e < 0 ? ~e : e);
+    }
+#endif
+    rIndex = 0;
+    do {
+        bool forward = true;
+        bool first = true;
+        int sIndex = sLink[rIndex];
+        SkASSERT(sIndex != SK_MaxS32);
+        sLink[rIndex] = SK_MaxS32;
+        int eIndex;
+        if (sIndex < 0) {
+            eIndex = sLink[~sIndex];
+            sLink[~sIndex] = SK_MaxS32;
+        } else {
+            eIndex = eLink[sIndex];
+            eLink[sIndex] = SK_MaxS32;
+        }
+        SkASSERT(eIndex != SK_MaxS32);
+#if DEBUG_ASSEMBLE
+        SkDebugf("%s sIndex=%c%d eIndex=%c%d\n", __FUNCTION__, sIndex < 0 ? 's' : 'e',
+                    sIndex < 0 ? ~sIndex : sIndex, eIndex < 0 ? 's' : 'e',
+                    eIndex < 0 ? ~eIndex : eIndex);
+#endif
+        do {
+            outer = runs[rIndex];
+            const SkOpContour& contour = contours[outer];
+            if (first) {
+                first = false;
+                const SkPoint* startPtr = &contour.start();
+                simple->deferredMove(startPtr[0]);
+            }
+            if (forward) {
+                contour.toPartialForward(simple);
+            } else {
+                contour.toPartialBackward(simple);
+            }
+#if DEBUG_ASSEMBLE
+            SkDebugf("%s rIndex=%d eIndex=%s%d close=%d\n", __FUNCTION__, rIndex,
+                eIndex < 0 ? "~" : "", eIndex < 0 ? ~eIndex : eIndex,
+                sIndex == ((rIndex != eIndex) ^ forward ? eIndex : ~eIndex));
+#endif
+            if (sIndex == ((rIndex != eIndex) ^ forward ? eIndex : ~eIndex)) {
+                simple->close();
+                break;
+            }
+            if (forward) {
+                eIndex = eLink[rIndex];
+                SkASSERT(eIndex != SK_MaxS32);
+                eLink[rIndex] = SK_MaxS32;
+                if (eIndex >= 0) {
+                    SkASSERT(sLink[eIndex] == rIndex);
+                    sLink[eIndex] = SK_MaxS32;
+                } else {
+                    SkASSERT(eLink[~eIndex] == ~rIndex);
+                    eLink[~eIndex] = SK_MaxS32;
+                }
+            } else {
+                eIndex = sLink[rIndex];
+                SkASSERT(eIndex != SK_MaxS32);
+                sLink[rIndex] = SK_MaxS32;
+                if (eIndex >= 0) {
+                    SkASSERT(eLink[eIndex] == rIndex);
+                    eLink[eIndex] = SK_MaxS32;
+                } else {
+                    SkASSERT(sLink[~eIndex] == ~rIndex);
+                    sLink[~eIndex] = SK_MaxS32;
+                }
+            }
+            rIndex = eIndex;
+            if (rIndex < 0) {
+                forward ^= 1;
+                rIndex = ~rIndex;
+            }
+        } while (true);
+        for (rIndex = 0; rIndex < count; ++rIndex) {
+            if (sLink[rIndex] != SK_MaxS32) {
+                break;
+            }
+        }
+    } while (rIndex < count);
+#if DEBUG_ASSEMBLE
+    for (rIndex = 0; rIndex < count; ++rIndex) {
+       SkASSERT(sLink[rIndex] == SK_MaxS32);
+       SkASSERT(eLink[rIndex] == SK_MaxS32);
+    }
+#endif
+}
+
diff --git a/src/pathops/SkPathOpsCommon.h b/src/pathops/SkPathOpsCommon.h
new file mode 100644
index 0000000..5a46807
--- /dev/null
+++ b/src/pathops/SkPathOpsCommon.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOpsCommon_DEFINED
+#define SkPathOpsCommon_DEFINED
+
+#include "SkOpContour.h"
+
+class SkPathWriter;
+
+void Assemble(const SkPathWriter& path, SkPathWriter* simple);
+SkOpSegment* FindChase(SkTDArray<SkOpSpan*>& chase, int& tIndex, int& endIndex);
+SkOpSegment* FindSortableTop(const SkTDArray<SkOpContour*>& contourList, bool* firstContour,
+                             int* index, int* endIndex, SkPoint* topLeft, bool* unsortable,
+                             bool* done, bool binary);
+SkOpSegment* FindUndone(SkTDArray<SkOpContour*>& contourList, int* start, int* end);
+void FixOtherTIndex(SkTDArray<SkOpContour*>* contourList);
+void MakeContourList(SkTArray<SkOpContour>& contours, SkTDArray<SkOpContour*>& list,
+                     bool evenOdd, bool oppEvenOdd);
+void SortSegments(SkTDArray<SkOpContour*>* contourList);
+
+#if DEBUG_ACTIVE_SPANS
+void DebugShowActiveSpans(SkTDArray<SkOpContour*>& contourList);
+#endif
+
+#endif
diff --git a/src/pathops/SkPathOpsCubic.cpp b/src/pathops/SkPathOpsCubic.cpp
new file mode 100644
index 0000000..674213c
--- /dev/null
+++ b/src/pathops/SkPathOpsCubic.cpp
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkLineParameters.h"
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsQuad.h"
+#include "SkPathOpsRect.h"
+
+const int SkDCubic::gPrecisionUnit = 256;  // FIXME: test different values in test framework
+
+// FIXME: cache keep the bounds and/or precision with the caller?
+double SkDCubic::calcPrecision() const {
+    SkDRect dRect;
+    dRect.setBounds(*this);  // OPTIMIZATION: just use setRawBounds ?
+    double width = dRect.fRight - dRect.fLeft;
+    double height = dRect.fBottom - dRect.fTop;
+    return (width > height ? width : height) / gPrecisionUnit;
+}
+
+bool SkDCubic::clockwise() const {
+    double sum = (fPts[0].fX - fPts[3].fX) * (fPts[0].fY + fPts[3].fY);
+    for (int idx = 0; idx < 3; ++idx) {
+        sum += (fPts[idx + 1].fX - fPts[idx].fX) * (fPts[idx + 1].fY + fPts[idx].fY);
+    }
+    return sum <= 0;
+}
+
+void SkDCubic::Coefficients(const double* src, double* A, double* B, double* C, double* D) {
+    *A = src[6];  // d
+    *B = src[4] * 3;  // 3*c
+    *C = src[2] * 3;  // 3*b
+    *D = src[0];  // a
+    *A -= *D - *C + *B;     // A =   -a + 3*b - 3*c + d
+    *B += 3 * *D - 2 * *C;  // B =  3*a - 6*b + 3*c
+    *C -= 3 * *D;           // C = -3*a + 3*b
+}
+
+bool SkDCubic::controlsContainedByEnds() const {
+    SkDVector startTan = fPts[1] - fPts[0];
+    if (startTan.fX == 0 && startTan.fY == 0) {
+        startTan = fPts[2] - fPts[0];
+    }
+    SkDVector endTan = fPts[2] - fPts[3];
+    if (endTan.fX == 0 && endTan.fY == 0) {
+        endTan = fPts[1] - fPts[3];
+    }
+    if (startTan.dot(endTan) >= 0) {
+        return false;
+    }
+    SkDLine startEdge = {{fPts[0], fPts[0]}};
+    startEdge[1].fX -= startTan.fY;
+    startEdge[1].fY += startTan.fX;
+    SkDLine endEdge = {{fPts[3], fPts[3]}};
+    endEdge[1].fX -= endTan.fY;
+    endEdge[1].fY += endTan.fX;
+    double leftStart1 = startEdge.isLeft(fPts[1]);
+    if (leftStart1 * startEdge.isLeft(fPts[2]) < 0) {
+        return false;
+    }
+    double leftEnd1 = endEdge.isLeft(fPts[1]);
+    if (leftEnd1 * endEdge.isLeft(fPts[2]) < 0) {
+        return false;
+    }
+    return leftStart1 * leftEnd1 >= 0;
+}
+
+bool SkDCubic::endsAreExtremaInXOrY() const {
+    return (between(fPts[0].fX, fPts[1].fX, fPts[3].fX)
+            && between(fPts[0].fX, fPts[2].fX, fPts[3].fX))
+            || (between(fPts[0].fY, fPts[1].fY, fPts[3].fY)
+            && between(fPts[0].fY, fPts[2].fY, fPts[3].fY));
+}
+
+bool SkDCubic::isLinear(int startIndex, int endIndex) const {
+    SkLineParameters lineParameters;
+    lineParameters.cubicEndPoints(*this, startIndex, endIndex);
+    // FIXME: maybe it's possible to avoid this and compare non-normalized
+    lineParameters.normalize();
+    double distance = lineParameters.controlPtDistance(*this, 1);
+    if (!approximately_zero(distance)) {
+        return false;
+    }
+    distance = lineParameters.controlPtDistance(*this, 2);
+    return approximately_zero(distance);
+}
+
+bool SkDCubic::monotonicInY() const {
+    return between(fPts[0].fY, fPts[1].fY, fPts[3].fY)
+            && between(fPts[0].fY, fPts[2].fY, fPts[3].fY);
+}
+
+bool SkDCubic::serpentine() const {
+    if (!controlsContainedByEnds()) {
+        return false;
+    }
+    double wiggle = (fPts[0].fX - fPts[2].fX) * (fPts[0].fY + fPts[2].fY);
+    for (int idx = 0; idx < 2; ++idx) {
+        wiggle += (fPts[idx + 1].fX - fPts[idx].fX) * (fPts[idx + 1].fY + fPts[idx].fY);
+    }
+    double waggle = (fPts[1].fX - fPts[3].fX) * (fPts[1].fY + fPts[3].fY);
+    for (int idx = 1; idx < 3; ++idx) {
+        waggle += (fPts[idx + 1].fX - fPts[idx].fX) * (fPts[idx + 1].fY + fPts[idx].fY);
+    }
+    return wiggle * waggle < 0;
+}
+
+// cubic roots
+
+static const double PI = 3.141592653589793;
+
+// from SkGeometry.cpp (and Numeric Solutions, 5.6)
+int SkDCubic::RootsValidT(double A, double B, double C, double D, double t[3]) {
+    double s[3];
+    int realRoots = RootsReal(A, B, C, D, s);
+    int foundRoots = SkDQuad::AddValidTs(s, realRoots, t);
+    return foundRoots;
+}
+
+int SkDCubic::RootsReal(double A, double B, double C, double D, double s[3]) {
+#ifdef SK_DEBUG
+    // create a string mathematica understands
+    // GDB set print repe 15 # if repeated digits is a bother
+    //     set print elements 400 # if line doesn't fit
+    char str[1024];
+    sk_bzero(str, sizeof(str));
+    SK_SNPRINTF(str, sizeof(str), "Solve[%1.19g x^3 + %1.19g x^2 + %1.19g x + %1.19g == 0, x]",
+            A, B, C, D);
+    mathematica_ize(str, sizeof(str));
+#if ONE_OFF_DEBUG && ONE_OFF_DEBUG_MATHEMATICA
+    SkDebugf("%s\n", str);
+#endif
+#endif
+    if (approximately_zero(A)
+            && approximately_zero_when_compared_to(A, B)
+            && approximately_zero_when_compared_to(A, C)
+            && approximately_zero_when_compared_to(A, D)) {  // we're just a quadratic
+        return SkDQuad::RootsReal(B, C, D, s);
+    }
+    if (approximately_zero_when_compared_to(D, A)
+            && approximately_zero_when_compared_to(D, B)
+            && approximately_zero_when_compared_to(D, C)) {  // 0 is one root
+        int num = SkDQuad::RootsReal(A, B, C, s);
+        for (int i = 0; i < num; ++i) {
+            if (approximately_zero(s[i])) {
+                return num;
+            }
+        }
+        s[num++] = 0;
+        return num;
+    }
+    if (approximately_zero(A + B + C + D)) {  // 1 is one root
+        int num = SkDQuad::RootsReal(A, A + B, -D, s);
+        for (int i = 0; i < num; ++i) {
+            if (AlmostEqualUlps(s[i], 1)) {
+                return num;
+            }
+        }
+        s[num++] = 1;
+        return num;
+    }
+    double a, b, c;
+    {
+        double invA = 1 / A;
+        a = B * invA;
+        b = C * invA;
+        c = D * invA;
+    }
+    double a2 = a * a;
+    double Q = (a2 - b * 3) / 9;
+    double R = (2 * a2 * a - 9 * a * b + 27 * c) / 54;
+    double R2 = R * R;
+    double Q3 = Q * Q * Q;
+    double R2MinusQ3 = R2 - Q3;
+    double adiv3 = a / 3;
+    double r;
+    double* roots = s;
+    if (R2MinusQ3 < 0) {   // we have 3 real roots
+        double theta = acos(R / sqrt(Q3));
+        double neg2RootQ = -2 * sqrt(Q);
+
+        r = neg2RootQ * cos(theta / 3) - adiv3;
+        *roots++ = r;
+
+        r = neg2RootQ * cos((theta + 2 * PI) / 3) - adiv3;
+        if (!AlmostEqualUlps(s[0], r)) {
+            *roots++ = r;
+        }
+        r = neg2RootQ * cos((theta - 2 * PI) / 3) - adiv3;
+        if (!AlmostEqualUlps(s[0], r) && (roots - s == 1 || !AlmostEqualUlps(s[1], r))) {
+            *roots++ = r;
+        }
+    } else {  // we have 1 real root
+        double sqrtR2MinusQ3 = sqrt(R2MinusQ3);
+        double A = fabs(R) + sqrtR2MinusQ3;
+        A = SkDCubeRoot(A);
+        if (R > 0) {
+            A = -A;
+        }
+        if (A != 0) {
+            A += Q / A;
+        }
+        r = A - adiv3;
+        *roots++ = r;
+        if (AlmostEqualUlps(R2, Q3)) {
+            r = -A / 2 - adiv3;
+            if (!AlmostEqualUlps(s[0], r)) {
+                *roots++ = r;
+            }
+        }
+    }
+    return static_cast<int>(roots - s);
+}
+
+// from http://www.cs.sunysb.edu/~qin/courses/geometry/4.pdf
+// c(t)  = a(1-t)^3 + 3bt(1-t)^2 + 3c(1-t)t^2 + dt^3
+// c'(t) = -3a(1-t)^2 + 3b((1-t)^2 - 2t(1-t)) + 3c(2t(1-t) - t^2) + 3dt^2
+//       = 3(b-a)(1-t)^2 + 6(c-b)t(1-t) + 3(d-c)t^2
+static double derivative_at_t(const double* src, double t) {
+    double one_t = 1 - t;
+    double a = src[0];
+    double b = src[2];
+    double c = src[4];
+    double d = src[6];
+    return 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
+}
+
+// OPTIMIZE? compute t^2, t(1-t), and (1-t)^2 and pass them to another version of derivative at t?
+SkDVector SkDCubic::dxdyAtT(double t) const {
+    SkDVector result = { derivative_at_t(&fPts[0].fX, t), derivative_at_t(&fPts[0].fY, t) };
+    return result;
+}
+
+// OPTIMIZE? share code with formulate_F1DotF2
+int SkDCubic::findInflections(double tValues[]) const {
+    double Ax = fPts[1].fX - fPts[0].fX;
+    double Ay = fPts[1].fY - fPts[0].fY;
+    double Bx = fPts[2].fX - 2 * fPts[1].fX + fPts[0].fX;
+    double By = fPts[2].fY - 2 * fPts[1].fY + fPts[0].fY;
+    double Cx = fPts[3].fX + 3 * (fPts[1].fX - fPts[2].fX) - fPts[0].fX;
+    double Cy = fPts[3].fY + 3 * (fPts[1].fY - fPts[2].fY) - fPts[0].fY;
+    return SkDQuad::RootsValidT(Bx * Cy - By * Cx, Ax * Cy - Ay * Cx, Ax * By - Ay * Bx, tValues);
+}
+
+static void formulate_F1DotF2(const double src[], double coeff[4]) {
+    double a = src[2] - src[0];
+    double b = src[4] - 2 * src[2] + src[0];
+    double c = src[6] + 3 * (src[2] - src[4]) - src[0];
+    coeff[0] = c * c;
+    coeff[1] = 3 * b * c;
+    coeff[2] = 2 * b * b + c * a;
+    coeff[3] = a * b;
+}
+
+/** SkDCubic'(t) = At^2 + Bt + C, where
+    A = 3(-a + 3(b - c) + d)
+    B = 6(a - 2b + c)
+    C = 3(b - a)
+    Solve for t, keeping only those that fit between 0 < t < 1
+*/
+int SkDCubic::FindExtrema(double a, double b, double c, double d, double tValues[2]) {
+    // we divide A,B,C by 3 to simplify
+    double A = d - a + 3*(b - c);
+    double B = 2*(a - b - b + c);
+    double C = b - a;
+
+    return SkDQuad::RootsValidT(A, B, C, tValues);
+}
+
+/*  from SkGeometry.cpp
+    Looking for F' dot F'' == 0
+
+    A = b - a
+    B = c - 2b + a
+    C = d - 3c + 3b - a
+
+    F' = 3Ct^2 + 6Bt + 3A
+    F'' = 6Ct + 6B
+
+    F' dot F'' -> CCt^3 + 3BCt^2 + (2BB + CA)t + AB
+*/
+int SkDCubic::findMaxCurvature(double tValues[]) const {
+    double coeffX[4], coeffY[4];
+    int i;
+    formulate_F1DotF2(&fPts[0].fX, coeffX);
+    formulate_F1DotF2(&fPts[0].fY, coeffY);
+    for (i = 0; i < 4; i++) {
+        coeffX[i] = coeffX[i] + coeffY[i];
+    }
+    return RootsValidT(coeffX[0], coeffX[1], coeffX[2], coeffX[3], tValues);
+}
+
+SkDPoint SkDCubic::top(double startT, double endT) const {
+    SkDCubic sub = subDivide(startT, endT);
+    SkDPoint topPt = sub[0];
+    if (topPt.fY > sub[3].fY || (topPt.fY == sub[3].fY && topPt.fX > sub[3].fX)) {
+        topPt = sub[3];
+    }
+    double extremeTs[2];
+    if (!sub.monotonicInY()) {
+        int roots = FindExtrema(sub[0].fY, sub[1].fY, sub[2].fY, sub[3].fY, extremeTs);
+        for (int index = 0; index < roots; ++index) {
+            double t = startT + (endT - startT) * extremeTs[index];
+            SkDPoint mid = xyAtT(t);
+            if (topPt.fY > mid.fY || (topPt.fY == mid.fY && topPt.fX > mid.fX)) {
+                topPt = mid;
+            }
+        }
+    }
+    return topPt;
+}
+
+SkDPoint SkDCubic::xyAtT(double t) const {
+    double one_t = 1 - t;
+    double one_t2 = one_t * one_t;
+    double a = one_t2 * one_t;
+    double b = 3 * one_t2 * t;
+    double t2 = t * t;
+    double c = 3 * one_t * t2;
+    double d = t2 * t;
+    SkDPoint result = {a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX + d * fPts[3].fX,
+            a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY + d * fPts[3].fY};
+    return result;
+}
+
+/*
+ Given a cubic c, t1, and t2, find a small cubic segment.
+
+ The new cubic is defined as points A, B, C, and D, where
+ s1 = 1 - t1
+ s2 = 1 - t2
+ A = c[0]*s1*s1*s1 + 3*c[1]*s1*s1*t1 + 3*c[2]*s1*t1*t1 + c[3]*t1*t1*t1
+ D = c[0]*s2*s2*s2 + 3*c[1]*s2*s2*t2 + 3*c[2]*s2*t2*t2 + c[3]*t2*t2*t2
+
+ We don't have B or C. So We define two equations to isolate them.
+ First, compute two reference T values 1/3 and 2/3 from t1 to t2:
+
+ c(at (2*t1 + t2)/3) == E
+ c(at (t1 + 2*t2)/3) == F
+
+ Next, compute where those values must be if we know the values of B and C:
+
+ _12   =  A*2/3 + B*1/3
+ 12_   =  A*1/3 + B*2/3
+ _23   =  B*2/3 + C*1/3
+ 23_   =  B*1/3 + C*2/3
+ _34   =  C*2/3 + D*1/3
+ 34_   =  C*1/3 + D*2/3
+ _123  = (A*2/3 + B*1/3)*2/3 + (B*2/3 + C*1/3)*1/3 = A*4/9 + B*4/9 + C*1/9
+ 123_  = (A*1/3 + B*2/3)*1/3 + (B*1/3 + C*2/3)*2/3 = A*1/9 + B*4/9 + C*4/9
+ _234  = (B*2/3 + C*1/3)*2/3 + (C*2/3 + D*1/3)*1/3 = B*4/9 + C*4/9 + D*1/9
+ 234_  = (B*1/3 + C*2/3)*1/3 + (C*1/3 + D*2/3)*2/3 = B*1/9 + C*4/9 + D*4/9
+ _1234 = (A*4/9 + B*4/9 + C*1/9)*2/3 + (B*4/9 + C*4/9 + D*1/9)*1/3
+       =  A*8/27 + B*12/27 + C*6/27 + D*1/27
+       =  E
+ 1234_ = (A*1/9 + B*4/9 + C*4/9)*1/3 + (B*1/9 + C*4/9 + D*4/9)*2/3
+       =  A*1/27 + B*6/27 + C*12/27 + D*8/27
+       =  F
+ E*27  =  A*8    + B*12   + C*6     + D
+ F*27  =  A      + B*6    + C*12    + D*8
+
+Group the known values on one side:
+
+ M       = E*27 - A*8 - D     = B*12 + C* 6
+ N       = F*27 - A   - D*8   = B* 6 + C*12
+ M*2 - N = B*18
+ N*2 - M = C*18
+ B       = (M*2 - N)/18
+ C       = (N*2 - M)/18
+ */
+
+static double interp_cubic_coords(const double* src, double t) {
+    double ab = SkDInterp(src[0], src[2], t);
+    double bc = SkDInterp(src[2], src[4], t);
+    double cd = SkDInterp(src[4], src[6], t);
+    double abc = SkDInterp(ab, bc, t);
+    double bcd = SkDInterp(bc, cd, t);
+    double abcd = SkDInterp(abc, bcd, t);
+    return abcd;
+}
+
+SkDCubic SkDCubic::subDivide(double t1, double t2) const {
+    if (t1 == 0 && t2 == 1) {
+        return *this;
+    }
+    SkDCubic dst;
+    double ax = dst[0].fX = interp_cubic_coords(&fPts[0].fX, t1);
+    double ay = dst[0].fY = interp_cubic_coords(&fPts[0].fY, t1);
+    double ex = interp_cubic_coords(&fPts[0].fX, (t1*2+t2)/3);
+    double ey = interp_cubic_coords(&fPts[0].fY, (t1*2+t2)/3);
+    double fx = interp_cubic_coords(&fPts[0].fX, (t1+t2*2)/3);
+    double fy = interp_cubic_coords(&fPts[0].fY, (t1+t2*2)/3);
+    double dx = dst[3].fX = interp_cubic_coords(&fPts[0].fX, t2);
+    double dy = dst[3].fY = interp_cubic_coords(&fPts[0].fY, t2);
+    double mx = ex * 27 - ax * 8 - dx;
+    double my = ey * 27 - ay * 8 - dy;
+    double nx = fx * 27 - ax - dx * 8;
+    double ny = fy * 27 - ay - dy * 8;
+    /* bx = */ dst[1].fX = (mx * 2 - nx) / 18;
+    /* by = */ dst[1].fY = (my * 2 - ny) / 18;
+    /* cx = */ dst[2].fX = (nx * 2 - mx) / 18;
+    /* cy = */ dst[2].fY = (ny * 2 - my) / 18;
+    return dst;
+}
+
+void SkDCubic::subDivide(const SkDPoint& a, const SkDPoint& d,
+                         double t1, double t2, SkDPoint dst[2]) const {
+    double ex = interp_cubic_coords(&fPts[0].fX, (t1 * 2 + t2) / 3);
+    double ey = interp_cubic_coords(&fPts[0].fY, (t1 * 2 + t2) / 3);
+    double fx = interp_cubic_coords(&fPts[0].fX, (t1 + t2 * 2) / 3);
+    double fy = interp_cubic_coords(&fPts[0].fY, (t1 + t2 * 2) / 3);
+    double mx = ex * 27 - a.fX * 8 - d.fX;
+    double my = ey * 27 - a.fY * 8 - d.fY;
+    double nx = fx * 27 - a.fX - d.fX * 8;
+    double ny = fy * 27 - a.fY - d.fY * 8;
+    /* bx = */ dst[0].fX = (mx * 2 - nx) / 18;
+    /* by = */ dst[0].fY = (my * 2 - ny) / 18;
+    /* cx = */ dst[1].fX = (nx * 2 - mx) / 18;
+    /* cy = */ dst[1].fY = (ny * 2 - my) / 18;
+}
+
+/* classic one t subdivision */
+static void interp_cubic_coords(const double* src, double* dst, double t) {
+    double ab = SkDInterp(src[0], src[2], t);
+    double bc = SkDInterp(src[2], src[4], t);
+    double cd = SkDInterp(src[4], src[6], t);
+    double abc = SkDInterp(ab, bc, t);
+    double bcd = SkDInterp(bc, cd, t);
+    double abcd = SkDInterp(abc, bcd, t);
+
+    dst[0] = src[0];
+    dst[2] = ab;
+    dst[4] = abc;
+    dst[6] = abcd;
+    dst[8] = bcd;
+    dst[10] = cd;
+    dst[12] = src[6];
+}
+
+SkDCubicPair SkDCubic::chopAt(double t) const {
+    SkDCubicPair dst;
+    if (t == 0.5) {
+        dst.pts[0] = fPts[0];
+        dst.pts[1].fX = (fPts[0].fX + fPts[1].fX) / 2;
+        dst.pts[1].fY = (fPts[0].fY + fPts[1].fY) / 2;
+        dst.pts[2].fX = (fPts[0].fX + 2 * fPts[1].fX + fPts[2].fX) / 4;
+        dst.pts[2].fY = (fPts[0].fY + 2 * fPts[1].fY + fPts[2].fY) / 4;
+        dst.pts[3].fX = (fPts[0].fX + 3 * (fPts[1].fX + fPts[2].fX) + fPts[3].fX) / 8;
+        dst.pts[3].fY = (fPts[0].fY + 3 * (fPts[1].fY + fPts[2].fY) + fPts[3].fY) / 8;
+        dst.pts[4].fX = (fPts[1].fX + 2 * fPts[2].fX + fPts[3].fX) / 4;
+        dst.pts[4].fY = (fPts[1].fY + 2 * fPts[2].fY + fPts[3].fY) / 4;
+        dst.pts[5].fX = (fPts[2].fX + fPts[3].fX) / 2;
+        dst.pts[5].fY = (fPts[2].fY + fPts[3].fY) / 2;
+        dst.pts[6] = fPts[3];
+        return dst;
+    }
+    interp_cubic_coords(&fPts[0].fX, &dst.pts[0].fX, t);
+    interp_cubic_coords(&fPts[0].fY, &dst.pts[0].fY, t);
+    return dst;
+}
diff --git a/src/pathops/SkPathOpsCubic.h b/src/pathops/SkPathOpsCubic.h
new file mode 100644
index 0000000..48280fd
--- /dev/null
+++ b/src/pathops/SkPathOpsCubic.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPathOpsCubic_DEFINED
+#define SkPathOpsCubic_DEFINED
+
+#include "SkPathOpsPoint.h"
+#include "SkTDArray.h"
+
+struct SkDCubicPair {
+    const SkDCubic& first() const { return (const SkDCubic&) pts[0]; }
+    const SkDCubic& second() const { return (const SkDCubic&) pts[3]; }
+    SkDPoint pts[7];
+};
+
+struct SkDCubic {
+    SkDPoint fPts[4];
+
+    void set(const SkPoint pts[4]) {
+        fPts[0] = pts[0];
+        fPts[1] = pts[1];
+        fPts[2] = pts[2];
+        fPts[3] = pts[3];
+    }
+
+    static const int gPrecisionUnit;
+
+    const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < 4); return fPts[n]; }
+    SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < 4); return fPts[n]; }
+
+    double calcPrecision() const;
+    SkDCubicPair chopAt(double t) const;
+    bool clockwise() const;
+    static void Coefficients(const double* cubic, double* A, double* B, double* C, double* D);
+    bool controlsContainedByEnds() const;
+    SkDVector dxdyAtT(double t) const;
+    bool endsAreExtremaInXOrY() const;
+    static int FindExtrema(double a, double b, double c, double d, double tValue[2]);
+    int findInflections(double tValues[]) const;
+    int findMaxCurvature(double tValues[]) const;
+    bool isLinear(int startIndex, int endIndex) const;
+    bool monotonicInY() const;
+    static int RootsReal(double A, double B, double C, double D, double t[3]);
+    static int RootsValidT(const double A, const double B, const double C, double D, double s[3]);
+    bool serpentine() const;
+    SkDCubic subDivide(double t1, double t2) const;
+    static SkDCubic SubDivide(const SkPoint a[4], double t1, double t2) {
+        SkDCubic cubic;
+        cubic.set(a);
+        return cubic.subDivide(t1, t2);
+    }
+    void subDivide(const SkDPoint& a, const SkDPoint& d, double t1, double t2, SkDPoint p[2]) const;
+
+    static void SubDivide(const SkPoint pts[4], const SkDPoint& a, const SkDPoint& d, double t1,
+                          double t2, SkDPoint p[2]) {
+        SkDCubic cubic;
+        cubic.set(pts);
+        cubic.subDivide(a, d, t1, t2, p);
+    }
+
+    SkDPoint top(double startT, double endT) const;
+    void toQuadraticTs(double precision, SkTDArray<double>* ts) const;
+    SkDQuad toQuad() const;
+    SkDPoint xyAtT(double t) const;
+};
+
+#endif
diff --git a/src/pathops/SkPathOpsCurve.h b/src/pathops/SkPathOpsCurve.h
new file mode 100644
index 0000000..ca68a66
--- /dev/null
+++ b/src/pathops/SkPathOpsCurve.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOpsCurve_DEFINE
+#define SkPathOpsCurve_DEFINE
+
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsQuad.h"
+
+static SkDPoint dline_xy_at_t(const SkPoint a[2], double t) {
+    SkDLine line;
+    line.set(a);
+    return line.xyAtT(t);
+}
+
+static SkDPoint dquad_xy_at_t(const SkPoint a[3], double t) {
+    SkDQuad quad;
+    quad.set(a);
+    return quad.xyAtT(t);
+}
+
+static SkDPoint dcubic_xy_at_t(const SkPoint a[4], double t) {
+    SkDCubic cubic;
+    cubic.set(a);
+    return cubic.xyAtT(t);
+}
+
+static SkDPoint (* const CurveDPointAtT[])(const SkPoint[], double ) = {
+    NULL,
+    dline_xy_at_t,
+    dquad_xy_at_t,
+    dcubic_xy_at_t
+};
+
+static SkPoint fline_xy_at_t(const SkPoint a[2], double t) {
+    return dline_xy_at_t(a, t).asSkPoint();
+}
+
+static SkPoint fquad_xy_at_t(const SkPoint a[3], double t) {
+    return dquad_xy_at_t(a, t).asSkPoint();
+}
+
+static SkPoint fcubic_xy_at_t(const SkPoint a[4], double t) {
+    return dcubic_xy_at_t(a, t).asSkPoint();
+}
+
+static SkPoint (* const CurvePointAtT[])(const SkPoint[], double ) = {
+    NULL,
+    fline_xy_at_t,
+    fquad_xy_at_t,
+    fcubic_xy_at_t
+};
+
+static SkDVector dline_dxdy_at_t(const SkPoint a[2], double ) {
+    SkDLine line;
+    line.set(a);
+    return line[1] - line[0];
+}
+
+static SkDVector dquad_dxdy_at_t(const SkPoint a[3], double t) {
+    SkDQuad quad;
+    quad.set(a);
+    return quad.dxdyAtT(t);
+}
+
+static SkDVector dcubic_dxdy_at_t(const SkPoint a[4], double t) {
+    SkDCubic cubic;
+    cubic.set(a);
+    return cubic.dxdyAtT(t);
+}
+
+static SkDVector (* const CurveDSlopeAtT[])(const SkPoint[], double ) = {
+    NULL,
+    dline_dxdy_at_t,
+    dquad_dxdy_at_t,
+    dcubic_dxdy_at_t
+};
+
+static SkVector fline_dxdy_at_t(const SkPoint a[2], double ) {
+    return a[1] - a[0];
+}
+
+static SkVector fquad_dxdy_at_t(const SkPoint a[3], double t) {
+    return dquad_dxdy_at_t(a, t).asSkVector();
+}
+
+static SkVector fcubic_dxdy_at_t(const SkPoint a[4], double t) {
+    return dcubic_dxdy_at_t(a, t).asSkVector();
+}
+
+static SkVector (* const CurveSlopeAtT[])(const SkPoint[], double ) = {
+    NULL,
+    fline_dxdy_at_t,
+    fquad_dxdy_at_t,
+    fcubic_dxdy_at_t
+};
+
+static SkPoint quad_top(const SkPoint a[3], double startT, double endT) {
+    SkDQuad quad;
+    quad.set(a);
+    SkDPoint topPt = quad.top(startT, endT);
+    return topPt.asSkPoint();
+}
+
+static SkPoint cubic_top(const SkPoint a[4], double startT, double endT) {
+    SkDCubic cubic;
+    cubic.set(a);
+    SkDPoint topPt = cubic.top(startT, endT);
+    return topPt.asSkPoint();
+}
+
+static SkPoint (* const CurveTop[])(const SkPoint[], double , double ) = {
+    NULL,
+    NULL,
+    quad_top,
+    cubic_top
+};
+
+static bool line_is_vertical(const SkPoint a[2], double startT, double endT) {
+    SkDLine line;
+    line.set(a);
+    SkDPoint dst[2] = { line.xyAtT(startT), line.xyAtT(endT) };
+    return AlmostEqualUlps(dst[0].fX, dst[1].fX);
+}
+
+static bool quad_is_vertical(const SkPoint a[3], double startT, double endT) {
+    SkDQuad quad;
+    quad.set(a);
+    SkDQuad dst = quad.subDivide(startT, endT);
+    return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX);
+}
+
+static bool cubic_is_vertical(const SkPoint a[4], double startT, double endT) {
+    SkDCubic cubic;
+    cubic.set(a);
+    SkDCubic dst = cubic.subDivide(startT, endT);
+    return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, dst[2].fX)
+            && AlmostEqualUlps(dst[2].fX, dst[3].fX);
+}
+
+static bool (* const CurveIsVertical[])(const SkPoint[], double , double) = {
+    NULL,
+    line_is_vertical,
+    quad_is_vertical,
+    cubic_is_vertical
+};
+
+#endif
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
new file mode 100644
index 0000000..bef129c
--- /dev/null
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkPathOpsDebug.h"
+
+#if defined SK_DEBUG || !FORCE_RELEASE
+
+int gDebugMaxWindSum = SK_MaxS32;
+int gDebugMaxWindValue = SK_MaxS32;
+
+void mathematica_ize(char* str, size_t bufferLen) {
+    size_t len = strlen(str);
+    bool num = false;
+    for (size_t idx = 0; idx < len; ++idx) {
+        if (num && str[idx] == 'e') {
+            if (len + 2 >= bufferLen) {
+                return;
+            }
+            memmove(&str[idx + 2], &str[idx + 1], len - idx);
+            str[idx] = '*';
+            str[idx + 1] = '^';
+            ++len;
+        }
+        num = str[idx] >= '0' && str[idx] <= '9';
+    }
+}
+
+bool valid_wind(int wind) {
+    return wind > SK_MinS32 + 0xFFFF && wind < SK_MaxS32 - 0xFFFF;
+}
+
+void winding_printf(int wind) {
+    if (wind == SK_MinS32) {
+        SkDebugf("?");
+    } else {
+        SkDebugf("%d", wind);
+    }
+}
+#endif
+
+#if DEBUG_DUMP
+const char* kLVerbStr[] = {"", "line", "quad", "cubic"};
+// static const char* kUVerbStr[] = {"", "Line", "Quad", "Cubic"};
+int gContourID;
+int gSegmentID;
+#endif
+
+#if DEBUG_SORT || DEBUG_SWAP_TOP
+int gDebugSortCountDefault = SK_MaxS32;
+int gDebugSortCount;
+#endif
+
+#if DEBUG_ACTIVE_OP
+const char* kPathOpStr[] = {"diff", "sect", "union", "xor"};
+#endif
diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h
new file mode 100644
index 0000000..16ca176
--- /dev/null
+++ b/src/pathops/SkPathOpsDebug.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOpsDebug_DEFINED
+#define SkPathOpsDebug_DEFINED
+
+#include "SkTypes.h"
+
+#ifdef SK_RELEASE
+#define FORCE_RELEASE 1
+#else
+#define FORCE_RELEASE 1  // set force release to 1 for multiple thread -- no debugging
+#endif
+
+#define ONE_OFF_DEBUG 0
+#define ONE_OFF_DEBUG_MATHEMATICA 0
+
+#if defined SK_DEBUG || !FORCE_RELEASE
+
+#ifdef SK_BUILD_FOR_WIN
+    #define SK_RAND(seed) rand()
+    #define SK_SNPRINTF _snprintf 
+#else
+    #define SK_RAND(seed) rand_r(&seed)
+	#define SK_SNPRINTF snprintf
+#endif
+
+void mathematica_ize(char* str, size_t bufferSize);
+bool valid_wind(int winding);
+void winding_printf(int winding);
+
+extern int gDebugMaxWindSum;
+extern int gDebugMaxWindValue;
+#endif
+
+#if FORCE_RELEASE
+
+#define DEBUG_ACTIVE_OP 0
+#define DEBUG_ACTIVE_SPANS 0
+#define DEBUG_ACTIVE_SPANS_SHORT_FORM 0
+#define DEBUG_ADD_INTERSECTING_TS 0
+#define DEBUG_ADD_T_PAIR 0
+#define DEBUG_ANGLE 0
+#define DEBUG_AS_C_CODE 1
+#define DEBUG_ASSEMBLE 0
+#define DEBUG_CONCIDENT 0
+#define DEBUG_CROSS 0
+#define DEBUG_FLAT_QUADS 0
+#define DEBUG_FLOW 0
+#define DEBUG_MARK_DONE 0
+#define DEBUG_PATH_CONSTRUCTION 0
+#define DEBUG_SHOW_TEST_PROGRESS 0
+#define DEBUG_SHOW_WINDING 0
+#define DEBUG_SORT 0
+#define DEBUG_SWAP_TOP 0
+#define DEBUG_UNSORTABLE 0
+#define DEBUG_WIND_BUMP 0
+#define DEBUG_WINDING 0
+#define DEBUG_WINDING_AT_T 0
+
+#else
+
+#define DEBUG_ACTIVE_OP 1
+#define DEBUG_ACTIVE_SPANS 1
+#define DEBUG_ACTIVE_SPANS_SHORT_FORM 0
+#define DEBUG_ADD_INTERSECTING_TS 1
+#define DEBUG_ADD_T_PAIR 1
+#define DEBUG_ANGLE 1
+#define DEBUG_AS_C_CODE 1
+#define DEBUG_ASSEMBLE 1
+#define DEBUG_CONCIDENT 1
+#define DEBUG_CROSS 0
+#define DEBUG_FLAT_QUADS 0
+#define DEBUG_FLOW 1
+#define DEBUG_MARK_DONE 1
+#define DEBUG_PATH_CONSTRUCTION 1
+#define DEBUG_SHOW_TEST_PROGRESS 1
+#define DEBUG_SHOW_WINDING 0
+#define DEBUG_SORT 1
+#define DEBUG_SWAP_TOP 1
+#define DEBUG_UNSORTABLE 1
+#define DEBUG_WIND_BUMP 0
+#define DEBUG_WINDING 1
+#define DEBUG_WINDING_AT_T 1
+
+#endif
+
+#define DEBUG_DUMP (DEBUG_ACTIVE_OP | DEBUG_ACTIVE_SPANS | DEBUG_CONCIDENT | DEBUG_SORT | \
+        DEBUG_PATH_CONSTRUCTION)
+
+#if DEBUG_AS_C_CODE
+#define CUBIC_DEBUG_STR "{{%1.17g,%1.17g}, {%1.17g,%1.17g}, {%1.17g,%1.17g}, {%1.17g,%1.17g}}"
+#define QUAD_DEBUG_STR  "{{%1.17g,%1.17g}, {%1.17g,%1.17g}, {%1.17g,%1.17g}}"
+#define LINE_DEBUG_STR  "{{%1.17g,%1.17g}, {%1.17g,%1.17g}}"
+#define PT_DEBUG_STR "{{%1.17g,%1.17g}}"
+#else
+#define CUBIC_DEBUG_STR "(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)"
+#define QUAD_DEBUG_STR  "(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)"
+#define LINE_DEBUG_STR  "(%1.9g,%1.9g %1.9g,%1.9g)"
+#define PT_DEBUG_STR "(%1.9g,%1.9g)"
+#endif
+#define T_DEBUG_STR(t, n) #t "[" #n "]=%1.9g"
+#define TX_DEBUG_STR(t) #t "[%d]=%1.9g"
+#define CUBIC_DEBUG_DATA(c) c[0].fX, c[0].fY, c[1].fX, c[1].fY, c[2].fX, c[2].fY, c[3].fX, c[3].fY
+#define QUAD_DEBUG_DATA(q)  q[0].fX, q[0].fY, q[1].fX, q[1].fY, q[2].fX, q[2].fY
+#define LINE_DEBUG_DATA(l)  l[0].fX, l[0].fY, l[1].fX, l[1].fY
+#define PT_DEBUG_DATA(i, n) i.pt(n).fX, i.pt(n).fY
+
+#if DEBUG_DUMP
+extern const char* kLVerbStr[];
+// extern const char* kUVerbStr[];
+extern int gContourID;
+extern int gSegmentID;
+#endif
+
+#if DEBUG_SORT || DEBUG_SWAP_TOP
+extern int gDebugSortCountDefault;
+extern int gDebugSortCount;
+#endif
+
+#if DEBUG_ACTIVE_OP
+extern const char* kPathOpStr[];
+#endif
+
+#ifndef DEBUG_TEST
+#define DEBUG_TEST 0
+#endif
+
+#endif
diff --git a/src/pathops/SkPathOpsLine.cpp b/src/pathops/SkPathOpsLine.cpp
new file mode 100644
index 0000000..b7c91c9
--- /dev/null
+++ b/src/pathops/SkPathOpsLine.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkPathOpsLine.h"
+
+SkDLine SkDLine::subDivide(double t1, double t2) const {
+    SkDVector delta = tangent();
+    SkDLine dst = {{{
+            fPts[0].fX - t1 * delta.fX, fPts[0].fY - t1 * delta.fY}, {
+            fPts[0].fX - t2 * delta.fX, fPts[0].fY - t2 * delta.fY}}};
+    return dst;
+}
+
+// may have this below somewhere else already:
+// copying here because I thought it was clever
+
+// Copyright 2001, softSurfer (www.softsurfer.com)
+// This code may be freely used and modified for any purpose
+// providing that this copyright notice is included with it.
+// SoftSurfer makes no warranty for this code, and cannot be held
+// liable for any real or imagined damage resulting from its use.
+// Users of this code must verify correctness for their application.
+
+// Assume that a class is already given for the object:
+//    Point with coordinates {float x, y;}
+//===================================================================
+
+// isLeft(): tests if a point is Left|On|Right of an infinite line.
+//    Input:  three points P0, P1, and P2
+//    Return: >0 for P2 left of the line through P0 and P1
+//            =0 for P2 on the line
+//            <0 for P2 right of the line
+//    See: the January 2001 Algorithm on Area of Triangles
+//    return (float) ((P1.x - P0.x)*(P2.y - P0.y) - (P2.x - P0.x)*(P1.y - P0.y));
+double SkDLine::isLeft(const SkDPoint& pt) const {
+    SkDVector p0 = fPts[1] - fPts[0];
+    SkDVector p2 = pt - fPts[0];
+    return p0.cross(p2);
+}
+
+SkDPoint SkDLine::xyAtT(double t) const {
+    double one_t = 1 - t;
+    SkDPoint result = { one_t * fPts[0].fX + t * fPts[1].fX, one_t * fPts[0].fY + t * fPts[1].fY };
+    return result;
+}
diff --git a/src/pathops/SkPathOpsLine.h b/src/pathops/SkPathOpsLine.h
new file mode 100644
index 0000000..34bb658
--- /dev/null
+++ b/src/pathops/SkPathOpsLine.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOpsLine_DEFINED
+#define SkPathOpsLine_DEFINED
+
+#include "SkPathOpsPoint.h"
+
+struct SkDLine {
+    SkDPoint fPts[2];
+
+    void set(const SkPoint pts[2]) {
+        fPts[0] = pts[0];
+        fPts[1] = pts[1];
+    }
+
+    const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < 2); return fPts[n]; }
+    SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < 2); return fPts[n]; }
+
+    double isLeft(const SkDPoint& pt) const;
+    SkDLine subDivide(double t1, double t2) const;
+    static SkDLine SubDivide(const SkPoint a[2], double t1, double t2) {
+        SkDLine line;
+        line.set(a);
+        return line.subDivide(t1, t2);
+    }
+    SkDPoint xyAtT(double t) const;
+private:
+    SkDVector tangent() const { return fPts[0] - fPts[1]; }
+};
+
+#endif
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp
new file mode 100644
index 0000000..5a3576ff
--- /dev/null
+++ b/src/pathops/SkPathOpsOp.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkAddIntersections.h"
+#include "SkOpEdgeBuilder.h"
+#include "SkPathOpsCommon.h"
+#include "SkPathWriter.h"
+
+// FIXME: this and find chase should be merge together, along with
+// other code that walks winding in angles
+// OPTIMIZATION: Probably, the walked winding should be rolled into the angle structure
+// so it isn't duplicated by walkers like this one
+static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int& nextStart, int& nextEnd) {
+    while (chase.count()) {
+        SkOpSpan* span;
+        chase.pop(&span);
+        const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex);
+        SkOpSegment* segment = backPtr.fOther;
+        nextStart = backPtr.fOtherIndex;
+        SkTDArray<SkOpAngle> angles;
+        int done = 0;
+        if (segment->activeAngle(nextStart, &done, &angles)) {
+            SkOpAngle* last = angles.end() - 1;
+            nextStart = last->start();
+            nextEnd = last->end();
+   #if TRY_ROTATE
+            *chase.insert(0) = span;
+   #else
+            *chase.append() = span;
+   #endif
+            return last->segment();
+        }
+        if (done == angles.count()) {
+            continue;
+        }
+        SkTDArray<SkOpAngle*> sorted;
+        bool sortable = SkOpSegment::SortAngles(angles, &sorted);
+        int angleCount = sorted.count();
+#if DEBUG_SORT
+        sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0);
+#endif
+        if (!sortable) {
+            continue;
+        }
+        // find first angle, initialize winding to computed fWindSum
+        int firstIndex = -1;
+        const SkOpAngle* angle;
+        do {
+            angle = sorted[++firstIndex];
+            segment = angle->segment();
+        } while (segment->windSum(angle) == SK_MinS32);
+    #if DEBUG_SORT
+        segment->debugShowSort(__FUNCTION__, sorted, firstIndex);
+    #endif
+        int sumMiWinding = segment->updateWindingReverse(angle);
+        int sumSuWinding = segment->updateOppWindingReverse(angle);
+        if (segment->operand()) {
+            SkTSwap<int>(sumMiWinding, sumSuWinding);
+        }
+        int nextIndex = firstIndex + 1;
+        int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
+        SkOpSegment* first = NULL;
+        do {
+            SkASSERT(nextIndex != firstIndex);
+            if (nextIndex == angleCount) {
+                nextIndex = 0;
+            }
+            angle = sorted[nextIndex];
+            segment = angle->segment();
+            int start = angle->start();
+            int end = angle->end();
+            int maxWinding, sumWinding, oppMaxWinding, oppSumWinding;
+            segment->setUpWindings(start, end, &sumMiWinding, &sumSuWinding,
+                    &maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
+            if (!segment->done(angle)) {
+                if (!first) {
+                    first = segment;
+                    nextStart = start;
+                    nextEnd = end;
+                }
+                (void) segment->markAngle(maxWinding, sumWinding, oppMaxWinding,
+                    oppSumWinding, true, angle);
+            }
+        } while (++nextIndex != lastIndex);
+        if (first) {
+       #if TRY_ROTATE
+            *chase.insert(0) = span;
+       #else
+            *chase.append() = span;
+       #endif
+            return first;
+        }
+    }
+    return NULL;
+}
+
+/*
+static bool windingIsActive(int winding, int oppWinding, int spanWinding, int oppSpanWinding,
+        bool windingIsOp, PathOp op) {
+    bool active = windingIsActive(winding, spanWinding);
+    if (!active) {
+        return false;
+    }
+    if (oppSpanWinding && windingIsActive(oppWinding, oppSpanWinding)) {
+        switch (op) {
+            case kIntersect_Op:
+            case kUnion_Op:
+                return true;
+            case kDifference_Op: {
+                int absSpan = abs(spanWinding);
+                int absOpp = abs(oppSpanWinding);
+                return windingIsOp ? absSpan < absOpp : absSpan > absOpp;
+            }
+            case kXor_Op:
+                return spanWinding != oppSpanWinding;
+            default:
+                SkASSERT(0);
+        }
+    }
+    bool opActive = oppWinding != 0;
+    return gOpLookup[op][opActive][windingIsOp];
+}
+*/
+
+static bool bridgeOp(SkTDArray<SkOpContour*>& contourList, const SkPathOp op,
+        const int xorMask, const int xorOpMask, SkPathWriter* simple) {
+    bool firstContour = true;
+    bool unsortable = false;
+    bool topUnsortable = false;
+    SkPoint topLeft = {SK_ScalarMin, SK_ScalarMin};
+    do {
+        int index, endIndex;
+        bool done;
+        SkOpSegment* current = FindSortableTop(contourList, &firstContour, &index, &endIndex,
+                &topLeft, &topUnsortable, &done, true);
+        if (!current) {
+            if (topUnsortable || !done) {
+                topUnsortable = false;
+                SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMin);
+                topLeft.fX = topLeft.fY = SK_ScalarMin;
+                continue;
+            }
+            break;
+        }
+        SkTDArray<SkOpSpan*> chaseArray;
+        do {
+            if (current->activeOp(index, endIndex, xorMask, xorOpMask, op)) {
+                do {
+            #if DEBUG_ACTIVE_SPANS
+                    if (!unsortable && current->done()) {
+                        DebugShowActiveSpans(contourList);
+                    }
+            #endif
+                    SkASSERT(unsortable || !current->done());
+                    int nextStart = index;
+                    int nextEnd = endIndex;
+                    SkOpSegment* next = current->findNextOp(&chaseArray, &nextStart, &nextEnd,
+                            &unsortable, op, xorMask, xorOpMask);
+                    if (!next) {
+                        if (!unsortable && simple->hasMove()
+                                && current->verb() != SkPath::kLine_Verb
+                                && !simple->isClosed()) {
+                            current->addCurveTo(index, endIndex, simple, true);
+                            SkASSERT(simple->isClosed());
+                        }
+                        break;
+                    }
+        #if DEBUG_FLOW
+            SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
+                    current->debugID(), current->xyAtT(index).fX, current->xyAtT(index).fY,
+                    current->xyAtT(endIndex).fX, current->xyAtT(endIndex).fY);
+        #endif
+                    current->addCurveTo(index, endIndex, simple, true);
+                    current = next;
+                    index = nextStart;
+                    endIndex = nextEnd;
+                } while (!simple->isClosed() && ((!unsortable)
+                        || !current->done(SkMin32(index, endIndex))));
+                if (current->activeWinding(index, endIndex) && !simple->isClosed()) {
+                    SkASSERT(unsortable);
+                    int min = SkMin32(index, endIndex);
+                    if (!current->done(min)) {
+                        current->addCurveTo(index, endIndex, simple, true);
+                        current->markDoneBinary(min);
+                    }
+                }
+                simple->close();
+            } else {
+                SkOpSpan* last = current->markAndChaseDoneBinary(index, endIndex);
+                if (last && !last->fLoop) {
+                    *chaseArray.append() = last;
+                }
+            }
+            current = findChaseOp(chaseArray, index, endIndex);
+        #if DEBUG_ACTIVE_SPANS
+            DebugShowActiveSpans(contourList);
+        #endif
+            if (!current) {
+                break;
+            }
+        } while (true);
+    } while (true);
+    return simple->someAssemblyRequired();
+}
+
+void Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) {
+#if DEBUG_SORT || DEBUG_SWAP_TOP
+    gDebugSortCount = gDebugSortCountDefault;
+#endif
+    result->reset();
+    result->setFillType(SkPath::kEvenOdd_FillType);
+    // turn path into list of segments
+    SkTArray<SkOpContour> contours;
+    // FIXME: add self-intersecting cubics' T values to segment
+    SkOpEdgeBuilder builder(one, contours);
+    const int xorMask = builder.xorMask();
+    builder.addOperand(two);
+    builder.finish();
+    const int xorOpMask = builder.xorMask();
+    SkTDArray<SkOpContour*> contourList;
+    MakeContourList(contours, contourList, xorMask == kEvenOdd_PathOpsMask,
+            xorOpMask == kEvenOdd_PathOpsMask);
+    SkOpContour** currentPtr = contourList.begin();
+    if (!currentPtr) {
+        return;
+    }
+    SkOpContour** listEnd = contourList.end();
+    // find all intersections between segments
+    do {
+        SkOpContour** nextPtr = currentPtr;
+        SkOpContour* current = *currentPtr++;
+        if (current->containsCubics()) {
+            AddSelfIntersectTs(current);
+        }
+        SkOpContour* next;
+        do {
+            next = *nextPtr++;
+        } while (AddIntersectTs(current, next) && nextPtr != listEnd);
+    } while (currentPtr != listEnd);
+    // eat through coincident edges
+
+    int total = 0;
+    int index;
+    for (index = 0; index < contourList.count(); ++index) {
+        total += contourList[index]->segments().count();
+    }
+#if DEBUG_SHOW_WINDING
+    SkOpContour::debugShowWindingValues(contourList);
+#endif
+    CoincidenceCheck(&contourList, total);
+#if DEBUG_SHOW_WINDING
+    SkOpContour::debugShowWindingValues(contourList);
+#endif
+    FixOtherTIndex(&contourList);
+    SortSegments(&contourList);
+#if DEBUG_ACTIVE_SPANS
+    DebugShowActiveSpans(contourList);
+#endif
+    // construct closed contours
+    SkPathWriter wrapper(*result);
+    bridgeOp(contourList, op, xorMask, xorOpMask, &wrapper);
+    {  // if some edges could not be resolved, assemble remaining fragments
+        SkPath temp;
+        temp.setFillType(SkPath::kEvenOdd_FillType);
+        SkPathWriter assembled(temp);
+        Assemble(wrapper, &assembled);
+        *result = *assembled.nativePath();
+    }
+}
diff --git a/src/pathops/SkPathOpsPoint.cpp b/src/pathops/SkPathOpsPoint.cpp
new file mode 100644
index 0000000..dc9cde5
--- /dev/null
+++ b/src/pathops/SkPathOpsPoint.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkPathOpsPoint.h"
+
+SkDVector operator-(const SkDPoint& a, const SkDPoint& b) {
+    SkDVector v = {a.fX - b.fX, a.fY - b.fY};
+    return v;
+}
+
+SkDPoint operator+(const SkDPoint& a, const SkDVector& b) {
+    SkDPoint v = {a.fX + b.fX, a.fY + b.fY};
+    return v;
+}
diff --git a/src/pathops/SkPathOpsPoint.h b/src/pathops/SkPathOpsPoint.h
new file mode 100644
index 0000000..3805100
--- /dev/null
+++ b/src/pathops/SkPathOpsPoint.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOpsPoint_DEFINED
+#define SkPathOpsPoint_DEFINED
+
+#include "SkPathOpsTypes.h"
+#include "SkPoint.h"
+
+struct SkDVector {
+    double fX, fY;
+
+    friend SkDPoint operator+(const SkDPoint& a, const SkDVector& b);
+
+    void operator+=(const SkDVector& v) {
+        fX += v.fX;
+        fY += v.fY;
+    }
+
+    void operator-=(const SkDVector& v) {
+        fX -= v.fX;
+        fY -= v.fY;
+    }
+
+    void operator/=(const double s) {
+        fX /= s;
+        fY /= s;
+    }
+
+    void operator*=(const double s) {
+        fX *= s;
+        fY *= s;
+    }
+
+    SkVector asSkVector() const {
+        SkVector v = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)};
+        return v;
+    }
+
+    double cross(const SkDVector& a) const {
+        return fX * a.fY - fY * a.fX;
+    }
+
+    double dot(const SkDVector& a) const {
+        return fX * a.fX + fY * a.fY;
+    }
+
+    double length() const {
+        return sqrt(lengthSquared());
+    }
+
+    double lengthSquared() const {
+        return fX * fX + fY * fY;
+    }
+};
+
+struct SkDPoint {
+    double fX;
+    double fY;
+
+    void set(const SkPoint& pt) {
+        fX = pt.fX;
+        fY = pt.fY;
+    }
+
+    friend SkDVector operator-(const SkDPoint& a, const SkDPoint& b);
+
+    friend bool operator==(const SkDPoint& a, const SkDPoint& b) {
+        return a.fX == b.fX && a.fY == b.fY;
+    }
+
+    friend bool operator!=(const SkDPoint& a, const SkDPoint& b) {
+        return a.fX != b.fX || a.fY != b.fY;
+    }
+
+    void operator=(const SkPoint& pt) {
+        fX = pt.fX;
+        fY = pt.fY;
+    }
+
+
+    void operator+=(const SkDVector& v) {
+        fX += v.fX;
+        fY += v.fY;
+    }
+
+    void operator-=(const SkDVector& v) {
+        fX -= v.fX;
+        fY -= v.fY;
+    }
+
+    // note: this can not be implemented with
+    // return approximately_equal(a.fY, fY) && approximately_equal(a.fX, fX);
+    // because that will not take the magnitude of the values
+    bool approximatelyEqual(const SkDPoint& a) const {
+        double denom = SkTMax<double>(fabs(fX), SkTMax<double>(fabs(fY),
+                SkTMax<double>(fabs(a.fX), fabs(a.fY))));
+        if (denom == 0) {
+            return true;
+        }
+        double inv = 1 / denom;
+        return approximately_equal(fX * inv, a.fX * inv)
+                && approximately_equal(fY * inv, a.fY * inv);
+    }
+
+    bool approximatelyEqual(const SkPoint& a) const {
+        double denom = SkTMax<double>(fabs(fX), SkTMax<double>(fabs(fY),
+                SkScalarToDouble(SkTMax<SkScalar>(fabs(a.fX), fabs(a.fY)))));
+        if (denom == 0) {
+            return true;
+        }
+        double inv = 1 / denom;
+        return approximately_equal(fX * inv, a.fX * inv)
+                && approximately_equal(fY * inv, a.fY * inv);
+    }
+
+    bool approximatelyEqualHalf(const SkDPoint& a) const {
+        double denom = SkTMax<double>(fabs(fX), SkTMax<double>(fabs(fY),
+                SkTMax<double>(fabs(a.fX), fabs(a.fY))));
+        if (denom == 0) {
+            return true;
+        }
+        double inv = 1 / denom;
+        return approximately_equal_half(fX * inv, a.fX * inv)
+                && approximately_equal_half(fY * inv, a.fY * inv);
+    }
+
+    bool approximatelyZero() const {
+        return approximately_zero(fX) && approximately_zero(fY);
+    }
+
+    SkPoint asSkPoint() const {
+        SkPoint pt = {SkDoubleToScalar(fX), SkDoubleToScalar(fY)};
+        return pt;
+    }
+
+    double distance(const SkDPoint& a) const {
+        SkDVector temp = *this - a;
+        return temp.length();
+    }
+
+    double distanceSquared(const SkDPoint& a) const {
+        SkDVector temp = *this - a;
+        return temp.lengthSquared();
+    }
+
+    double moreRoughlyEqual(const SkDPoint& a) const {
+        return more_roughly_equal(a.fY, fY) && more_roughly_equal(a.fX, fX);
+    }
+
+    double roughlyEqual(const SkDPoint& a) const {
+        return roughly_equal(a.fY, fY) && roughly_equal(a.fX, fX);
+    }
+};
+
+#endif
diff --git a/src/pathops/SkPathOpsQuad.cpp b/src/pathops/SkPathOpsQuad.cpp
new file mode 100644
index 0000000..cbba2a3
--- /dev/null
+++ b/src/pathops/SkPathOpsQuad.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkLineParameters.h"
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsQuad.h"
+#include "SkPathOpsTriangle.h"
+
+// from http://blog.gludion.com/2009/08/distance-to-quadratic-bezier-curve.html
+// (currently only used by testing)
+double SkDQuad::nearestT(const SkDPoint& pt) const {
+    SkDVector pos = fPts[0] - pt;
+    // search points P of bezier curve with PM.(dP / dt) = 0
+    // a calculus leads to a 3d degree equation :
+    SkDVector A = fPts[1] - fPts[0];
+    SkDVector B = fPts[2] - fPts[1];
+    B -= A;
+    double a = B.dot(B);
+    double b = 3 * A.dot(B);
+    double c = 2 * A.dot(A) + pos.dot(B);
+    double d = pos.dot(A);
+    double ts[3];
+    int roots = SkDCubic::RootsValidT(a, b, c, d, ts);
+    double d0 = pt.distanceSquared(fPts[0]);
+    double d2 = pt.distanceSquared(fPts[2]);
+    double distMin = SkTMin<double>(d0, d2);
+    int bestIndex = -1;
+    for (int index = 0; index < roots; ++index) {
+        SkDPoint onQuad = xyAtT(ts[index]);
+        double dist = pt.distanceSquared(onQuad);
+        if (distMin > dist) {
+            distMin = dist;
+            bestIndex = index;
+        }
+    }
+    if (bestIndex >= 0) {
+        return ts[bestIndex];
+    }
+    return d0 < d2 ? 0 : 1;
+}
+
+bool SkDQuad::pointInHull(const SkDPoint& pt) const {
+    return ((const SkDTriangle&) fPts).contains(pt);
+}
+
+SkDPoint SkDQuad::top(double startT, double endT) const {
+    SkDQuad sub = subDivide(startT, endT);
+    SkDPoint topPt = sub[0];
+    if (topPt.fY > sub[2].fY || (topPt.fY == sub[2].fY && topPt.fX > sub[2].fX)) {
+        topPt = sub[2];
+    }
+    if (!between(sub[0].fY, sub[1].fY, sub[2].fY)) {
+        double extremeT;
+        if (FindExtrema(sub[0].fY, sub[1].fY, sub[2].fY, &extremeT)) {
+            extremeT = startT + (endT - startT) * extremeT;
+            SkDPoint test = xyAtT(extremeT);
+            if (topPt.fY > test.fY || (topPt.fY == test.fY && topPt.fX > test.fX)) {
+                topPt = test;
+            }
+        }
+    }
+    return topPt;
+}
+
+int SkDQuad::AddValidTs(double s[], int realRoots, double* t) {
+    int foundRoots = 0;
+    for (int index = 0; index < realRoots; ++index) {
+        double tValue = s[index];
+        if (approximately_zero_or_more(tValue) && approximately_one_or_less(tValue)) {
+            if (approximately_less_than_zero(tValue)) {
+                tValue = 0;
+            } else if (approximately_greater_than_one(tValue)) {
+                tValue = 1;
+            }
+            for (int idx2 = 0; idx2 < foundRoots; ++idx2) {
+                if (approximately_equal(t[idx2], tValue)) {
+                    goto nextRoot;
+                }
+            }
+            t[foundRoots++] = tValue;
+        }
+nextRoot:
+        {}
+    }
+    return foundRoots;
+}
+
+// note: caller expects multiple results to be sorted smaller first
+// note: http://en.wikipedia.org/wiki/Loss_of_significance has an interesting
+//  analysis of the quadratic equation, suggesting why the following looks at
+//  the sign of B -- and further suggesting that the greatest loss of precision
+//  is in b squared less two a c
+int SkDQuad::RootsValidT(double A, double B, double C, double t[2]) {
+    double s[2];
+    int realRoots = RootsReal(A, B, C, s);
+    int foundRoots = AddValidTs(s, realRoots, t);
+    return foundRoots;
+}
+
+/*
+Numeric Solutions (5.6) suggests to solve the quadratic by computing
+       Q = -1/2(B + sgn(B)Sqrt(B^2 - 4 A C))
+and using the roots
+      t1 = Q / A
+      t2 = C / Q
+*/
+// this does not discard real roots <= 0 or >= 1
+int SkDQuad::RootsReal(const double A, const double B, const double C, double s[2]) {
+    const double p = B / (2 * A);
+    const double q = C / A;
+    if (approximately_zero(A) && (approximately_zero_inverse(p) || approximately_zero_inverse(q))) {
+        if (approximately_zero(B)) {
+            s[0] = 0;
+            return C == 0;
+        }
+        s[0] = -C / B;
+        return 1;
+    }
+    /* normal form: x^2 + px + q = 0 */
+    const double p2 = p * p;
+    if (!AlmostEqualUlps(p2, q) && p2 < q) {
+        return 0;
+    }
+    double sqrt_D = 0;
+    if (p2 > q) {
+        sqrt_D = sqrt(p2 - q);
+    }
+    s[0] = sqrt_D - p;
+    s[1] = -sqrt_D - p;
+    return 1 + !AlmostEqualUlps(s[0], s[1]);
+}
+
+bool SkDQuad::isLinear(int startIndex, int endIndex) const {
+    SkLineParameters lineParameters;
+    lineParameters.quadEndPoints(*this, startIndex, endIndex);
+    // FIXME: maybe it's possible to avoid this and compare non-normalized
+    lineParameters.normalize();
+    double distance = lineParameters.controlPtDistance(*this);
+    return approximately_zero(distance);
+}
+
+SkDCubic SkDQuad::toCubic() const {
+    SkDCubic cubic;
+    cubic[0] = fPts[0];
+    cubic[2] = fPts[1];
+    cubic[3] = fPts[2];
+    cubic[1].fX = (cubic[0].fX + cubic[2].fX * 2) / 3;
+    cubic[1].fY = (cubic[0].fY + cubic[2].fY * 2) / 3;
+    cubic[2].fX = (cubic[3].fX + cubic[2].fX * 2) / 3;
+    cubic[2].fY = (cubic[3].fY + cubic[2].fY * 2) / 3;
+    return cubic;
+}
+
+SkDVector SkDQuad::dxdyAtT(double t) const {
+    double a = t - 1;
+    double b = 1 - 2 * t;
+    double c = t;
+    SkDVector result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX,
+            a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY };
+    return result;
+}
+
+SkDPoint SkDQuad::xyAtT(double t) const {
+    double one_t = 1 - t;
+    double a = one_t * one_t;
+    double b = 2 * one_t * t;
+    double c = t * t;
+    SkDPoint result = { a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX,
+            a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY };
+    return result;
+}
+
+/*
+Given a quadratic q, t1, and t2, find a small quadratic segment.
+
+The new quadratic is defined by A, B, and C, where
+ A = c[0]*(1 - t1)*(1 - t1) + 2*c[1]*t1*(1 - t1) + c[2]*t1*t1
+ C = c[3]*(1 - t1)*(1 - t1) + 2*c[2]*t1*(1 - t1) + c[1]*t1*t1
+
+To find B, compute the point halfway between t1 and t2:
+
+q(at (t1 + t2)/2) == D
+
+Next, compute where D must be if we know the value of B:
+
+_12 = A/2 + B/2
+12_ = B/2 + C/2
+123 = A/4 + B/2 + C/4
+    = D
+
+Group the known values on one side:
+
+B   = D*2 - A/2 - C/2
+*/
+
+static double interp_quad_coords(const double* src, double t) {
+    double ab = SkDInterp(src[0], src[2], t);
+    double bc = SkDInterp(src[2], src[4], t);
+    double abc = SkDInterp(ab, bc, t);
+    return abc;
+}
+
+bool SkDQuad::monotonicInY() const {
+    return between(fPts[0].fY, fPts[1].fY, fPts[2].fY);
+}
+
+SkDQuad SkDQuad::subDivide(double t1, double t2) const {
+    SkDQuad dst;
+    double ax = dst[0].fX = interp_quad_coords(&fPts[0].fX, t1);
+    double ay = dst[0].fY = interp_quad_coords(&fPts[0].fY, t1);
+    double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2);
+    double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2);
+    double cx = dst[2].fX = interp_quad_coords(&fPts[0].fX, t2);
+    double cy = dst[2].fY = interp_quad_coords(&fPts[0].fY, t2);
+    /* bx = */ dst[1].fX = 2*dx - (ax + cx)/2;
+    /* by = */ dst[1].fY = 2*dy - (ay + cy)/2;
+    return dst;
+}
+
+SkDPoint SkDQuad::subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2) const {
+    SkDPoint b;
+    double dx = interp_quad_coords(&fPts[0].fX, (t1 + t2) / 2);
+    double dy = interp_quad_coords(&fPts[0].fY, (t1 + t2) / 2);
+    b.fX = 2 * dx - (a.fX + c.fX) / 2;
+    b.fY = 2 * dy - (a.fY + c.fY) / 2;
+    return b;
+}
+
+/* classic one t subdivision */
+static void interp_quad_coords(const double* src, double* dst, double t) {
+    double ab = SkDInterp(src[0], src[2], t);
+    double bc = SkDInterp(src[2], src[4], t);
+    dst[0] = src[0];
+    dst[2] = ab;
+    dst[4] = SkDInterp(ab, bc, t);
+    dst[6] = bc;
+    dst[8] = src[4];
+}
+
+SkDQuadPair SkDQuad::chopAt(double t) const
+{
+    SkDQuadPair dst;
+    interp_quad_coords(&fPts[0].fX, &dst.pts[0].fX, t);
+    interp_quad_coords(&fPts[0].fY, &dst.pts[0].fY, t);
+    return dst;
+}
+
+static int valid_unit_divide(double numer, double denom, double* ratio)
+{
+    if (numer < 0) {
+        numer = -numer;
+        denom = -denom;
+    }
+    if (denom == 0 || numer == 0 || numer >= denom) {
+        return 0;
+    }
+    double r = numer / denom;
+    if (r == 0) {  // catch underflow if numer <<<< denom
+        return 0;
+    }
+    *ratio = r;
+    return 1;
+}
+
+/** Quad'(t) = At + B, where
+    A = 2(a - 2b + c)
+    B = 2(b - a)
+    Solve for t, only if it fits between 0 < t < 1
+*/
+int SkDQuad::FindExtrema(double a, double b, double c, double tValue[1]) {
+    /*  At + B == 0
+        t = -B / A
+    */
+    return valid_unit_divide(a - b, a - b - b + c, tValue);
+}
+
+/* Parameterization form, given A*t*t + 2*B*t*(1-t) + C*(1-t)*(1-t)
+ *
+ * a = A - 2*B +   C
+ * b =     2*B - 2*C
+ * c =             C
+ */
+void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) {
+    *a = quad[0];      // a = A
+    *b = 2 * quad[2];  // b =     2*B
+    *c = quad[4];      // c =             C
+    *b -= *c;          // b =     2*B -   C
+    *a -= *b;          // a = A - 2*B +   C
+    *b -= *c;          // b =     2*B - 2*C
+}
diff --git a/src/pathops/SkPathOpsQuad.h b/src/pathops/SkPathOpsQuad.h
new file mode 100644
index 0000000..d5ca0c7
--- /dev/null
+++ b/src/pathops/SkPathOpsQuad.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPathOpsQuad_DEFINED
+#define SkPathOpsQuad_DEFINED
+
+#include "SkPathOpsPoint.h"
+
+struct SkDQuadPair {
+    const SkDQuad& first() const { return (const SkDQuad&) pts[0]; }
+    const SkDQuad& second() const { return (const SkDQuad&) pts[2]; }
+    SkDPoint pts[5];
+};
+
+struct SkDQuad {
+    SkDPoint fPts[3];
+
+    void set(const SkPoint pts[3]) {
+        fPts[0] = pts[0];
+        fPts[1] = pts[1];
+        fPts[2] = pts[2];
+    }
+
+    const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < 3); return fPts[n]; }
+    SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < 3); return fPts[n]; }
+
+    static int AddValidTs(double s[], int realRoots, double* t);
+    SkDQuadPair chopAt(double t) const;
+    SkDVector dxdyAtT(double t) const;
+    static int FindExtrema(double a, double b, double c, double tValue[1]);
+    bool isLinear(int startIndex, int endIndex) const;
+    bool monotonicInY() const;
+    double nearestT(const SkDPoint&) const;
+    bool pointInHull(const SkDPoint&) const;
+    static int RootsReal(double A, double B, double C, double t[2]);
+    static int RootsValidT(const double A, const double B, const double C, double s[2]);
+    static void SetABC(const double* quad, double* a, double* b, double* c);
+    SkDQuad subDivide(double t1, double t2) const;
+    static SkDQuad SubDivide(const SkPoint a[3], double t1, double t2) {
+        SkDQuad quad;
+        quad.set(a);
+        return quad.subDivide(t1, t2);
+    }
+    SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2) const;
+    static SkDPoint SubDivide(const SkPoint pts[3], const SkDPoint& a, const SkDPoint& c,
+                              double t1, double t2) {
+        SkDQuad quad;
+        quad.set(pts);
+        return quad.subDivide(a, c, t1, t2);
+    }
+    SkDCubic toCubic() const;
+    SkDPoint top(double startT, double endT) const;
+    SkDPoint xyAtT(double t) const;
+private:
+//  static double Tangent(const double* quadratic, double t);  // uncalled
+};
+
+#endif
diff --git a/src/pathops/SkPathOpsRect.cpp b/src/pathops/SkPathOpsRect.cpp
new file mode 100644
index 0000000..9d7f876
--- /dev/null
+++ b/src/pathops/SkPathOpsRect.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsQuad.h"
+#include "SkPathOpsRect.h"
+
+void SkDRect::setBounds(const SkDLine& line) {
+    set(line[0]);
+    add(line[1]);
+}
+
+void SkDRect::setBounds(const SkDQuad& quad) {
+    set(quad[0]);
+    add(quad[2]);
+    double tValues[2];
+    int roots = 0;
+    if (!between(quad[0].fX, quad[1].fX, quad[2].fX)) {
+        roots = SkDQuad::FindExtrema(quad[0].fX, quad[1].fX, quad[2].fX, tValues);
+    }
+    if (!between(quad[0].fY, quad[1].fY, quad[2].fY)) {
+        roots += SkDQuad::FindExtrema(quad[0].fY, quad[1].fY, quad[2].fY, &tValues[roots]);
+    }
+    for (int x = 0; x < roots; ++x) {
+        add(quad.xyAtT(tValues[x]));
+    }
+}
+
+void SkDRect::setRawBounds(const SkDQuad& quad) {
+    set(quad[0]);
+    for (int x = 1; x < 3; ++x) {
+        add(quad[x]);
+    }
+}
+
+static bool is_bounded_by_end_points(double a, double b, double c, double d) {
+    return between(a, b, d) && between(a, c, d);
+}
+
+void SkDRect::setBounds(const SkDCubic& c) {
+    set(c[0]);
+    add(c[3]);
+    double tValues[4];
+    int roots = 0;
+    if (!is_bounded_by_end_points(c[0].fX, c[1].fX, c[2].fX, c[3].fX)) {
+        roots = SkDCubic::FindExtrema(c[0].fX, c[1].fX, c[2].fX, c[3].fX, tValues);
+    }
+    if (!is_bounded_by_end_points(c[0].fY, c[1].fY, c[2].fY, c[3].fY)) {
+        roots += SkDCubic::FindExtrema(c[0].fY, c[1].fY, c[2].fY, c[3].fY, &tValues[roots]);
+    }
+    for (int x = 0; x < roots; ++x) {
+        add(c.xyAtT(tValues[x]));
+    }
+}
+
+void SkDRect::setRawBounds(const SkDCubic& cubic) {
+    set(cubic[0]);
+    for (int x = 1; x < 4; ++x) {
+        add(cubic[x]);
+    }
+}
diff --git a/src/pathops/SkPathOpsRect.h b/src/pathops/SkPathOpsRect.h
new file mode 100644
index 0000000..7b516a4
--- /dev/null
+++ b/src/pathops/SkPathOpsRect.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOpsRect_DEFINED
+#define SkPathOpsRect_DEFINED
+
+#include "SkPathOpsPoint.h"
+
+struct SkDRect {
+    double fLeft, fTop, fRight, fBottom;
+
+    void add(const SkDPoint& pt) {
+        if (fLeft > pt.fX) {
+            fLeft = pt.fX;
+        }
+        if (fTop > pt.fY) {
+            fTop = pt.fY;
+        }
+        if (fRight < pt.fX) {
+            fRight = pt.fX;
+        }
+        if (fBottom < pt.fY) {
+            fBottom = pt.fY;
+        }
+    }
+
+    // FIXME: used by debugging only ?
+    bool contains(const SkDPoint& pt) const {
+        return approximately_between(fLeft, pt.fX, fRight)
+                && approximately_between(fTop, pt.fY, fBottom);
+    }
+
+    bool intersects(SkDRect* r) const {
+        SkASSERT(fLeft <= fRight);
+        SkASSERT(fTop <= fBottom);
+        SkASSERT(r->fLeft <= r->fRight);
+        SkASSERT(r->fTop <= r->fBottom);
+        return r->fLeft <= fRight && fLeft <= r->fRight && r->fTop <= fBottom && fTop <= r->fBottom;
+    }
+
+    void set(const SkDPoint& pt) {
+        fLeft = fRight = pt.fX;
+        fTop = fBottom = pt.fY;
+    }
+
+    void setBounds(const SkDLine&);
+    void setBounds(const SkDCubic&);
+    void setBounds(const SkDQuad&);
+    void setRawBounds(const SkDCubic&);
+    void setRawBounds(const SkDQuad&);
+};
+
+#endif
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp
new file mode 100644
index 0000000..2213c68
--- /dev/null
+++ b/src/pathops/SkPathOpsSimplify.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkAddIntersections.h"
+#include "SkOpEdgeBuilder.h"
+#include "SkPathOpsCommon.h"
+#include "SkPathWriter.h"
+
+static bool bridgeWinding(SkTDArray<SkOpContour*>& contourList, SkPathWriter* simple) {
+    bool firstContour = true;
+    bool unsortable = false;
+    bool topUnsortable = false;
+    SkPoint topLeft = {SK_ScalarMin, SK_ScalarMin};
+    do {
+        int index, endIndex;
+        bool topDone;
+        SkOpSegment* current = FindSortableTop(contourList, &firstContour, &index, &endIndex,
+                &topLeft, &topUnsortable, &topDone, false);
+        if (!current) {
+            if (topUnsortable || !topDone) {
+                topUnsortable = false;
+                SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMin);
+                topLeft.fX = topLeft.fY = SK_ScalarMin;
+                continue;
+            }
+            break;
+        }
+        SkTDArray<SkOpSpan*> chaseArray;
+        do {
+            if (current->activeWinding(index, endIndex)) {
+                do {
+            #if DEBUG_ACTIVE_SPANS
+                    if (!unsortable && current->done()) {
+                        DebugShowActiveSpans(contourList);
+                    }
+            #endif
+                    SkASSERT(unsortable || !current->done());
+                    int nextStart = index;
+                    int nextEnd = endIndex;
+                    SkOpSegment* next = current->findNextWinding(&chaseArray, &nextStart, &nextEnd,
+                            &unsortable);
+                    if (!next) {
+                        if (!unsortable && simple->hasMove()
+                                && current->verb() != SkPath::kLine_Verb
+                                && !simple->isClosed()) {
+                            current->addCurveTo(index, endIndex, simple, true);
+                            SkASSERT(simple->isClosed());
+                        }
+                        break;
+                    }
+        #if DEBUG_FLOW
+            SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
+                    current->debugID(), current->xyAtT(index).fX, current->xyAtT(index).fY,
+                    current->xyAtT(endIndex).fX, current->xyAtT(endIndex).fY);
+        #endif
+                    current->addCurveTo(index, endIndex, simple, true);
+                    current = next;
+                    index = nextStart;
+                    endIndex = nextEnd;
+                } while (!simple->isClosed() && (!unsortable
+                        || !current->done(SkMin32(index, endIndex))));
+                if (current->activeWinding(index, endIndex) && !simple->isClosed()) {
+                    SkASSERT(unsortable);
+                    int min = SkMin32(index, endIndex);
+                    if (!current->done(min)) {
+                        current->addCurveTo(index, endIndex, simple, true);
+                        current->markDoneUnary(min);
+                    }
+                }
+                simple->close();
+            } else {
+                SkOpSpan* last = current->markAndChaseDoneUnary(index, endIndex);
+                if (last && !last->fLoop) {
+                    *chaseArray.append() = last;
+                }
+            }
+            current = FindChase(chaseArray, index, endIndex);
+        #if DEBUG_ACTIVE_SPANS
+            DebugShowActiveSpans(contourList);
+        #endif
+            if (!current) {
+                break;
+            }
+        } while (true);
+    } while (true);
+    return simple->someAssemblyRequired();
+}
+
+// returns true if all edges were processed
+static bool bridgeXor(SkTDArray<SkOpContour*>& contourList, SkPathWriter* simple) {
+    SkOpSegment* current;
+    int start, end;
+    bool unsortable = false;
+    bool closable = true;
+    while ((current = FindUndone(contourList, &start, &end))) {
+        do {
+    #if DEBUG_ACTIVE_SPANS
+            if (!unsortable && current->done()) {
+                DebugShowActiveSpans(contourList);
+            }
+    #endif
+            SkASSERT(unsortable || !current->done());
+            int nextStart = start;
+            int nextEnd = end;
+            SkOpSegment* next = current->findNextXor(&nextStart, &nextEnd, &unsortable);
+            if (!next) {
+                if (!unsortable && simple->hasMove()
+                        && current->verb() != SkPath::kLine_Verb
+                        && !simple->isClosed()) {
+                    current->addCurveTo(start, end, simple, true);
+                    SkASSERT(simple->isClosed());
+                }
+                break;
+            }
+        #if DEBUG_FLOW
+            SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
+                    current->debugID(), current->xyAtT(start).fX, current->xyAtT(start).fY,
+                    current->xyAtT(end).fX, current->xyAtT(end).fY);
+        #endif
+            current->addCurveTo(start, end, simple, true);
+            current = next;
+            start = nextStart;
+            end = nextEnd;
+        } while (!simple->isClosed() && (!unsortable || !current->done(SkMin32(start, end))));
+        if (!simple->isClosed()) {
+            SkASSERT(unsortable);
+            int min = SkMin32(start, end);
+            if (!current->done(min)) {
+                current->addCurveTo(start, end, simple, true);
+                current->markDone(min, 1);
+            }
+            closable = false;
+        }
+        simple->close();
+    #if DEBUG_ACTIVE_SPANS
+        DebugShowActiveSpans(contourList);
+    #endif
+    }
+    return closable;
+}
+
+// FIXME : add this as a member of SkPath
+void Simplify(const SkPath& path, SkPath* result) {
+#if DEBUG_SORT || DEBUG_SWAP_TOP
+    gDebugSortCount = gDebugSortCountDefault;
+#endif
+    // returns 1 for evenodd, -1 for winding, regardless of inverse-ness
+    result->reset();
+    result->setFillType(SkPath::kEvenOdd_FillType);
+    SkPathWriter simple(*result);
+
+    // turn path into list of segments
+    SkTArray<SkOpContour> contours;
+    SkOpEdgeBuilder builder(path, contours);
+    builder.finish();
+    SkTDArray<SkOpContour*> contourList;
+    MakeContourList(contours, contourList, false, false);
+    SkOpContour** currentPtr = contourList.begin();
+    if (!currentPtr) {
+        return;
+    }
+    SkOpContour** listEnd = contourList.end();
+    // find all intersections between segments
+    do {
+        SkOpContour** nextPtr = currentPtr;
+        SkOpContour* current = *currentPtr++;
+        if (current->containsCubics()) {
+            AddSelfIntersectTs(current);
+        }
+        SkOpContour* next;
+        do {
+            next = *nextPtr++;
+        } while (AddIntersectTs(current, next) && nextPtr != listEnd);
+    } while (currentPtr != listEnd);
+    // eat through coincident edges
+    CoincidenceCheck(&contourList, 0);
+    FixOtherTIndex(&contourList);
+    SortSegments(&contourList);
+#if DEBUG_ACTIVE_SPANS
+    DebugShowActiveSpans(contourList);
+#endif
+    // construct closed contours
+    if (builder.xorMask() == kWinding_PathOpsMask ? bridgeWinding(contourList, &simple)
+                : !bridgeXor(contourList, &simple))
+    {  // if some edges could not be resolved, assemble remaining fragments
+        SkPath temp;
+        temp.setFillType(SkPath::kEvenOdd_FillType);
+        SkPathWriter assembled(temp);
+        Assemble(simple, &assembled);
+        *result = *assembled.nativePath();
+    }
+}
diff --git a/src/pathops/SkPathOpsSpan.h b/src/pathops/SkPathOpsSpan.h
new file mode 100644
index 0000000..3396592
--- /dev/null
+++ b/src/pathops/SkPathOpsSpan.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkOpSpan_DEFINED
+#define SkOpSpan_DEFINED
+
+#include "SkPoint.h"
+
+class SkOpSegment;
+
+struct SkOpSpan {
+    SkOpSegment* fOther;
+    SkPoint fPt; // computed when the curves are intersected
+    double fT;
+    double fOtherT; // value at fOther[fOtherIndex].fT
+    int fOtherIndex;  // can't be used during intersection
+    int fWindSum; // accumulated from contours surrounding this one.
+    int fOppSum; // for binary operators: the opposite winding sum
+    int fWindValue; // 0 == canceled; 1 == normal; >1 == coincident
+    int fOppValue; // normally 0 -- when binary coincident edges combine, opp value goes here
+    bool fDone; // if set, this span to next higher T has been processed
+    bool fUnsortableStart; // set when start is part of an unsortable pair
+    bool fUnsortableEnd; // set when end is part of an unsortable pair
+    bool fTiny; // if set, span may still be considered once for edge following
+    bool fLoop; // set when a cubic loops back to this point
+};
+
+#endif
diff --git a/src/pathops/SkPathOpsTriangle.cpp b/src/pathops/SkPathOpsTriangle.cpp
new file mode 100644
index 0000000..4939166
--- /dev/null
+++ b/src/pathops/SkPathOpsTriangle.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkPathOpsTriangle.h"
+
+// http://www.blackpawn.com/texts/pointinpoly/default.html
+bool SkDTriangle::contains(const SkDPoint& pt) const {
+// Compute vectors
+    SkDVector v0 = fPts[2] - fPts[0];
+    SkDVector v1 = fPts[1] - fPts[0];
+    SkDVector v2 = pt - fPts[0];
+
+// Compute dot products
+    double dot00 = v0.dot(v0);
+    double dot01 = v0.dot(v1);
+    double dot02 = v0.dot(v2);
+    double dot11 = v1.dot(v1);
+    double dot12 = v1.dot(v2);
+
+// Compute barycentric coordinates
+    double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+    double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+    double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+// Check if point is in triangle
+    return (u >= 0) && (v >= 0) && (u + v < 1);
+}
diff --git a/src/pathops/SkPathOpsTriangle.h b/src/pathops/SkPathOpsTriangle.h
new file mode 100644
index 0000000..cbeea8c
--- /dev/null
+++ b/src/pathops/SkPathOpsTriangle.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPathOpsTriangle_DEFINED
+#define SkPathOpsTriangle_DEFINED
+
+#include "SkPathOpsPoint.h"
+
+struct SkDTriangle {
+    SkDPoint fPts[3];
+    
+    bool contains(const SkDPoint& pt) const;
+
+};
+
+#endif
diff --git a/src/pathops/SkPathOpsTypes.cpp b/src/pathops/SkPathOpsTypes.cpp
new file mode 100644
index 0000000..199d7be
--- /dev/null
+++ b/src/pathops/SkPathOpsTypes.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkPathOpsTypes.h"
+
+const int UlpsEpsilon = 16;
+
+// from http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
+union SkPathOpsUlpsFloat {
+    int32_t fInt;
+    float fFloat;
+
+    SkPathOpsUlpsFloat(float num = 0.0f) : fFloat(num) {}
+    bool negative() const { return fInt < 0; }
+};
+
+bool AlmostEqualUlps(float A, float B) {
+    SkPathOpsUlpsFloat uA(A);
+    SkPathOpsUlpsFloat uB(B);
+    // Different signs means they do not match.
+    if (uA.negative() != uB.negative())
+    {
+        // Check for equality to make sure +0 == -0
+        return A == B;
+    }
+    // Find the difference in ULPs.
+    int ulpsDiff = abs(uA.fInt - uB.fInt);
+    return ulpsDiff <= UlpsEpsilon;
+}
+
+// cube root approximation using bit hack for 64-bit float
+// adapted from Kahan's cbrt
+static  double cbrt_5d(double d) {
+    const unsigned int B1 = 715094163;
+    double t = 0.0;
+    unsigned int* pt = (unsigned int*) &t;
+    unsigned int* px = (unsigned int*) &d;
+    pt[1] = px[1] / 3 + B1;
+    return t;
+}
+
+// iterative cube root approximation using Halley's method (double)
+static  double cbrta_halleyd(const double a, const double R) {
+    const double a3 = a * a * a;
+    const double b = a * (a3 + R + R) / (a3 + a3 + R);
+    return b;
+}
+
+// cube root approximation using 3 iterations of Halley's method (double)
+static double halley_cbrt3d(double d) {
+    double a = cbrt_5d(d);
+    a = cbrta_halleyd(a, d);
+    a = cbrta_halleyd(a, d);
+    return cbrta_halleyd(a, d);
+}
+
+double SkDCubeRoot(double x) {
+    if (approximately_zero_cubed(x)) {
+        return 0;
+    }
+    double result = halley_cbrt3d(fabs(x));
+    if (x < 0) {
+        result = -result;
+    }
+    return result;
+}
diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h
new file mode 100644
index 0000000..aadaca8
--- /dev/null
+++ b/src/pathops/SkPathOpsTypes.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathOpsTypes_DEFINED
+#define SkPathOpsTypes_DEFINED
+
+#include <float.h>  // for FLT_EPSILON
+#include <math.h>   // for fabs, sqrt
+
+#include "SkFloatingPoint.h"
+#include "SkPathOps.h"
+#include "SkPathOpsDebug.h"
+#include "SkScalar.h"
+
+// FIXME: move these into SkTypes.h
+template <typename T> inline T SkTMax(T a, T b) {
+    if (a < b)
+        a = b;
+    return a;
+}
+
+template <typename T> inline T SkTMin(T a, T b) {
+    if (a > b)
+        a = b;
+    return a;
+}
+
+// FIXME: move this into SkFloatingPoint.h
+#define sk_double_isnan(a) sk_float_isnan(a)
+
+enum SkPathOpsMask {
+    kWinding_PathOpsMask = -1,
+    kNo_PathOpsMask = 0,
+    kEvenOdd_PathOpsMask = 1
+};
+
+extern bool AlmostEqualUlps(float A, float B);
+inline bool AlmostEqualUlps(double A, double B) {
+    return AlmostEqualUlps(SkDoubleToScalar(A), SkDoubleToScalar(B));
+}
+
+// FLT_EPSILON == 1.19209290E-07 == 1 / (2 ^ 23)
+// DBL_EPSILON == 2.22045e-16
+const double FLT_EPSILON_CUBED = FLT_EPSILON * FLT_EPSILON * FLT_EPSILON;
+const double FLT_EPSILON_HALF = FLT_EPSILON / 2;
+const double FLT_EPSILON_SQUARED = FLT_EPSILON * FLT_EPSILON;
+const double FLT_EPSILON_SQRT = sqrt(FLT_EPSILON);
+const double FLT_EPSILON_INVERSE = 1 / FLT_EPSILON;
+const double DBL_EPSILON_ERR = DBL_EPSILON * 4;  // FIXME: tune -- allow a few bits of error
+const double ROUGH_EPSILON = FLT_EPSILON * 64;
+const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256;
+
+inline bool approximately_zero(double x) {
+    return fabs(x) < FLT_EPSILON;
+}
+
+inline bool precisely_zero(double x) {
+    return fabs(x) < DBL_EPSILON_ERR;
+}
+
+inline bool approximately_zero(float x) {
+    return fabs(x) < FLT_EPSILON;
+}
+
+inline bool approximately_zero_cubed(double x) {
+    return fabs(x) < FLT_EPSILON_CUBED;
+}
+
+inline bool approximately_zero_half(double x) {
+    return fabs(x) < FLT_EPSILON_HALF;
+}
+
+inline bool approximately_zero_squared(double x) {
+    return fabs(x) < FLT_EPSILON_SQUARED;
+}
+
+inline bool approximately_zero_sqrt(double x) {
+    return fabs(x) < FLT_EPSILON_SQRT;
+}
+
+inline bool approximately_zero_inverse(double x) {
+    return fabs(x) > FLT_EPSILON_INVERSE;
+}
+
+// OPTIMIZATION: if called multiple times with the same denom, we want to pass 1/y instead
+inline bool approximately_zero_when_compared_to(double x, double y) {
+    return x == 0 || fabs(x / y) < FLT_EPSILON;
+}
+
+// Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use
+// AlmostEqualUlps instead.
+inline bool approximately_equal(double x, double y) {
+    return approximately_zero(x - y);
+}
+
+inline bool precisely_equal(double x, double y) {
+    return precisely_zero(x - y);
+}
+
+inline bool approximately_equal_half(double x, double y) {
+    return approximately_zero_half(x - y);
+}
+
+inline bool approximately_equal_squared(double x, double y) {
+    return approximately_equal(x, y);
+}
+
+inline bool approximately_greater(double x, double y) {
+    return x - FLT_EPSILON >= y;
+}
+
+inline bool approximately_greater_or_equal(double x, double y) {
+    return x + FLT_EPSILON > y;
+}
+
+inline bool approximately_lesser(double x, double y) {
+    return x + FLT_EPSILON <= y;
+}
+
+inline bool approximately_lesser_or_equal(double x, double y) {
+    return x - FLT_EPSILON < 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_greater_than_one(double x) {
+    return x > 1 - FLT_EPSILON;
+}
+
+inline bool precisely_greater_than_one(double x) {
+    return x > 1 - DBL_EPSILON_ERR;
+}
+
+inline bool approximately_less_than_zero(double x) {
+    return x < FLT_EPSILON;
+}
+
+inline bool precisely_less_than_zero(double x) {
+    return x < DBL_EPSILON_ERR;
+}
+
+inline bool approximately_negative(double x) {
+    return x < FLT_EPSILON;
+}
+
+inline bool precisely_negative(double x) {
+    return x < DBL_EPSILON_ERR;
+}
+
+inline bool approximately_one_or_less(double x) {
+    return x < 1 + FLT_EPSILON;
+}
+
+inline bool approximately_positive(double x) {
+    return x > -FLT_EPSILON;
+}
+
+inline bool approximately_positive_squared(double x) {
+    return x > -(FLT_EPSILON_SQUARED);
+}
+
+inline bool approximately_zero_or_more(double x) {
+    return x > -FLT_EPSILON;
+}
+
+inline bool approximately_between(double a, double b, double c) {
+    return a <= c ? approximately_negative(a - b) && approximately_negative(b - c)
+            : approximately_negative(b - a) && approximately_negative(c - b);
+}
+
+// returns true if (a <= b <= c) || (a >= b >= c)
+inline bool between(double a, double b, double c) {
+    SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0));
+    return (a - b) * (c - b) <= 0;
+}
+
+inline bool more_roughly_equal(double x, double y) {
+    return fabs(x - y) < MORE_ROUGH_EPSILON;
+}
+
+inline bool roughly_equal(double x, double y) {
+    return fabs(x - y) < ROUGH_EPSILON;
+}
+
+struct SkDPoint;
+struct SkDVector;
+struct SkDLine;
+struct SkDQuad;
+struct SkDTriangle;
+struct SkDCubic;
+struct SkDRect;
+
+inline double SkDInterp(double A, double B, double t) {
+    return A + (B - A) * t;
+}
+
+double SkDCubeRoot(double x);
+
+/* Returns -1 if negative, 0 if zero, 1 if positive
+*/
+inline int SkDSign(double x) {
+    return (x > 0) - (x < 0);
+}
+
+/* Returns 0 if negative, 1 if zero, 2 if positive
+*/
+inline int SKDSide(double x) {
+    return (x > 0) + (x >= 0);
+}
+
+/* Returns 1 if negative, 2 if zero, 4 if positive
+*/
+inline int SkDSideBit(double x) {
+    return 1 << SKDSide(x);
+}
+
+#endif
diff --git a/src/pathops/SkPathWriter.cpp b/src/pathops/SkPathWriter.cpp
new file mode 100644
index 0000000..e367228
--- /dev/null
+++ b/src/pathops/SkPathWriter.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkPathOpsTypes.h"
+#include "SkPathWriter.h"
+
+// wrap path to keep track of whether the contour is initialized and non-empty
+SkPathWriter::SkPathWriter(SkPath& path)
+    : fPathPtr(&path)
+    , fCloses(0)
+    , fMoves(0)
+{
+    init();
+}
+
+void SkPathWriter::close() {
+    if (!fHasMove) {
+        return;
+    }
+    bool callClose = isClosed();
+    lineTo();
+    if (fEmpty) {
+        return;
+    }
+    if (callClose) {
+#if DEBUG_PATH_CONSTRUCTION
+        SkDebugf("path.close();\n");
+#endif
+        fPathPtr->close();
+        fCloses++;
+    }
+    init();
+}
+
+void SkPathWriter::cubicTo(const SkPoint& pt1, const SkPoint& pt2, const SkPoint& pt3) {
+    lineTo();
+    moveTo();
+    fDefer[1] = pt3;
+    nudge();
+    fDefer[0] = fDefer[1];
+#if DEBUG_PATH_CONSTRUCTION
+    SkDebugf("path.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1.9g);\n",
+            pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY);
+#endif
+    fPathPtr->cubicTo(pt1.fX, pt1.fY, pt2.fX, pt2.fY, fDefer[1].fX, fDefer[1].fY);
+    fEmpty = false;
+}
+
+void SkPathWriter::deferredLine(const SkPoint& pt) {
+    if (pt == fDefer[1]) {
+        return;
+    }
+    if (changedSlopes(pt)) {
+        lineTo();
+        fDefer[0] = fDefer[1];
+    }
+    fDefer[1] = pt;
+}
+
+void SkPathWriter::deferredMove(const SkPoint& pt) {
+    fMoved = true;
+    fHasMove = true;
+    fEmpty = true;
+    fDefer[0] = fDefer[1] = pt;
+}
+
+void SkPathWriter::deferredMoveLine(const SkPoint& pt) {
+    if (!fHasMove) {
+        deferredMove(pt);
+    }
+    deferredLine(pt);
+}
+
+bool SkPathWriter::hasMove() const {
+    return fHasMove;
+}
+
+void SkPathWriter::init() {
+    fEmpty = true;
+    fHasMove = false;
+    fMoved = false;
+}
+
+bool SkPathWriter::isClosed() const {
+    return !fEmpty && fFirstPt == fDefer[1];
+}
+
+void SkPathWriter::lineTo() {
+    if (fDefer[0] == fDefer[1]) {
+        return;
+    }
+    moveTo();
+    nudge();
+    fEmpty = false;
+#if DEBUG_PATH_CONSTRUCTION
+    SkDebugf("path.lineTo(%1.9g,%1.9g);\n", fDefer[1].fX, fDefer[1].fY);
+#endif
+    fPathPtr->lineTo(fDefer[1].fX, fDefer[1].fY);
+    fDefer[0] = fDefer[1];
+}
+
+const SkPath* SkPathWriter::nativePath() const {
+    return fPathPtr;
+}
+
+void SkPathWriter::nudge() {
+    if (fEmpty || !AlmostEqualUlps(fDefer[1].fX, fFirstPt.fX)
+            || !AlmostEqualUlps(fDefer[1].fY, fFirstPt.fY)) {
+        return;
+    }
+    fDefer[1] = fFirstPt;
+}
+
+void SkPathWriter::quadTo(const SkPoint& pt1, const SkPoint& pt2) {
+    lineTo();
+    moveTo();
+    fDefer[1] = pt2;
+    nudge();
+    fDefer[0] = fDefer[1];
+#if DEBUG_PATH_CONSTRUCTION
+    SkDebugf("path.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n",
+            pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY);
+#endif
+    fPathPtr->quadTo(pt1.fX, pt1.fY, fDefer[1].fX, fDefer[1].fY);
+    fEmpty = false;
+}
+
+bool SkPathWriter::someAssemblyRequired() const {
+    return fCloses < fMoves;
+}
+
+bool SkPathWriter::changedSlopes(const SkPoint& pt) const {
+    if (fDefer[0] == fDefer[1]) {
+        return false;
+    }
+    SkScalar deferDx = fDefer[1].fX - fDefer[0].fX;
+    SkScalar deferDy = fDefer[1].fY - fDefer[0].fY;
+    SkScalar lineDx = pt.fX - fDefer[1].fX;
+    SkScalar lineDy = pt.fY - fDefer[1].fY;
+    return deferDx * lineDy != deferDy * lineDx;
+}
+
+void SkPathWriter::moveTo() {
+    if (!fMoved) {
+        return;
+    }
+    fFirstPt = fDefer[0];
+#if DEBUG_PATH_CONSTRUCTION
+    SkDebugf("path.moveTo(%1.9g,%1.9g);\n", fDefer[0].fX, fDefer[0].fY);
+#endif
+    fPathPtr->moveTo(fDefer[0].fX, fDefer[0].fY);
+    fMoved = false;
+    fMoves++;
+}
diff --git a/src/pathops/SkPathWriter.h b/src/pathops/SkPathWriter.h
new file mode 100644
index 0000000..2989b35
--- /dev/null
+++ b/src/pathops/SkPathWriter.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkPathWriter_DEFINED
+#define SkPathWriter_DEFINED
+
+#include "SkPath.h"
+
+class SkPathWriter {
+public:
+    SkPathWriter(SkPath& path);
+    void close();
+    void cubicTo(const SkPoint& pt1, const SkPoint& pt2, const SkPoint& pt3);
+    void deferredLine(const SkPoint& pt);
+    void deferredMove(const SkPoint& pt);
+    void deferredMoveLine(const SkPoint& pt);
+    bool hasMove() const;
+    void init();
+    bool isClosed() const;
+    void lineTo();
+    const SkPath* nativePath() const;
+    void nudge();
+    void quadTo(const SkPoint& pt1, const SkPoint& pt2);
+    bool someAssemblyRequired() const;
+    
+private:
+    bool changedSlopes(const SkPoint& pt) const;
+    void moveTo();
+    
+    SkPath* fPathPtr;
+    SkPoint fDefer[2];
+    SkPoint fFirstPt;
+    int fCloses;
+    int fMoves;
+    bool fEmpty;
+    bool fHasMove;
+    bool fMoved;
+};
+
+
+#endif /* defined(__PathOps__SkPathWriter__) */
diff --git a/src/pathops/SkQuarticRoot.cpp b/src/pathops/SkQuarticRoot.cpp
new file mode 100644
index 0000000..09a92c6
--- /dev/null
+++ b/src/pathops/SkQuarticRoot.cpp
@@ -0,0 +1,165 @@
+// from http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c
+/*
+ *  Roots3And4.c
+ *
+ *  Utility functions to find cubic and quartic roots,
+ *  coefficients are passed like this:
+ *
+ *      c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0
+ *
+ *  The functions return the number of non-complex roots and
+ *  put the values into the s array.
+ *
+ *  Author:         Jochen Schwarze (schwarze@isa.de)
+ *
+ *  Jan 26, 1990    Version for Graphics Gems
+ *  Oct 11, 1990    Fixed sign problem for negative q's in SolveQuartic
+ *                  (reported by Mark Podlipec),
+ *                  Old-style function definitions,
+ *                  IsZero() as a macro
+ *  Nov 23, 1990    Some systems do not declare acos() and cbrt() in
+ *                  <math.h>, though the functions exist in the library.
+ *                  If large coefficients are used, EQN_EPS should be
+ *                  reduced considerably (e.g. to 1E-30), results will be
+ *                  correct but multiple roots might be reported more
+ *                  than once.
+ */
+
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsQuad.h"
+#include "SkQuarticRoot.h"
+
+int SkReducedQuarticRoots(const double t4, const double t3, const double t2, const double t1,
+        const double t0, const bool oneHint, double roots[4]) {
+#ifdef SK_DEBUG
+    // create a string mathematica understands
+    // GDB set print repe 15 # if repeated digits is a bother
+    //     set print elements 400 # if line doesn't fit
+    char str[1024];
+    sk_bzero(str, sizeof(str));
+    SK_SNPRINTF(str, sizeof(str),
+            "Solve[%1.19g x^4 + %1.19g x^3 + %1.19g x^2 + %1.19g x + %1.19g == 0, x]",
+            t4, t3, t2, t1, t0);
+    mathematica_ize(str, sizeof(str));
+#if ONE_OFF_DEBUG && ONE_OFF_DEBUG_MATHEMATICA
+    SkDebugf("%s\n", str);
+#endif
+#endif
+    if (approximately_zero_when_compared_to(t4, t0)  // 0 is one root
+            && approximately_zero_when_compared_to(t4, t1)
+            && approximately_zero_when_compared_to(t4, t2)) {
+        if (approximately_zero_when_compared_to(t3, t0)
+            && approximately_zero_when_compared_to(t3, t1)
+            && approximately_zero_when_compared_to(t3, t2)) {
+            return SkDQuad::RootsReal(t2, t1, t0, roots);
+        }
+        if (approximately_zero_when_compared_to(t4, t3)) {
+            return SkDCubic::RootsReal(t3, t2, t1, t0, roots);
+        }
+    }
+    if ((approximately_zero_when_compared_to(t0, t1) || approximately_zero(t1))  // 0 is one root
+      //      && approximately_zero_when_compared_to(t0, t2)
+            && approximately_zero_when_compared_to(t0, t3)
+            && approximately_zero_when_compared_to(t0, t4)) {
+        int num = SkDCubic::RootsReal(t4, t3, t2, t1, roots);
+        for (int i = 0; i < num; ++i) {
+            if (approximately_zero(roots[i])) {
+                return num;
+            }
+        }
+        roots[num++] = 0;
+        return num;
+    }
+    if (oneHint) {
+        SkASSERT(approximately_zero(t4 + t3 + t2 + t1 + t0));  // 1 is one root
+        // note that -C == A + B + D + E
+        int num = SkDCubic::RootsReal(t4, t4 + t3, -(t1 + t0), -t0, roots);  
+        for (int i = 0; i < num; ++i) {
+            if (approximately_equal(roots[i], 1)) {
+                return num;
+            }
+        }
+        roots[num++] = 1;
+        return num;
+    }
+    return -1;
+}
+
+int SkQuarticRootsReal(int firstCubicRoot, const double A, const double B, const double C,
+        const double D, const double E, double s[4]) {
+    double  u, v;
+    /* normal form: x^4 + Ax^3 + Bx^2 + Cx + D = 0 */
+    const double invA = 1 / A;
+    const double a = B * invA;
+    const double b = C * invA;
+    const double c = D * invA;
+    const double d = E * invA;
+    /*  substitute x = y - a/4 to eliminate cubic term:
+    x^4 + px^2 + qx + r = 0 */
+    const double a2 = a * a;
+    const double p = -3 * a2 / 8 + b;
+    const double q = a2 * a / 8 - a * b / 2 + c;
+    const double r = -3 * a2 * a2 / 256 + a2 * b / 16 - a * c / 4 + d;
+    int num;
+    if (approximately_zero(r)) {
+    /* no absolute term: y(y^3 + py + q) = 0 */
+        num = SkDCubic::RootsReal(1, 0, p, q, s);
+        s[num++] = 0;
+    } else {
+        /* solve the resolvent cubic ... */
+        double cubicRoots[3];
+        int roots = SkDCubic::RootsReal(1, -p / 2, -r, r * p / 2 - q * q / 8, cubicRoots);
+        int index;
+        /* ... and take one real solution ... */
+        double z;
+        num = 0;
+        int num2 = 0;
+        for (index = firstCubicRoot; index < roots; ++index) {
+            z = cubicRoots[index];
+            /* ... to build two quadric equations */
+            u = z * z - r;
+            v = 2 * z - p;
+            if (approximately_zero_squared(u)) {
+                u = 0;
+            } else if (u > 0) {
+                u = sqrt(u);
+            } else {
+                continue;
+            }
+            if (approximately_zero_squared(v)) {
+                v = 0;
+            } else if (v > 0) {
+                v = sqrt(v);
+            } else {
+                continue;
+            }
+            num = SkDQuad::RootsReal(1, q < 0 ? -v : v, z - u, s);
+            num2 = SkDQuad::RootsReal(1, q < 0 ? v : -v, z + u, s + num);
+            if (!((num | num2) & 1)) {
+                break;  // prefer solutions without single quad roots
+            }
+        }
+        num += num2;
+        if (!num) {
+            return 0;  // no valid cubic root
+        }
+    }
+    /* resubstitute */
+    const double sub = a / 4;
+    for (int i = 0; i < num; ++i) {
+        s[i] -= sub;
+    }
+    // eliminate duplicates
+    for (int i = 0; i < num - 1; ++i) {
+        for (int j = i + 1; j < num; ) {
+            if (AlmostEqualUlps(s[i], s[j])) {
+                if (j < --num) {
+                    s[j] = s[num];
+                }
+            } else {
+                ++j;
+            }
+        }
+    }
+    return num;
+}
diff --git a/src/pathops/SkQuarticRoot.h b/src/pathops/SkQuarticRoot.h
new file mode 100644
index 0000000..6ce0867
--- /dev/null
+++ b/src/pathops/SkQuarticRoot.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkDQuarticRoot_DEFINED
+#define SkDQuarticRoot_DEFINED
+
+int SkReducedQuarticRoots(const double t4, const double t3, const double t2, const double t1,
+        const double t0, const bool oneHint, double s[4]);
+
+int SkQuarticRootsReal(int firstCubicRoot, const double A, const double B, const double C,
+        const double D, const double E, double s[4]);
+
+#endif
diff --git a/src/pathops/SkReduceOrder.cpp b/src/pathops/SkReduceOrder.cpp
new file mode 100644
index 0000000..14da4cc
--- /dev/null
+++ b/src/pathops/SkReduceOrder.cpp
@@ -0,0 +1,450 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SkReduceOrder.h"
+
+int SkReduceOrder::reduce(const SkDLine& line) {
+    fLine[0] = line[0];
+    int different = line[0] != line[1];
+    fLine[1] = line[different];
+    return 1 + different;
+}
+
+static double interp_quad_coords(double a, double b, double c, double t) {
+    double ab = SkDInterp(a, b, t);
+    double bc = SkDInterp(b, c, t);
+    return SkDInterp(ab, bc, t);
+}
+
+static int coincident_line(const SkDQuad& quad, SkDQuad& reduction) {
+    reduction[0] = reduction[1] = quad[0];
+    return 1;
+}
+
+static int reductionLineCount(const SkDQuad& reduction) {
+    return 1 + !reduction[0].approximatelyEqual(reduction[1]);
+}
+
+static int vertical_line(const SkDQuad& quad, SkReduceOrder::Style reduceStyle,
+        SkDQuad& reduction) {
+    double tValue;
+    reduction[0] = quad[0];
+    reduction[1] = quad[2];
+    if (reduceStyle == SkReduceOrder::kFill_Style) {
+        return reductionLineCount(reduction);
+    }
+    int smaller = reduction[1].fY > reduction[0].fY;
+    int larger = smaller ^ 1;
+    if (SkDQuad::FindExtrema(quad[0].fY, quad[1].fY, quad[2].fY, &tValue)) {
+        double yExtrema = interp_quad_coords(quad[0].fY, quad[1].fY, quad[2].fY, tValue);
+        if (reduction[smaller].fY > yExtrema) {
+            reduction[smaller].fY = yExtrema;
+        } else if (reduction[larger].fY < yExtrema) {
+            reduction[larger].fY = yExtrema;
+        }
+    }
+    return reductionLineCount(reduction);
+}
+
+static int horizontal_line(const SkDQuad& quad, SkReduceOrder::Style reduceStyle,
+        SkDQuad& reduction) {
+    double tValue;
+    reduction[0] = quad[0];
+    reduction[1] = quad[2];
+    if (reduceStyle == SkReduceOrder::kFill_Style) {
+        return reductionLineCount(reduction);
+    }
+    int smaller = reduction[1].fX > reduction[0].fX;
+    int larger = smaller ^ 1;
+    if (SkDQuad::FindExtrema(quad[0].fX, quad[1].fX, quad[2].fX, &tValue)) {
+        double xExtrema = interp_quad_coords(quad[0].fX, quad[1].fX, quad[2].fX, tValue);
+        if (reduction[smaller].fX > xExtrema) {
+            reduction[smaller].fX = xExtrema;
+        }  else if (reduction[larger].fX < xExtrema) {
+            reduction[larger].fX = xExtrema;
+        }
+    }
+    return reductionLineCount(reduction);
+}
+
+static int check_linear(const SkDQuad& quad, SkReduceOrder::Style reduceStyle,
+        int minX, int maxX, int minY, int maxY, SkDQuad& reduction) {
+    int startIndex = 0;
+    int endIndex = 2;
+    while (quad[startIndex].approximatelyEqual(quad[endIndex])) {
+        --endIndex;
+        if (endIndex == 0) {
+            SkDebugf("%s shouldn't get here if all four points are about equal", __FUNCTION__);
+            SkASSERT(0);
+        }
+    }
+    if (!quad.isLinear(startIndex, endIndex)) {
+        return 0;
+    }
+    // four are colinear: return line formed by outside
+    reduction[0] = quad[0];
+    reduction[1] = quad[2];
+    if (reduceStyle == SkReduceOrder::kFill_Style) {
+        return reductionLineCount(reduction);
+    }
+    int sameSide;
+    bool useX = quad[maxX].fX - quad[minX].fX >= quad[maxY].fY - quad[minY].fY;
+    if (useX) {
+        sameSide = SkDSign(quad[0].fX - quad[1].fX) + SkDSign(quad[2].fX - quad[1].fX);
+    } else {
+        sameSide = SkDSign(quad[0].fY - quad[1].fY) + SkDSign(quad[2].fY - quad[1].fY);
+    }
+    if ((sameSide & 3) != 2) {
+        return reductionLineCount(reduction);
+    }
+    double tValue;
+    int root;
+    if (useX) {
+        root = SkDQuad::FindExtrema(quad[0].fX, quad[1].fX, quad[2].fX, &tValue);
+    } else {
+        root = SkDQuad::FindExtrema(quad[0].fY, quad[1].fY, quad[2].fY, &tValue);
+    }
+    if (root) {
+        SkDPoint extrema;
+        extrema.fX = interp_quad_coords(quad[0].fX, quad[1].fX, quad[2].fX, tValue);
+        extrema.fY = interp_quad_coords(quad[0].fY, quad[1].fY, quad[2].fY, tValue);
+        // sameSide > 0 means mid is smaller than either [0] or [2], so replace smaller
+        int replace;
+        if (useX) {
+            if ((extrema.fX < quad[0].fX) ^ (extrema.fX < quad[2].fX)) {
+                return reductionLineCount(reduction);
+            }
+            replace = ((extrema.fX < quad[0].fX) | (extrema.fX < quad[2].fX))
+                    ^ (quad[0].fX < quad[2].fX);
+        } else {
+            if ((extrema.fY < quad[0].fY) ^ (extrema.fY < quad[2].fY)) {
+                return reductionLineCount(reduction);
+            }
+            replace = ((extrema.fY < quad[0].fY) | (extrema.fY < quad[2].fY))
+                    ^ (quad[0].fY < quad[2].fY);
+        }
+        reduction[replace] = extrema;
+    }
+    return reductionLineCount(reduction);
+}
+
+// reduce to a quadratic or smaller
+// look for identical points
+// look for all four points in a line
+    // note that three points in a line doesn't simplify a cubic
+// look for approximation with single quadratic
+    // save approximation with multiple quadratics for later
+int SkReduceOrder::reduce(const SkDQuad& quad, Style reduceStyle) {
+    int index, minX, maxX, minY, maxY;
+    int minXSet, minYSet;
+    minX = maxX = minY = maxY = 0;
+    minXSet = minYSet = 0;
+    for (index = 1; index < 3; ++index) {
+        if (quad[minX].fX > quad[index].fX) {
+            minX = index;
+        }
+        if (quad[minY].fY > quad[index].fY) {
+            minY = index;
+        }
+        if (quad[maxX].fX < quad[index].fX) {
+            maxX = index;
+        }
+        if (quad[maxY].fY < quad[index].fY) {
+            maxY = index;
+        }
+    }
+    for (index = 0; index < 3; ++index) {
+        if (AlmostEqualUlps(quad[index].fX, quad[minX].fX)) {
+            minXSet |= 1 << index;
+        }
+        if (AlmostEqualUlps(quad[index].fY, quad[minY].fY)) {
+            minYSet |= 1 << index;
+        }
+    }
+    if (minXSet == 0x7) {  // test for vertical line
+        if (minYSet == 0x7) {  // return 1 if all four are coincident
+            return coincident_line(quad, fQuad);
+        }
+        return vertical_line(quad, reduceStyle, fQuad);
+    }
+    if (minYSet == 0xF) {  // test for horizontal line
+        return horizontal_line(quad, reduceStyle, fQuad);
+    }
+    int result = check_linear(quad, reduceStyle, minX, maxX, minY, maxY, fQuad);
+    if (result) {
+        return result;
+    }
+    fQuad = quad;
+    return 3;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
+static double interp_cubic_coords(const double* src, double t) {
+    double ab = SkDInterp(src[0], src[2], t);
+    double bc = SkDInterp(src[2], src[4], t);
+    double cd = SkDInterp(src[4], src[6], t);
+    double abc = SkDInterp(ab, bc, t);
+    double bcd = SkDInterp(bc, cd, t);
+    return SkDInterp(abc, bcd, t);
+}
+
+static int coincident_line(const SkDCubic& cubic, SkDCubic& reduction) {
+    reduction[0] = reduction[1] = cubic[0];
+    return 1;
+}
+
+static int reductionLineCount(const SkDCubic& reduction) {
+    return 1 + !reduction[0].approximatelyEqual(reduction[1]);
+}
+
+static int vertical_line(const SkDCubic& cubic, SkReduceOrder::Style reduceStyle,
+                         SkDCubic& reduction) {
+    double tValues[2];
+    reduction[0] = cubic[0];
+    reduction[1] = cubic[3];
+    if (reduceStyle == SkReduceOrder::kFill_Style) {
+        return reductionLineCount(reduction);
+    }
+    int smaller = reduction[1].fY > reduction[0].fY;
+    int larger = smaller ^ 1;
+    int roots = SkDCubic::FindExtrema(cubic[0].fY, cubic[1].fY, cubic[2].fY, cubic[3].fY, tValues);
+    for (int index = 0; index < roots; ++index) {
+        double yExtrema = interp_cubic_coords(&cubic[0].fY, tValues[index]);
+        if (reduction[smaller].fY > yExtrema) {
+            reduction[smaller].fY = yExtrema;
+            continue;
+        }
+        if (reduction[larger].fY < yExtrema) {
+            reduction[larger].fY = yExtrema;
+        }
+    }
+    return reductionLineCount(reduction);
+}
+
+static int horizontal_line(const SkDCubic& cubic, SkReduceOrder::Style reduceStyle,
+                           SkDCubic& reduction) {
+    double tValues[2];
+    reduction[0] = cubic[0];
+    reduction[1] = cubic[3];
+    if (reduceStyle == SkReduceOrder::kFill_Style) {
+        return reductionLineCount(reduction);
+    }
+    int smaller = reduction[1].fX > reduction[0].fX;
+    int larger = smaller ^ 1;
+    int roots = SkDCubic::FindExtrema(cubic[0].fX, cubic[1].fX, cubic[2].fX, cubic[3].fX, tValues);
+    for (int index = 0; index < roots; ++index) {
+        double xExtrema = interp_cubic_coords(&cubic[0].fX, tValues[index]);
+        if (reduction[smaller].fX > xExtrema) {
+            reduction[smaller].fX = xExtrema;
+            continue;
+        }
+        if (reduction[larger].fX < xExtrema) {
+            reduction[larger].fX = xExtrema;
+        }
+    }
+    return reductionLineCount(reduction);
+}
+
+// check to see if it is a quadratic or a line
+static int check_quadratic(const SkDCubic& cubic, SkDCubic& reduction) {
+    double dx10 = cubic[1].fX - cubic[0].fX;
+    double dx23 = cubic[2].fX - cubic[3].fX;
+    double midX = cubic[0].fX + dx10 * 3 / 2;
+    if (!AlmostEqualUlps(midX - cubic[3].fX, dx23 * 3 / 2)) {
+        return 0;
+    }
+    double dy10 = cubic[1].fY - cubic[0].fY;
+    double dy23 = cubic[2].fY - cubic[3].fY;
+    double midY = cubic[0].fY + dy10 * 3 / 2;
+    if (!AlmostEqualUlps(midY - cubic[3].fY, dy23 * 3 / 2)) {
+        return 0;
+    }
+    reduction[0] = cubic[0];
+    reduction[1].fX = midX;
+    reduction[1].fY = midY;
+    reduction[2] = cubic[3];
+    return 3;
+}
+
+static int check_linear(const SkDCubic& cubic, SkReduceOrder::Style reduceStyle,
+        int minX, int maxX, int minY, int maxY, SkDCubic& reduction) {
+    int startIndex = 0;
+    int endIndex = 3;
+    while (cubic[startIndex].approximatelyEqual(cubic[endIndex])) {
+        --endIndex;
+        if (endIndex == 0) {
+            SkDebugf("%s shouldn't get here if all four points are about equal\n", __FUNCTION__);
+            SkASSERT(0);
+        }
+    }
+    if (!cubic.isLinear(startIndex, endIndex)) {
+        return 0;
+    }
+    // four are colinear: return line formed by outside
+    reduction[0] = cubic[0];
+    reduction[1] = cubic[3];
+    if (reduceStyle == SkReduceOrder::kFill_Style) {
+        return reductionLineCount(reduction);
+    }
+    int sameSide1;
+    int sameSide2;
+    bool useX = cubic[maxX].fX - cubic[minX].fX >= cubic[maxY].fY - cubic[minY].fY;
+    if (useX) {
+        sameSide1 = SkDSign(cubic[0].fX - cubic[1].fX) + SkDSign(cubic[3].fX - cubic[1].fX);
+        sameSide2 = SkDSign(cubic[0].fX - cubic[2].fX) + SkDSign(cubic[3].fX - cubic[2].fX);
+    } else {
+        sameSide1 = SkDSign(cubic[0].fY - cubic[1].fY) + SkDSign(cubic[3].fY - cubic[1].fY);
+        sameSide2 = SkDSign(cubic[0].fY - cubic[2].fY) + SkDSign(cubic[3].fY - cubic[2].fY);
+    }
+    if (sameSide1 == sameSide2 && (sameSide1 & 3) != 2) {
+        return reductionLineCount(reduction);
+    }
+    double tValues[2];
+    int roots;
+    if (useX) {
+        roots = SkDCubic::FindExtrema(cubic[0].fX, cubic[1].fX, cubic[2].fX, cubic[3].fX, tValues);
+    } else {
+        roots = SkDCubic::FindExtrema(cubic[0].fY, cubic[1].fY, cubic[2].fY, cubic[3].fY, tValues);
+    }
+    for (int index = 0; index < roots; ++index) {
+        SkDPoint extrema;
+        extrema.fX = interp_cubic_coords(&cubic[0].fX, tValues[index]);
+        extrema.fY = interp_cubic_coords(&cubic[0].fY, tValues[index]);
+        // sameSide > 0 means mid is smaller than either [0] or [3], so replace smaller
+        int replace;
+        if (useX) {
+            if ((extrema.fX < cubic[0].fX) ^ (extrema.fX < cubic[3].fX)) {
+                continue;
+            }
+            replace = ((extrema.fX < cubic[0].fX) | (extrema.fX < cubic[3].fX))
+                    ^ (cubic[0].fX < cubic[3].fX);
+        } else {
+            if ((extrema.fY < cubic[0].fY) ^ (extrema.fY < cubic[3].fY)) {
+                continue;
+            }
+            replace = ((extrema.fY < cubic[0].fY) | (extrema.fY < cubic[3].fY))
+                    ^ (cubic[0].fY < cubic[3].fY);
+        }
+        reduction[replace] = extrema;
+    }
+    return reductionLineCount(reduction);
+}
+
+/* food for thought:
+http://objectmix.com/graphics/132906-fast-precision-driven-cubic-quadratic-piecewise-degree-reduction-algos-2-a.html
+
+Given points c1, c2, c3 and c4 of a cubic Bezier, the points of the
+corresponding quadratic Bezier are (given in convex combinations of
+points):
+
+q1 = (11/13)c1 + (3/13)c2 -(3/13)c3 + (2/13)c4
+q2 = -c1 + (3/2)c2 + (3/2)c3 - c4
+q3 = (2/13)c1 - (3/13)c2 + (3/13)c3 + (11/13)c4
+
+Of course, this curve does not interpolate the end-points, but it would
+be interesting to see the behaviour of such a curve in an applet.
+
+--
+Kalle Rutanen
+http://kaba.hilvi.org
+
+*/
+
+// reduce to a quadratic or smaller
+// look for identical points
+// look for all four points in a line
+    // note that three points in a line doesn't simplify a cubic
+// look for approximation with single quadratic
+    // save approximation with multiple quadratics for later
+int SkReduceOrder::reduce(const SkDCubic& cubic, Quadratics allowQuadratics,
+        Style reduceStyle) {
+    int index, minX, maxX, minY, maxY;
+    int minXSet, minYSet;
+    minX = maxX = minY = maxY = 0;
+    minXSet = minYSet = 0;
+    for (index = 1; index < 4; ++index) {
+        if (cubic[minX].fX > cubic[index].fX) {
+            minX = index;
+        }
+        if (cubic[minY].fY > cubic[index].fY) {
+            minY = index;
+        }
+        if (cubic[maxX].fX < cubic[index].fX) {
+            maxX = index;
+        }
+        if (cubic[maxY].fY < cubic[index].fY) {
+            maxY = index;
+        }
+    }
+    for (index = 0; index < 4; ++index) {
+        double cx = cubic[index].fX;
+        double cy = cubic[index].fY;
+        double denom = SkTMax(fabs(cx), SkTMax(fabs(cy),
+                SkTMax(fabs(cubic[minX].fX), fabs(cubic[minY].fY))));
+        if (denom == 0) {
+            minXSet |= 1 << index;
+            minYSet |= 1 << index;
+            continue;
+        }
+        double inv = 1 / denom;
+        if (approximately_equal_half(cx * inv, cubic[minX].fX * inv)) {
+            minXSet |= 1 << index;
+        }
+        if (approximately_equal_half(cy * inv, cubic[minY].fY * inv)) {
+            minYSet |= 1 << index;
+        }
+    }
+    if (minXSet == 0xF) {  // test for vertical line
+        if (minYSet == 0xF) {  // return 1 if all four are coincident
+            return coincident_line(cubic, fCubic);
+        }
+        return vertical_line(cubic, reduceStyle, fCubic);
+    }
+    if (minYSet == 0xF) {  // test for horizontal line
+        return horizontal_line(cubic, reduceStyle, fCubic);
+    }
+    int result = check_linear(cubic, reduceStyle, minX, maxX, minY, maxY, fCubic);
+    if (result) {
+        return result;
+    }
+    if (allowQuadratics == SkReduceOrder::kAllow_Quadratics
+            && (result = check_quadratic(cubic, fCubic))) {
+        return result;
+    }
+    fCubic = cubic;
+    return 4;
+}
+
+SkPath::Verb SkReduceOrder::Quad(const SkPoint a[3], SkTDArray<SkPoint>* reducePts) {
+    SkDQuad quad;
+    quad.set(a);
+    SkReduceOrder reducer;
+    int order = reducer.reduce(quad, kFill_Style);
+    if (order == 2) {  // quad became line
+        for (int index = 0; index < order; ++index) {
+            SkPoint* pt = reducePts->append();
+            pt->fX = SkDoubleToScalar(reducer.fLine[index].fX);
+            pt->fY = SkDoubleToScalar(reducer.fLine[index].fY);
+        }
+    }
+    return (SkPath::Verb) (order - 1);
+}
+
+SkPath::Verb SkReduceOrder::Cubic(const SkPoint a[4], SkTDArray<SkPoint>* reducePts) {
+    SkDCubic cubic;
+    cubic.set(a);
+    SkReduceOrder reducer;
+    int order = reducer.reduce(cubic, kAllow_Quadratics, kFill_Style);
+    if (order == 2 || order == 3) {  // cubic became line or quad
+        for (int index = 0; index < order; ++index) {
+            SkPoint* pt = reducePts->append();
+            pt->fX = SkDoubleToScalar(reducer.fQuad[index].fX);
+            pt->fY = SkDoubleToScalar(reducer.fQuad[index].fY);
+        }
+    }
+    return (SkPath::Verb) (order - 1);
+}
diff --git a/src/pathops/SkReduceOrder.h b/src/pathops/SkReduceOrder.h
new file mode 100644
index 0000000..62b4af9
--- /dev/null
+++ b/src/pathops/SkReduceOrder.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef SkReduceOrder_DEFINED
+#define SkReduceOrder_DEFINED
+
+#include "SkPath.h"
+#include "SkPathOpsCubic.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsQuad.h"
+#include "SkTDArray.h"
+
+union SkReduceOrder {
+    enum Quadratics {
+        kNo_Quadratics,
+        kAllow_Quadratics
+    };
+    enum Style {
+        kStroke_Style,
+        kFill_Style
+    };
+
+    int reduce(const SkDCubic& cubic, Quadratics, Style);
+    int reduce(const SkDLine& line);
+    int reduce(const SkDQuad& quad, Style);
+
+    static SkPath::Verb Cubic(const SkPoint pts[4], SkTDArray<SkPoint>* reducePts);
+    static SkPath::Verb Quad(const SkPoint pts[3], SkTDArray<SkPoint>* reducePts);
+
+    SkDLine fLine;
+    SkDQuad fQuad;
+    SkDCubic fCubic;
+};
+
+#endif
diff --git a/src/pathops/TSearch.h b/src/pathops/TSearch.h
new file mode 100644
index 0000000..2550448
--- /dev/null
+++ b/src/pathops/TSearch.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef TSearch_DEFINED
+#define TSearch_DEFINED
+
+// FIXME: Move this templated version into SKTSearch.h
+
+template <typename T>
+static T* QSort_Partition(T* left, T* right, T* pivot)
+{
+    T pivotValue = *pivot;
+    SkTSwap(*pivot, *right);
+    T* newPivot = left;
+    while (left < right) {
+        if (*left < pivotValue) {
+            SkTSwap(*left, *newPivot);
+            newPivot += 1;
+        }
+        left += 1;
+    }
+    SkTSwap(*newPivot, *right);
+    return newPivot;
+}
+
+template <typename T>
+void QSort(T* left, T* right)
+{
+    if (left >= right) {
+        return;
+    }
+    T* pivot = left + ((right - left) >> 1);
+    pivot = QSort_Partition(left, right, pivot);
+    QSort(left, pivot - 1);
+    QSort(pivot + 1, right);
+}
+
+template <typename T>
+static T** QSort_Partition(T** left, T** right, T** pivot)
+{
+    T* pivotValue = *pivot;
+    SkTSwap(*pivot, *right);
+    T** newPivot = left;
+    while (left < right) {
+        if (**left < *pivotValue) {
+            SkTSwap(*left, *newPivot);
+            newPivot += 1;
+        }
+        left += 1;
+    }
+    SkTSwap(*newPivot, *right);
+    return newPivot;
+}
+
+template <typename T>
+void QSort(T** left, T** right)
+{
+    if (left >= right) {
+        return;
+    }
+    T** pivot = left + ((right - left) >> 1);
+    pivot = QSort_Partition(left, right, pivot);
+    QSort(left, pivot - 1);
+    QSort(pivot + 1, right);
+}
+
+template <typename S, typename T>
+static T* QSort_Partition(S& context, T* left, T* right, T* pivot,
+        bool (*lessThan)(S&, const T, const T))
+{
+    T pivotValue = *pivot;
+    SkTSwap(*pivot, *right);
+    T* newPivot = left;
+    while (left < right) {
+        if (lessThan(context, *left, pivotValue)) {
+            SkTSwap(*left, *newPivot);
+            newPivot += 1;
+        }
+        left += 1;
+    }
+    SkTSwap(*newPivot, *right);
+    return newPivot;
+}
+
+template <typename S, typename T>
+void QSort(S& context, T* left, T* right,
+        bool (*lessThan)(S& , const T, const T))
+{
+    if (left >= right) {
+        return;
+    }
+    T* pivot = left + ((right - left) >> 1);
+    pivot = QSort_Partition(context, left, right, pivot, lessThan);
+    QSort(context, left, pivot - 1, lessThan);
+    QSort(context, pivot + 1, right, lessThan);
+}
+
+#endif
diff --git a/src/pathops/main.cpp b/src/pathops/main.cpp
new file mode 100644
index 0000000..65479c2
--- /dev/null
+++ b/src/pathops/main.cpp
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Test.h"
+
+using namespace skiatest;
+
+int main(int /*argc*/, char** /*argv*/) {
+    Test tester;
+    tester.run();
+    return 0;
+}
