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

#include "src/utils/SkPolyUtils.h"

#include "include/core/SkRect.h"
#include "include/core/SkTypes.h"
#include "include/private/SkFloatingPoint.h"
#include "include/private/SkMalloc.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTDArray.h"
#include "include/private/SkTemplates.h"
#include "include/private/SkVx.h"
#include "src/core/SkPointPriv.h"
#include "src/core/SkRectPriv.h"
#include "src/core/SkTDPQueue.h"
#include "src/core/SkTInternalLList.h"

#include <algorithm>
#include <cstdint>
#include <limits>
#include <new>

#if !defined(SK_ENABLE_OPTIMIZE_SIZE)

//////////////////////////////////////////////////////////////////////////////////
// Helper data structures and functions

struct OffsetSegment {
    SkPoint fP0;
    SkVector fV;
};

constexpr SkScalar kCrossTolerance = SK_ScalarNearlyZero * SK_ScalarNearlyZero;

// Computes perpDot for point p compared to segment defined by origin p0 and vector v.
// A positive value means the point is to the left of the segment,
// negative is to the right, 0 is collinear.
static int compute_side(const SkPoint& p0, const SkVector& v, const SkPoint& p) {
    SkVector w = p - p0;
    SkScalar perpDot = v.cross(w);
    if (!SkScalarNearlyZero(perpDot, kCrossTolerance)) {
        return ((perpDot > 0) ? 1 : -1);
    }

    return 0;
}

// Returns 1 for cw, -1 for ccw and 0 if zero signed area (either degenerate or self-intersecting)
int SkGetPolygonWinding(const SkPoint* polygonVerts, int polygonSize) {
    if (polygonSize < 3) {
        return 0;
    }

    // compute area and use sign to determine winding
    SkScalar quadArea = 0;
    SkVector v0 = polygonVerts[1] - polygonVerts[0];
    for (int curr = 2; curr < polygonSize; ++curr) {
        SkVector v1 = polygonVerts[curr] - polygonVerts[0];
        quadArea += v0.cross(v1);
        v0 = v1;
    }
    if (SkScalarNearlyZero(quadArea, kCrossTolerance)) {
        return 0;
    }
    // 1 == ccw, -1 == cw
    return (quadArea > 0) ? 1 : -1;
}

// Compute difference vector to offset p0-p1 'offset' units in direction specified by 'side'
bool compute_offset_vector(const SkPoint& p0, const SkPoint& p1, SkScalar offset, int side,
                           SkPoint* vector) {
    SkASSERT(side == -1 || side == 1);
    // if distances are equal, can just outset by the perpendicular
    SkVector perp = SkVector::Make(p0.fY - p1.fY, p1.fX - p0.fX);
    if (!perp.setLength(offset*side)) {
        return false;
    }
    *vector = perp;
    return true;
}

// check interval to see if intersection is in segment
static inline bool outside_interval(SkScalar numer, SkScalar denom, bool denomPositive) {
    return (denomPositive && (numer < 0 || numer > denom)) ||
           (!denomPositive && (numer > 0 || numer < denom));
}

// special zero-length test when we're using vdotv as a denominator
static inline bool zero_length(const SkPoint& v, SkScalar vdotv) {
    return !(SkScalarsAreFinite(v.fX, v.fY) && vdotv);
}

// Compute the intersection 'p' between segments s0 and s1, if any.
// 's' is the parametric value for the intersection along 's0' & 't' is the same for 's1'.
// Returns false if there is no intersection.
// If the length squared of a segment is 0, then we treat the segment as degenerate
// and use only the first endpoint for tests.
static bool compute_intersection(const OffsetSegment& s0, const OffsetSegment& s1,
                                 SkPoint* p, SkScalar* s, SkScalar* t) {
    const SkVector& v0 = s0.fV;
    const SkVector& v1 = s1.fV;
    SkVector w = s1.fP0 - s0.fP0;
    SkScalar denom = v0.cross(v1);
    bool denomPositive = (denom > 0);
    SkScalar sNumer, tNumer;
    if (SkScalarNearlyZero(denom, kCrossTolerance)) {
        // segments are parallel, but not collinear
        if (!SkScalarNearlyZero(w.cross(v0), kCrossTolerance) ||
            !SkScalarNearlyZero(w.cross(v1), kCrossTolerance)) {
            return false;
        }

        // Check for zero-length segments
        SkScalar v0dotv0 = v0.dot(v0);
        if (zero_length(v0, v0dotv0)) {
            // Both are zero-length
            SkScalar v1dotv1 = v1.dot(v1);
            if (zero_length(v1, v1dotv1)) {
                // Check if they're the same point
                if (!SkPointPriv::CanNormalize(w.fX, w.fY)) {
                    *p = s0.fP0;
                    *s = 0;
                    *t = 0;
                    return true;
                } else {
                    // Intersection is indeterminate
                    return false;
                }
            }
            // Otherwise project segment0's origin onto segment1
            tNumer = v1.dot(-w);
            denom = v1dotv1;
            if (outside_interval(tNumer, denom, true)) {
                return false;
            }
            sNumer = 0;
        } else {
            // Project segment1's endpoints onto segment0
            sNumer = v0.dot(w);
            denom = v0dotv0;
            tNumer = 0;
            if (outside_interval(sNumer, denom, true)) {
                // The first endpoint doesn't lie on segment0
                // If segment1 is degenerate, then there's no collision
                SkScalar v1dotv1 = v1.dot(v1);
                if (zero_length(v1, v1dotv1)) {
                    return false;
                }

                // Otherwise try the other one
                SkScalar oldSNumer = sNumer;
                sNumer = v0.dot(w + v1);
                tNumer = denom;
                if (outside_interval(sNumer, denom, true)) {
                    // it's possible that segment1's interval surrounds segment0
                    // this is false if params have the same signs, and in that case no collision
                    if (sNumer*oldSNumer > 0) {
                        return false;
                    }
                    // otherwise project segment0's endpoint onto segment1 instead
                    sNumer = 0;
                    tNumer = v1.dot(-w);
                    denom = v1dotv1;
                }
            }
        }
    } else {
        sNumer = w.cross(v1);
        if (outside_interval(sNumer, denom, denomPositive)) {
            return false;
        }
        tNumer = w.cross(v0);
        if (outside_interval(tNumer, denom, denomPositive)) {
            return false;
        }
    }

    SkScalar localS = sNumer/denom;
    SkScalar localT = tNumer/denom;

    *p = s0.fP0 + v0*localS;
    *s = localS;
    *t = localT;

    return true;
}

bool SkIsConvexPolygon(const SkPoint* polygonVerts, int polygonSize) {
    if (polygonSize < 3) {
        return false;
    }

    SkScalar lastPerpDot = 0;
    int xSignChangeCount = 0;
    int ySignChangeCount = 0;

    int prevIndex = polygonSize - 1;
    int currIndex = 0;
    int nextIndex = 1;
    SkVector v0 = polygonVerts[currIndex] - polygonVerts[prevIndex];
    SkScalar lastVx = v0.fX;
    SkScalar lastVy = v0.fY;
    SkVector v1 = polygonVerts[nextIndex] - polygonVerts[currIndex];
    for (int i = 0; i < polygonSize; ++i) {
        if (!polygonVerts[i].isFinite()) {
            return false;
        }

        // Check that winding direction is always the same (otherwise we have a reflex vertex)
        SkScalar perpDot = v0.cross(v1);
        if (lastPerpDot*perpDot < 0) {
            return false;
        }
        if (0 != perpDot) {
            lastPerpDot = perpDot;
        }

        // Check that the signs of the edge vectors don't change more than twice per coordinate
        if (lastVx*v1.fX < 0) {
            xSignChangeCount++;
        }
        if (lastVy*v1.fY < 0) {
            ySignChangeCount++;
        }
        if (xSignChangeCount > 2 || ySignChangeCount > 2) {
            return false;
        }
        prevIndex = currIndex;
        currIndex = nextIndex;
        nextIndex = (currIndex + 1) % polygonSize;
        if (v1.fX != 0) {
            lastVx = v1.fX;
        }
        if (v1.fY != 0) {
            lastVy = v1.fY;
        }
        v0 = v1;
        v1 = polygonVerts[nextIndex] - polygonVerts[currIndex];
    }

    return true;
}

