/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Simplify.h"

#undef SkASSERT
#define SkASSERT(cond) while (!(cond)) { sk_throw(); }

// FIXME: remove once debugging is complete
#if 01 // set to 1 for no debugging whatsoever

//const bool gRunTestsInOneThread = false;

#define DEBUG_ACTIVE_LESS_THAN 0
#define DEBUG_ADD 0
#define DEBUG_ADD_BOTTOM_TS 0
#define DEBUG_ADD_INTERSECTING_TS 0
#define DEBUG_ADJUST_COINCIDENT 0
#define DEBUG_ASSEMBLE 0
#define DEBUG_BOTTOM 0
#define DEBUG_BRIDGE 0
#define DEBUG_DUMP 0
#define DEBUG_SORT_HORIZONTAL 0
#define DEBUG_OUT 0
#define DEBUG_OUT_LESS_THAN 0
#define DEBUG_SPLIT 0
#define DEBUG_STITCH_EDGE 0
#define DEBUG_TRIM_LINE 0

#else

//const bool gRunTestsInOneThread = true;

#define DEBUG_ACTIVE_LESS_THAN 0
#define DEBUG_ADD 01
#define DEBUG_ADD_BOTTOM_TS 0
#define DEBUG_ADD_INTERSECTING_TS 0
#define DEBUG_ADJUST_COINCIDENT 1
#define DEBUG_ASSEMBLE 1
#define DEBUG_BOTTOM 0
#define DEBUG_BRIDGE 1
#define DEBUG_DUMP 1
#define DEBUG_SORT_HORIZONTAL 01
#define DEBUG_OUT 01
#define DEBUG_OUT_LESS_THAN 0
#define DEBUG_SPLIT 1
#define DEBUG_STITCH_EDGE 1
#define DEBUG_TRIM_LINE 1

#endif

#if DEBUG_ASSEMBLE || DEBUG_BRIDGE
static const char* kLVerbStr[] = {"", "line", "quad", "cubic"};
#endif
#if DEBUG_STITCH_EDGE
static const char* kUVerbStr[] = {"", "Line", "Quad", "Cubic"};
#endif

static int LineIntersect(const SkPoint a[2], const SkPoint b[2],
        Intersections& intersections) {
    const _Line aLine = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}};
    const _Line bLine = {{b[0].fX, b[0].fY}, {b[1].fX, b[1].fY}};
    return intersect(aLine, bLine, intersections);
}

static int QuadLineIntersect(const SkPoint a[3], const SkPoint b[2],
        Intersections& intersections) {
    const Quadratic aQuad = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY}};
    const _Line bLine = {{b[0].fX, b[0].fY}, {b[1].fX, b[1].fY}};
    intersect(aQuad, bLine, intersections);
    return intersections.fUsed;
}

static int CubicLineIntersect(const SkPoint a[2], const SkPoint b[3],
        Intersections& intersections) {
    const Cubic aCubic = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY},
            {a[3].fX, a[3].fY}};
    const _Line bLine = {{b[0].fX, b[0].fY}, {b[1].fX, b[1].fY}};
    return intersect(aCubic, bLine, intersections);
}

static int QuadIntersect(const SkPoint a[3], const SkPoint b[3],
        Intersections& intersections) {
    const Quadratic aQuad = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY}};
    const Quadratic bQuad = {{b[0].fX, b[0].fY}, {b[1].fX, b[1].fY}, {b[2].fX, b[2].fY}};
    intersect2(aQuad, bQuad, intersections);
    return intersections.fUsed;
}

static int CubicIntersect(const SkPoint a[4], const SkPoint b[4],
        Intersections& intersections) {
    const Cubic aCubic = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY},
            {a[3].fX, a[3].fY}};
    const Cubic bCubic = {{b[0].fX, b[0].fY}, {b[1].fX, b[1].fY}, {b[2].fX, b[2].fY},
            {b[3].fX, b[3].fY}};
    intersect(aCubic, bCubic, intersections);
    return intersections.fUsed;
}

static int LineIntersect(const SkPoint a[2], SkScalar left, SkScalar right,
        SkScalar y, double aRange[2]) {
    const _Line aLine = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}};
    return horizontalLineIntersect(aLine, left, right, y, aRange);
}

static int QuadIntersect(const SkPoint a[3], SkScalar left, SkScalar right,
        SkScalar y, double aRange[3]) {
    const Quadratic aQuad = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY}};
    return horizontalIntersect(aQuad, left, right, y, aRange);
}

static int CubicIntersect(const SkPoint a[4], SkScalar left, SkScalar right,
        SkScalar y, double aRange[4]) {
    const Cubic aCubic = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY},
            {a[3].fX, a[3].fY}};
    return horizontalIntersect(aCubic, left, right, y, aRange);
}

static void LineXYAtT(const SkPoint a[2], double t, SkPoint* out) {
    const _Line line = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}};
    double x, y;
    xy_at_t(line, t, x, y);
    out->fX = SkDoubleToScalar(x);
    out->fY = SkDoubleToScalar(y);
}

static void QuadXYAtT(const SkPoint a[3], double t, SkPoint* out) {
    const Quadratic quad = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY}};
    double x, y;
    xy_at_t(quad, t, x, y);
    out->fX = SkDoubleToScalar(x);
    out->fY = SkDoubleToScalar(y);
}

static void CubicXYAtT(const SkPoint a[4], double t, SkPoint* out) {
    const Cubic cubic = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY},
            {a[3].fX, a[3].fY}};
    double x, y;
    xy_at_t(cubic, t, x, y);
    out->fX = SkDoubleToScalar(x);
    out->fY = SkDoubleToScalar(y);
}

static SkScalar LineYAtT(const SkPoint a[2], double t) {
    const _Line aLine = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}};
    double y;
    xy_at_t(aLine, t, *(double*) 0, y);
    return SkDoubleToScalar(y);
}

static SkScalar QuadYAtT(const SkPoint a[3], double t) {
    const Quadratic quad = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY}};
    double y;
    xy_at_t(quad, t, *(double*) 0, y);
    return SkDoubleToScalar(y);
}

static SkScalar CubicYAtT(const SkPoint a[4], double t) {
    const Cubic cubic = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}, {a[2].fX, a[2].fY},
            {a[3].fX, a[3].fY}};
    double y;
    xy_at_t(cubic, t, *(double*) 0, y);
    return SkDoubleToScalar(y);
}

static void LineSubDivide(const SkPoint a[2], double startT, double endT,
        SkPoint sub[2]) {
    const _Line aLine = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}};
    _Line dst;
    sub_divide(aLine, startT, endT, dst);
    sub[0].fX = SkDoubleToScalar(dst[0].x);
    sub[0].fY = SkDoubleToScalar(dst[0].y);
    sub[1].fX = SkDoubleToScalar(dst[1].x);
    sub[1].fY = SkDoubleToScalar(dst[1].y);
}

static void QuadSubDivide(const SkPoint a[3], double startT, double endT,
        SkPoint sub[3]) {
    const Quadratic aQuad = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY},
            {a[2].fX, a[2].fY}};
    Quadratic dst;
    sub_divide(aQuad, startT, endT, dst);
    sub[0].fX = SkDoubleToScalar(dst[0].x);
    sub[0].fY = SkDoubleToScalar(dst[0].y);
    sub[1].fX = SkDoubleToScalar(dst[1].x);
    sub[1].fY = SkDoubleToScalar(dst[1].y);
    sub[2].fX = SkDoubleToScalar(dst[2].x);
    sub[2].fY = SkDoubleToScalar(dst[2].y);
}

static void CubicSubDivide(const SkPoint a[4], double startT, double endT,
        SkPoint sub[4]) {
    const Cubic aCubic = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY},
            {a[2].fX, a[2].fY}, {a[3].fX, a[3].fY}};
    Cubic dst;
    sub_divide(aCubic, startT, endT, dst);
    sub[0].fX = SkDoubleToScalar(dst[0].x);
    sub[0].fY = SkDoubleToScalar(dst[0].y);
    sub[1].fX = SkDoubleToScalar(dst[1].x);
    sub[1].fY = SkDoubleToScalar(dst[1].y);
    sub[2].fX = SkDoubleToScalar(dst[2].x);
    sub[2].fY = SkDoubleToScalar(dst[2].y);
    sub[3].fX = SkDoubleToScalar(dst[3].x);
    sub[3].fY = SkDoubleToScalar(dst[3].y);
}

static void QuadSubBounds(const SkPoint a[3], double startT, double endT,
        SkRect& bounds) {
    SkPoint dst[3];
    QuadSubDivide(a, startT, endT, dst);
    bounds.fLeft = bounds.fRight = dst[0].fX;
    bounds.fTop = bounds.fBottom = dst[0].fY;
    for (int index = 1; index < 3; ++index) {
        bounds.growToInclude(dst[index].fX, dst[index].fY);
    }
}

static void CubicSubBounds(const SkPoint a[4], double startT, double endT,
        SkRect& bounds) {
    SkPoint dst[4];
    CubicSubDivide(a, startT, endT, dst);
    bounds.fLeft = bounds.fRight = dst[0].fX;
    bounds.fTop = bounds.fBottom = dst[0].fY;
    for (int index = 1; index < 4; ++index) {
        bounds.growToInclude(dst[index].fX, dst[index].fY);
    }
}

static SkPath::Verb QuadReduceOrder(SkPoint a[4]) {
    const Quadratic aQuad =  {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY},
            {a[2].fX, a[2].fY}};
    Quadratic dst;
    int order = reduceOrder(aQuad, dst, kReduceOrder_TreatAsFill);
    for (int index = 0; index < order; ++index) {
        a[index].fX = SkDoubleToScalar(dst[index].x);
        a[index].fY = SkDoubleToScalar(dst[index].y);
    }
    if (order == 1) { // FIXME: allow returning points, caller should discard
        a[1] = a[0];
        return (SkPath::Verb) order;
    }
    return (SkPath::Verb) (order - 1);
}

static SkPath::Verb CubicReduceOrder(SkPoint a[4]) {
    const Cubic aCubic = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY},
            {a[2].fX, a[2].fY}, {a[3].fX, a[3].fY}};
    Cubic dst;
    int order = reduceOrder(aCubic, dst, kReduceOrder_QuadraticsAllowed, kReduceOrder_TreatAsFill);
    for (int index = 0; index < order; ++index) {
        a[index].fX = SkDoubleToScalar(dst[index].x);
        a[index].fY = SkDoubleToScalar(dst[index].y);
    }
    if (order == 1) { // FIXME: allow returning points, caller should discard
        a[1] = a[0];
        return (SkPath::Verb) order;
    }
    return (SkPath::Verb) (order - 1);
}

static bool IsCoincident(const SkPoint a[2], const SkPoint& above,
        const SkPoint& below) {
    const _Line aLine = {{a[0].fX, a[0].fY}, {a[1].fX, a[1].fY}};
    const _Line bLine = {{above.fX, above.fY}, {below.fX, below.fY}};
    return implicit_matches_ulps(aLine, bLine, 32);
}

/*
list of edges
bounds for edge
sort
active T

if a contour's bounds is outside of the active area, no need to create edges
*/

/* given one or more paths,
 find the bounds of each contour, select the active contours
 for each active contour, compute a set of edges
 each edge corresponds to one or more lines and curves
 leave edges unbroken as long as possible
 when breaking edges, compute the t at the break but leave the control points alone

 */

void contourBounds(const SkPath& path, SkTDArray<SkRect>& boundsArray) {
    SkPath::Iter iter(path, false);
    SkPoint pts[4];
    SkPath::Verb verb;
    SkRect bounds;
    bounds.setEmpty();
    int count = 0;
    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
        switch (verb) {
            case SkPath::kMove_Verb:
                if (!bounds.isEmpty()) {
                    *boundsArray.append() = bounds;
                }
                bounds.set(pts[0].fX, pts[0].fY, pts[0].fX, pts[0].fY);
                count = 0;
                break;
            case SkPath::kLine_Verb:
                count = 1;
                break;
            case SkPath::kQuad_Verb:
                count = 2;
                break;
            case SkPath::kCubic_Verb:
                count = 3;
                break;
            case SkPath::kClose_Verb:
                count = 0;
                break;
            default:
                SkDEBUGFAIL("bad verb");
                return;
        }
        for (int i = 1; i <= count; ++i) {
            bounds.growToInclude(pts[i].fX, pts[i].fY);
        }
    }
}

static bool extendLine(const SkPoint line[2], const SkPoint& add) {
    // FIXME: allow this to extend lines that have slopes that are nearly equal
    SkScalar dx1 = line[1].fX - line[0].fX;
    SkScalar dy1 = line[1].fY - line[0].fY;
    SkScalar dx2 = add.fX - line[0].fX;
    SkScalar dy2 = add.fY - line[0].fY;
    return dx1 * dy2 == dx2 * dy1;
}

// OPTIMIZATION: this should point to a list of input data rather than duplicating
// the line data here. This would reduce the need to assemble the results.
struct OutEdge {
    bool operator<(const OutEdge& rh) const {
        const SkPoint& first = fPts[0];
        const SkPoint& rhFirst = rh.fPts[0];
        return first.fY == rhFirst.fY
                ? first.fX < rhFirst.fX
                : first.fY < rhFirst.fY;
    }

