/*
 * Copyright 2009 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/core/SkEdgeClipper.h"

#include "include/core/SkRect.h"
#include "include/core/SkTypes.h"
#include "include/private/SkAssert.h"
#include "include/private/SkMacros.h"
#include "src/core/SkGeometry.h"
#include "src/core/SkLineClipper.h"
#include "src/core/SkPathPriv.h"

#include <algorithm>
#include <array>
#include <cstring>

static bool quick_reject(const SkRect& bounds, const SkRect& clip) {
    return bounds.fTop >= clip.fBottom || bounds.fBottom <= clip.fTop;
}

static inline void clamp_le(SkScalar& value, SkScalar max) {
    if (value > max) {
        value = max;
    }
}

static inline void clamp_ge(SkScalar& value, SkScalar min) {
    if (value < min) {
        value = min;
    }
}

/*  src[] must be monotonic in Y. This routine copies src into dst, and sorts
 it to be increasing in Y. If it had to reverse the order of the points,
 it returns true, otherwise it returns false
 */
static bool sort_increasing_Y(SkPoint dst[], const SkPoint src[], int count) {
    // we need the data to be monotonically increasing in Y
    if (src[0].fY > src[count - 1].fY) {
        for (int i = 0; i < count; i++) {
            dst[i] = src[count - i - 1];
        }
        return true;
    } else {
        memcpy(dst, src, count * sizeof(SkPoint));
        return false;
    }
}

bool SkEdgeClipper::clipLine(SkPoint p0, SkPoint p1, const SkRect& clip) {
    fCurrPoint = fPoints;
    fCurrVerb = fVerbs;

    SkPoint lines[SkLineClipper::kMaxPoints];
    const SkPoint pts[] = { p0, p1 };
    int lineCount = SkLineClipper::ClipLine(pts, clip, lines, fCanCullToTheRight);
    for (int i = 0; i < lineCount; i++) {
        this->appendLine(lines[i], lines[i + 1]);
    }

    fCurrVerbStop = fCurrVerb;
    fCurrPoint = fPoints;
    fCurrVerb = fVerbs;
    return fCurrVerbStop != fCurrVerb;
}

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

static bool chopMonoQuadAt(SkScalar c0, SkScalar c1, SkScalar c2,
                           SkScalar target, SkScalar* t) {
    /* Solve F(t) = y where F(t) := [0](1-t)^2 + 2[1]t(1-t) + [2]t^2
     *  We solve for t, using quadratic equation, hence we have to rearrange
     * our cooefficents to look like At^2 + Bt + C
     */
    SkScalar A = c0 - c1 - c1 + c2;
    SkScalar B = 2*(c1 - c0);
    SkScalar C = c0 - target;

    SkScalar roots[2];  // we only expect one, but make room for 2 for safety
    int count = SkFindUnitQuadRoots(A, B, C, roots);
    if (count) {
        *t = roots[0];
        return true;
    }
    return false;
}

static bool chopMonoQuadAtY(SkPoint pts[3], SkScalar y, SkScalar* t) {
    return chopMonoQuadAt(pts[0].fY, pts[1].fY, pts[2].fY, y, t);
}

static bool chopMonoQuadAtX(SkPoint pts[3], SkScalar x, SkScalar* t) {
    return chopMonoQuadAt(pts[0].fX, pts[1].fX, pts[2].fX, x, t);
}

// Modify pts[] in place so that it is clipped in Y to the clip rect
static void chop_quad_in_Y(SkPoint pts[3], const SkRect& clip) {
    SkScalar t;
    SkPoint tmp[5]; // for SkChopQuadAt

    // are we partially above
    if (pts[0].fY < clip.fTop) {
        if (chopMonoQuadAtY(pts, clip.fTop, &t)) {
            // take the 2nd chopped quad
            SkChopQuadAt(pts, tmp, t);
            // clamp to clean up imprecise numerics in the chop
            tmp[2].fY = clip.fTop;
            clamp_ge(tmp[3].fY, clip.fTop);

            pts[0] = tmp[2];
            pts[1] = tmp[3];
        } else {
            // if chopMonoQuadAtY failed, then we may have hit inexact numerics
            // so we just clamp against the top
            for (int i = 0; i < 3; i++) {
                if (pts[i].fY < clip.fTop) {
                    pts[i].fY = clip.fTop;
                }
            }
        }
    }

    // are we partially below
    if (pts[2].fY > clip.fBottom) {
        if (chopMonoQuadAtY(pts, clip.fBottom, &t)) {
            SkChopQuadAt(pts, tmp, t);
            // clamp to clean up imprecise numerics in the chop
            clamp_le(tmp[1].fY, clip.fBottom);
            tmp[2].fY = clip.fBottom;

            pts[1] = tmp[1];
            pts[2] = tmp[2];
        } else {
            // if chopMonoQuadAtY failed, then we may have hit inexact numerics
            // so we just clamp against the bottom
            for (int i = 0; i < 3; i++) {
                if (pts[i].fY > clip.fBottom) {
                    pts[i].fY = clip.fBottom;
                }
            }
        }
    }
}