struct OffsetEdge {
    OffsetEdge*   fPrev;
    OffsetEdge*   fNext;
    OffsetSegment fOffset;
    SkPoint       fIntersection;
    SkScalar      fTValue;
    uint16_t      fIndex;
    uint16_t      fEnd;

    void init(uint16_t start = 0, uint16_t end = 0) {
        fIntersection = fOffset.fP0;
        fTValue = SK_ScalarMin;
        fIndex = start;
        fEnd = end;
    }

    // special intersection check that looks for endpoint intersection
    bool checkIntersection(const OffsetEdge* that,
                           SkPoint* p, SkScalar* s, SkScalar* t) {
        if (this->fEnd == that->fIndex) {
            SkPoint p1 = this->fOffset.fP0 + this->fOffset.fV;
            if (SkPointPriv::EqualsWithinTolerance(p1, that->fOffset.fP0)) {
                *p = p1;
                *s = SK_Scalar1;
                *t = 0;
                return true;
            }
        }

        return compute_intersection(this->fOffset, that->fOffset, p, s, t);
    }

    // computes the line intersection and then the "distance" from that to this
    // this is really a signed squared distance, where negative means that
    // the intersection lies inside this->fOffset
    SkScalar computeCrossingDistance(const OffsetEdge* that) {
        const OffsetSegment& s0 = this->fOffset;
        const OffsetSegment& s1 = that->fOffset;
        const SkVector& v0 = s0.fV;
        const SkVector& v1 = s1.fV;

        SkScalar denom = v0.cross(v1);
        if (SkScalarNearlyZero(denom, kCrossTolerance)) {
            // segments are parallel
            return SK_ScalarMax;
        }

        SkVector w = s1.fP0 - s0.fP0;
        SkScalar localS = w.cross(v1) / denom;
        if (localS < 0) {
            localS = -localS;
        } else {
            localS -= SK_Scalar1;
        }

        localS *= SkScalarAbs(localS);
        localS *= v0.dot(v0);

        return localS;
    }

};

static void remove_node(const OffsetEdge* node, OffsetEdge** head) {
    // remove from linked list
    node->fPrev->fNext = node->fNext;
    node->fNext->fPrev = node->fPrev;
    if (node == *head) {
        *head = (node->fNext == node) ? nullptr : node->fNext;
    }
}

//////////////////////////////////////////////////////////////////////////////////

// The objective here is to inset all of the edges by the given distance, and then
// remove any invalid inset edges by detecting right-hand turns. In a ccw polygon,
// we should only be making left-hand turns (for cw polygons, we use the winding
// parameter to reverse this). We detect this by checking whether the second intersection
// on an edge is closer to its tail than the first one.
//
// We might also have the case that there is no intersection between two neighboring inset edges.
// In this case, one edge will lie to the right of the other and should be discarded along with
// its previous intersection (if any).
//
// Note: the assumption is that inputPolygon is convex and has no coincident points.
//
bool SkInsetConvexPolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize,
                          SkScalar inset, SkTDArray<SkPoint>* insetPolygon) {
    if (inputPolygonSize < 3) {
        return false;
    }

    // restrict this to match other routines
    // practically we don't want anything bigger than this anyway
    if (inputPolygonSize > std::numeric_limits<uint16_t>::max()) {
        return false;
    }

    // can't inset by a negative or non-finite amount
    if (inset < -SK_ScalarNearlyZero || !SkScalarIsFinite(inset)) {
        return false;
    }

    // insetting close to zero just returns the original poly
    if (inset <= SK_ScalarNearlyZero) {
        for (int i = 0; i < inputPolygonSize; ++i) {
            *insetPolygon->append() = inputPolygonVerts[i];
        }
        return true;
    }

    // get winding direction
    int winding = SkGetPolygonWinding(inputPolygonVerts, inputPolygonSize);
    if (0 == winding) {
        return false;
    }

    // set up
    SkAutoSTMalloc<64, OffsetEdge> edgeData(inputPolygonSize);
    int prev = inputPolygonSize - 1;
    for (int curr = 0; curr < inputPolygonSize; prev = curr, ++curr) {
        int next = (curr + 1) % inputPolygonSize;
        if (!inputPolygonVerts[curr].isFinite()) {
            return false;
        }
        // check for convexity just to be sure
        if (compute_side(inputPolygonVerts[prev], inputPolygonVerts[curr] - inputPolygonVerts[prev],
                         inputPolygonVerts[next])*winding < 0) {
            return false;
        }
        SkVector v = inputPolygonVerts[next] - inputPolygonVerts[curr];
        SkVector perp = SkVector::Make(-v.fY, v.fX);
        perp.setLength(inset*winding);
        edgeData[curr].fPrev = &edgeData[prev];
        edgeData[curr].fNext = &edgeData[next];
        edgeData[curr].fOffset.fP0 = inputPolygonVerts[curr] + perp;
        edgeData[curr].fOffset.fV = v;
        edgeData[curr].init();
    }

    OffsetEdge* head = &edgeData[0];
    OffsetEdge* currEdge = head;
    OffsetEdge* prevEdge = currEdge->fPrev;
    int insetVertexCount = inputPolygonSize;
    unsigned int iterations = 0;
    unsigned int maxIterations = inputPolygonSize * inputPolygonSize;
    while (head && prevEdge != currEdge) {
        ++iterations;
        // we should check each edge against each other edge at most once
        if (iterations > maxIterations) {
            return false;
        }

        SkScalar s, t;
        SkPoint intersection;
        if (compute_intersection(prevEdge->fOffset, currEdge->fOffset,
                                 &intersection, &s, &t)) {
            // if new intersection is further back on previous inset from the prior intersection
            if (s < prevEdge->fTValue) {
                // no point in considering this one again
                remove_node(prevEdge, &head);
                --insetVertexCount;
                // go back one segment
                prevEdge = prevEdge->fPrev;
            // we've already considered this intersection, we're done
            } else if (currEdge->fTValue > SK_ScalarMin &&
                       SkPointPriv::EqualsWithinTolerance(intersection,
                                                          currEdge->fIntersection,
                                                          1.0e-6f)) {
                break;
            } else {
                // add intersection
                currEdge->fIntersection = intersection;
                currEdge->fTValue = t;

                // go to next segment
                prevEdge = currEdge;
                currEdge = currEdge->fNext;
            }
        } else {
            // if prev to right side of curr
            int side = winding*compute_side(currEdge->fOffset.fP0,
                                            currEdge->fOffset.fV,
                                            prevEdge->fOffset.fP0);
            if (side < 0 &&
                side == winding*compute_side(currEdge->fOffset.fP0,
                                             currEdge->fOffset.fV,
                                             prevEdge->fOffset.fP0 + prevEdge->fOffset.fV)) {
                // no point in considering this one again
                remove_node(prevEdge, &head);
                --insetVertexCount;
                // go back one segment
                prevEdge = prevEdge->fPrev;
            } else {
                // move to next segment
                remove_node(currEdge, &head);
                --insetVertexCount;
                currEdge = currEdge->fNext;
            }
        }
    }

    // store all the valid intersections that aren't nearly coincident
    // TODO: look at the main algorithm and see if we can detect these better
    insetPolygon->reset();
    if (!head) {
        return false;
    }

    static constexpr SkScalar kCleanupTolerance = 0.01f;
    if (insetVertexCount >= 0) {
        insetPolygon->reserve(insetVertexCount);
    }
    int currIndex = 0;
    *insetPolygon->append() = head->fIntersection;
    currEdge = head->fNext;
    while (currEdge != head) {
        if (!SkPointPriv::EqualsWithinTolerance(currEdge->fIntersection,
                                                (*insetPolygon)[currIndex],
                                                kCleanupTolerance)) {
            *insetPolygon->append() = currEdge->fIntersection;
            currIndex++;
        }
        currEdge = currEdge->fNext;
    }
    // make sure the first and last points aren't coincident
    if (currIndex >= 1 &&
        SkPointPriv::EqualsWithinTolerance((*insetPolygon)[0], (*insetPolygon)[currIndex],
                                            kCleanupTolerance)) {
        insetPolygon->pop_back();
    }

    return SkIsConvexPolygon(insetPolygon->begin(), insetPolygon->size());
}