    SkPoint fPts[4];
    int fID; // id of edge generating data
    uint8_t fVerb; // FIXME: not read from everywhere
    bool fCloseCall; // edge is trimmable if not originally coincident
};

class OutEdgeBuilder {
public:
    OutEdgeBuilder(bool fill)
        : fFill(fill) {
        }

    void addCurve(const SkPoint line[4], SkPath::Verb verb, int id,
            bool closeCall) {
        OutEdge& newEdge = fEdges.push_back();
        memcpy(newEdge.fPts, line, (verb + 1) * sizeof(SkPoint));
        newEdge.fVerb = verb;
        newEdge.fID = id;
        newEdge.fCloseCall = closeCall;
    }

    bool trimLine(SkScalar y, int id) {
        size_t count = fEdges.count();
        while (count-- != 0) {
            OutEdge& edge = fEdges[count];
            if (edge.fID != id) {
                continue;
            }
            if (edge.fCloseCall) {
                return false;
            }
            SkASSERT(edge.fPts[0].fY <= y);
            if (edge.fPts[1].fY <= y) {
                continue;
            }
            edge.fPts[1].fX = edge.fPts[0].fX + (y - edge.fPts[0].fY)
                    * (edge.fPts[1].fX - edge.fPts[0].fX)
                    / (edge.fPts[1].fY - edge.fPts[0].fY);
            edge.fPts[1].fY = y;
#if DEBUG_TRIM_LINE
            SkDebugf("%s edge=%d %1.9g,%1.9g\n", __FUNCTION__, id,
                    edge.fPts[1].fX, y);
#endif
            return true;
        }
        return false;
    }

    void assemble(SkPath& simple) {
        size_t listCount = fEdges.count();
        if (listCount == 0) {
            return;
        }
        do {
            size_t listIndex = 0;
            int advance = 1;
            while (listIndex < listCount && fTops[listIndex] == 0) {
                ++listIndex;
            }
            if (listIndex >= listCount) {
                break;
            }
            int closeEdgeIndex = -listIndex - 1;
            // the curve is deferred and not added right away because the
            // following edge may extend the first curve.
            SkPoint firstPt, lastCurve[4];
            uint8_t lastVerb;
#if DEBUG_ASSEMBLE
            int firstIndex, lastIndex;
            const int tab = 8;
#endif
            bool doMove = true;
            int edgeIndex;
            do {
                SkPoint* ptArray = fEdges[listIndex].fPts;
                uint8_t verb = fEdges[listIndex].fVerb;
                SkPoint* curve[4];
                if (advance < 0) {
                    curve[0] = &ptArray[verb];
                    if (verb == SkPath::kCubic_Verb) {
                        curve[1] = &ptArray[2];
                        curve[2] = &ptArray[1];
                    }
                    curve[verb] = &ptArray[0];
                } else {
                    curve[0] = &ptArray[0];
                    if (verb == SkPath::kCubic_Verb) {
                        curve[1] = &ptArray[1];
                        curve[2] = &ptArray[2];
                    }
                    curve[verb] = &ptArray[verb];
                }
                if (verb == SkPath::kQuad_Verb) {
                    curve[1] = &ptArray[1];
                }
                if (doMove) {
                    firstPt = *curve[0];
                    simple.moveTo(curve[0]->fX, curve[0]->fY);
#if DEBUG_ASSEMBLE
                    SkDebugf("%s %d moveTo (%g,%g)\n", __FUNCTION__,
                            listIndex + 1, curve[0]->fX, curve[0]->fY);
                    firstIndex = listIndex;
#endif
                    for (int index = 0; index <= verb; ++index) {
                        lastCurve[index] = *curve[index];
                    }
                    doMove = false;
                } else {
                    bool gap = lastCurve[lastVerb] != *curve[0];
                    if (gap || lastVerb != SkPath::kLine_Verb) { // output the accumulated curve before the gap
                        // FIXME: see comment in bridge -- this probably
                        // conceals errors
                        SkASSERT(fFill && UlpsDiff(lastCurve[lastVerb].fY,
                                curve[0]->fY) <= 10);
                        switch (lastVerb) {
                            case SkPath::kLine_Verb:
                                simple.lineTo(lastCurve[1].fX, lastCurve[1].fY);
                                break;
                            case SkPath::kQuad_Verb:
                                simple.quadTo(lastCurve[1].fX, lastCurve[1].fY,
                                        lastCurve[2].fX, lastCurve[2].fY);
                                break;
                            case SkPath::kCubic_Verb:
                                simple.cubicTo(lastCurve[1].fX, lastCurve[1].fY,
                                        lastCurve[2].fX, lastCurve[2].fY,
                                        lastCurve[3].fX, lastCurve[3].fY);
                                break;
                        }
#if DEBUG_ASSEMBLE
                        SkDebugf("%*s %d %sTo (%g,%g)\n", tab, "", lastIndex + 1,
                                kLVerbStr[lastVerb], lastCurve[lastVerb].fX,
                                lastCurve[lastVerb].fY);
#endif
                    }
                    int firstCopy = 1;
                    if (gap || (lastVerb == SkPath::kLine_Verb
                             && (verb != SkPath::kLine_Verb
                             || !extendLine(lastCurve, *curve[verb])))) {
                        // FIXME: see comment in bridge -- this probably
                        // conceals errors
                        SkASSERT(lastCurve[lastVerb] == *curve[0] ||
                                (fFill && UlpsDiff(lastCurve[lastVerb].fY,
                                curve[0]->fY) <= 10));
                        simple.lineTo(curve[0]->fX, curve[0]->fY);
#if DEBUG_ASSEMBLE
                        SkDebugf("%*s %d gap lineTo (%g,%g)\n", tab, "",
                                lastIndex + 1, curve[0]->fX, curve[0]->fY);
#endif
                        firstCopy = 0;
                    } else if (lastVerb != SkPath::kLine_Verb) {
                        firstCopy = 0;
                    }
                    for (int index = firstCopy; index <= verb; ++index) {
                        lastCurve[index] = *curve[index];
                    }
                }
                lastVerb = verb;
#if DEBUG_ASSEMBLE
                lastIndex = listIndex;
#endif
                if (advance < 0) {
                    edgeIndex = fTops[listIndex];
                    fTops[listIndex] = 0;
                } else {
                    edgeIndex = fBottoms[listIndex];
                    fBottoms[listIndex] = 0;
                }
                if (edgeIndex) {
                    listIndex = abs(edgeIndex) - 1;
                    if (edgeIndex < 0) {
                        fTops[listIndex] = 0;
                    } else {
                        fBottoms[listIndex] = 0;
                    }
                }
                if (edgeIndex == closeEdgeIndex || edgeIndex == 0) {
                    switch (lastVerb) {
                        case SkPath::kLine_Verb:
                            simple.lineTo(lastCurve[1].fX, lastCurve[1].fY);
                            break;
                        case SkPath::kQuad_Verb:
                            simple.quadTo(lastCurve[1].fX, lastCurve[1].fY,
                                    lastCurve[2].fX, lastCurve[2].fY);
                            break;
                        case SkPath::kCubic_Verb:
                            simple.cubicTo(lastCurve[1].fX, lastCurve[1].fY,
                                    lastCurve[2].fX, lastCurve[2].fY,
                                    lastCurve[3].fX, lastCurve[3].fY);
                            break;
                    }
#if DEBUG_ASSEMBLE
                    SkDebugf("%*s %d %sTo last (%g, %g)\n", tab, "",
                            lastIndex + 1, kLVerbStr[lastVerb],
                            lastCurve[lastVerb].fX, lastCurve[lastVerb].fY);
#endif
                    if (lastCurve[lastVerb] != firstPt) {
                        simple.lineTo(firstPt.fX, firstPt.fY);
#if DEBUG_ASSEMBLE
                        SkDebugf("%*s %d final line (%g, %g)\n", tab, "",
                                firstIndex + 1, firstPt.fX, firstPt.fY);
#endif
                    }
                    simple.close();
#if DEBUG_ASSEMBLE
                    SkDebugf("%*s   close\n", tab, "");
#endif
                    break;
                }
                // if this and next edge go different directions
#if DEBUG_ASSEMBLE
                SkDebugf("%*s   advance=%d edgeIndex=%d flip=%s\n", tab, "",
                        advance, edgeIndex, advance > 0 ^ edgeIndex < 0 ?
                        "true" : "false");
#endif
                if (advance > 0 ^ edgeIndex < 0) {
                    advance = -advance;
                }
            } while (edgeIndex);
        } while (true);
    }

    // sort points by y, then x
    // if x/y is identical, sort bottoms before tops
    // if identical and both tops/bottoms, sort by angle
    static bool lessThan(SkTArray<OutEdge>& edges, const int one,
            const int two) {
        const OutEdge& oneEdge = edges[abs(one) - 1];
        int oneIndex = one < 0 ? 0 : oneEdge.fVerb;
        const SkPoint& startPt1 = oneEdge.fPts[oneIndex];
        const OutEdge& twoEdge = edges[abs(two) - 1];
        int twoIndex = two < 0 ? 0 : twoEdge.fVerb;
        const SkPoint& startPt2 = twoEdge.fPts[twoIndex];
        if (startPt1.fY != startPt2.fY) {
    #if DEBUG_OUT_LESS_THAN
            SkDebugf("%s %d<%d (%g,%g) %s startPt1.fY < startPt2.fY\n", __FUNCTION__,
                    one, two, startPt1.fY, startPt2.fY,
                    startPt1.fY < startPt2.fY ? "true" : "false");
    #endif
            return startPt1.fY < startPt2.fY;
        }
        if (startPt1.fX != startPt2.fX) {
    #if DEBUG_OUT_LESS_THAN
            SkDebugf("%s %d<%d (%g,%g) %s startPt1.fX < startPt2.fX\n", __FUNCTION__,
                    one, two, startPt1.fX, startPt2.fX,
                    startPt1.fX < startPt2.fX ? "true" : "false");
    #endif
            return startPt1.fX < startPt2.fX;
        }
        const SkPoint& endPt1 = oneEdge.fPts[oneIndex ^ oneEdge.fVerb];
        const SkPoint& endPt2 = twoEdge.fPts[twoIndex ^ twoEdge.fVerb];
        SkScalar dy1 = startPt1.fY - endPt1.fY;
        SkScalar dy2 = startPt2.fY - endPt2.fY;
        SkScalar dy1y2 = dy1 * dy2;
        if (dy1y2 < 0) { // different signs
    #if DEBUG_OUT_LESS_THAN
                SkDebugf("%s %d<%d %s dy1 > 0\n", __FUNCTION__, one, two,
                        dy1 > 0 ? "true" : "false");
    #endif
            return dy1 > 0; // one < two if one goes up and two goes down
        }
        if (dy1y2 == 0) {
    #if DEBUG_OUT_LESS_THAN
            SkDebugf("%s %d<%d %s endPt1.fX < endPt2.fX\n", __FUNCTION__,
                    one, two, endPt1.fX < endPt2.fX ? "true" : "false");
    #endif
            return endPt1.fX < endPt2.fX;
        }
        SkScalar dx1y2 = (startPt1.fX - endPt1.fX) * dy2;
        SkScalar dx2y1 = (startPt2.fX - endPt2.fX) * dy1;
    #if DEBUG_OUT_LESS_THAN
        SkDebugf("%s %d<%d %s dy2 < 0 ^ dx1y2 < dx2y1\n", __FUNCTION__,
                one, two, dy2 < 0 ^ dx1y2 < dx2y1 ? "true" : "false");
    #endif
        return dy2 > 0 ^ dx1y2 < dx2y1;
    }