// srcPts[] must be monotonic in X and Y
void SkEdgeClipper::clipMonoQuad(const SkPoint srcPts[3], const SkRect& clip) {
    SkPoint pts[3];
    bool reverse = sort_increasing_Y(pts, srcPts, 3);

    // are we completely above or below
    if (pts[2].fY <= clip.fTop || pts[0].fY >= clip.fBottom) {
        return;
    }

    // Now chop so that pts is contained within clip in Y
    chop_quad_in_Y(pts, clip);

    if (pts[0].fX > pts[2].fX) {
        using std::swap;
        swap(pts[0], pts[2]);
        reverse = !reverse;
    }
    SkASSERT(pts[0].fX <= pts[1].fX);
    SkASSERT(pts[1].fX <= pts[2].fX);

    // Now chop in X has needed, and record the segments

    if (pts[2].fX <= clip.fLeft) {  // wholly to the left
        this->appendVLine(clip.fLeft, pts[0].fY, pts[2].fY, reverse);
        return;
    }
    if (pts[0].fX >= clip.fRight) {  // wholly to the right
        if (!this->canCullToTheRight()) {
            this->appendVLine(clip.fRight, pts[0].fY, pts[2].fY, reverse);
        }
        return;
    }

    SkScalar t;
    SkPoint tmp[5]; // for SkChopQuadAt

    // are we partially to the left
    if (pts[0].fX < clip.fLeft) {
        if (chopMonoQuadAtX(pts, clip.fLeft, &t)) {
            SkChopQuadAt(pts, tmp, t);
            this->appendVLine(clip.fLeft, tmp[0].fY, tmp[2].fY, reverse);
            // clamp to clean up imprecise numerics in the chop
            tmp[2].fX = clip.fLeft;
            clamp_ge(tmp[3].fX, clip.fLeft);

            pts[0] = tmp[2];
            pts[1] = tmp[3];
        } else {
            // if chopMonoQuadAtY failed, then we may have hit inexact numerics
            // so we just clamp against the left
            this->appendVLine(clip.fLeft, pts[0].fY, pts[2].fY, reverse);
            return;
        }
    }

    // are we partially to the right
    if (pts[2].fX > clip.fRight) {
        if (chopMonoQuadAtX(pts, clip.fRight, &t)) {
            SkChopQuadAt(pts, tmp, t);
            // clamp to clean up imprecise numerics in the chop
            clamp_le(tmp[1].fX, clip.fRight);
            tmp[2].fX = clip.fRight;

            this->appendQuad(tmp, reverse);
            this->appendVLine(clip.fRight, tmp[2].fY, tmp[4].fY, reverse);
        } else {
            // if chopMonoQuadAtY failed, then we may have hit inexact numerics
            // so we just clamp against the right
            pts[1].fX = std::min(pts[1].fX, clip.fRight);
            pts[2].fX = std::min(pts[2].fX, clip.fRight);
            this->appendQuad(pts, reverse);
        }
    } else {    // wholly inside the clip
        this->appendQuad(pts, reverse);
    }
}

bool SkEdgeClipper::clipQuad(const SkPoint srcPts[3], const SkRect& clip) {
    fCurrPoint = fPoints;
    fCurrVerb = fVerbs;

    const SkRect bounds = SkRect::BoundsOrEmpty({srcPts, 3});

    if (!quick_reject(bounds, clip)) {
        std::array<SkPoint, 5> monoY;
        int countY = SkChopQuadAtYExtrema(srcPts, monoY.data());
        for (int y = 0; y <= countY; y++) {
            std::array<SkPoint, 5> monoX;
            int countX = SkChopQuadAtXExtrema(&monoY[y * 2], monoX.data());
            for (int x = 0; x <= countX; x++) {
                this->clipMonoQuad(&monoX[x * 2], clip);
                SkASSERT_RELEASE(fCurrVerb - fVerbs < kMaxVerbs);
                SkASSERT_RELEASE(fCurrPoint - fPoints <= kMaxPoints);
            }
        }
    }

    fCurrVerbStop = fCurrVerb;
    fCurrPoint = fPoints;
    fCurrVerb = fVerbs;
    return fCurrVerbStop != fCurrVerb;
}

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