///////////////////////////////////////////////////////////////////////////////////////////

// compute the number of points needed for a circular join when offsetting a reflex vertex
bool SkComputeRadialSteps(const SkVector& v1, const SkVector& v2, SkScalar offset,
                          SkScalar* rotSin, SkScalar* rotCos, int* n) {
    const SkScalar kRecipPixelsPerArcSegment = 0.25f;

    SkScalar rCos = v1.dot(v2);
    if (!SkScalarIsFinite(rCos)) {
        return false;
    }
    SkScalar rSin = v1.cross(v2);
    if (!SkScalarIsFinite(rSin)) {
        return false;
    }
    SkScalar theta = SkScalarATan2(rSin, rCos);

    SkScalar floatSteps = SkScalarAbs(offset*theta*kRecipPixelsPerArcSegment);
    // limit the number of steps to at most max uint16_t (that's all we can index)
    // knock one value off the top to account for rounding
    if (floatSteps >= std::numeric_limits<uint16_t>::max()) {
        return false;
    }
    int steps = SkScalarRoundToInt(floatSteps);

    SkScalar dTheta = steps > 0 ? theta / steps : 0;
    *rotSin = SkScalarSin(dTheta);
    *rotCos = SkScalarCos(dTheta);
    // Our offset may be so large that we end up with a tiny dTheta, in which case we
    // lose precision when computing rotSin and rotCos.
    if (steps > 0 && (*rotSin == 0 || *rotCos == 1)) {
        return false;
    }
    *n = steps;
    return true;
}

///////////////////////////////////////////////////////////////////////////////////////////

// a point is "left" to another if its x-coord is less, or if equal, its y-coord is greater
static bool left(const SkPoint& p0, const SkPoint& p1) {
    return p0.fX < p1.fX || (!(p0.fX > p1.fX) && p0.fY > p1.fY);
}

// a point is "right" to another if its x-coord is greater, or if equal, its y-coord is less
static bool right(const SkPoint& p0, const SkPoint& p1) {
    return p0.fX > p1.fX || (!(p0.fX < p1.fX) && p0.fY < p1.fY);
}

struct Vertex {
    static bool Left(const Vertex& qv0, const Vertex& qv1) {
        return left(qv0.fPosition, qv1.fPosition);
    }

    // packed to fit into 16 bytes (one cache line)
    SkPoint  fPosition;
    uint16_t fIndex;       // index in unsorted polygon
    uint16_t fPrevIndex;   // indices for previous and next vertex in unsorted polygon
    uint16_t fNextIndex;
    uint16_t fFlags;
};

enum VertexFlags {
    kPrevLeft_VertexFlag = 0x1,
    kNextLeft_VertexFlag = 0x2,
};

struct ActiveEdge {
    ActiveEdge() : fChild{ nullptr, nullptr }, fAbove(nullptr), fBelow(nullptr), fRed(false) {}
    ActiveEdge(const SkPoint& p0, const SkVector& v, uint16_t index0, uint16_t index1)
        : fSegment({ p0, v })
        , fIndex0(index0)
        , fIndex1(index1)
        , fAbove(nullptr)
        , fBelow(nullptr)
        , fRed(true) {
        fChild[0] = nullptr;
        fChild[1] = nullptr;
    }

    // Returns true if "this" is above "that", assuming this->p0 is to the left of that->p0
    // This is only used to verify the edgelist -- the actual test for insertion/deletion is much
    // simpler because we can make certain assumptions then.
    bool aboveIfLeft(const ActiveEdge* that) const {
        const SkPoint& p0 = this->fSegment.fP0;
        const SkPoint& q0 = that->fSegment.fP0;
        SkASSERT(p0.fX <= q0.fX);
        SkVector d = q0 - p0;
        const SkVector& v = this->fSegment.fV;
        const SkVector& w = that->fSegment.fV;
        // The idea here is that if the vector between the origins of the two segments (d)
        // rotates counterclockwise up to the vector representing the "this" segment (v),
        // then we know that "this" is above "that". If the result is clockwise we say it's below.
        if (this->fIndex0 != that->fIndex0) {
            SkScalar cross = d.cross(v);
            if (cross > kCrossTolerance) {
                return true;
            } else if (cross < -kCrossTolerance) {
                return false;
            }
        } else if (this->fIndex1 == that->fIndex1) {
            return false;
        }
        // At this point either the two origins are nearly equal or the origin of "that"
        // lies on dv. So then we try the same for the vector from the tail of "this"
        // to the head of "that". Again, ccw means "this" is above "that".
        // d = that.P1 - this.P0
        //   = that.fP0 + that.fV - this.fP0
        //   = that.fP0 - this.fP0 + that.fV
        //   = old_d + that.fV
        d += w;
        SkScalar cross = d.cross(v);
        if (cross > kCrossTolerance) {
            return true;
        } else if (cross < -kCrossTolerance) {
            return false;
        }
        // If the previous check fails, the two segments are nearly collinear
        // First check y-coord of first endpoints
        if (p0.fX < q0.fX) {
            return (p0.fY >= q0.fY);
        } else if (p0.fY > q0.fY) {
            return true;
        } else if (p0.fY < q0.fY) {
            return false;
        }
        // The first endpoints are the same, so check the other endpoint
        SkPoint p1 = p0 + v;
        SkPoint q1 = q0 + w;
        if (p1.fX < q1.fX) {
            return (p1.fY >= q1.fY);
        } else {
            return (p1.fY > q1.fY);
        }
    }

    // same as leftAndAbove(), but generalized
    bool above(const ActiveEdge* that) const {
        const SkPoint& p0 = this->fSegment.fP0;
        const SkPoint& q0 = that->fSegment.fP0;
        if (right(p0, q0)) {
            return !that->aboveIfLeft(this);
        } else {
            return this->aboveIfLeft(that);
        }
    }

    bool intersect(const SkPoint& q0, const SkVector& w, uint16_t index0, uint16_t index1) const {
        // check first to see if these edges are neighbors in the polygon
        if (this->fIndex0 == index0 || this->fIndex1 == index0 ||
            this->fIndex0 == index1 || this->fIndex1 == index1) {
            return false;
        }

        // We don't need the exact intersection point so we can do a simpler test here.
        const SkPoint& p0 = this->fSegment.fP0;
        const SkVector& v = this->fSegment.fV;
        SkPoint p1 = p0 + v;
        SkPoint q1 = q0 + w;

        // We assume some x-overlap due to how the edgelist works
        // This allows us to simplify our test
        // We need some slop here because storing the vector and recomputing the second endpoint
        // doesn't necessary give us the original result in floating point.
        // TODO: Store vector as double? Store endpoint as well?
        SkASSERT(q0.fX <= p1.fX + SK_ScalarNearlyZero);

        // if each segment straddles the other (i.e., the endpoints have different sides)
        // then they intersect
        bool result;
        if (p0.fX < q0.fX) {
            if (q1.fX < p1.fX) {
                result = (compute_side(p0, v, q0)*compute_side(p0, v, q1) < 0);
            } else {
                result = (compute_side(p0, v, q0)*compute_side(q0, w, p1) > 0);
            }
        } else {
            if (p1.fX < q1.fX) {
                result = (compute_side(q0, w, p0)*compute_side(q0, w, p1) < 0);
            } else {
                result = (compute_side(q0, w, p0)*compute_side(p0, v, q1) > 0);
            }
        }
        return result;
    }