    // Sort the indices of paired points and then create more indices so
    // assemble() can find the next edge and connect the top or bottom
    void bridge() {
        size_t index;
        size_t count = fEdges.count();
        if (!count) {
            return;
        }
        SkASSERT(!fFill || count > 1);
        fTops.setCount(count);
        sk_bzero(fTops.begin(), sizeof(fTops[0]) * count);
        fBottoms.setCount(count);
        sk_bzero(fBottoms.begin(), sizeof(fBottoms[0]) * count);
        SkTDArray<int> order;
        for (index = 1; index <= count; ++index) {
            *order.append() = -index;
        }
        for (index = 1; index <= count; ++index) {
            *order.append() = index;
        }
        QSort<SkTArray<OutEdge>, int>(fEdges, order.begin(), order.end() - 1, lessThan);
        int* lastPtr = order.end() - 1;
        int* leftPtr = order.begin();
        while (leftPtr < lastPtr) {
            int leftIndex = *leftPtr;
            int leftOutIndex = abs(leftIndex) - 1;
            const OutEdge& left = fEdges[leftOutIndex];
            int* rightPtr = leftPtr + 1;
            int rightIndex = *rightPtr;
            int rightOutIndex = abs(rightIndex) - 1;
            const OutEdge& right = fEdges[rightOutIndex];
            bool pairUp = fFill;
            if (!pairUp) {
                const SkPoint& leftMatch =
                        left.fPts[leftIndex < 0 ? 0 : left.fVerb];
                const SkPoint& rightMatch =
                        right.fPts[rightIndex < 0 ? 0 : right.fVerb];
                pairUp = leftMatch == rightMatch;
            } else {
        #if DEBUG_OUT
        // FIXME : not happy that error in low bit is allowed
        // this probably conceals error elsewhere
                if (UlpsDiff(left.fPts[leftIndex < 0 ? 0 : left.fVerb].fY,
                        right.fPts[rightIndex < 0 ? 0 : right.fVerb].fY) > 1) {
                    *fMismatches.append() = leftIndex;
                    if (rightPtr == lastPtr) {
                        *fMismatches.append() = rightIndex;
                    }
                    pairUp = false;
                }
        #else
                SkASSERT(UlpsDiff(left.fPts[leftIndex < 0 ? 0 : left.fVerb].fY,
                        right.fPts[rightIndex < 0 ? 0 : right.fVerb].fY) <= 10);
        #endif
            }
            if (pairUp) {
                if (leftIndex < 0) {
                    fTops[leftOutIndex] = rightIndex;
                } else {
                    fBottoms[leftOutIndex] = rightIndex;
                }
                if (rightIndex < 0) {
                    fTops[rightOutIndex] = leftIndex;
                } else {
                    fBottoms[rightOutIndex] = leftIndex;
                }
                ++rightPtr;
            }
            leftPtr = rightPtr;
        }
#if DEBUG_OUT
        int* mismatch = fMismatches.begin();
        while (mismatch != fMismatches.end()) {
            int leftIndex = *mismatch++;
            int leftOutIndex = abs(leftIndex) - 1;
            const OutEdge& left = fEdges[leftOutIndex];
            const SkPoint& leftPt = left.fPts[leftIndex < 0 ? 0 : left.fVerb];
            SkDebugf("%s left=%d %s (%1.9g,%1.9g)\n",
                    __FUNCTION__, left.fID, leftIndex < 0 ? "top" : "bot",
                    leftPt.fX, leftPt.fY);
        }
        SkASSERT(fMismatches.count() == 0);
#endif
#if DEBUG_BRIDGE
    for (index = 0; index < count; ++index) {
        const OutEdge& edge = fEdges[index];
        uint8_t verb = edge.fVerb;
        SkDebugf("%s %d edge=%d %s (%1.9g,%1.9g) (%1.9g,%1.9g)\n",
                index == 0 ? __FUNCTION__ : "      ",
                index + 1, edge.fID, kLVerbStr[verb], edge.fPts[0].fX,
                edge.fPts[0].fY, edge.fPts[verb].fX, edge.fPts[verb].fY);
    }
    for (index = 0; index < count; ++index) {
        SkDebugf("       top    of % 2d connects to %s of % 2d\n", index + 1,
                fTops[index] < 0 ? "top   " : "bottom", abs(fTops[index]));
        SkDebugf("       bottom of % 2d connects to %s of % 2d\n", index + 1,
                fBottoms[index] < 0 ? "top   " : "bottom", abs(fBottoms[index]));
    }
#endif
    }

protected:
    SkTArray<OutEdge> fEdges;
    SkTDArray<int> fTops;
    SkTDArray<int> fBottoms;
    bool fFill;
#if DEBUG_OUT
    SkTDArray<int> fMismatches;
#endif
};

// Bounds, unlike Rect, does not consider a vertical line to be empty.
struct Bounds : public SkRect {
    static bool Intersects(const Bounds& a, const Bounds& b) {
        return a.fLeft <= b.fRight && b.fLeft <= a.fRight &&
                a.fTop <= b.fBottom && b.fTop <= a.fBottom;
    }

    bool isEmpty() {
        return fLeft > fRight || fTop > fBottom
                || (fLeft == fRight && fTop == fBottom)
                || isnan(fLeft) || isnan(fRight)
                || isnan(fTop) || isnan(fBottom);
    }
};

class Intercepts {
public:
    Intercepts()
        : fTopIntercepts(0)
        , fBottomIntercepts(0)
        , fExplicit(false) {
    }

    Intercepts& operator=(const Intercepts& src) {
        fTs = src.fTs;
        fTopIntercepts = src.fTopIntercepts;
        fBottomIntercepts = src.fBottomIntercepts;
        return *this;
    }

    // OPTIMIZATION: remove this function if it's never called
    double t(int tIndex) const {
        if (tIndex == 0) {
            return 0;
        }
        if (tIndex > fTs.count()) {
            return 1;
        }
        return fTs[tIndex - 1];
    }

#if DEBUG_DUMP
    void dump(const SkPoint* pts, SkPath::Verb verb) {
        const char className[] = "Intercepts";
        const int tab = 8;
        for (int i = 0; i < fTs.count(); ++i) {
            SkPoint out;
            switch (verb) {
                case SkPath::kLine_Verb:
                    LineXYAtT(pts, fTs[i], &out);
                    break;
                case SkPath::kQuad_Verb:
                    QuadXYAtT(pts, fTs[i], &out);
                    break;
                case SkPath::kCubic_Verb:
                    CubicXYAtT(pts, fTs[i], &out);
                    break;
                default:
                    SkASSERT(0);
            }
            SkDebugf("%*s.fTs[%d]=%1.9g (%1.9g,%1.9g)\n", tab + sizeof(className),
                    className, i, fTs[i], out.fX, out.fY);
        }
        SkDebugf("%*s.fTopIntercepts=%u\n", tab + sizeof(className),
                className, fTopIntercepts);
        SkDebugf("%*s.fBottomIntercepts=%u\n", tab + sizeof(className),
                className, fBottomIntercepts);
        SkDebugf("%*s.fExplicit=%d\n", tab + sizeof(className),
                className, fExplicit);
    }
#endif

    SkTDArray<double> fTs;
    unsigned char fTopIntercepts; // 0=init state 1=1 edge >1=multiple edges
    unsigned char fBottomIntercepts;
    bool fExplicit; // if set, suppress 0 and 1

};

struct HorizontalEdge {
    bool operator<(const HorizontalEdge& rh) const {
        return fY == rh.fY ? fLeft == rh.fLeft ? fRight < rh.fRight
                : fLeft < rh.fLeft : fY < rh.fY;
    }

#if DEBUG_DUMP
    void dump() {
        const char className[] = "HorizontalEdge";
        const int tab = 4;
        SkDebugf("%*s.fLeft=%1.9g\n", tab + sizeof(className), className, fLeft);
        SkDebugf("%*s.fRight=%1.9g\n", tab + sizeof(className), className, fRight);
        SkDebugf("%*s.fY=%1.9g\n", tab + sizeof(className), className, fY);
    }
#endif

    SkScalar fLeft;
    SkScalar fRight;
    SkScalar fY;
};

struct InEdge {
    bool operator<(const InEdge& rh) const {
        return fBounds.fTop == rh.fBounds.fTop
                ? fBounds.fLeft < rh.fBounds.fLeft
                : fBounds.fTop < rh.fBounds.fTop;
    }

    // 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.
    int add(double* ts, size_t count, ptrdiff_t verbIndex) {
        // FIXME: in the pathological case where there is a ton of intercepts, binary search?
        bool foundIntercept = false;
        int insertedAt = -1;
        Intercepts& intercepts = fIntercepts[verbIndex];
        for (size_t index = 0; index < count; ++index) {
            double t = ts[index];
            if (t <= 0) {
                intercepts.fTopIntercepts <<= 1;
                fContainsIntercepts |= ++intercepts.fTopIntercepts > 1;
                continue;
            }
            if (t >= 1) {
                intercepts.fBottomIntercepts <<= 1;
                fContainsIntercepts |= ++intercepts.fBottomIntercepts > 1;
                continue;
            }
            fIntersected = true;
            foundIntercept = true;
            size_t tCount = intercepts.fTs.count();
            double delta;
            for (size_t idx2 = 0; idx2 < tCount; ++idx2) {
                if (t <= intercepts.fTs[idx2]) {
                    // FIXME: ?  if (t < intercepts.fTs[idx2]) // failed
                    delta = intercepts.fTs[idx2] - t;
                    if (delta > 0) {
                        insertedAt = idx2;
                        *intercepts.fTs.insert(idx2) = t;
                    }
                    goto nextPt;
                }
            }
            if (tCount == 0 || (delta = t - intercepts.fTs[tCount - 1]) > 0) {
                insertedAt = tCount;
                *intercepts.fTs.append() = t;
            }
    nextPt:
            ;
        }
        fContainsIntercepts |= foundIntercept;
        return insertedAt;
    }

    void addPartial(SkTArray<InEdge>& edges, int ptStart, int ptEnd,
            int verbStart, int verbEnd) {
        InEdge* edge = edges.push_back_n(1);
        int verbCount = verbEnd - verbStart;
        edge->fIntercepts.push_back_n(verbCount);
     //   uint8_t* verbs = &fVerbs[verbStart];
        for (int ceptIdx = 0; ceptIdx < verbCount; ++ceptIdx) {
            edge->fIntercepts[ceptIdx] = fIntercepts[verbStart + ceptIdx];
        }
        edge->fPts.append(ptEnd - ptStart, &fPts[ptStart]);
        edge->fVerbs.append(verbCount, &fVerbs[verbStart]);
        edge->setBounds();
        edge->fWinding = fWinding;
        edge->fContainsIntercepts = fContainsIntercepts; // FIXME: may not be correct -- but do we need to know?
    }

    void addSplit(SkTArray<InEdge>& edges, SkPoint* pts, uint8_t verb,
            Intercepts& intercepts, int firstT, int lastT, bool flipped) {
        InEdge* edge = edges.push_back_n(1);
        edge->fIntercepts.push_back_n(1);
        if (firstT == 0) {
            *edge->fIntercepts[0].fTs.append() = 0;
        } else {
            *edge->fIntercepts[0].fTs.append() = intercepts.fTs[firstT - 1];
        }
        bool add1 = lastT == intercepts.fTs.count();
        edge->fIntercepts[0].fTs.append(lastT - firstT, &intercepts.fTs[firstT]);
        if (add1) {
            *edge->fIntercepts[0].fTs.append() = 1;
        }
        edge->fIntercepts[0].fExplicit = true;
        edge->fPts.append(verb + 1, pts);
        edge->fVerbs.append(1, &verb);
        // FIXME: bounds could be better for partial Ts
        edge->setSubBounds();
        edge->fContainsIntercepts = fContainsIntercepts; // FIXME: may not be correct -- but do we need to know?
        if (flipped) {
            edge->flipTs();
            edge->fWinding = -fWinding;
        } else {
            edge->fWinding = fWinding;
        }
    }

    bool cached(const InEdge* edge) {
        // FIXME: in the pathological case where there is a ton of edges, binary search?
        size_t count = fCached.count();
        for (size_t index = 0; index < count; ++index) {
            if (edge == fCached[index]) {
                return true;
            }
            if (edge < fCached[index]) {
                *fCached.insert(index) = edge;
                return false;
            }
        }
        *fCached.append() = edge;
        return false;
    }

    void complete(signed char winding) {
        setBounds();
        fIntercepts.push_back_n(fVerbs.count());
        if ((fWinding = winding) < 0) { // reverse verbs, pts, if bottom to top
            flip();
        }
        fContainsIntercepts = fIntersected = false;
    }

    void flip() {
        size_t index;
        size_t last = fPts.count() - 1;
        for (index = 0; index < last; ++index, --last) {
            SkTSwap<SkPoint>(fPts[index], fPts[last]);
        }
        last = fVerbs.count() - 1;
        for (index = 0; index < last; ++index, --last) {
            SkTSwap<uint8_t>(fVerbs[index], fVerbs[last]);
        }
    }

    void flipTs() {
        SkASSERT(fIntercepts.count() == 1);
        Intercepts& intercepts = fIntercepts[0];
        SkASSERT(intercepts.fExplicit);
        SkTDArray<double>& ts = intercepts.fTs;
        size_t index;
        size_t last = ts.count() - 1;
        for (index = 0; index < last; ++index, --last) {
            SkTSwap<double>(ts[index], ts[last]);
        }
    }