static SkScalar mono_cubic_closestT(const SkScalar src[], SkScalar x) {
    SkScalar t = 0.5f;
    SkScalar lastT;
    SkScalar bestT  SK_INIT_TO_AVOID_WARNING;
    SkScalar step = 0.25f;
    SkScalar D = src[0];
    SkScalar A = src[6] + 3*(src[2] - src[4]) - D;
    SkScalar B = 3*(src[4] - src[2] - src[2] + D);
    SkScalar C = 3*(src[2] - D);
    x -= D;
    SkScalar closest = SK_ScalarMax;
    do {
        SkScalar loc = ((A * t + B) * t + C) * t;
        SkScalar dist = SkScalarAbs(loc - x);
        if (closest > dist) {
            closest = dist;
            bestT = t;
        }
        lastT = t;
        t += loc < x ? step : -step;
        step *= 0.5f;
    } while (closest > 0.25f && lastT != t);
    return bestT;
}

static void chop_mono_cubic_at_y(SkPoint src[4], SkScalar y, SkPoint dst[7]) {
    if (SkChopMonoCubicAtY(src, y, dst)) {
        return;
    }
    SkChopCubicAt(src, dst, mono_cubic_closestT(&src->fY, y));
}

// Modify pts[] in place so that it is clipped in Y to the clip rect
static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {

    // are we partially above
    if (pts[0].fY < clip.fTop) {
        SkPoint tmp[7];
        chop_mono_cubic_at_y(pts, clip.fTop, tmp);

        /*
         *  For a large range in the points, we can do a poor job of chopping, such that the t
         *  we computed resulted in the lower cubic still being partly above the clip.
         *
         *  If just the first or first 2 Y values are above the fTop, we can just smash them
         *  down. If the first 3 Ys are above fTop, we can't smash all 3, as that can really
         *  distort the cubic. In this case, we take the first output (tmp[3..6] and treat it as
         *  a guess, and re-chop against fTop. Then we fall through to checking if we need to
         *  smash the first 1 or 2 Y values.
         */
        if (tmp[3].fY < clip.fTop && tmp[4].fY < clip.fTop && tmp[5].fY < clip.fTop) {
            SkPoint tmp2[4];
            memcpy(tmp2, &tmp[3].fX, 4 * sizeof(SkPoint));
            chop_mono_cubic_at_y(tmp2, clip.fTop, tmp);
        }

        // tmp[3, 4].fY should all be to the below clip.fTop.
        // Since we can't trust the numerics of the chopper, we force those conditions now
        tmp[3].fY = clip.fTop;
        clamp_ge(tmp[4].fY, clip.fTop);

        pts[0] = tmp[3];
        pts[1] = tmp[4];
        pts[2] = tmp[5];
    }

    // are we partially below
    if (pts[3].fY > clip.fBottom) {
        SkPoint tmp[7];
        chop_mono_cubic_at_y(pts, clip.fBottom, tmp);
        tmp[3].fY = clip.fBottom;
        clamp_le(tmp[2].fY, clip.fBottom);

        pts[1] = tmp[1];
        pts[2] = tmp[2];
        pts[3] = tmp[3];
    }
}

static void chop_mono_cubic_at_x(SkPoint src[4], SkScalar x, SkPoint dst[7]) {
    if (SkChopMonoCubicAtX(src, x, dst)) {
        return;
    }
    SkChopCubicAt(src, dst, mono_cubic_closestT(&src->fX, x));
}

// srcPts[] must be monotonic in X and Y
void SkEdgeClipper::clipMonoCubic(const SkPoint src[4], const SkRect& clip) {
    SkPoint pts[4];
    bool reverse = sort_increasing_Y(pts, src, 4);

    // are we completely above or below
    if (pts[3].fY <= clip.fTop || pts[0].fY >= clip.fBottom) {
        return;
    }

    // Now chop so that pts is contained within clip in Y
    chop_cubic_in_Y(pts, clip);

    if (pts[0].fX > pts[3].fX) {
        using std::swap;
        swap(pts[0], pts[3]);
        swap(pts[1], pts[2]);
        reverse = !reverse;
    }

    // Now chop in X has needed, and record the segments

    if (pts[3].fX <= clip.fLeft) {  // wholly to the left
        this->appendVLine(clip.fLeft, pts[0].fY, pts[3].fY, reverse);
        return;
    }
    if (pts[0].fX >= clip.fRight) {  // wholly to the right
        if (!this->canCullToTheRight()) {
            this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse);
        }
        return;
    }

    // are we partially to the left
    if (pts[0].fX < clip.fLeft) {
        SkPoint tmp[7];
        chop_mono_cubic_at_x(pts, clip.fLeft, tmp);
        this->appendVLine(clip.fLeft, tmp[0].fY, tmp[3].fY, reverse);

        // tmp[3, 4].fX should all be to the right of clip.fLeft.
        // Since we can't trust the numerics of
        // the chopper, we force those conditions now
        tmp[3].fX = clip.fLeft;
        clamp_ge(tmp[4].fX, clip.fLeft);

        pts[0] = tmp[3];
        pts[1] = tmp[4];
        pts[2] = tmp[5];
    }

    // are we partially to the right
    if (pts[3].fX > clip.fRight) {
        SkPoint tmp[7];
        chop_mono_cubic_at_x(pts, clip.fRight, tmp);
        tmp[3].fX = clip.fRight;
        clamp_le(tmp[2].fX, clip.fRight);

        this->appendCubic(tmp, reverse);
        this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse);
    } else {    // wholly inside the clip
        this->appendCubic(pts, reverse);
    }
}