    bool intersect(const ActiveEdge* edge) {
        return this->intersect(edge->fSegment.fP0, edge->fSegment.fV, edge->fIndex0, edge->fIndex1);
    }

    bool lessThan(const ActiveEdge* that) const {
        SkASSERT(!this->above(this));
        SkASSERT(!that->above(that));
        SkASSERT(!(this->above(that) && that->above(this)));
        return this->above(that);
    }

    bool equals(uint16_t index0, uint16_t index1) const {
        return (this->fIndex0 == index0 && this->fIndex1 == index1);
    }

    OffsetSegment fSegment;
    uint16_t fIndex0;   // indices for previous and next vertex in polygon
    uint16_t fIndex1;
    ActiveEdge* fChild[2];
    ActiveEdge* fAbove;
    ActiveEdge* fBelow;
    int32_t  fRed;
};

class ActiveEdgeList {
public:
    ActiveEdgeList(int maxEdges) {
        fAllocation = (char*) sk_malloc_throw(sizeof(ActiveEdge)*maxEdges);
        fCurrFree = 0;
        fMaxFree = maxEdges;
    }
    ~ActiveEdgeList() {
        fTreeHead.fChild[1] = nullptr;
        sk_free(fAllocation);
    }

    bool insert(const SkPoint& p0, const SkPoint& p1, uint16_t index0, uint16_t index1) {
        SkVector v = p1 - p0;
        if (!v.isFinite()) {
            return false;
        }
        // empty tree case -- easy
        if (!fTreeHead.fChild[1]) {
            ActiveEdge* root = fTreeHead.fChild[1] = this->allocate(p0, v, index0, index1);
            SkASSERT(root);
            if (!root) {
                return false;
            }
            root->fRed = false;
            return true;
        }

        // set up helpers
        ActiveEdge* top = &fTreeHead;
        ActiveEdge *grandparent = nullptr;
        ActiveEdge *parent = nullptr;
        ActiveEdge *curr = top->fChild[1];
        int dir = 0;
        int last = 0; // ?
        // predecessor and successor, for intersection check
        ActiveEdge* pred = nullptr;
        ActiveEdge* succ = nullptr;

        // search down the tree
        while (true) {
            if (!curr) {
                // check for intersection with predecessor and successor
                if ((pred && pred->intersect(p0, v, index0, index1)) ||
                    (succ && succ->intersect(p0, v, index0, index1))) {
                    return false;
                }
                // insert new node at bottom
                parent->fChild[dir] = curr = this->allocate(p0, v, index0, index1);
                SkASSERT(curr);
                if (!curr) {
                    return false;
                }
                curr->fAbove = pred;
                curr->fBelow = succ;
                if (pred) {
                    if (pred->fSegment.fP0 == curr->fSegment.fP0 &&
                        pred->fSegment.fV == curr->fSegment.fV) {
                        return false;
                    }
                    pred->fBelow = curr;
                }
                if (succ) {
                    if (succ->fSegment.fP0 == curr->fSegment.fP0 &&
                        succ->fSegment.fV == curr->fSegment.fV) {
                        return false;
                    }
                    succ->fAbove = curr;
                }
                if (IsRed(parent)) {
                    int dir2 = (top->fChild[1] == grandparent);
                    if (curr == parent->fChild[last]) {
                        top->fChild[dir2] = SingleRotation(grandparent, !last);
                    } else {
                        top->fChild[dir2] = DoubleRotation(grandparent, !last);
                    }
                }
                break;
            } else if (IsRed(curr->fChild[0]) && IsRed(curr->fChild[1])) {
                // color flip
                curr->fRed = true;
                curr->fChild[0]->fRed = false;
                curr->fChild[1]->fRed = false;
                if (IsRed(parent)) {
                    int dir2 = (top->fChild[1] == grandparent);
                    if (curr == parent->fChild[last]) {
                        top->fChild[dir2] = SingleRotation(grandparent, !last);
                    } else {
                        top->fChild[dir2] = DoubleRotation(grandparent, !last);
                    }
                }
            }

            last = dir;
            int side;
            // check to see if segment is above or below
            if (curr->fIndex0 == index0) {
                side = compute_side(curr->fSegment.fP0, curr->fSegment.fV, p1);
            } else {
                side = compute_side(curr->fSegment.fP0, curr->fSegment.fV, p0);
            }
            if (0 == side) {
                return false;
            }
            dir = (side < 0);

            if (0 == dir) {
                succ = curr;
            } else {
                pred = curr;
            }

            // update helpers
            if (grandparent) {
                top = grandparent;
            }
            grandparent = parent;
            parent = curr;
            curr = curr->fChild[dir];
        }

        // update root and make it black
        fTreeHead.fChild[1]->fRed = false;

        SkDEBUGCODE(VerifyTree(fTreeHead.fChild[1]));

        return true;
    }

    // replaces edge p0p1 with p1p2
    bool replace(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2,
                 uint16_t index0, uint16_t index1, uint16_t index2) {
        if (!fTreeHead.fChild[1]) {
            return false;
        }

        SkVector v = p2 - p1;
        ActiveEdge* curr = &fTreeHead;
        ActiveEdge* found = nullptr;
        int dir = 1;

        // search
        while (curr->fChild[dir] != nullptr) {
            // update helpers
            curr = curr->fChild[dir];
            // save found node
            if (curr->equals(index0, index1)) {
                found = curr;
                break;
            } else {
                // check to see if segment is above or below
                int side;
                if (curr->fIndex1 == index1) {
                    side = compute_side(curr->fSegment.fP0, curr->fSegment.fV, p0);
                } else {
                    side = compute_side(curr->fSegment.fP0, curr->fSegment.fV, p1);
                }
                if (0 == side) {
                    return false;
                }
                dir = (side < 0);
            }
        }

        if (!found) {
            return false;
        }

        // replace if found
        ActiveEdge* pred = found->fAbove;
        ActiveEdge* succ = found->fBelow;
        // check deletion and insert intersection cases
        if (pred && (pred->intersect(found) || pred->intersect(p1, v, index1, index2))) {
            return false;
        }
        if (succ && (succ->intersect(found) || succ->intersect(p1, v, index1, index2))) {
            return false;
        }
        found->fSegment.fP0 = p1;
        found->fSegment.fV = v;
        found->fIndex0 = index1;
        found->fIndex1 = index2;
        // above and below should stay the same

        SkDEBUGCODE(VerifyTree(fTreeHead.fChild[1]));

        return true;
    }