    void reset() {
        fCached.reset();
        fIntercepts.reset();
        fPts.reset();
        fVerbs.reset();
        fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax);
        fWinding = 0;
        fContainsIntercepts = false;
        fIntersected = false;
    }

    void setBounds() {
        SkPoint* ptPtr = fPts.begin();
        SkPoint* ptLast = fPts.end();
        if (ptPtr == ptLast) {
            SkDebugf("%s empty edge\n", __FUNCTION__);
            SkASSERT(0);
            // FIXME: delete empty edge?
            return;
        }
        fBounds.set(ptPtr->fX, ptPtr->fY, ptPtr->fX, ptPtr->fY);
        ++ptPtr;
        while (ptPtr != ptLast) {
            fBounds.growToInclude(ptPtr->fX, ptPtr->fY);
            ++ptPtr;
        }
    }

    // recompute bounds based on subrange of T values
    void setSubBounds() {
        SkASSERT(fIntercepts.count() == 1);
        Intercepts& intercepts = fIntercepts[0];
        SkASSERT(intercepts.fExplicit);
        SkASSERT(fVerbs.count() == 1);
        SkTDArray<double>& ts = intercepts.fTs;
        if (fVerbs[0] == SkPath::kQuad_Verb) {
            SkASSERT(fPts.count() == 3);
            QuadSubBounds(fPts.begin(), ts[0], ts[ts.count() - 1], fBounds);
        } else {
            SkASSERT(fVerbs[0] == SkPath::kCubic_Verb);
            SkASSERT(fPts.count() == 4);
            CubicSubBounds(fPts.begin(), ts[0], ts[ts.count() - 1], fBounds);
        }
    }

    void splitInflectionPts(SkTArray<InEdge>& edges) {
        if (!fIntersected) {
            return;
        }
        uint8_t* verbs = fVerbs.begin();
        SkPoint* pts = fPts.begin();
        int lastVerb = 0;
        int lastPt = 0;
        uint8_t verb;
        bool edgeSplit = false;
        for (int ceptIdx = 0; ceptIdx < fIntercepts.count(); ++ceptIdx, pts += verb) {
            Intercepts& intercepts = fIntercepts[ceptIdx];
            verb = *verbs++;
            if (verb <= SkPath::kLine_Verb) {
                continue;
            }
            size_t tCount = intercepts.fTs.count();
            if (!tCount) {
                continue;
            }
            size_t tIndex = (size_t) -1;
            SkScalar y = pts[0].fY;
            int lastSplit = 0;
            int firstSplit = -1;
            bool curveSplit = false;
            while (++tIndex < tCount) {
                double nextT = intercepts.fTs[tIndex];
                SkScalar nextY = verb == SkPath::kQuad_Verb
                        ? QuadYAtT(pts, nextT) : CubicYAtT(pts, nextT);
                if (nextY < y) {
                    edgeSplit = curveSplit = true;
                    if (firstSplit < 0) {
                        firstSplit = tIndex;
                        int nextPt = pts - fPts.begin();
                        int nextVerb = verbs - 1 - fVerbs.begin();
                        if (lastVerb < nextVerb) {
                            addPartial(edges, lastPt, nextPt, lastVerb, nextVerb);
            #if DEBUG_SPLIT
                            SkDebugf("%s addPartial 1\n", __FUNCTION__);
            #endif
                        }
                        lastPt = nextPt;
                        lastVerb = nextVerb;
                    }
                } else {
                    if (firstSplit >= 0) {
                        if (lastSplit < firstSplit) {
                            addSplit(edges, pts, verb, intercepts,
                                    lastSplit, firstSplit, false);
            #if DEBUG_SPLIT
                            SkDebugf("%s addSplit 1 tIndex=%d,%d\n",
                                    __FUNCTION__, lastSplit, firstSplit);
            #endif
                        }
                        addSplit(edges, pts, verb, intercepts,
                                firstSplit, tIndex, true);
            #if DEBUG_SPLIT
                        SkDebugf("%s addSplit 2 tIndex=%d,%d flip\n",
                                __FUNCTION__, firstSplit, tIndex);
            #endif
                        lastSplit = tIndex;
                        firstSplit = -1;
                    }
                }
                y = nextY;
            }
            if (curveSplit) {
                if (firstSplit < 0) {
                    firstSplit = lastSplit;
                } else {
                    addSplit(edges, pts, verb, intercepts, lastSplit,
                            firstSplit, false);
            #if DEBUG_SPLIT
                    SkDebugf("%s addSplit 3 tIndex=%d,%d\n", __FUNCTION__,
                            lastSplit, firstSplit);
            #endif
                }
                addSplit(edges, pts, verb, intercepts, firstSplit,
                        tIndex, pts[verb].fY < y);
            #if DEBUG_SPLIT
                SkDebugf("%s addSplit 4 tIndex=%d,%d %s\n", __FUNCTION__,
                        firstSplit, tIndex, pts[verb].fY < y ? "flip" : "");
            #endif
            }
        }
        // collapse remainder -- if there's nothing left, clear it somehow?
        if (edgeSplit) {
            int nextVerb = verbs - 1 - fVerbs.begin();
            if (lastVerb < nextVerb) {
                int nextPt = pts - fPts.begin();
                addPartial(edges, lastPt, nextPt, lastVerb, nextVerb);
            #if DEBUG_SPLIT
                SkDebugf("%s addPartial 2\n", __FUNCTION__);
            #endif
            }
            // OPTIMIZATION: reuse the edge instead of marking it empty
            reset();
        }
    }

#if DEBUG_DUMP
    void dump() {
        int i;
        const char className[] = "InEdge";
        const int tab = 4;
        SkDebugf("InEdge %p (edge=%d)\n", this, fID);
        for (i = 0; i < fCached.count(); ++i) {
            SkDebugf("%*s.fCached[%d]=0x%08x\n", tab + sizeof(className),
                    className, i, fCached[i]);
        }
        uint8_t* verbs = fVerbs.begin();
        SkPoint* pts = fPts.begin();
        for (i = 0; i < fIntercepts.count(); ++i) {
            SkDebugf("%*s.fIntercepts[%d]:\n", tab + sizeof(className),
                    className, i);
            fIntercepts[i].dump(pts, (SkPath::Verb) *verbs);
            pts += *verbs++;
        }
        for (i = 0; i < fPts.count(); ++i) {
            SkDebugf("%*s.fPts[%d]=(%1.9g,%1.9g)\n", tab + sizeof(className),
                    className, i, fPts[i].fX, fPts[i].fY);
        }
        for (i = 0; i < fVerbs.count(); ++i) {
            SkDebugf("%*s.fVerbs[%d]=%d\n", tab + sizeof(className),
                    className, i, fVerbs[i]);
        }
        SkDebugf("%*s.fBounds=(%1.9g, %1.9g, %1.9g, %1.9g)\n", tab + sizeof(className),
                className, fBounds.fLeft, fBounds.fTop,
                fBounds.fRight, fBounds.fBottom);
        SkDebugf("%*s.fWinding=%d\n", tab + sizeof(className), className,
                fWinding);
        SkDebugf("%*s.fContainsIntercepts=%d\n", tab + sizeof(className),
                className, fContainsIntercepts);
        SkDebugf("%*s.fIntersected=%d\n", tab + sizeof(className),
                className, fIntersected);
    }
#endif

    // FIXME: temporary data : move this to a separate struct?
    SkTDArray<const InEdge*> fCached; // list of edges already intercepted
    SkTArray<Intercepts> fIntercepts; // one per verb

    // persistent data
    SkTDArray<SkPoint> fPts;
    SkTDArray<uint8_t> fVerbs;
    Bounds fBounds;
    int fID;
    signed char fWinding;
    bool fContainsIntercepts;
    bool fIntersected;
};

class InEdgeBuilder {
public:

InEdgeBuilder(const SkPath& path, bool ignoreHorizontal, SkTArray<InEdge>& edges,
        SkTDArray<HorizontalEdge>& horizontalEdges)
    : fPath(path)
    , fCurrentEdge(NULL)
    , fEdges(edges)
    , fHorizontalEdges(horizontalEdges)
    , fIgnoreHorizontal(ignoreHorizontal)
    , fContainsCurves(false)
{
    walk();
}

bool containsCurves() const {
    return fContainsCurves;
}

protected:

void addEdge() {
    SkASSERT(fCurrentEdge);
    fCurrentEdge->fPts.append(fPtCount - fPtOffset, &fPts[fPtOffset]);
    fPtOffset = 1;
    *fCurrentEdge->fVerbs.append() = fVerb;
}

bool complete() {
    if (fCurrentEdge && fCurrentEdge->fVerbs.count()) {
        fCurrentEdge->complete(fWinding);
        fCurrentEdge = NULL;
        return true;
    }
    return false;
}

int direction(SkPath::Verb verb) {
    fPtCount = verb + 1;
    if (fIgnoreHorizontal && isHorizontal()) {
        return 0;
    }
    return fPts[0].fY == fPts[verb].fY
            ? fPts[0].fX == fPts[verb].fX ? 0 : fPts[0].fX < fPts[verb].fX
            ? 1 : -1 : fPts[0].fY < fPts[verb].fY ? 1 : -1;
}

bool isHorizontal() {
    SkScalar y = fPts[0].fY;
    for (int i = 1; i < fPtCount; ++i) {
        if (fPts[i].fY != y) {
            return false;
        }
    }
    return true;
}

void startEdge() {
    if (!fCurrentEdge) {
        fCurrentEdge = fEdges.push_back_n(1);
    }
    fWinding = 0;
    fPtOffset = 0;
}

void walk() {
    SkPath::Iter iter(fPath, true);
    int winding = 0;
    while ((fVerb = iter.next(fPts)) != SkPath::kDone_Verb) {
        switch (fVerb) {
            case SkPath::kMove_Verb:
                startEdge();
                continue;
            case SkPath::kLine_Verb:
                winding = direction(SkPath::kLine_Verb);
                break;
            case SkPath::kQuad_Verb:
                fVerb = QuadReduceOrder(fPts);
                winding = direction(fVerb);
                fContainsCurves |= fVerb == SkPath::kQuad_Verb;
                break;
            case SkPath::kCubic_Verb:
                fVerb = CubicReduceOrder(fPts);
                winding = direction(fVerb);
                fContainsCurves |= fVerb >= SkPath::kQuad_Verb;
                break;
            case SkPath::kClose_Verb:
                SkASSERT(fCurrentEdge);
                complete();
                continue;
            default:
                SkDEBUGFAIL("bad verb");
                return;
        }
        if (winding == 0) {
            HorizontalEdge* horizontalEdge = fHorizontalEdges.append();
            // FIXME: for degenerate quads and cubics, compute x extremes
            horizontalEdge->fLeft = fPts[0].fX;
            horizontalEdge->fRight = fPts[fVerb].fX;
            horizontalEdge->fY = fPts[0].fY;
            if (horizontalEdge->fLeft > horizontalEdge->fRight) {
                SkTSwap<SkScalar>(horizontalEdge->fLeft, horizontalEdge->fRight);
            }
            if (complete()) {
                startEdge();
            }
            continue;
        }
        if (fWinding + winding == 0) {
            // FIXME: if prior verb or this verb is a horizontal line, reverse
            // it instead of starting a new edge
            SkASSERT(fCurrentEdge);
            if (complete()) {
                startEdge();
            }
        }
        fWinding = winding;
        addEdge();
    }
    if (!complete()) {
        if (fCurrentEdge) {
            fEdges.pop_back();
        }
    }
}

private:
    const SkPath& fPath;
    InEdge* fCurrentEdge;
    SkTArray<InEdge>& fEdges;
    SkTDArray<HorizontalEdge>& fHorizontalEdges;
    SkPoint fPts[4];
    SkPath::Verb fVerb;
    int fPtCount;
    int fPtOffset;
    int8_t fWinding;
    bool fIgnoreHorizontal;
    bool fContainsCurves;
};

struct WorkEdge {
    SkScalar bottom() const {
        return fPts[verb()].fY;
    }

    void init(const InEdge* edge) {
        fEdge = edge;
        fPts = edge->fPts.begin();
        fVerb = edge->fVerbs.begin();
    }

    bool advance() {
        SkASSERT(fVerb < fEdge->fVerbs.end());
        fPts += *fVerb++;
        return fVerb != fEdge->fVerbs.end();
    }

    const SkPoint* lastPoints() const {
        SkASSERT(fPts >= fEdge->fPts.begin() + lastVerb());
        return &fPts[-lastVerb()];
    }

    SkPath::Verb lastVerb() const {
        SkASSERT(fVerb > fEdge->fVerbs.begin());
        return (SkPath::Verb) fVerb[-1];
    }

    const SkPoint* points() const {
        return fPts;
    }

    SkPath::Verb verb() const {
        return (SkPath::Verb) *fVerb;
    }

    ptrdiff_t verbIndex() const {
        return fVerb - fEdge->fVerbs.begin();
    }

    int winding() const {
        return fEdge->fWinding;
    }

    const InEdge* fEdge;
    const SkPoint* fPts;
    const uint8_t* fVerb;
};

// always constructed with SkTDArray because new edges are inserted
// this may be a inappropriate optimization, suggesting that a separate array of
// ActiveEdge* may be faster to insert and search

// OPTIMIZATION: Brian suggests that global sorting should be unnecessary, since
// as active edges are introduced, only local sorting should be required
class ActiveEdge {
public:
    // this logic must be kept in sync with tooCloseToCall
    // callers expect this to only read fAbove, fTangent
    bool operator<(const ActiveEdge& rh) const {
        if (fVerb == rh.fVerb) {
            // FIXME: don't know what to do if verb is quad, cubic
            return abCompare(fAbove, fBelow, rh.fAbove, rh.fBelow);
        }
        // figure out which is quad, line
        // if cached data says line did not intersect quad, use top/bottom
        if (fVerb != SkPath::kLine_Verb ? noIntersect(rh) : rh.noIntersect(*this)) {
            return abCompare(fAbove, fBelow, rh.fAbove, rh.fBelow);
        }
        // use whichever of top/tangent tangent/bottom overlaps more
        // with line top/bot
        // assumes quad/cubic can already be upconverted to cubic/cubic
        const SkPoint* line[2];
        const SkPoint* curve[4];
        if (fVerb != SkPath::kLine_Verb) {
            line[0] = &rh.fAbove;
            line[1] = &rh.fBelow;
            curve[0] = &fAbove;
            curve[1] = &fTangent;
            curve[2] = &fBelow;
        } else {
            line[0] = &fAbove;
            line[1] = &fBelow;
            curve[0] = &rh.fAbove;
            curve[1] = &rh.fTangent;
            curve[2] = &rh.fBelow;
        }
        // FIXME: code has been abandoned, incomplete....
        return false;
    }