static SkRect compute_cubic_bounds(const SkPoint pts[4]) {
    return SkRect::BoundsOrEmpty({pts, 4});
}

static bool too_big_for_reliable_float_math(const SkRect& r) {
    // limit set as the largest float value for which we can still reliably compute things like
    // - chopping at XY extrema
    // - chopping at Y or X values for clipping
    //
    // Current value chosen just by experiment. Larger (and still succeeds) is always better.
    //
    const SkScalar limit = 1 << 22;
    return r.fLeft < -limit || r.fTop < -limit || r.fRight > limit || r.fBottom > limit;
}

bool SkEdgeClipper::clipCubic(const SkPoint srcPts[4], const SkRect& clip) {
    fCurrPoint = fPoints;
    fCurrVerb = fVerbs;

    const SkRect bounds = compute_cubic_bounds(srcPts);
    // check if we're clipped out vertically
    if (bounds.fBottom > clip.fTop && bounds.fTop < clip.fBottom) {
        if (too_big_for_reliable_float_math(bounds)) {
            // can't safely clip the cubic, so we give up and draw a line (which we can safely clip)
            //
            // If we rewrote chopcubicat*extrema and chopmonocubic using doubles, we could very
            // likely always handle the cubic safely, but (it seems) at a big loss in speed, so
            // we'd only want to take that alternate impl if needed. Perhaps a TODO to try it.
            //
            return this->clipLine(srcPts[0], srcPts[3], clip);
        } else {
            std::array<SkPoint, 10> monoY;
            int countY = SkChopCubicAtYExtrema(srcPts, monoY.data());
            for (int y = 0; y <= countY; y++) {
                std::array<SkPoint, 10> monoX;
                int countX = SkChopCubicAtXExtrema(&monoY[y * 3], monoX.data());
                for (int x = 0; x <= countX; x++) {
                    this->clipMonoCubic(&monoX[x * 3], clip);
                    SkASSERT(fCurrVerb - fVerbs < kMaxVerbs);
                    SkASSERT(fCurrPoint - fPoints <= kMaxPoints);
                }
            }
        }
    }

    fCurrVerbStop = fCurrVerb;
    fCurrPoint = fPoints;
    fCurrVerb = fVerbs;
    return fCurrVerbStop != fCurrVerb;
}

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

void SkEdgeClipper::appendLine(SkPoint p0, SkPoint p1) {
    *fCurrVerb++ = SkPathVerb::kLine;
    SkASSERT_RELEASE(fCurrPoint + 2 - fPoints <= kMaxPoints);
    fCurrPoint[0] = p0;
    fCurrPoint[1] = p1;
    fCurrPoint += 2;
}

void SkEdgeClipper::appendVLine(SkScalar x, SkScalar y0, SkScalar y1, bool reverse) {
    *fCurrVerb++ = SkPathVerb::kLine;

    if (reverse) {
        using std::swap;
        swap(y0, y1);
    }
    SkASSERT_RELEASE(fCurrPoint + 2 - fPoints <= kMaxPoints);
    fCurrPoint[0].set(x, y0);
    fCurrPoint[1].set(x, y1);
    fCurrPoint += 2;
}

void SkEdgeClipper::appendQuad(const SkPoint pts[3], bool reverse) {
    *fCurrVerb++ = SkPathVerb::kQuad;

    SkASSERT_RELEASE(fCurrPoint + 3 - fPoints <= kMaxPoints);
    if (reverse) {
        fCurrPoint[0] = pts[2];
        fCurrPoint[2] = pts[0];
    } else {
        fCurrPoint[0] = pts[0];
        fCurrPoint[2] = pts[2];
    }
    fCurrPoint[1] = pts[1];
    fCurrPoint += 3;
}