    bool remove(const SkPoint& p0, const SkPoint& p1, uint16_t index0, uint16_t index1) {
        if (!fTreeHead.fChild[1]) {
            return false;
        }

        ActiveEdge* curr = &fTreeHead;
        ActiveEdge* parent = nullptr;
        ActiveEdge* grandparent = nullptr;
        ActiveEdge* found = nullptr;
        int dir = 1;

        // search and push a red node down
        while (curr->fChild[dir] != nullptr) {
            int last = dir;

            // update helpers
            grandparent = parent;
            parent = curr;
            curr = curr->fChild[dir];
            // save found node
            if (curr->equals(index0, index1)) {
                found = curr;
                dir = 0;
            } else {
                // check to see if segment is above or below
                int side;
                if (curr->fIndex1 == index1) {
                    side = compute_side(curr->fSegment.fP0, curr->fSegment.fV, p0);
                } else {
                    side = compute_side(curr->fSegment.fP0, curr->fSegment.fV, p1);
                }
                if (0 == side) {
                    return false;
                }
                dir = (side < 0);
            }

            // push the red node down
            if (!IsRed(curr) && !IsRed(curr->fChild[dir])) {
                if (IsRed(curr->fChild[!dir])) {
                    parent = parent->fChild[last] = SingleRotation(curr, dir);
                } else {
                    ActiveEdge *s = parent->fChild[!last];

                    if (s != nullptr) {
                        if (!IsRed(s->fChild[!last]) && !IsRed(s->fChild[last])) {
                            // color flip
                            parent->fRed = false;
                            s->fRed = true;
                            curr->fRed = true;
                        } else {
                            int dir2 = (grandparent->fChild[1] == parent);

                            if (IsRed(s->fChild[last])) {
                                grandparent->fChild[dir2] = DoubleRotation(parent, last);
                            } else if (IsRed(s->fChild[!last])) {
                                grandparent->fChild[dir2] = SingleRotation(parent, last);
                            }

                            // ensure correct coloring
                            curr->fRed = grandparent->fChild[dir2]->fRed = true;
                            grandparent->fChild[dir2]->fChild[0]->fRed = false;
                            grandparent->fChild[dir2]->fChild[1]->fRed = false;
                        }
                    }
                }
            }
        }

        // replace and remove if found
        if (found) {
            ActiveEdge* pred = found->fAbove;
            ActiveEdge* succ = found->fBelow;
            if ((pred && pred->intersect(found)) || (succ && succ->intersect(found))) {
                return false;
            }
            if (found != curr) {
                found->fSegment = curr->fSegment;
                found->fIndex0 = curr->fIndex0;
                found->fIndex1 = curr->fIndex1;
                found->fAbove = curr->fAbove;
                pred = found->fAbove;
                // we don't need to set found->fBelow here
            } else {
                if (succ) {
                    succ->fAbove = pred;
                }
            }
            if (pred) {
                pred->fBelow = curr->fBelow;
            }
            parent->fChild[parent->fChild[1] == curr] = curr->fChild[!curr->fChild[0]];

            // no need to delete
            curr->fAbove = reinterpret_cast<ActiveEdge*>(0xdeadbeefll);
            curr->fBelow = reinterpret_cast<ActiveEdge*>(0xdeadbeefll);
            if (fTreeHead.fChild[1]) {
                fTreeHead.fChild[1]->fRed = false;
            }
        }

        // update root and make it black
        if (fTreeHead.fChild[1]) {
            fTreeHead.fChild[1]->fRed = false;
        }

        SkDEBUGCODE(VerifyTree(fTreeHead.fChild[1]));

        return true;
    }

private:
    // allocator
    ActiveEdge * allocate(const SkPoint& p0, const SkPoint& p1, uint16_t index0, uint16_t index1) {
        if (fCurrFree >= fMaxFree) {
            return nullptr;
        }
        char* bytes = fAllocation + sizeof(ActiveEdge)*fCurrFree;
        ++fCurrFree;
        return new(bytes) ActiveEdge(p0, p1, index0, index1);
    }

    ///////////////////////////////////////////////////////////////////////////////////
    // Red-black tree methods
    ///////////////////////////////////////////////////////////////////////////////////
    static bool IsRed(const ActiveEdge* node) {
        return node && node->fRed;
    }

    static ActiveEdge* SingleRotation(ActiveEdge* node, int dir) {
        ActiveEdge* tmp = node->fChild[!dir];

        node->fChild[!dir] = tmp->fChild[dir];
        tmp->fChild[dir] = node;

        node->fRed = true;
        tmp->fRed = false;

        return tmp;
    }

    static ActiveEdge* DoubleRotation(ActiveEdge* node, int dir) {
        node->fChild[!dir] = SingleRotation(node->fChild[!dir], !dir);

        return SingleRotation(node, dir);
    }

    // returns black link count
    static int VerifyTree(const ActiveEdge* tree) {
        if (!tree) {
            return 1;
        }

        const ActiveEdge* left = tree->fChild[0];
        const ActiveEdge* right = tree->fChild[1];

        // no consecutive red links
        if (IsRed(tree) && (IsRed(left) || IsRed(right))) {
            SkASSERT(false);
            return 0;
        }

        // check secondary links
        if (tree->fAbove) {
            SkASSERT(tree->fAbove->fBelow == tree);
            SkASSERT(tree->fAbove->lessThan(tree));
        }
        if (tree->fBelow) {
            SkASSERT(tree->fBelow->fAbove == tree);
            SkASSERT(tree->lessThan(tree->fBelow));
        }

        // violates binary tree order
        if ((left && tree->lessThan(left)) || (right && right->lessThan(tree))) {
            SkASSERT(false);
            return 0;
        }

        int leftCount = VerifyTree(left);
        int rightCount = VerifyTree(right);

        // return black link count
        if (leftCount != 0 && rightCount != 0) {
            // black height mismatch
            if (leftCount != rightCount) {
                SkASSERT(false);
                return 0;
            }
            return IsRed(tree) ? leftCount : leftCount + 1;
        } else {
            return 0;
        }
    }

    ActiveEdge fTreeHead;
    char*      fAllocation;
    int        fCurrFree;
    int        fMaxFree;
};

// Here we implement a sweep line algorithm to determine whether the provided points
// represent a simple polygon, i.e., the polygon is non-self-intersecting.
// We first insert the vertices into a priority queue sorting horizontally from left to right.
// Then as we pop the vertices from the queue we generate events which indicate that an edge
// should be added or removed from an edge list. If any intersections are detected in the edge
// list, then we know the polygon is self-intersecting and hence not simple.
bool SkIsSimplePolygon(const SkPoint* polygon, int polygonSize) {
    if (polygonSize < 3) {
        return false;
    }

    // If it's convex, it's simple
    if (SkIsConvexPolygon(polygon, polygonSize)) {
        return true;
    }

    // practically speaking, it takes too long to process large polygons
    if (polygonSize > 2048) {
        return false;
    }

    SkTDPQueue <Vertex, Vertex::Left> vertexQueue(polygonSize);
    for (int i = 0; i < polygonSize; ++i) {
        Vertex newVertex;
        if (!polygon[i].isFinite()) {
            return false;
        }
        newVertex.fPosition = polygon[i];
        newVertex.fIndex = i;
        newVertex.fPrevIndex = (i - 1 + polygonSize) % polygonSize;
        newVertex.fNextIndex = (i + 1) % polygonSize;
        newVertex.fFlags = 0;
        // The two edges adjacent to this vertex are the same, so polygon is not simple
        if (polygon[newVertex.fPrevIndex] == polygon[newVertex.fNextIndex]) {
            return false;
        }
        if (left(polygon[newVertex.fPrevIndex], polygon[i])) {
            newVertex.fFlags |= kPrevLeft_VertexFlag;
        }
        if (left(polygon[newVertex.fNextIndex], polygon[i])) {
            newVertex.fFlags |= kNextLeft_VertexFlag;
        }
        vertexQueue.insert(newVertex);
    }

    // pop each vertex from the queue and generate events depending on
    // where it lies relative to its neighboring edges
    ActiveEdgeList sweepLine(polygonSize);
    while (vertexQueue.count() > 0) {
        const Vertex& v = vertexQueue.peek();

        // both to the right -- insert both
        if (v.fFlags == 0) {
            if (!sweepLine.insert(v.fPosition, polygon[v.fPrevIndex], v.fIndex, v.fPrevIndex)) {
                break;
            }
            if (!sweepLine.insert(v.fPosition, polygon[v.fNextIndex], v.fIndex, v.fNextIndex)) {
                break;
            }
        // both to the left -- remove both
        } else if (v.fFlags == (kPrevLeft_VertexFlag | kNextLeft_VertexFlag)) {
            if (!sweepLine.remove(polygon[v.fPrevIndex], v.fPosition, v.fPrevIndex, v.fIndex)) {
                break;
            }
            if (!sweepLine.remove(polygon[v.fNextIndex], v.fPosition, v.fNextIndex, v.fIndex)) {
                break;
            }
        // one to left and right -- replace one with another
        } else {
            if (v.fFlags & kPrevLeft_VertexFlag) {
                if (!sweepLine.replace(polygon[v.fPrevIndex], v.fPosition, polygon[v.fNextIndex],
                                       v.fPrevIndex, v.fIndex, v.fNextIndex)) {
                    break;
                }
            } else {
                SkASSERT(v.fFlags & kNextLeft_VertexFlag);
                if (!sweepLine.replace(polygon[v.fNextIndex], v.fPosition, polygon[v.fPrevIndex],
                                       v.fNextIndex, v.fIndex, v.fPrevIndex)) {
                    break;
                }
            }
        }

        vertexQueue.pop();
    }

    return (vertexQueue.count() == 0);
}