    bool abCompare(const SkPoint& a1, const SkPoint& a2, const SkPoint& b1,
            const SkPoint& b2) const {
        double topD = a1.fX - b1.fX;
        if (b1.fY < a1.fY) {
            topD = (b2.fY - b1.fY) * topD - (a1.fY - b1.fY) * (b2.fX - b1.fX);
        } else if (b1.fY > a1.fY) {
            topD = (a2.fY - a1.fY) * topD + (b1.fY - a1.fY) * (a2.fX - a1.fX);
        }
        double botD = a2.fX - b2.fX;
        if (b2.fY > a2.fY) {
            botD = (b2.fY - b1.fY) * botD - (a2.fY - b2.fY) * (b2.fX - b1.fX);
        } else if (b2.fY < a2.fY) {
            botD = (a2.fY - a1.fY) * botD + (b2.fY - a2.fY) * (a2.fX - a1.fX);
        }
        // return sign of greater absolute value
        return (fabs(topD) > fabs(botD) ? topD : botD) < 0;
    }

    // If a pair of edges are nearly coincident for some span, add a T in the
    // edge so it can be shortened to match the other edge. Note that another
    // approach is to trim the edge after it is added to the OutBuilder list --
    // FIXME: since this has no effect if the edge is already done (i.e.,
    // fYBottom >= y) maybe this can only be done by calling trimLine later.
    void addTatYBelow(SkScalar y) {
        if (fBelow.fY <= y || fYBottom >= y) {
            return;
        }
        addTatYInner(y);
        fFixBelow = true;
    }

    void addTatYAbove(SkScalar y) {
        if (fBelow.fY <= y) {
            return;
        }
        addTatYInner(y);
    }

    void addTatYInner(SkScalar y) {
        if (fWorkEdge.fPts[0].fY > y) {
            backup(y);
        }
        SkScalar left = fWorkEdge.fPts[0].fX;
        SkScalar right = fWorkEdge.fPts[1].fX;
        if (left > right) {
            SkTSwap(left, right);
        }
        double ts[2];
        SkASSERT(fWorkEdge.fVerb[0] == SkPath::kLine_Verb);
        int pts = LineIntersect(fWorkEdge.fPts, left, right, y, ts);
        SkASSERT(pts == 1);
        // An ActiveEdge or WorkEdge has no need to modify the T values computed
        // in the InEdge, except in the following case. If a pair of edges are
        // nearly coincident, this may not be detected when the edges are
        // intersected. Later, when sorted, and this near-coincidence is found,
        // an additional t value must be added, requiring the cast below.
        InEdge* writable = const_cast<InEdge*>(fWorkEdge.fEdge);
        int insertedAt = writable->add(ts, pts, fWorkEdge.verbIndex());
    #if DEBUG_ADJUST_COINCIDENT
        SkDebugf("%s edge=%d y=%1.9g t=%1.9g\n", __FUNCTION__, ID(), y, ts[0]);
    #endif
        if (insertedAt >= 0) {
            if (insertedAt + 1 < fTIndex) {
                SkASSERT(insertedAt + 2 == fTIndex);
                --fTIndex;
            }
        }
    }

    bool advanceT() {
        SkASSERT(fTIndex <= fTs->count() - fExplicitTs);
        return ++fTIndex <= fTs->count() - fExplicitTs;
    }

    bool advance() {
    // FIXME: flip sense of next
        bool result = fWorkEdge.advance();
        fDone = !result;
        initT();
        return result;
    }

    void backup(SkScalar y) {
        do {
            SkASSERT(fWorkEdge.fEdge->fVerbs.begin() < fWorkEdge.fVerb);
            fWorkEdge.fPts -= *--fWorkEdge.fVerb;
            SkASSERT(fWorkEdge.fEdge->fPts.begin() <= fWorkEdge.fPts);
        } while (fWorkEdge.fPts[0].fY >= y);
        initT();
        SkASSERT(!fExplicitTs);
        fTIndex = fTs->count() + 1;
    }

    void calcAboveBelow(double tAbove, double tBelow) {
        fVerb = fWorkEdge.verb();
        switch (fVerb) {
            case SkPath::kLine_Verb:
                LineXYAtT(fWorkEdge.fPts, tAbove, &fAbove);
                LineXYAtT(fWorkEdge.fPts, tBelow, &fTangent);
                fBelow = fTangent;
                break;
            case SkPath::kQuad_Verb:
                // FIXME: put array in struct to avoid copy?
                SkPoint quad[3];
                QuadSubDivide(fWorkEdge.fPts, tAbove, tBelow, quad);
                fAbove = quad[0];
                fTangent = quad[0] != quad[1] ? quad[1] : quad[2];
                fBelow = quad[2];
                break;
            case SkPath::kCubic_Verb:
                SkPoint cubic[3];
                CubicSubDivide(fWorkEdge.fPts, tAbove, tBelow, cubic);
                fAbove = cubic[0];
                // FIXME: can't see how quad logic for how tangent is used
                // extends to cubic
                fTangent = cubic[0] != cubic[1] ? cubic[1]
                        : cubic[0] != cubic[2] ? cubic[2] : cubic[3];
                fBelow = cubic[3];
                break;
            default:
                SkASSERT(0);
        }
    }

    void calcLeft(SkScalar y) {
        // OPTIMIZE: put a kDone_Verb at the end of the verb list?
        if (fDone || fBelow.fY > y) {
            return; // nothing to do; use last
        }
        calcLeft();
        if (fAbove.fY == fBelow.fY) {
            SkDebugf("%s edge=%d fAbove.fY != fBelow.fY %1.9g\n", __FUNCTION__,
                    ID(), fAbove.fY);
        }
    }

    void calcLeft() {
        int add = (fTIndex <= fTs->count() - fExplicitTs) - 1;
        double tAbove = t(fTIndex + add);
        double tBelow = t(fTIndex - ~add);
        // OPTIMIZATION: if fAbove, fBelow have already been computed
        //  for the fTIndex, don't do it again
        calcAboveBelow(tAbove, tBelow);
        // For identical x, this lets us know which edge is first.
        // If both edges have T values < 1, check x at next T (fBelow).
        SkASSERT(tAbove != tBelow);
        // FIXME: this can loop forever
        // need a break if we hit the end
        // FIXME: in unit test, figure out how explicit Ts work as well
        while (fAbove.fY == fBelow.fY) {
            if (add < 0 || fTIndex == fTs->count()) {
                add -= 1;
                SkASSERT(fTIndex + add >= 0);
                tAbove = t(fTIndex + add);
            } else {
                add += 1;
                SkASSERT(fTIndex - ~add <= fTs->count() + 1);
                tBelow = t(fTIndex - ~add);
            }
            calcAboveBelow(tAbove, tBelow);
        }
        fTAbove = tAbove;
        fTBelow = tBelow;
    }

    bool done(SkScalar bottom) const {
        return fDone || fYBottom >= bottom;
    }

    void fixBelow() {
        if (fFixBelow) {
            fTBelow = nextT();
            calcAboveBelow(fTAbove, fTBelow);
            fFixBelow = false;
        }
    }

    void init(const InEdge* edge) {
        fWorkEdge.init(edge);
        fDone = false;
        initT();
        fBelow.fY = SK_ScalarMin;
        fYBottom = SK_ScalarMin;
    }

    void initT() {
        const Intercepts& intercepts = fWorkEdge.fEdge->fIntercepts.front();
        SkASSERT(fWorkEdge.verbIndex() <= fWorkEdge.fEdge->fIntercepts.count());
        const Intercepts* interceptPtr = &intercepts + fWorkEdge.verbIndex();
        fTs = &interceptPtr->fTs;
        fExplicitTs = interceptPtr->fExplicit;
  //  the above is conceptually the same as
  //    fTs = &fWorkEdge.fEdge->fIntercepts[fWorkEdge.verbIndex()].fTs;
  //  but templated arrays don't allow returning a pointer to the end() element
        fTIndex = 0;
        if (!fDone) {
            fVerb = fWorkEdge.verb();
        }
        SkASSERT(fVerb > SkPath::kMove_Verb);
    }

    // OPTIMIZATION: record if two edges are coincident when the are intersected
    // It's unclear how to do this -- seems more complicated than recording the
    // t values, since the same t values could exist intersecting non-coincident
    // edges.
    bool isCoincidentWith(const ActiveEdge* edge) const {
        if (fAbove != edge->fAbove || fBelow != edge->fBelow) {
            return false;
        }
        if (fVerb != edge->fVerb) {
            return false;
        }
        switch (fVerb) {
            case SkPath::kLine_Verb:
                return true;
            default:
                // FIXME: add support for quads, cubics
                SkASSERT(0);
                return false;
        }
        return false;
    }

    bool isUnordered(const ActiveEdge* edge) const {
        return fAbove == edge->fAbove && fBelow == edge->fBelow;
    }

//    SkPath::Verb lastVerb() const {
//        return fDone ? fWorkEdge.lastVerb() : fWorkEdge.verb();
//    }

    const SkPoint* lastPoints() const {
        return fDone ? fWorkEdge.lastPoints() : fWorkEdge.points();
    }

    bool noIntersect(const ActiveEdge& ) const {
        // incomplete
        return false;
    }

    // The shortest close call edge should be moved into a position where
    // it contributes if the winding is transitioning to or from zero.
    bool swapClose(const ActiveEdge* next, int prev, int wind, int mask) const {
#if DEBUG_ADJUST_COINCIDENT
        SkDebugf("%s edge=%d (%g) next=%d (%g) prev=%d wind=%d nextWind=%d\n",
                __FUNCTION__, ID(), fBelow.fY, next->ID(), next->fBelow.fY,
                prev, wind, wind + next->fWorkEdge.winding());
#endif
        if ((prev & mask) == 0 || (wind & mask) == 0) {
            return next->fBelow.fY < fBelow.fY;
        }
        int nextWinding = wind + next->fWorkEdge.winding();
        if ((nextWinding & mask) == 0) {
            return fBelow.fY < next->fBelow.fY;
        }
        return false;
    }

    bool swapCoincident(const ActiveEdge* edge, SkScalar bottom) const {
        if (fBelow.fY >= bottom || fDone || edge->fDone) {
            return false;
        }
        ActiveEdge thisWork = *this;
        ActiveEdge edgeWork = *edge;
        while ((thisWork.advanceT() || thisWork.advance())
                && (edgeWork.advanceT() || edgeWork.advance())) {
            thisWork.calcLeft();
            edgeWork.calcLeft();
            if (thisWork < edgeWork) {
                return false;
            }
            if (edgeWork < thisWork) {
                return true;
            }
        }
        return false;
    }

    bool swapUnordered(const ActiveEdge* edge, SkScalar /* bottom */) const {
        SkASSERT(fVerb != SkPath::kLine_Verb
                || edge->fVerb != SkPath::kLine_Verb);
        if (fDone || edge->fDone) {
            return false;
        }
        ActiveEdge thisWork, edgeWork;
        extractAboveBelow(thisWork);
        edge->extractAboveBelow(edgeWork);
        return edgeWork < thisWork;
    }