void SkEdgeClipper::appendCubic(const SkPoint pts[4], bool reverse) {
    *fCurrVerb++ = SkPathVerb::kCubic;

    SkASSERT_RELEASE(fCurrPoint + 4 - fPoints <= kMaxPoints);
    if (reverse) {
        for (int i = 0; i < 4; i++) {
            fCurrPoint[i] = pts[3 - i];
        }
    } else {
        memcpy(fCurrPoint, pts, 4 * sizeof(SkPoint));
    }
    fCurrPoint += 4;
}

std::optional<SkPathVerb> SkEdgeClipper::next(SkPoint pts[]) {
    SkASSERT(fCurrVerb <= fCurrVerbStop);
    if (fCurrVerb >= fCurrVerbStop) {
        return {};
    }

    auto verb = *fCurrVerb++;
    switch (verb) {
        case SkPathVerb::kLine:
            SkASSERT_RELEASE(fCurrPoint + 2 - fPoints <= kMaxPoints);
            memcpy(pts, fCurrPoint, 2 * sizeof(SkPoint));
            fCurrPoint += 2;
            break;
        case SkPathVerb::kQuad:
            SkASSERT_RELEASE(fCurrPoint + 3 - fPoints <= kMaxPoints);
            memcpy(pts, fCurrPoint, 3 * sizeof(SkPoint));
            fCurrPoint += 3;
            break;
        case SkPathVerb::kCubic:
            SkASSERT_RELEASE(fCurrPoint + 4 - fPoints <= kMaxPoints);
            memcpy(pts, fCurrPoint, 4 * sizeof(SkPoint));
            fCurrPoint += 4;
            break;
        default:
            SkDEBUGFAIL("unexpected verb in quadclippper2 iter");
            break;
    }
    return verb;
}

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

#ifdef SK_DEBUG
static void assert_monotonic(const SkScalar coord[], int count) {
    if (coord[0] > coord[(count - 1) * 2]) {
        for (int i = 1; i < count; i++) {
            SkASSERT(coord[2 * (i - 1)] >= coord[i * 2]);
        }
    } else if (coord[0] < coord[(count - 1) * 2]) {
        for (int i = 1; i < count; i++) {
            SkASSERT(coord[2 * (i - 1)] <= coord[i * 2]);
        }
    } else {
        for (int i = 1; i < count; i++) {
            SkASSERT(coord[2 * (i - 1)] == coord[i * 2]);
        }
    }
}

void sk_assert_monotonic_y(const SkPoint pts[], int count) {
    if (count > 1) {
        assert_monotonic(&pts[0].fY, count);
    }
}

void sk_assert_monotonic_x(const SkPoint pts[], int count) {
    if (count > 1) {
        assert_monotonic(&pts[0].fX, count);
    }
}
#endif

void SkEdgeClipper::ClipPath(const SkPathRaw& raw, const SkRect& clip, bool canCullToTheRight,
                             void (*consume)(SkEdgeClipper*, bool newCtr, void* ctx), void* ctx) {
    SkAutoConicToQuads quadder;
    constexpr float kConicTol = 0.25f;

    SkPathEdgeIter iter(raw);
    SkEdgeClipper clipper(canCullToTheRight);

    while (auto e = iter.next()) {
        switch (e.fEdge) {
            case SkPathEdgeIter::Edge::kLine:
                if (clipper.clipLine(e.fPts[0], e.fPts[1], clip)) {
                    consume(&clipper, e.fIsNewContour, ctx);
                }
                break;
            case SkPathEdgeIter::Edge::kQuad:
                if (clipper.clipQuad(e.fPts, clip)) {
                    consume(&clipper, e.fIsNewContour, ctx);
                }
                break;
            case SkPathEdgeIter::Edge::kConic: {
                const SkPoint* quadPts =
                        quadder.computeQuads(e.fPts, iter.conicWeight(), kConicTol);
                for (int i = 0; i < quadder.countQuads(); ++i) {
                    if (clipper.clipQuad(quadPts, clip)) {
                        consume(&clipper, e.fIsNewContour, ctx);
                    }
                    quadPts += 2;
                }
            } break;
            case SkPathEdgeIter::Edge::kCubic:
                if (clipper.clipCubic(e.fPts, clip)) {
                    consume(&clipper, e.fIsNewContour, ctx);
                }
                break;
            default:
                SkDEBUGFAIL("Unknown edge type");
                break;
        }
    }
}