///////////////////////////////////////////////////////////////////////////////////////////

// helper function for SkOffsetSimplePolygon
static void setup_offset_edge(OffsetEdge* currEdge,
                              const SkPoint& endpoint0, const SkPoint& endpoint1,
                              uint16_t startIndex, uint16_t endIndex) {
    currEdge->fOffset.fP0 = endpoint0;
    currEdge->fOffset.fV = endpoint1 - endpoint0;
    currEdge->init(startIndex, endIndex);
}

static bool is_reflex_vertex(const SkPoint* inputPolygonVerts, int winding, SkScalar offset,
                             uint16_t prevIndex, uint16_t currIndex, uint16_t nextIndex) {
    int side = compute_side(inputPolygonVerts[prevIndex],
                            inputPolygonVerts[currIndex] - inputPolygonVerts[prevIndex],
                            inputPolygonVerts[nextIndex]);
    // if reflex point, we need to add extra edges
    return (side*winding*offset < 0);
}

bool SkOffsetSimplePolygon(const SkPoint* inputPolygonVerts, int inputPolygonSize,
                           const SkRect& bounds, SkScalar offset,
                           SkTDArray<SkPoint>* offsetPolygon, SkTDArray<int>* polygonIndices) {
    if (inputPolygonSize < 3) {
        return false;
    }

    // need to be able to represent all the vertices in the 16-bit indices
    if (inputPolygonSize >= std::numeric_limits<uint16_t>::max()) {
        return false;
    }

    if (!SkScalarIsFinite(offset)) {
        return false;
    }

    // can't inset more than the half bounds of the polygon
    if (offset > std::min(SkTAbs(SkRectPriv::HalfWidth(bounds)),
                          SkTAbs(SkRectPriv::HalfHeight(bounds)))) {
        return false;
    }

    // offsetting close to zero just returns the original poly
    if (SkScalarNearlyZero(offset)) {
        for (int i = 0; i < inputPolygonSize; ++i) {
            *offsetPolygon->append() = inputPolygonVerts[i];
            if (polygonIndices) {
                *polygonIndices->append() = i;
            }
        }
        return true;
    }

    // get winding direction
    int winding = SkGetPolygonWinding(inputPolygonVerts, inputPolygonSize);
    if (0 == winding) {
        return false;
    }

    // build normals
    SkAutoSTMalloc<64, SkVector> normals(inputPolygonSize);
    unsigned int numEdges = 0;
    for (int currIndex = 0, prevIndex = inputPolygonSize - 1;
         currIndex < inputPolygonSize;
         prevIndex = currIndex, ++currIndex) {
        if (!inputPolygonVerts[currIndex].isFinite()) {
            return false;
        }
        int nextIndex = (currIndex + 1) % inputPolygonSize;
        if (!compute_offset_vector(inputPolygonVerts[currIndex], inputPolygonVerts[nextIndex],
                                   offset, winding, &normals[currIndex])) {
            return false;
        }
        if (currIndex > 0) {
            // if reflex point, we need to add extra edges
            if (is_reflex_vertex(inputPolygonVerts, winding, offset,
                                 prevIndex, currIndex, nextIndex)) {
                SkScalar rotSin, rotCos;
                int numSteps;
                if (!SkComputeRadialSteps(normals[prevIndex], normals[currIndex], offset,
                                          &rotSin, &rotCos, &numSteps)) {
                    return false;
                }
                numEdges += std::max(numSteps, 1);
            }
        }
        numEdges++;
    }
    // finish up the edge counting
    if (is_reflex_vertex(inputPolygonVerts, winding, offset, inputPolygonSize-1, 0, 1)) {
        SkScalar rotSin, rotCos;
        int numSteps;
        if (!SkComputeRadialSteps(normals[inputPolygonSize-1], normals[0], offset,
                                  &rotSin, &rotCos, &numSteps)) {
            return false;
        }
        numEdges += std::max(numSteps, 1);
    }

    // Make sure we don't overflow the max array count.
    // We shouldn't overflow numEdges, as SkComputeRadialSteps returns a max of 2^16-1,
    // and we have a max of 2^16-1 original vertices.
    if (numEdges > (unsigned int)std::numeric_limits<int32_t>::max()) {
        return false;
    }

    // build initial offset edge list
    SkSTArray<64, OffsetEdge> edgeData(numEdges);
    OffsetEdge* prevEdge = nullptr;
    for (int currIndex = 0, prevIndex = inputPolygonSize - 1;
         currIndex < inputPolygonSize;
         prevIndex = currIndex, ++currIndex) {
        int nextIndex = (currIndex + 1) % inputPolygonSize;
        // if reflex point, fill in curve
        if (is_reflex_vertex(inputPolygonVerts, winding, offset,
                             prevIndex, currIndex, nextIndex)) {
            SkScalar rotSin, rotCos;
            int numSteps;
            SkVector prevNormal = normals[prevIndex];
            if (!SkComputeRadialSteps(prevNormal, normals[currIndex], offset,
                                      &rotSin, &rotCos, &numSteps)) {
                return false;
            }
            auto currEdge = edgeData.push_back_n(std::max(numSteps, 1));
            for (int i = 0; i < numSteps - 1; ++i) {
                SkVector currNormal = SkVector::Make(prevNormal.fX*rotCos - prevNormal.fY*rotSin,
                                                     prevNormal.fY*rotCos + prevNormal.fX*rotSin);
                setup_offset_edge(currEdge,
                                  inputPolygonVerts[currIndex] + prevNormal,
                                  inputPolygonVerts[currIndex] + currNormal,
                                  currIndex, currIndex);
                prevNormal = currNormal;
                currEdge->fPrev = prevEdge;
                if (prevEdge) {
                    prevEdge->fNext = currEdge;
                }
                prevEdge = currEdge;
                ++currEdge;
            }
            setup_offset_edge(currEdge,
                              inputPolygonVerts[currIndex] + prevNormal,
                              inputPolygonVerts[currIndex] + normals[currIndex],
                              currIndex, currIndex);
            currEdge->fPrev = prevEdge;
            if (prevEdge) {
                prevEdge->fNext = currEdge;
            }
            prevEdge = currEdge;
        }

        // Add the edge
        auto currEdge = edgeData.push_back_n(1);
        setup_offset_edge(currEdge,
                          inputPolygonVerts[currIndex] + normals[currIndex],
                          inputPolygonVerts[nextIndex] + normals[currIndex],
                          currIndex, nextIndex);
        currEdge->fPrev = prevEdge;
        if (prevEdge) {
            prevEdge->fNext = currEdge;
        }
        prevEdge = currEdge;
    }
    // close up the linked list
    SkASSERT(prevEdge);
    prevEdge->fNext = &edgeData[0];
    edgeData[0].fPrev = prevEdge;

    // now clip edges
    SkASSERT(edgeData.size() == (int)numEdges);
    auto head = &edgeData[0];
    auto currEdge = head;
    unsigned int offsetVertexCount = numEdges;
    unsigned long long iterations = 0;
    unsigned long long maxIterations = (unsigned long long)(numEdges) * numEdges;
    while (head && prevEdge != currEdge && offsetVertexCount > 0) {
        ++iterations;
        // we should check each edge against each other edge at most once
        if (iterations > maxIterations) {
            return false;
        }

        SkScalar s, t;
        SkPoint intersection;
        if (prevEdge->checkIntersection(currEdge, &intersection, &s, &t)) {
            // if new intersection is further back on previous inset from the prior intersection
            if (s < prevEdge->fTValue) {
                // no point in considering this one again
                remove_node(prevEdge, &head);
                --offsetVertexCount;
                // go back one segment
                prevEdge = prevEdge->fPrev;
                // we've already considered this intersection, we're done
            } else if (currEdge->fTValue > SK_ScalarMin &&
                       SkPointPriv::EqualsWithinTolerance(intersection,
                                                          currEdge->fIntersection,
                                                          1.0e-6f)) {
                break;
            } else {
                // add intersection
                currEdge->fIntersection = intersection;
                currEdge->fTValue = t;
                currEdge->fIndex = prevEdge->fEnd;

                // go to next segment
                prevEdge = currEdge;
                currEdge = currEdge->fNext;
            }
        } else {
            // If there is no intersection, we want to minimize the distance between
            // the point where the segment lines cross and the segments themselves.
            OffsetEdge* prevPrevEdge = prevEdge->fPrev;
            OffsetEdge* currNextEdge = currEdge->fNext;
            SkScalar dist0 = currEdge->computeCrossingDistance(prevPrevEdge);
            SkScalar dist1 = prevEdge->computeCrossingDistance(currNextEdge);
            // if both lead to direct collision
            if (dist0 < 0 && dist1 < 0) {
                // check first to see if either represent parts of one contour
                SkPoint p1 = prevPrevEdge->fOffset.fP0 + prevPrevEdge->fOffset.fV;
                bool prevSameContour = SkPointPriv::EqualsWithinTolerance(p1,
                                                                          prevEdge->fOffset.fP0);
                p1 = currEdge->fOffset.fP0 + currEdge->fOffset.fV;
                bool currSameContour = SkPointPriv::EqualsWithinTolerance(p1,
                                                                         currNextEdge->fOffset.fP0);

                // want to step along contour to find intersections rather than jump to new one
                if (currSameContour && !prevSameContour) {
                    remove_node(currEdge, &head);
                    currEdge = currNextEdge;
                    --offsetVertexCount;
                    continue;
                } else if (prevSameContour && !currSameContour) {
                    remove_node(prevEdge, &head);
                    prevEdge = prevPrevEdge;
                    --offsetVertexCount;
                    continue;
                }
            }

            // otherwise minimize collision distance along segment
            if (dist0 < dist1) {
                remove_node(prevEdge, &head);
                prevEdge = prevPrevEdge;
            } else {
                remove_node(currEdge, &head);
                currEdge = currNextEdge;
            }
            --offsetVertexCount;
        }
    }

    // store all the valid intersections that aren't nearly coincident
    // TODO: look at the main algorithm and see if we can detect these better
    offsetPolygon->reset();
    if (!head || offsetVertexCount == 0 ||
        offsetVertexCount >= std::numeric_limits<uint16_t>::max()) {
        return false;
    }

    static constexpr SkScalar kCleanupTolerance = 0.01f;
    offsetPolygon->reserve(offsetVertexCount);
    int currIndex = 0;
    *offsetPolygon->append() = head->fIntersection;
    if (polygonIndices) {
        *polygonIndices->append() = head->fIndex;
    }
    currEdge = head->fNext;
    while (currEdge != head) {
        if (!SkPointPriv::EqualsWithinTolerance(currEdge->fIntersection,
                                                (*offsetPolygon)[currIndex],
                                                kCleanupTolerance)) {
            *offsetPolygon->append() = currEdge->fIntersection;
            if (polygonIndices) {
                *polygonIndices->append() = currEdge->fIndex;
            }
            currIndex++;
        }
        currEdge = currEdge->fNext;
    }
    // make sure the first and last points aren't coincident
    if (currIndex >= 1 &&
        SkPointPriv::EqualsWithinTolerance((*offsetPolygon)[0], (*offsetPolygon)[currIndex],
                                            kCleanupTolerance)) {
        offsetPolygon->pop_back();
        if (polygonIndices) {
            polygonIndices->pop_back();
        }
    }

    // check winding of offset polygon (it should be same as the original polygon)
    SkScalar offsetWinding = SkGetPolygonWinding(offsetPolygon->begin(), offsetPolygon->size());

    return (winding*offsetWinding > 0 &&
            SkIsSimplePolygon(offsetPolygon->begin(), offsetPolygon->size()));
}