    bool tooCloseToCall(const ActiveEdge* edge) const {
        int ulps;
        double t1, t2, b1, b2;
        // This logic must be kept in sync with operator <
        if (edge->fAbove.fY < fAbove.fY) {
            t1 = (edge->fTangent.fY - edge->fAbove.fY) * (fAbove.fX - edge->fAbove.fX);
            t2 = (fAbove.fY - edge->fAbove.fY) * (edge->fTangent.fX - edge->fAbove.fX);
        } else if (edge->fAbove.fY > fAbove.fY) {
            t1 = (fTangent.fY - fAbove.fY) * (fAbove.fX - edge->fAbove.fX);
            t2 = (fAbove.fY - edge->fAbove.fY) * (fTangent.fX - fAbove.fX);
        } else {
            t1 = fAbove.fX;
            t2 = edge->fAbove.fX;
        }
        if (edge->fTangent.fY > fTangent.fY) {
            b1 = (edge->fTangent.fY - edge->fAbove.fY) * (fTangent.fX - edge->fTangent.fX);
            b2 = (fTangent.fY - edge->fTangent.fY) * (edge->fTangent.fX - edge->fAbove.fX);
        } else if (edge->fTangent.fY < fTangent.fY) {
            b1 = (fTangent.fY - fAbove.fY) * (fTangent.fX - edge->fTangent.fX);
            b2 = (fTangent.fY - edge->fTangent.fY) * (fTangent.fX - fAbove.fX);
        } else {
            b1 = fTangent.fX;
            b2 = edge->fTangent.fX;
        }
        if (fabs(t1 - t2) > fabs(b1 - b2)) {
            ulps = UlpsDiff((float) t1, (float) t2);
        } else {
            ulps = UlpsDiff((float) b1, (float) b2);
        }
#if DEBUG_ADJUST_COINCIDENT
        SkDebugf("%s this=%d edge=%d ulps=%d\n", __FUNCTION__, ID(), edge->ID(),
                ulps);
#endif
        if (ulps < 0 || ulps > 32) {
            return false;
        }
        if (fVerb == SkPath::kLine_Verb && edge->fVerb == SkPath::kLine_Verb) {
            return true;
        }
        if (fVerb != SkPath::kLine_Verb && edge->fVerb != SkPath::kLine_Verb) {
            return false;
        }

        double ts[2];
        bool isLine = true;
        bool curveQuad = true;
        if (fVerb == SkPath::kCubic_Verb) {
            ts[0] = (fTAbove * 2 + fTBelow) / 3;
            ts[1] = (fTAbove + fTBelow * 2) / 3;
            curveQuad = isLine = false;
        } else if (edge->fVerb == SkPath::kCubic_Verb) {
            ts[0] = (edge->fTAbove * 2 + edge->fTBelow) / 3;
            ts[1] = (edge->fTAbove + edge->fTBelow * 2) / 3;
            curveQuad = false;
        } else if (fVerb == SkPath::kQuad_Verb) {
                ts[0] = fTAbove;
                ts[1] = (fTAbove + fTBelow) / 2;
                isLine = false;
        } else {
            SkASSERT(edge->fVerb == SkPath::kQuad_Verb);
            ts[0] = edge->fTAbove;
            ts[1] = (edge->fTAbove + edge->fTBelow) / 2;
        }
        const SkPoint* curvePts = isLine ? edge->lastPoints() : lastPoints();
        const ActiveEdge* lineEdge = isLine ? this : edge;
        SkPoint curveSample[2];
        for (int index = 0; index < 2; ++index) {
            if (curveQuad) {
                QuadXYAtT(curvePts, ts[index], &curveSample[index]);
            } else {
                CubicXYAtT(curvePts, ts[index], &curveSample[index]);
            }
        }
        return IsCoincident(curveSample, lineEdge->fAbove, lineEdge->fBelow);
    }

    double nextT() const {
        SkASSERT(fTIndex <= fTs->count() - fExplicitTs);
        return t(fTIndex + 1);
    }

    double t() const {
        return t(fTIndex);
    }

    double t(int tIndex) const {
        if (fExplicitTs) {
            SkASSERT(tIndex < fTs->count());
            return (*fTs)[tIndex];
        }
        if (tIndex == 0) {
            return 0;
        }
        if (tIndex > fTs->count()) {
            return 1;
        }
        return (*fTs)[tIndex - 1];
    }

    // FIXME: debugging only
    int ID() const {
        return fWorkEdge.fEdge->fID;
    }

private:
    // utility used only by swapUnordered
    void extractAboveBelow(ActiveEdge& extracted) const {
        SkPoint curve[4];
        switch (fVerb) {
            case SkPath::kLine_Verb:
                extracted.fAbove = fAbove;
                extracted.fTangent = fTangent;
                return;
            case SkPath::kQuad_Verb:
                QuadSubDivide(lastPoints(), fTAbove, fTBelow, curve);
                break;
            case SkPath::kCubic_Verb:
                CubicSubDivide(lastPoints(), fTAbove, fTBelow, curve);
                break;
            default:
                SkASSERT(0);
        }
        extracted.fAbove = curve[0];
        extracted.fTangent = curve[1];
    }

public:
    WorkEdge fWorkEdge;
    const SkTDArray<double>* fTs;
    SkPoint fAbove;
    SkPoint fTangent;
    SkPoint fBelow;
    double fTAbove; // OPTIMIZATION: only required if edge has quads or cubics
    double fTBelow;
    SkScalar fYBottom;
    int fCoincident;
    int fTIndex;
    SkPath::Verb fVerb;
    bool fSkip; // OPTIMIZATION: use bitfields?
    bool fCloseCall;
    bool fDone;
    bool fFixBelow;
    bool fExplicitTs;
};

static void addToActive(SkTDArray<ActiveEdge>& activeEdges, const InEdge* edge) {
    size_t count = activeEdges.count();
    for (size_t index = 0; index < count; ++index) {
        if (edge == activeEdges[index].fWorkEdge.fEdge) {
            return;
        }
    }
    ActiveEdge* active = activeEdges.append();
    active->init(edge);
}

// Find any intersections in the range of active edges. A pair of edges, on
// either side of another edge, may change the winding contribution for part of
// the edge.
// Keep horizontal edges just for
// the purpose of computing when edges change their winding contribution, since
// this is essentially computing the horizontal intersection.
static void addBottomT(InEdge** currentPtr, InEdge** lastPtr,
        HorizontalEdge** horizontal) {
    InEdge** testPtr = currentPtr - 1;
    HorizontalEdge* horzEdge = *horizontal;
    SkScalar left = horzEdge->fLeft;
    SkScalar bottom = horzEdge->fY;
    while (++testPtr != lastPtr) {
        InEdge* test = *testPtr;
        if (test->fBounds.fBottom <= bottom || test->fBounds.fRight <= left) {
            continue;
        }
        WorkEdge wt;
        wt.init(test);
        do {
            HorizontalEdge** sorted = horizontal;
            horzEdge = *sorted;
            do {
                double wtTs[4];
                int pts;
                uint8_t verb = wt.verb();
                switch (verb) {
                    case SkPath::kLine_Verb:
                        pts = LineIntersect(wt.fPts, horzEdge->fLeft,
                                horzEdge->fRight, horzEdge->fY, wtTs);
                        break;
                    case SkPath::kQuad_Verb:
                        pts = QuadIntersect(wt.fPts, horzEdge->fLeft,
                                horzEdge->fRight, horzEdge->fY, wtTs);
                        break;
                    case SkPath::kCubic_Verb:
                        pts = CubicIntersect(wt.fPts, horzEdge->fLeft,
                                horzEdge->fRight, horzEdge->fY, wtTs);
                        break;
                }
                if (pts) {
#if DEBUG_ADD_BOTTOM_TS
                    for (int x = 0; x < pts; ++x) {
                        SkDebugf("%s y=%g wtTs[0]=%g (%g,%g", __FUNCTION__,
                                horzEdge->fY, wtTs[x], wt.fPts[0].fX, wt.fPts[0].fY);
                        for (int y = 0; y < verb; ++y) {
                            SkDebugf(" %g,%g", wt.fPts[y + 1].fX, wt.fPts[y + 1].fY));
                        }
                        SkDebugf(")\n");
                    }
                    if (pts > verb) {
                        SkASSERT(0); // FIXME ? should this work?
                        SkDebugf("%s wtTs[1]=%g\n", __FUNCTION__, wtTs[1]);
                    }
#endif
                    test->add(wtTs, pts, wt.verbIndex());
                }
                horzEdge = *++sorted;
            } while (horzEdge->fY == bottom
                    && horzEdge->fLeft <= test->fBounds.fRight);
        } while (wt.advance());
    }
}

#if DEBUG_ADD_INTERSECTING_TS
static void debugShowLineIntersection(int pts, const WorkEdge& wt,
        const WorkEdge& wn, const double wtTs[2], const double wnTs[2]) {
    if (!pts) {
        return;
    }
    SkPoint wtOutPt, wnOutPt;
    LineXYAtT(wt.fPts, wtTs[0], &wtOutPt);
    LineXYAtT(wn.fPts, wnTs[0], &wnOutPt);
    SkDebugf("%s wtTs[0]=%g (%g,%g, %g,%g) (%g,%g)\n",
            __FUNCTION__,
            wtTs[0], wt.fPts[0].fX, wt.fPts[0].fY,
            wt.fPts[1].fX, wt.fPts[1].fY, wtOutPt.fX, wtOutPt.fY);
    if (pts == 2) {
        SkDebugf("%s wtTs[1]=%g\n", __FUNCTION__, wtTs[1]);
    }
    SkDebugf("%s wnTs[0]=%g (%g,%g, %g,%g) (%g,%g)\n",
            __FUNCTION__,
            wnTs[0], wn.fPts[0].fX, wn.fPts[0].fY,
            wn.fPts[1].fX, wn.fPts[1].fY, wnOutPt.fX, wnOutPt.fY);
    if (pts == 2) {
        SkDebugf("%s wnTs[1]=%g\n", __FUNCTION__, wnTs[1]);
    }
}
#else
static void debugShowLineIntersection(int , const WorkEdge& ,
        const WorkEdge& , const double [2], const double [2]) {
}
#endif

static void addIntersectingTs(InEdge** currentPtr, InEdge** lastPtr) {
    InEdge** testPtr = currentPtr - 1;
    // FIXME: lastPtr should be past the point of interest, so
    // test below should be  lastPtr - 2
    // that breaks testSimplifyTriangle22, so further investigation is needed
    while (++testPtr != lastPtr - 1) {
        InEdge* test = *testPtr;
        InEdge** nextPtr = testPtr;
        do {
            InEdge* next = *++nextPtr;
            // FIXME: this compares against the sentinel sometimes
            // OPTIMIZATION: this may never be needed since this gets called
            // in two passes now. Verify that double hits are appropriate.
            if (test->cached(next)) {
                continue;
            }
            if (!Bounds::Intersects(test->fBounds, next->fBounds)) {
                continue;
            }
            WorkEdge wt, wn;
            wt.init(test);
            wn.init(next);
            do {
                int pts;
                Intersections ts;
                bool swap = false;
                switch (wt.verb()) {
                    case SkPath::kLine_Verb:
                        switch (wn.verb()) {
                            case SkPath::kLine_Verb: {
                                pts = LineIntersect(wt.fPts, wn.fPts, ts);
                                debugShowLineIntersection(pts, wt, wn,
                                        ts.fT[0], ts.fT[1]);
                                break;
                            }
                            case SkPath::kQuad_Verb: {
                                swap = true;
                                pts = QuadLineIntersect(wn.fPts, wt.fPts, ts);
                                break;
                            }
                            case SkPath::kCubic_Verb: {
                                swap = true;
                                pts = CubicLineIntersect(wn.fPts, wt.fPts, ts);
                                break;
                            }
                            default:
                                SkASSERT(0);
                        }
                        break;
                    case SkPath::kQuad_Verb:
                        switch (wn.verb()) {
                            case SkPath::kLine_Verb: {
                                pts = QuadLineIntersect(wt.fPts, wn.fPts, ts);
                                break;
                            }
                            case SkPath::kQuad_Verb: {
                                pts = QuadIntersect(wt.fPts, wn.fPts, ts);
                                break;
                            }
                            case SkPath::kCubic_Verb: {
                                // FIXME: promote quad to cubic
                                pts = CubicIntersect(wt.fPts, wn.fPts, ts);
                                break;
                            }
                            default:
                                SkASSERT(0);
                        }
                        break;
                    case SkPath::kCubic_Verb:
                        switch (wn.verb()) {
                            case SkPath::kLine_Verb: {
                                pts = CubicLineIntersect(wt.fPts, wn.fPts, ts);
                                break;
                            }
                            case SkPath::kQuad_Verb: {
                                 // FIXME: promote quad to cubic
                                pts = CubicIntersect(wt.fPts, wn.fPts, ts);
                                break;
                            }
                            case SkPath::kCubic_Verb: {
                                pts = CubicIntersect(wt.fPts, wn.fPts, ts);
                                break;
                            }
                            default:
                                SkASSERT(0);
                        }
                        break;
                    default:
                        SkASSERT(0);
                }
                test->add(ts.fT[swap], pts, wt.verbIndex());
                next->add(ts.fT[!swap], pts, wn.verbIndex());
            } while (wt.bottom() <= wn.bottom() ? wt.advance() : wn.advance());
        } while (nextPtr != lastPtr);
    }
}

static InEdge** advanceEdges(SkTDArray<ActiveEdge>* activeEdges,
        InEdge** currentPtr, InEdge** lastPtr,  SkScalar y) {
    InEdge** testPtr = currentPtr - 1;
    while (++testPtr != lastPtr) {
        if ((*testPtr)->fBounds.fBottom > y) {
            continue;
        }
        if (activeEdges) {
            InEdge* test = *testPtr;
            ActiveEdge* activePtr = activeEdges->begin() - 1;
            ActiveEdge* lastActive = activeEdges->end();
            while (++activePtr != lastActive) {
                if (activePtr->fWorkEdge.fEdge == test) {
                    activeEdges->remove(activePtr - activeEdges->begin());
                    break;
                }
            }
        }
        if (testPtr == currentPtr) {
            ++currentPtr;
        }
    }
    return currentPtr;
}

// OPTIMIZE: inline?
static HorizontalEdge** advanceHorizontal(HorizontalEdge** edge, SkScalar y) {
    while ((*edge)->fY < y) {
        ++edge;
    }
    return edge;
}