//////////////////////////////////////////////////////////////////////////////////////////

struct TriangulationVertex {
    SK_DECLARE_INTERNAL_LLIST_INTERFACE(TriangulationVertex);

    enum class VertexType { kConvex, kReflex };

    SkPoint    fPosition;
    VertexType fVertexType;
    uint16_t   fIndex;
    uint16_t   fPrevIndex;
    uint16_t   fNextIndex;
};

static void compute_triangle_bounds(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2,
                                    SkRect* bounds) {
    skvx::float4 min, max;
    min = max = skvx::float4(p0.fX, p0.fY, p0.fX, p0.fY);
    skvx::float4 xy(p1.fX, p1.fY, p2.fX, p2.fY);
    min = skvx::min(min, xy);
    max = skvx::max(max, xy);
    bounds->setLTRB(std::min(min[0], min[2]), std::min(min[1], min[3]),
                    std::max(max[0], max[2]), std::max(max[1], max[3]));
}

// test to see if point p is in triangle p0p1p2.
// for now assuming strictly inside -- if on the edge it's outside
static bool point_in_triangle(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2,
                              const SkPoint& p) {
    SkVector v0 = p1 - p0;
    SkVector v1 = p2 - p1;
    SkScalar n = v0.cross(v1);

    SkVector w0 = p - p0;
    if (n*v0.cross(w0) < SK_ScalarNearlyZero) {
        return false;
    }

    SkVector w1 = p - p1;
    if (n*v1.cross(w1) < SK_ScalarNearlyZero) {
        return false;
    }

    SkVector v2 = p0 - p2;
    SkVector w2 = p - p2;
    if (n*v2.cross(w2) < SK_ScalarNearlyZero) {
        return false;
    }

    return true;
}

// Data structure to track reflex vertices and check whether any are inside a given triangle
class ReflexHash {
public:
    bool init(const SkRect& bounds, int vertexCount) {
        fBounds = bounds;
        fNumVerts = 0;
        SkScalar width = bounds.width();
        SkScalar height = bounds.height();
        if (!SkScalarIsFinite(width) || !SkScalarIsFinite(height)) {
            return false;
        }

        // We want vertexCount grid cells, roughly distributed to match the bounds ratio
        SkScalar hCount = SkScalarSqrt(sk_ieee_float_divide(vertexCount*width, height));
        if (!SkScalarIsFinite(hCount)) {
            return false;
        }
        fHCount = std::max(std::min(SkScalarRoundToInt(hCount), vertexCount), 1);
        fVCount = vertexCount/fHCount;
        fGridConversion.set(sk_ieee_float_divide(fHCount - 0.001f, width),
                            sk_ieee_float_divide(fVCount - 0.001f, height));
        if (!fGridConversion.isFinite()) {
            return false;
        }

        fGrid.resize(fHCount*fVCount);
        for (int i = 0; i < fGrid.size(); ++i) {
            fGrid[i].reset();
        }

        return true;
    }

    void add(TriangulationVertex* v) {
        int index = hash(v);
        fGrid[index].addToTail(v);
        ++fNumVerts;
    }

    void remove(TriangulationVertex* v) {
        int index = hash(v);
        fGrid[index].remove(v);
        --fNumVerts;
    }

    bool checkTriangle(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2,
                       uint16_t ignoreIndex0, uint16_t ignoreIndex1) const {
        if (!fNumVerts) {
            return false;
        }

        SkRect triBounds;
        compute_triangle_bounds(p0, p1, p2, &triBounds);
        int h0 = (triBounds.fLeft - fBounds.fLeft)*fGridConversion.fX;
        int h1 = (triBounds.fRight - fBounds.fLeft)*fGridConversion.fX;
        int v0 = (triBounds.fTop - fBounds.fTop)*fGridConversion.fY;
        int v1 = (triBounds.fBottom - fBounds.fTop)*fGridConversion.fY;

        for (int v = v0; v <= v1; ++v) {
            for (int h = h0; h <= h1; ++h) {
                int i = v * fHCount + h;
                for (SkTInternalLList<TriangulationVertex>::Iter reflexIter = fGrid[i].begin();
                     reflexIter != fGrid[i].end(); ++reflexIter) {
                    TriangulationVertex* reflexVertex = *reflexIter;
                    if (reflexVertex->fIndex != ignoreIndex0 &&
                        reflexVertex->fIndex != ignoreIndex1 &&
                        point_in_triangle(p0, p1, p2, reflexVertex->fPosition)) {
                        return true;
                    }
                }

            }
        }

        return false;
    }

private:
    int hash(TriangulationVertex* vert) const {
        int h = (vert->fPosition.fX - fBounds.fLeft)*fGridConversion.fX;
        int v = (vert->fPosition.fY - fBounds.fTop)*fGridConversion.fY;
        SkASSERT(v*fHCount + h >= 0);
        return v*fHCount + h;
    }