// compute bottom taking into account any intersected edges
static SkScalar computeInterceptBottom(SkTDArray<ActiveEdge>& activeEdges,
        SkScalar y, SkScalar bottom) {
    ActiveEdge* activePtr = activeEdges.begin() - 1;
    ActiveEdge* lastActive = activeEdges.end();
    while (++activePtr != lastActive) {
        const InEdge* test = activePtr->fWorkEdge.fEdge;
        if (!test->fContainsIntercepts) {
            continue;
        }
        WorkEdge wt;
        wt.init(test);
        do {
            const Intercepts& intercepts = test->fIntercepts[wt.verbIndex()];
            if (intercepts.fTopIntercepts > 1) {
                SkScalar yTop = wt.fPts[0].fY;
                if (yTop > y && bottom > yTop) {
                    bottom = yTop;
                }
            }
            if (intercepts.fBottomIntercepts > 1) {
                SkScalar yBottom = wt.fPts[wt.verb()].fY;
                if (yBottom > y && bottom > yBottom) {
                    bottom = yBottom;
                }
            }
            const SkTDArray<double>& fTs = intercepts.fTs;
            size_t count = fTs.count();
            for (size_t index = 0; index < count; ++index) {
                SkScalar yIntercept;
                switch (wt.verb()) {
                    case SkPath::kLine_Verb: {
                        yIntercept = LineYAtT(wt.fPts, fTs[index]);
                        break;
                    }
                    case SkPath::kQuad_Verb: {
                        yIntercept = QuadYAtT(wt.fPts, fTs[index]);
                        break;
                    }
                    case SkPath::kCubic_Verb: {
                        yIntercept = CubicYAtT(wt.fPts, fTs[index]);
                        break;
                    }
                    default:
                        SkASSERT(0); // should never get here
                }
                if (yIntercept > y && bottom > yIntercept) {
                    bottom = yIntercept;
                }
            }
        } while (wt.advance());
    }
#if DEBUG_BOTTOM
    SkDebugf("%s bottom=%1.9g\n", __FUNCTION__, bottom);
#endif
    return bottom;
}

static SkScalar findBottom(InEdge** currentPtr,
        InEdge** edgeListEnd, SkTDArray<ActiveEdge>* activeEdges, SkScalar y,
        bool /*asFill*/, InEdge**& testPtr) {
    InEdge* current = *currentPtr;
    SkScalar bottom = current->fBounds.fBottom;

    // find the list of edges that cross y
    InEdge* test = *testPtr;
    while (testPtr != edgeListEnd) {
        SkScalar testTop = test->fBounds.fTop;
        if (bottom <= testTop) {
            break;
        }
        SkScalar testBottom = test->fBounds.fBottom;
        // OPTIMIZATION: Shortening the bottom is only interesting when filling
        // and when the edge is to the left of a longer edge. If it's a framing
        // edge, or part of the right, it won't effect the longer edges.
        if (testTop > y) {
            bottom = testTop;
            break;
        }
        if (y < testBottom) {
            if (bottom > testBottom) {
                bottom = testBottom;
            }
            if (activeEdges) {
                addToActive(*activeEdges, test);
            }
        }
        test = *++testPtr;
    }
#if DEBUG_BOTTOM
    SkDebugf("%s %d bottom=%1.9g\n", __FUNCTION__, activeEdges ? 2 : 1, bottom);
#endif
    return bottom;
}

static void makeEdgeList(SkTArray<InEdge>& edges, InEdge& edgeSentinel,
        SkTDArray<InEdge*>& edgeList) {
    size_t edgeCount = edges.count();
    if (edgeCount == 0) {
        return;
    }
    int id = 0;
    for (size_t index = 0; index < edgeCount; ++index) {
        InEdge& edge = edges[index];
        if (!edge.fWinding) {
            continue;
        }
        edge.fID = ++id;
        *edgeList.append() = &edge;
    }
    *edgeList.append() = &edgeSentinel;
    QSort<InEdge>(edgeList.begin(), edgeList.end() - 1);
}

static void makeHorizontalList(SkTDArray<HorizontalEdge>& edges,
        HorizontalEdge& edgeSentinel, SkTDArray<HorizontalEdge*>& edgeList) {
    size_t edgeCount = edges.count();
    if (edgeCount == 0) {
        return;
    }
    for (size_t index = 0; index < edgeCount; ++index) {
        *edgeList.append() = &edges[index];
    }
    edgeSentinel.fLeft = edgeSentinel.fRight = edgeSentinel.fY = SK_ScalarMax;
    *edgeList.append() = &edgeSentinel;
    QSort<HorizontalEdge>(edgeList.begin(), edgeList.end() - 1);
}

static void skipCoincidence(int lastWinding, int winding, int windingMask,
            ActiveEdge* activePtr, ActiveEdge* firstCoincident) {
    if (((lastWinding & windingMask) == 0) ^ ((winding & windingMask) != 0)) {
        return;
    }
    // FIXME: ? shouldn't this be if (lastWinding & windingMask) ?
    if (lastWinding) {
#if DEBUG_ADJUST_COINCIDENT
        SkDebugf("%s edge=%d 1 set skip=false\n", __FUNCTION__, activePtr->ID());
#endif
        activePtr->fSkip = false;
    } else {
#if DEBUG_ADJUST_COINCIDENT
        SkDebugf("%s edge=%d 2 set skip=false\n", __FUNCTION__, firstCoincident->ID());
#endif
        firstCoincident->fSkip = false;
    }
}

static void sortHorizontal(SkTDArray<ActiveEdge>& activeEdges,
        SkTDArray<ActiveEdge*>& edgeList, SkScalar y) {
    size_t edgeCount = activeEdges.count();
    if (edgeCount == 0) {
        return;
    }
#if DEBUG_SORT_HORIZONTAL
    const int tab = 3; // FIXME: debugging only
    SkDebugf("%s y=%1.9g\n", __FUNCTION__, y);
#endif
    size_t index;
    for (index = 0; index < edgeCount; ++index) {
        ActiveEdge& activeEdge = activeEdges[index];
        do {
            activeEdge.calcLeft(y);
            // skip segments that don't span y
            if (activeEdge.fAbove != activeEdge.fBelow) {
                break;
            }
            if (activeEdge.fDone) {
#if DEBUG_SORT_HORIZONTAL
                SkDebugf("%*s edge=%d done\n", tab, "", activeEdge.ID());
#endif
                goto nextEdge;
            }
#if DEBUG_SORT_HORIZONTAL
            SkDebugf("%*s edge=%d above==below\n", tab, "", activeEdge.ID());
#endif
        } while (activeEdge.advanceT() || activeEdge.advance());
#if DEBUG_SORT_HORIZONTAL
        SkDebugf("%*s edge=%d above=(%1.9g,%1.9g) (%1.9g) below=(%1.9g,%1.9g)"
                " (%1.9g)\n", tab, "", activeEdge.ID(),
                activeEdge.fAbove.fX, activeEdge.fAbove.fY, activeEdge.fTAbove,
                activeEdge.fBelow.fX, activeEdge.fBelow.fY, activeEdge.fTBelow);
#endif
        activeEdge.fSkip = activeEdge.fCloseCall = activeEdge.fFixBelow = false;
        *edgeList.append() = &activeEdge;
nextEdge:
        ;
    }
    QSort<ActiveEdge>(edgeList.begin(), edgeList.end() - 1);
}

// remove coincident edges
// OPTIMIZE: remove edges? This is tricky because the current logic expects
// the winding count to be maintained while skipping coincident edges. In
// addition to removing the coincident edges, the remaining edges would need
// to have a different winding value, possibly different per intercept span.
static SkScalar adjustCoincident(SkTDArray<ActiveEdge*>& edgeList,
        int windingMask, SkScalar y, SkScalar bottom, OutEdgeBuilder& outBuilder)
{
#if DEBUG_ADJUST_COINCIDENT
    SkDebugf("%s y=%1.9g bottom=%1.9g\n", __FUNCTION__, y, bottom);
#endif
    size_t edgeCount = edgeList.count();
    if (edgeCount == 0) {
        return bottom;
    }
    ActiveEdge* activePtr, * nextPtr = edgeList[0];
    size_t index;
    bool foundCoincident = false;
    size_t firstIndex = 0;
    for (index = 1; index < edgeCount; ++index) {
        activePtr = nextPtr;
        nextPtr = edgeList[index];
        if (firstIndex != index - 1 && activePtr->fVerb > SkPath::kLine_Verb
                && nextPtr->fVerb == SkPath::kLine_Verb
                && activePtr->isUnordered(nextPtr)) {
            // swap the line with the curve
            // back up to the previous edge and retest
            SkTSwap<ActiveEdge*>(edgeList[index - 1], edgeList[index]);
            SkASSERT(index > 1);
            index -= 2;
            nextPtr = edgeList[index];
            continue;
        }
        bool closeCall = false;
        activePtr->fCoincident = firstIndex;
        if (activePtr->isCoincidentWith(nextPtr)
                || (closeCall = activePtr->tooCloseToCall(nextPtr))) {
            activePtr->fSkip = nextPtr->fSkip = foundCoincident = true;
            activePtr->fCloseCall = nextPtr->fCloseCall = closeCall;
        } else if (activePtr->isUnordered(nextPtr)) {
            foundCoincident = true;
        } else {
            firstIndex = index;
        }
    }
    nextPtr->fCoincident = firstIndex;
    if (!foundCoincident) {
        return bottom;
    }
    int winding = 0;
    nextPtr = edgeList[0];
    for (index = 1; index < edgeCount; ++index) {
        int priorWinding = winding;
        winding += activePtr->fWorkEdge.winding();
        activePtr = nextPtr;
        nextPtr = edgeList[index];
        SkASSERT(activePtr == edgeList[index - 1]);
        SkASSERT(nextPtr == edgeList[index]);
        if (activePtr->fCoincident != nextPtr->fCoincident) {
            continue;
        }
        // the coincident edges may not have been sorted above -- advance
        // the edges and resort if needed
        // OPTIMIZE: if sorting is done incrementally as new edges are added
        // and not all at once as is done here, fold this test into the
        // current less than test.
        while ((!activePtr->fSkip || !nextPtr->fSkip)
                && activePtr->fCoincident == nextPtr->fCoincident) {
            if (activePtr->swapUnordered(nextPtr, bottom)) {
                winding -= activePtr->fWorkEdge.winding();
                SkASSERT(activePtr == edgeList[index - 1]);
                SkASSERT(nextPtr == edgeList[index]);
                SkTSwap<ActiveEdge*>(edgeList[index - 1], edgeList[index]);
                if (--index == 0) {
                    winding += activePtr->fWorkEdge.winding();
                    break;
                }
                // back up one
                activePtr = edgeList[index - 1];
                continue;
            }
            SkASSERT(activePtr == edgeList[index - 1]);
            SkASSERT(nextPtr == edgeList[index]);
            break;
        }
        if (activePtr->fSkip && nextPtr->fSkip) {
            if (activePtr->fCloseCall ? activePtr->swapClose(nextPtr,
                    priorWinding, winding, windingMask)
                    : activePtr->swapCoincident(nextPtr, bottom)) {
                winding -= activePtr->fWorkEdge.winding();
                SkASSERT(activePtr == edgeList[index - 1]);
                SkASSERT(nextPtr == edgeList[index]);
                SkTSwap<ActiveEdge*>(edgeList[index - 1], edgeList[index]);
                SkTSwap<ActiveEdge*>(activePtr, nextPtr);
                winding += activePtr->fWorkEdge.winding();
                SkASSERT(activePtr == edgeList[index - 1]);
                SkASSERT(nextPtr == edgeList[index]);
            }
        }
    }
    int firstCoincidentWinding = 0;
    ActiveEdge* firstCoincident = NULL;
    winding = 0;
    activePtr = edgeList[0];
    for (index = 1; index < edgeCount; ++index) {
        int priorWinding = winding;
        winding += activePtr->fWorkEdge.winding();
        nextPtr = edgeList[index];
        if (activePtr->fSkip && nextPtr->fSkip
                && activePtr->fCoincident == nextPtr->fCoincident) {
            if (!firstCoincident) {
                firstCoincident = activePtr;
                firstCoincidentWinding = priorWinding;
            }
            if (activePtr->fCloseCall) {
                // If one of the edges has already been added to out as a non
                // coincident edge, trim it back to the top of this span
                if (outBuilder.trimLine(y, activePtr->ID())) {
                    activePtr->addTatYAbove(y);
            #if DEBUG_ADJUST_COINCIDENT
                    SkDebugf("%s 1 edge=%d y=%1.9g (was fYBottom=%1.9g)\n",
                            __FUNCTION__, activePtr->ID(), y, activePtr->fYBottom);
            #endif
                    activePtr->fYBottom = y;
                }
                if (outBuilder.trimLine(y, nextPtr->ID())) {
                    nextPtr->addTatYAbove(y);
            #if DEBUG_ADJUST_COINCIDENT
                    SkDebugf("%s 2 edge=%d y=%1.9g (was fYBottom=%1.9g)\n",
                            __FUNCTION__, nextPtr->ID(), y, nextPtr->fYBottom);
            #endif
                    nextPtr->fYBottom = y;
                }
                // add missing t values so edges can be the same length
                SkScalar testY = activePtr->fBelow.fY;
                nextPtr->addTatYBelow(testY);
                if (bottom > testY && testY > y) {
            #if DEBUG_ADJUST_COINCIDENT
                    SkDebugf("%s 3 edge=%d bottom=%1.9g (was bottom=%1.9g)\n",
                            __FUNCTION__, activePtr->ID(), testY, bottom);
            #endif
                    bottom = testY;
                }
                testY = nextPtr->fBelow.fY;
                activePtr->addTatYBelow(testY);
                if (bottom > testY && testY > y) {
            #if DEBUG_ADJUST_COINCIDENT
                    SkDebugf("%s 4 edge=%d bottom=%1.9g (was bottom=%1.9g)\n",
                            __FUNCTION__, nextPtr->ID(), testY, bottom);
            #endif
                    bottom = testY;
                }
            }
        } else if (firstCoincident) {
            skipCoincidence(firstCoincidentWinding, winding, windingMask,
                    activePtr, firstCoincident);
            firstCoincident = NULL;
        }
        activePtr = nextPtr;
    }
    if (firstCoincident) {
        winding += activePtr->fWorkEdge.winding();
        skipCoincidence(firstCoincidentWinding, winding, windingMask, activePtr,
                firstCoincident);
    }
    // fix up the bottom for close call edges. OPTIMIZATION: maybe this could
    // be in the loop above, but moved here since loop above reads fBelow and
    // it felt unsafe to write it in that loop
    for (index = 0; index < edgeCount; ++index) {
        (edgeList[index])->fixBelow();
    }
    return bottom;
}

// stitch edge and t range that satisfies operation
static void stitchEdge(SkTDArray<ActiveEdge*>& edgeList, SkScalar
#if DEBUG_STITCH_EDGE
y
#endif
,
        SkScalar bottom, int windingMask, bool fill, OutEdgeBuilder& outBuilder) {
    int winding = 0;
    ActiveEdge** activeHandle = edgeList.begin() - 1;
    ActiveEdge** lastActive = edgeList.end();
#if DEBUG_STITCH_EDGE
    const int tab = 7; // FIXME: debugging only
    SkDebugf("%s y=%1.9g bottom=%1.9g\n", __FUNCTION__, y, bottom);
#endif
    while (++activeHandle != lastActive) {
        ActiveEdge* activePtr = *activeHandle;
        const WorkEdge& wt = activePtr->fWorkEdge;
        int lastWinding = winding;
        winding += wt.winding();
#if DEBUG_STITCH_EDGE
        SkDebugf("%*s edge=%d lastWinding=%d winding=%d skip=%d close=%d"
                " above=%1.9g below=%1.9g\n",
                tab-4, "", activePtr->ID(), lastWinding,
                winding, activePtr->fSkip, activePtr->fCloseCall,
                activePtr->fTAbove, activePtr->fTBelow);
#endif
        if (activePtr->done(bottom)) {
#if DEBUG_STITCH_EDGE
            SkDebugf("%*s fDone=%d || fYBottom=%1.9g >= bottom\n", tab, "",
                    activePtr->fDone, activePtr->fYBottom);
#endif
            continue;
        }
        int opener = (lastWinding & windingMask) == 0;
        bool closer = (winding & windingMask) == 0;
        SkASSERT(!opener | !closer);
        bool inWinding = opener | closer;
        SkPoint clippedPts[4];
        const SkPoint* clipped = NULL;
        bool moreToDo, aboveBottom;
        do {
            double currentT = activePtr->t();
            const SkPoint* points = wt.fPts;
            double nextT;
            SkPath::Verb verb = activePtr->fVerb;
            do {
                nextT = activePtr->nextT();
                // FIXME: obtuse: want efficient way to say
                // !currentT && currentT != 1 || !nextT && nextT != 1
                if (currentT * nextT != 0 || currentT + nextT != 1) {
                    // OPTIMIZATION: if !inWinding, we only need
                    // clipped[1].fY
                    switch (verb) {
                        case SkPath::kLine_Verb:
                            LineSubDivide(points, currentT, nextT, clippedPts);
                            break;
                        case SkPath::kQuad_Verb:
                            QuadSubDivide(points, currentT, nextT, clippedPts);
                            break;
                        case SkPath::kCubic_Verb:
                            CubicSubDivide(points, currentT, nextT, clippedPts);
                            break;
                        default:
                            SkASSERT(0);
                            break;
                    }
                    clipped = clippedPts;
                } else {
                    clipped = points;
                }
                if (inWinding && !activePtr->fSkip && (fill ? clipped[0].fY
                        != clipped[verb].fY : clipped[0] != clipped[verb])) {
#if DEBUG_STITCH_EDGE
                    SkDebugf("%*s add%s %1.9g,%1.9g %1.9g,%1.9g edge=%d"
                            " v=%d t=(%1.9g,%1.9g)\n", tab, "",
                            kUVerbStr[verb], clipped[0].fX, clipped[0].fY,
                            clipped[verb].fX, clipped[verb].fY,
                            activePtr->ID(),
                            activePtr->fWorkEdge.fVerb
                            - activePtr->fWorkEdge.fEdge->fVerbs.begin(),
                            currentT, nextT);
#endif
                    outBuilder.addCurve(clipped, (SkPath::Verb) verb,
                            activePtr->fWorkEdge.fEdge->fID,
                            activePtr->fCloseCall);
                } else {
#if DEBUG_STITCH_EDGE
                    SkDebugf("%*s skip%s %1.9g,%1.9g %1.9g,%1.9g"
                            " edge=%d v=%d t=(%1.9g,%1.9g)\n", tab, "",
                            kUVerbStr[verb], clipped[0].fX, clipped[0].fY,
                            clipped[verb].fX, clipped[verb].fY,
                            activePtr->ID(),
                            activePtr->fWorkEdge.fVerb
                            - activePtr->fWorkEdge.fEdge->fVerbs.begin(),
                            currentT, nextT);
#endif
                }
            // by advancing fAbove/fBelow, the next call to sortHorizontal
            // will use these values if they're still valid instead of
            // recomputing
                if (clipped[verb].fY > activePtr->fBelow.fY
                        && bottom >= activePtr->fBelow.fY
                        && verb == SkPath::kLine_Verb) {
                    activePtr->fAbove = activePtr->fBelow;
                    activePtr->fBelow = activePtr->fTangent = clipped[verb];
                    activePtr->fTAbove = activePtr->fTBelow < 1
                            ? activePtr->fTBelow : 0;
                    activePtr->fTBelow = nextT;
                }
                currentT = nextT;
                moreToDo = activePtr->advanceT();
                activePtr->fYBottom = clipped[verb].fY; // was activePtr->fCloseCall ? bottom :

                // clearing the fSkip/fCloseCall bit here means that trailing edges
                // fall out of sync, if one edge is long and another is a series of short pieces
                // if fSkip/fCloseCall is set, need to recompute coincidence/too-close-to-call
                // after advancing
                // another approach would be to restrict bottom to smaller part of close call
                // maybe this is already happening with coincidence when intersection is computed,
                // and needs to be added to the close call computation as well
                // this is hard to do because that the bottom is important is not known when
                // the lines are intersected; only when the computation for edge sorting is done
                // does the need for new bottoms become apparent.
                // maybe this is good incentive to scrap the current sort and do an insertion
                // sort that can take this into consideration when the x value is computed

                // FIXME: initialized in sortHorizontal, cleared here as well so
                // that next edge is not skipped -- but should skipped edges ever
                // continue? (probably not)
                aboveBottom = clipped[verb].fY < bottom;
                if (clipped[0].fY != clipped[verb].fY) {
                    activePtr->fSkip = false;
                    activePtr->fCloseCall = false;
                    aboveBottom &= !activePtr->fCloseCall;
                }
#if DEBUG_STITCH_EDGE
                 else {
                    if (activePtr->fSkip || activePtr->fCloseCall) {
                        SkDebugf("%s skip or close == %1.9g\n", __FUNCTION__,
                                clippedPts[0].fY);
                    }
                }
#endif
            } while (moreToDo & aboveBottom);
        } while ((moreToDo || activePtr->advance()) & aboveBottom);
    }
}

#if DEBUG_DUMP
static void dumpEdgeList(const SkTDArray<InEdge*>& edgeList,
        const InEdge& edgeSentinel) {
    InEdge** debugPtr = edgeList.begin();
    do {
        (*debugPtr++)->dump();
    } while (*debugPtr != &edgeSentinel);
}
#else
static void dumpEdgeList(const SkTDArray<InEdge*>& ,
        const InEdge& ) {
}
#endif

void simplify(const SkPath& path, bool asFill, SkPath& simple) {
    // returns 1 for evenodd, -1 for winding, regardless of inverse-ness
    int windingMask = (path.getFillType() & 1) ? 1 : -1;
    simple.reset();
    simple.setFillType(SkPath::kEvenOdd_FillType);
    // turn path into list of edges increasing in y
    // if an edge is a quad or a cubic with a y extrema, note it, but leave it
    // unbroken. Once we have a list, sort it, then walk the list (walk edges
    // twice that have y extrema's on top)  and detect crossings -- look for raw
    // bounds that cross over, then tight bounds that cross
    SkTArray<InEdge> edges;
    SkTDArray<HorizontalEdge> horizontalEdges;
    InEdgeBuilder builder(path, asFill, edges, horizontalEdges);
    SkTDArray<InEdge*> edgeList;
    InEdge edgeSentinel;
    edgeSentinel.reset();
    makeEdgeList(edges, edgeSentinel, edgeList);
    SkTDArray<HorizontalEdge*> horizontalList;
    HorizontalEdge horizontalSentinel;
    makeHorizontalList(horizontalEdges, horizontalSentinel, horizontalList);
    InEdge** currentPtr = edgeList.begin();
    if (!currentPtr) {
        return;
    }
    // find all intersections between edges
// beyond looking for horizontal intercepts, we need to know if any active edges
// intersect edges below 'bottom', but above the active edge segment.
// maybe it makes more sense to compute all intercepts before doing anything
// else, since the intercept list is long-lived, at least in the current design.
    SkScalar y = (*currentPtr)->fBounds.fTop;
    HorizontalEdge** currentHorizontal = horizontalList.begin();
    do {
        InEdge** lastPtr = currentPtr; // find the edge below the bottom of the first set
        SkScalar bottom = findBottom(currentPtr, edgeList.end(),
                NULL, y, asFill, lastPtr);
        if (lastPtr > currentPtr) {
            if (currentHorizontal) {
                if ((*currentHorizontal)->fY < SK_ScalarMax) {
                    addBottomT(currentPtr, lastPtr, currentHorizontal);
                }
                currentHorizontal = advanceHorizontal(currentHorizontal, bottom);
            }
            addIntersectingTs(currentPtr, lastPtr);
        }
        y = bottom;
        currentPtr = advanceEdges(NULL, currentPtr, lastPtr, y);
    } while (*currentPtr != &edgeSentinel);
    // if a quadratic or cubic now has an intermediate T value, see if the Ts
    // on either side cause the Y values to monotonically increase. If not, split
    // the curve at the new T.

    // try an alternate approach which does not split curves or stitch edges
    // (may still need adjustCoincident, though)
    // the idea is to output non-intersecting contours, then figure out their
    // respective winding contribution
    // each contour will need to know whether it is CW or CCW, and then whether
    // a ray from that contour hits any a contour that contains it. The ray can
    // move to the left and then arbitrarily move up or down (as long as it never
    // moves to the right) to find a reference sibling contour or containing
    // contour. If the contour is part of an intersection, the companion contour
    // that is part of the intersection can determine the containership.
    if (builder.containsCurves()) {
        currentPtr = edgeList.begin();
        SkTArray<InEdge> splits;
        do {
            (*currentPtr)->splitInflectionPts(splits);
        } while (*++currentPtr != &edgeSentinel);
        if (splits.count()) {
            for (int index = 0; index < splits.count(); ++index) {
                edges.push_back(splits[index]);
            }
            edgeList.reset();
            makeEdgeList(edges, edgeSentinel, edgeList);
        }
    }
    dumpEdgeList(edgeList, edgeSentinel);
    // walk the sorted edges from top to bottom, computing accumulated winding
    SkTDArray<ActiveEdge> activeEdges;
    OutEdgeBuilder outBuilder(asFill);
    currentPtr = edgeList.begin();
    y = (*currentPtr)->fBounds.fTop;
    do {
        InEdge** lastPtr = currentPtr; // find the edge below the bottom of the first set
        SkScalar bottom = findBottom(currentPtr, edgeList.end(),
                &activeEdges, y, asFill, lastPtr);
        if (lastPtr > currentPtr) {
            bottom = computeInterceptBottom(activeEdges, y, bottom);
            SkTDArray<ActiveEdge*> activeEdgeList;
            sortHorizontal(activeEdges, activeEdgeList, y);
            bottom = adjustCoincident(activeEdgeList, windingMask, y, bottom,
                outBuilder);
            stitchEdge(activeEdgeList, y, bottom, windingMask, asFill, outBuilder);
        }
        y = bottom;
        // OPTIMIZATION: as edges expire, InEdge allocations could be released
        currentPtr = advanceEdges(&activeEdges, currentPtr, lastPtr, y);
    } while (*currentPtr != &edgeSentinel);
    // assemble output path from string of pts, verbs
    outBuilder.bridge();
    outBuilder.assemble(simple);
}