    SkRect fBounds;
    int fHCount;
    int fVCount;
    int fNumVerts;
    // converts distance from the origin to a grid location (when cast to int)
    SkVector fGridConversion;
    SkTDArray<SkTInternalLList<TriangulationVertex>> fGrid;
};

// Check to see if a reflex vertex has become a convex vertex after clipping an ear
static void reclassify_vertex(TriangulationVertex* p, const SkPoint* polygonVerts,
                              int winding, ReflexHash* reflexHash,
                              SkTInternalLList<TriangulationVertex>* convexList) {
    if (TriangulationVertex::VertexType::kReflex == p->fVertexType) {
        SkVector v0 = p->fPosition - polygonVerts[p->fPrevIndex];
        SkVector v1 = polygonVerts[p->fNextIndex] - p->fPosition;
        if (winding*v0.cross(v1) > SK_ScalarNearlyZero*SK_ScalarNearlyZero) {
            p->fVertexType = TriangulationVertex::VertexType::kConvex;
            reflexHash->remove(p);
            p->fPrev = p->fNext = nullptr;
            convexList->addToTail(p);
        }
    }
}

bool SkTriangulateSimplePolygon(const SkPoint* polygonVerts, uint16_t* indexMap, int polygonSize,
                                SkTDArray<uint16_t>* triangleIndices) {
    if (polygonSize < 3) {
        return false;
    }
    // need to be able to represent all the vertices in the 16-bit indices
    if (polygonSize >= std::numeric_limits<uint16_t>::max()) {
        return false;
    }

    // get bounds
    SkRect bounds;
    if (!bounds.setBoundsCheck(polygonVerts, polygonSize)) {
        return false;
    }
    // get winding direction
    // TODO: we do this for all the polygon routines -- might be better to have the client
    // compute it and pass it in
    int winding = SkGetPolygonWinding(polygonVerts, polygonSize);
    if (0 == winding) {
        return false;
    }

    // Set up vertices
    SkAutoSTArray<64, TriangulationVertex> triangulationVertices(polygonSize);
    int prevIndex = polygonSize - 1;
    SkVector v0 = polygonVerts[0] - polygonVerts[prevIndex];
    for (int currIndex = 0; currIndex < polygonSize; ++currIndex) {
        int nextIndex = (currIndex + 1) % polygonSize;

        triangulationVertices[currIndex] = TriangulationVertex{};
        triangulationVertices[currIndex].fPosition = polygonVerts[currIndex];
        triangulationVertices[currIndex].fIndex = currIndex;
        triangulationVertices[currIndex].fPrevIndex = prevIndex;
        triangulationVertices[currIndex].fNextIndex = nextIndex;
        SkVector v1 = polygonVerts[nextIndex] - polygonVerts[currIndex];
        if (winding*v0.cross(v1) > SK_ScalarNearlyZero*SK_ScalarNearlyZero) {
            triangulationVertices[currIndex].fVertexType = TriangulationVertex::VertexType::kConvex;
        } else {
            triangulationVertices[currIndex].fVertexType = TriangulationVertex::VertexType::kReflex;
        }

        prevIndex = currIndex;
        v0 = v1;
    }

    // Classify initial vertices into a list of convex vertices and a hash of reflex vertices
    // TODO: possibly sort the convexList in some way to get better triangles
    SkTInternalLList<TriangulationVertex> convexList;
    ReflexHash reflexHash;
    if (!reflexHash.init(bounds, polygonSize)) {
        return false;
    }
    prevIndex = polygonSize - 1;
    for (int currIndex = 0; currIndex < polygonSize; prevIndex = currIndex, ++currIndex) {
        TriangulationVertex::VertexType currType = triangulationVertices[currIndex].fVertexType;
        if (TriangulationVertex::VertexType::kConvex == currType) {
            int nextIndex = (currIndex + 1) % polygonSize;
            TriangulationVertex::VertexType prevType = triangulationVertices[prevIndex].fVertexType;
            TriangulationVertex::VertexType nextType = triangulationVertices[nextIndex].fVertexType;
            // We prioritize clipping vertices with neighboring reflex vertices.
            // The intent here is that it will cull reflex vertices more quickly.
            if (TriangulationVertex::VertexType::kReflex == prevType ||
                TriangulationVertex::VertexType::kReflex == nextType) {
                convexList.addToHead(&triangulationVertices[currIndex]);
            } else {
                convexList.addToTail(&triangulationVertices[currIndex]);
            }
        } else {
            // We treat near collinear vertices as reflex
            reflexHash.add(&triangulationVertices[currIndex]);
        }
    }

    // The general concept: We are trying to find three neighboring vertices where
    // no other vertex lies inside the triangle (an "ear"). If we find one, we clip
    // that ear off, and then repeat on the new polygon. Once we get down to three vertices
    // we have triangulated the entire polygon.
    // In the worst case this is an n^2 algorithm. We can cut down the search space somewhat by
    // noting that only convex vertices can be potential ears, and we only need to check whether
    // any reflex vertices lie inside the ear.
    triangleIndices->reserve(triangleIndices->size() + 3 * (polygonSize - 2));
    int vertexCount = polygonSize;
    while (vertexCount > 3) {
        bool success = false;
        TriangulationVertex* earVertex = nullptr;
        TriangulationVertex* p0 = nullptr;
        TriangulationVertex* p2 = nullptr;
        // find a convex vertex to clip
        for (SkTInternalLList<TriangulationVertex>::Iter convexIter = convexList.begin();
             convexIter != convexList.end(); ++convexIter) {
            earVertex = *convexIter;
            SkASSERT(TriangulationVertex::VertexType::kReflex != earVertex->fVertexType);

            p0 = &triangulationVertices[earVertex->fPrevIndex];
            p2 = &triangulationVertices[earVertex->fNextIndex];

            // see if any reflex vertices are inside the ear
            bool failed = reflexHash.checkTriangle(p0->fPosition, earVertex->fPosition,
                                                   p2->fPosition, p0->fIndex, p2->fIndex);
            if (failed) {
                continue;
            }

            // found one we can clip
            success = true;
            break;
        }
        // If we can't find any ears to clip, this probably isn't a simple polygon
        if (!success) {
            return false;
        }

        // add indices
        auto indices = triangleIndices->append(3);
        indices[0] = indexMap[p0->fIndex];
        indices[1] = indexMap[earVertex->fIndex];
        indices[2] = indexMap[p2->fIndex];

        // clip the ear
        convexList.remove(earVertex);
        --vertexCount;

        // reclassify reflex verts
        p0->fNextIndex = earVertex->fNextIndex;
        reclassify_vertex(p0, polygonVerts, winding, &reflexHash, &convexList);

        p2->fPrevIndex = earVertex->fPrevIndex;
        reclassify_vertex(p2, polygonVerts, winding, &reflexHash, &convexList);
    }

    // output indices
    for (SkTInternalLList<TriangulationVertex>::Iter vertexIter = convexList.begin();
         vertexIter != convexList.end(); ++vertexIter) {
        TriangulationVertex* vertex = *vertexIter;
        *triangleIndices->append() = indexMap[vertex->fIndex];
    }

    return true;
}

#endif // !defined(SK_ENABLE_OPTIMIZE_SIZE)

