/*
 * 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 "SkGeometry.h"
#include "SkLineParameters.h"
#include "SkPathOpsConic.h"
#include "SkPathOpsCubic.h"
#include "SkPathOpsCurve.h"
#include "SkPathOpsLine.h"
#include "SkPathOpsQuad.h"
#include "SkPathOpsRect.h"
#include "SkTSort.h"

const int SkDCubic::gPrecisionUnit = 256;  // FIXME: test different values in test framework

void SkDCubic::align(int endIndex, int ctrlIndex, SkDPoint* dstPt) const {
    if (fPts[endIndex].fX == fPts[ctrlIndex].fX) {
        dstPt->fX = fPts[endIndex].fX;
    }
    if (fPts[endIndex].fY == fPts[ctrlIndex].fY) {
        dstPt->fY = fPts[endIndex].fY;
    }
}

// give up when changing t no longer moves point
// also, copy point rather than recompute it when it does change
double SkDCubic::binarySearch(double min, double max, double axisIntercept,
        SearchAxis xAxis) const {
    double t = (min + max) / 2;
    double step = (t - min) / 2;
    SkDPoint cubicAtT = ptAtT(t);
    double calcPos = (&cubicAtT.fX)[xAxis];
    double calcDist = calcPos - axisIntercept;
    do {
        double priorT = t - step;
        SkASSERT(priorT >= min);
        SkDPoint lessPt = ptAtT(priorT);
        if (approximately_equal_half(lessPt.fX, cubicAtT.fX)
                && approximately_equal_half(lessPt.fY, cubicAtT.fY)) {
            return -1;  // binary search found no point at this axis intercept
        }
        double lessDist = (&lessPt.fX)[xAxis] - axisIntercept;
#if DEBUG_CUBIC_BINARY_SEARCH
        SkDebugf("t=%1.9g calc=%1.9g dist=%1.9g step=%1.9g less=%1.9g\n", t, calcPos, calcDist,
                step, lessDist);
#endif
        double lastStep = step;
        step /= 2;
        if (calcDist > 0 ? calcDist > lessDist : calcDist < lessDist) {
            t = priorT;
        } else {
            double nextT = t + lastStep;
            if (nextT > max) {
                return -1;
            }
            SkDPoint morePt = ptAtT(nextT);
            if (approximately_equal_half(morePt.fX, cubicAtT.fX)
                    && approximately_equal_half(morePt.fY, cubicAtT.fY)) {
                return -1;  // binary search found no point at this axis intercept
            }
            double moreDist = (&morePt.fX)[xAxis] - axisIntercept;
            if (calcDist > 0 ? calcDist <= moreDist : calcDist >= moreDist) {
                continue;
            }
            t = nextT;
        }
        SkDPoint testAtT = ptAtT(t);
        cubicAtT = testAtT;
        calcPos = (&cubicAtT.fX)[xAxis];
        calcDist = calcPos - axisIntercept;
    } while (!approximately_equal(calcPos, axisIntercept));
    return t;
}

// FIXME: cache keep the bounds and/or precision with the caller?
double SkDCubic::calcPrecision() const {
    SkDRect dRect;
    dRect.setBounds(*this);  // OPTIMIZATION: just use setRawBounds ?
    double width = dRect.fRight - dRect.fLeft;
    double height = dRect.fBottom - dRect.fTop;
    return (width > height ? width : height) / gPrecisionUnit;
}


/* classic one t subdivision */
static void interp_cubic_coords(const double* src, double* dst, double t) {
    double ab = SkDInterp(src[0], src[2], t);
    double bc = SkDInterp(src[2], src[4], t);
    double cd = SkDInterp(src[4], src[6], t);
    double abc = SkDInterp(ab, bc, t);
    double bcd = SkDInterp(bc, cd, t);
    double abcd = SkDInterp(abc, bcd, t);

    dst[0] = src[0];
    dst[2] = ab;
    dst[4] = abc;
    dst[6] = abcd;
    dst[8] = bcd;
    dst[10] = cd;
    dst[12] = src[6];
}

SkDCubicPair SkDCubic::chopAt(double t) const {
    SkDCubicPair dst;
    if (t == 0.5) {
        dst.pts[0] = fPts[0];
        dst.pts[1].fX = (fPts[0].fX + fPts[1].fX) / 2;
        dst.pts[1].fY = (fPts[0].fY + fPts[1].fY) / 2;
        dst.pts[2].fX = (fPts[0].fX + 2 * fPts[1].fX + fPts[2].fX) / 4;
        dst.pts[2].fY = (fPts[0].fY + 2 * fPts[1].fY + fPts[2].fY) / 4;
        dst.pts[3].fX = (fPts[0].fX + 3 * (fPts[1].fX + fPts[2].fX) + fPts[3].fX) / 8;
        dst.pts[3].fY = (fPts[0].fY + 3 * (fPts[1].fY + fPts[2].fY) + fPts[3].fY) / 8;
        dst.pts[4].fX = (fPts[1].fX + 2 * fPts[2].fX + fPts[3].fX) / 4;
        dst.pts[4].fY = (fPts[1].fY + 2 * fPts[2].fY + fPts[3].fY) / 4;
        dst.pts[5].fX = (fPts[2].fX + fPts[3].fX) / 2;
        dst.pts[5].fY = (fPts[2].fY + fPts[3].fY) / 2;
        dst.pts[6] = fPts[3];
        return dst;
    }
    interp_cubic_coords(&fPts[0].fX, &dst.pts[0].fX, t);
    interp_cubic_coords(&fPts[0].fY, &dst.pts[0].fY, t);
    return dst;
}

void SkDCubic::Coefficients(const double* src, double* A, double* B, double* C, double* D) {
    *A = src[6];  // d
    *B = src[4] * 3;  // 3*c
    *C = src[2] * 3;  // 3*b
    *D = src[0];  // a
    *A -= *D - *C + *B;     // A =   -a + 3*b - 3*c + d
    *B += 3 * *D - 2 * *C;  // B =  3*a - 6*b + 3*c
    *C -= 3 * *D;           // C = -3*a + 3*b
}

bool SkDCubic::endsAreExtremaInXOrY() const {
    return (between(fPts[0].fX, fPts[1].fX, fPts[3].fX)
            && between(fPts[0].fX, fPts[2].fX, fPts[3].fX))
            || (between(fPts[0].fY, fPts[1].fY, fPts[3].fY)
            && between(fPts[0].fY, fPts[2].fY, fPts[3].fY));
}

// Do a quick reject by rotating all points relative to a line formed by
// a pair of one cubic's points. If the 2nd cubic's points
// are on the line or on the opposite side from the 1st cubic's 'odd man', the
// curves at most intersect at the endpoints.
/* if returning true, check contains true if cubic's hull collapsed, making the cubic linear
   if returning false, check contains true if the the cubic pair have only the end point in common
*/
bool SkDCubic::hullIntersects(const SkDPoint* pts, int ptCount, bool* isLinear) const {
    bool linear = true;
    char hullOrder[4];
    int hullCount = convexHull(hullOrder);
    int end1 = hullOrder[0];
    int hullIndex = 0;
    const SkDPoint* endPt[2];
    endPt[0] = &fPts[end1];
    do {
        hullIndex = (hullIndex + 1) % hullCount;
        int end2 = hullOrder[hullIndex];
        endPt[1] = &fPts[end2];
        double origX = endPt[0]->fX;
        double origY = endPt[0]->fY;
        double adj = endPt[1]->fX - origX;
        double opp = endPt[1]->fY - origY;
        int oddManMask = other_two(end1, end2);
        int oddMan = end1 ^ oddManMask;
        double sign = (fPts[oddMan].fY - origY) * adj - (fPts[oddMan].fX - origX) * opp;
        int oddMan2 = end2 ^ oddManMask;
        double sign2 = (fPts[oddMan2].fY - origY) * adj - (fPts[oddMan2].fX - origX) * opp;
        if (sign * sign2 < 0) {
            continue;
        }
        if (approximately_zero(sign)) {
            sign = sign2;
            if (approximately_zero(sign)) {
                continue;
            }
        }
        linear = false;
        bool foundOutlier = false;
        for (int n = 0; n < ptCount; ++n) {
            double test = (pts[n].fY - origY) * adj - (pts[n].fX - origX) * opp;
            if (test * sign > 0 && !precisely_zero(test)) {
                foundOutlier = true;
                break;
            }
        }
        if (!foundOutlier) {
            return false;
        }
        endPt[0] = endPt[1];
        end1 = end2;
    } while (hullIndex);
    *isLinear = linear;
    return true;
}

bool SkDCubic::hullIntersects(const SkDCubic& c2, bool* isLinear) const {
    return hullIntersects(c2.fPts, c2.kPointCount, isLinear);
}

bool SkDCubic::hullIntersects(const SkDQuad& quad, bool* isLinear) const {
    return hullIntersects(quad.fPts, quad.kPointCount, isLinear);
}

bool SkDCubic::hullIntersects(const SkDConic& conic, bool* isLinear) const {

    return hullIntersects(conic.fPts, isLinear);
}

bool SkDCubic::isLinear(int startIndex, int endIndex) const {
    SkLineParameters lineParameters;
    lineParameters.cubicEndPoints(*this, startIndex, endIndex);
    // FIXME: maybe it's possible to avoid this and compare non-normalized
    lineParameters.normalize();
    double tiniest = SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(SkTMin(fPts[0].fX, fPts[0].fY),
            fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY), fPts[3].fX), fPts[3].fY);
    double largest = SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(SkTMax(fPts[0].fX, fPts[0].fY),
            fPts[1].fX), fPts[1].fY), fPts[2].fX), fPts[2].fY), fPts[3].fX), fPts[3].fY);
    largest = SkTMax(largest, -tiniest);
    double distance = lineParameters.controlPtDistance(*this, 1);
    if (!approximately_zero_when_compared_to(distance, largest)) {
        return false;
    }
    distance = lineParameters.controlPtDistance(*this, 2);
    return approximately_zero_when_compared_to(distance, largest);
}

bool SkDCubic::ComplexBreak(const SkPoint pointsPtr[4], SkScalar* t) {
    SkScalar d[3];
    SkCubicType cubicType = SkClassifyCubic(pointsPtr, d);
    if (cubicType == kLoop_SkCubicType) {
        // crib code from gpu path utils that finds t values where loop self-intersects
        // use it to find mid of t values which should be a friendly place to chop
        SkScalar tempSqrt = SkScalarSqrt(4.f * d[0] * d[2] - 3.f * d[1] * d[1]);
        SkScalar ls = d[1] - tempSqrt;
        SkScalar lt = 2.f * d[0];
        SkScalar ms = d[1] + tempSqrt;
        SkScalar mt = 2.f * d[0];
        if (roughly_between(0, ls, lt) && roughly_between(0, ms, mt)) {
            ls = ls / lt;
            ms = ms / mt;
            SkASSERT(roughly_between(0, ls, 1) && roughly_between(0, ms, 1));
            *t = (ls + ms) / 2;
            SkASSERT(roughly_between(0, *t, 1));
            return *t > 0 && *t < 1;
        }
    } else if (kSerpentine_SkCubicType == cubicType || kCusp_SkCubicType == cubicType) {
        SkDCubic cubic;
        cubic.set(pointsPtr);
        double inflectionTs[2];
        int infTCount = cubic.findInflections(inflectionTs);
        if (infTCount == 2) {
            double maxCurvature[3];
            int roots = cubic.findMaxCurvature(maxCurvature);
#if DEBUG_CUBIC_SPLIT
            SkDebugf("%s\n", __FUNCTION__);
            cubic.dump();
            for (int index = 0; index < infTCount; ++index) {
                SkDebugf("inflectionsTs[%d]=%1.9g ", index, inflectionTs[index]);
                SkDPoint pt = cubic.ptAtT(inflectionTs[index]);
                SkDVector dPt = cubic.dxdyAtT(inflectionTs[index]);
                SkDLine perp = {{pt - dPt, pt + dPt}};
                perp.dump();
            }
            for (int index = 0; index < roots; ++index) {
                SkDebugf("maxCurvature[%d]=%1.9g ", index, maxCurvature[index]);
                SkDPoint pt = cubic.ptAtT(maxCurvature[index]);
                SkDVector dPt = cubic.dxdyAtT(maxCurvature[index]);
                SkDLine perp = {{pt - dPt, pt + dPt}};
                perp.dump();
            }
#endif
            for (int index = 0; index < roots; ++index) {
                if (between(inflectionTs[0], maxCurvature[index], inflectionTs[1])) {
                    *t = maxCurvature[index];
                    return true;
                }
            }
        } else if (infTCount == 1) {
            *t = inflectionTs[0];
            return *t > 0 && *t < 1;
        }
    }
    return false;
}

bool SkDCubic::monotonicInX() const {
    return precisely_between(fPts[0].fX, fPts[1].fX, fPts[3].fX)
            && precisely_between(fPts[0].fX, fPts[2].fX, fPts[3].fX);
}

bool SkDCubic::monotonicInY() const {
    return precisely_between(fPts[0].fY, fPts[1].fY, fPts[3].fY)
            && precisely_between(fPts[0].fY, fPts[2].fY, fPts[3].fY);
}

void SkDCubic::otherPts(int index, const SkDPoint* o1Pts[kPointCount - 1]) const {
    int offset = (int) !SkToBool(index);
    o1Pts[0] = &fPts[offset];
    o1Pts[1] = &fPts[++offset];
    o1Pts[2] = &fPts[++offset];
}

int SkDCubic::searchRoots(double extremeTs[6], int extrema, double axisIntercept,
        SearchAxis xAxis, double* validRoots) const {
    extrema += findInflections(&extremeTs[extrema]);
    extremeTs[extrema++] = 0;
    extremeTs[extrema] = 1;
    SkTQSort(extremeTs, extremeTs + extrema);
    int validCount = 0;
    for (int index = 0; index < extrema; ) {
        double min = extremeTs[index];
        double max = extremeTs[++index];
        if (min == max) {
            continue;
        }
        double newT = binarySearch(min, max, axisIntercept, xAxis);
        if (newT >= 0) {
            validRoots[validCount++] = newT;
        }
    }
    return validCount;
}

// cubic roots

static const double PI = 3.141592653589793;

// from SkGeometry.cpp (and Numeric Solutions, 5.6)
int SkDCubic::RootsValidT(double A, double B, double C, double D, double t[3]) {
    double s[3];
    int realRoots = RootsReal(A, B, C, D, s);
    int foundRoots = SkDQuad::AddValidTs(s, realRoots, t);
    for (int index = 0; index < realRoots; ++index) {
        double tValue = s[index];
        if (!approximately_one_or_less(tValue) && between(1, tValue, 1.00005)) {
            for (int idx2 = 0; idx2 < foundRoots; ++idx2) {
                if (approximately_equal(t[idx2], 1)) {
                    goto nextRoot;
                }
            }
            SkASSERT(foundRoots < 3);
            t[foundRoots++] = 1;
        } else if (!approximately_zero_or_more(tValue) && between(-0.00005, tValue, 0)) {
            for (int idx2 = 0; idx2 < foundRoots; ++idx2) {
                if (approximately_equal(t[idx2], 0)) {
                    goto nextRoot;
                }
            }
            SkASSERT(foundRoots < 3);
            t[foundRoots++] = 0;
        }
nextRoot:
        ;
    }
    return foundRoots;
}

int SkDCubic::RootsReal(double A, double B, double C, double D, double s[3]) {
#ifdef SK_DEBUG
    // create a string mathematica understands
    // GDB set print repe 15 # if repeated digits is a bother
    //     set print elements 400 # if line doesn't fit
    char str[1024];
    sk_bzero(str, sizeof(str));
    SK_SNPRINTF(str, sizeof(str), "Solve[%1.19g x^3 + %1.19g x^2 + %1.19g x + %1.19g == 0, x]",
            A, B, C, D);
    SkPathOpsDebug::MathematicaIze(str, sizeof(str));
#if ONE_OFF_DEBUG && ONE_OFF_DEBUG_MATHEMATICA
    SkDebugf("%s\n", str);
#endif
#endif
    if (approximately_zero(A)
            && approximately_zero_when_compared_to(A, B)
            && approximately_zero_when_compared_to(A, C)
            && approximately_zero_when_compared_to(A, D)) {  // we're just a quadratic
        return SkDQuad::RootsReal(B, C, D, s);
    }
    if (approximately_zero_when_compared_to(D, A)
            && approximately_zero_when_compared_to(D, B)
            && approximately_zero_when_compared_to(D, C)) {  // 0 is one root
        int num = SkDQuad::RootsReal(A, B, C, s);
        for (int i = 0; i < num; ++i) {
            if (approximately_zero(s[i])) {
                return num;
            }
        }
        s[num++] = 0;
        return num;
    }
    if (approximately_zero(A + B + C + D)) {  // 1 is one root
        int num = SkDQuad::RootsReal(A, A + B, -D, s);
        for (int i = 0; i < num; ++i) {
            if (AlmostDequalUlps(s[i], 1)) {
                return num;
            }
        }
        s[num++] = 1;
        return num;
    }
    double a, b, c;
    {
        double invA = 1 / A;
        a = B * invA;
        b = C * invA;
        c = D * invA;
    }
    double a2 = a * a;
    double Q = (a2 - b * 3) / 9;
    double R = (2 * a2 * a - 9 * a * b + 27 * c) / 54;
    double R2 = R * R;
    double Q3 = Q * Q * Q;
    double R2MinusQ3 = R2 - Q3;
    double adiv3 = a / 3;
    double r;
    double* roots = s;
    if (R2MinusQ3 < 0) {   // we have 3 real roots
        // the divide/root can, due to finite precisions, be slightly outside of -1...1
        double theta = acos(SkTPin(R / sqrt(Q3), -1., 1.));
        double neg2RootQ = -2 * sqrt(Q);

        r = neg2RootQ * cos(theta / 3) - adiv3;
        *roots++ = r;

        r = neg2RootQ * cos((theta + 2 * PI) / 3) - adiv3;
        if (!AlmostDequalUlps(s[0], r)) {
            *roots++ = r;
        }
        r = neg2RootQ * cos((theta - 2 * PI) / 3) - adiv3;
        if (!AlmostDequalUlps(s[0], r) && (roots - s == 1 || !AlmostDequalUlps(s[1], r))) {
            *roots++ = r;
        }
    } else {  // we have 1 real root
        double sqrtR2MinusQ3 = sqrt(R2MinusQ3);
        double A = fabs(R) + sqrtR2MinusQ3;
        A = SkDCubeRoot(A);
        if (R > 0) {
            A = -A;
        }
        if (A != 0) {
            A += Q / A;
        }
        r = A - adiv3;
        *roots++ = r;
        if (AlmostDequalUlps((double) R2, (double) Q3)) {
            r = -A / 2 - adiv3;
            if (!AlmostDequalUlps(s[0], r)) {
                *roots++ = r;
            }
        }
    }
    return static_cast<int>(roots - s);
}

// from http://www.cs.sunysb.edu/~qin/courses/geometry/4.pdf
// c(t)  = a(1-t)^3 + 3bt(1-t)^2 + 3c(1-t)t^2 + dt^3
// c'(t) = -3a(1-t)^2 + 3b((1-t)^2 - 2t(1-t)) + 3c(2t(1-t) - t^2) + 3dt^2
//       = 3(b-a)(1-t)^2 + 6(c-b)t(1-t) + 3(d-c)t^2
static double derivative_at_t(const double* src, double t) {
    double one_t = 1 - t;
    double a = src[0];
    double b = src[2];
    double c = src[4];
    double d = src[6];
    return 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
}

// OPTIMIZE? compute t^2, t(1-t), and (1-t)^2 and pass them to another version of derivative at t?
SkDVector SkDCubic::dxdyAtT(double t) const {
    SkDVector result = { derivative_at_t(&fPts[0].fX, t), derivative_at_t(&fPts[0].fY, t) };
    if (result.fX == 0 && result.fY == 0) {
        if (t == 0) {
            result = fPts[2] - fPts[0];
        } else if (t == 1) {
            result = fPts[3] - fPts[1];
        } else {
            // incomplete
            SkDebugf("!c");
        }
        if (result.fX == 0 && result.fY == 0 && zero_or_one(t)) {
            result = fPts[3] - fPts[0];
        }
    }
    return result;
}

// OPTIMIZE? share code with formulate_F1DotF2
int SkDCubic::findInflections(double tValues[]) const {
    double Ax = fPts[1].fX - fPts[0].fX;
    double Ay = fPts[1].fY - fPts[0].fY;
    double Bx = fPts[2].fX - 2 * fPts[1].fX + fPts[0].fX;
    double By = fPts[2].fY - 2 * fPts[1].fY + fPts[0].fY;
    double Cx = fPts[3].fX + 3 * (fPts[1].fX - fPts[2].fX) - fPts[0].fX;
    double Cy = fPts[3].fY + 3 * (fPts[1].fY - fPts[2].fY) - fPts[0].fY;
    return SkDQuad::RootsValidT(Bx * Cy - By * Cx, Ax * Cy - Ay * Cx, Ax * By - Ay * Bx, tValues);
}

static void formulate_F1DotF2(const double src[], double coeff[4]) {
    double a = src[2] - src[0];
    double b = src[4] - 2 * src[2] + src[0];
    double c = src[6] + 3 * (src[2] - src[4]) - src[0];
    coeff[0] = c * c;
    coeff[1] = 3 * b * c;
    coeff[2] = 2 * b * b + c * a;
    coeff[3] = a * b;
}

/** SkDCubic'(t) = At^2 + Bt + C, where
    A = 3(-a + 3(b - c) + d)
    B = 6(a - 2b + c)
    C = 3(b - a)
    Solve for t, keeping only those that fit between 0 < t < 1
*/
int SkDCubic::FindExtrema(const double src[], double tValues[2]) {
    // we divide A,B,C by 3 to simplify
    double a = src[0];
    double b = src[2];
    double c = src[4];
    double d = src[6];
    double A = d - a + 3 * (b - c);
    double B = 2 * (a - b - b + c);
    double C = b - a;

    return SkDQuad::RootsValidT(A, B, C, tValues);
}

/*  from SkGeometry.cpp
    Looking for F' dot F'' == 0

    A = b - a
    B = c - 2b + a
    C = d - 3c + 3b - a

    F' = 3Ct^2 + 6Bt + 3A
    F'' = 6Ct + 6B

    F' dot F'' -> CCt^3 + 3BCt^2 + (2BB + CA)t + AB
*/
int SkDCubic::findMaxCurvature(double tValues[]) const {
    double coeffX[4], coeffY[4];
    int i;
    formulate_F1DotF2(&fPts[0].fX, coeffX);
    formulate_F1DotF2(&fPts[0].fY, coeffY);
    for (i = 0; i < 4; i++) {
        coeffX[i] = coeffX[i] + coeffY[i];
    }
    return RootsValidT(coeffX[0], coeffX[1], coeffX[2], coeffX[3], tValues);
}

SkDPoint SkDCubic::ptAtT(double t) const {
    if (0 == t) {
        return fPts[0];
    }
    if (1 == t) {
        return fPts[3];
    }
    double one_t = 1 - t;
    double one_t2 = one_t * one_t;
    double a = one_t2 * one_t;
    double b = 3 * one_t2 * t;
    double t2 = t * t;
    double c = 3 * one_t * t2;
    double d = t2 * t;
    SkDPoint result = {a * fPts[0].fX + b * fPts[1].fX + c * fPts[2].fX + d * fPts[3].fX,
            a * fPts[0].fY + b * fPts[1].fY + c * fPts[2].fY + d * fPts[3].fY};
    return result;
}

/*
 Given a cubic c, t1, and t2, find a small cubic segment.

 The new cubic is defined as points A, B, C, and D, where
 s1 = 1 - t1
 s2 = 1 - t2
 A = c[0]*s1*s1*s1 + 3*c[1]*s1*s1*t1 + 3*c[2]*s1*t1*t1 + c[3]*t1*t1*t1
 D = c[0]*s2*s2*s2 + 3*c[1]*s2*s2*t2 + 3*c[2]*s2*t2*t2 + c[3]*t2*t2*t2

 We don't have B or C. So We define two equations to isolate them.
 First, compute two reference T values 1/3 and 2/3 from t1 to t2:

 c(at (2*t1 + t2)/3) == E
 c(at (t1 + 2*t2)/3) == F

 Next, compute where those values must be if we know the values of B and C:

 _12   =  A*2/3 + B*1/3
 12_   =  A*1/3 + B*2/3
 _23   =  B*2/3 + C*1/3
 23_   =  B*1/3 + C*2/3
 _34   =  C*2/3 + D*1/3
 34_   =  C*1/3 + D*2/3
 _123  = (A*2/3 + B*1/3)*2/3 + (B*2/3 + C*1/3)*1/3 = A*4/9 + B*4/9 + C*1/9
 123_  = (A*1/3 + B*2/3)*1/3 + (B*1/3 + C*2/3)*2/3 = A*1/9 + B*4/9 + C*4/9
 _234  = (B*2/3 + C*1/3)*2/3 + (C*2/3 + D*1/3)*1/3 = B*4/9 + C*4/9 + D*1/9
 234_  = (B*1/3 + C*2/3)*1/3 + (C*1/3 + D*2/3)*2/3 = B*1/9 + C*4/9 + D*4/9
 _1234 = (A*4/9 + B*4/9 + C*1/9)*2/3 + (B*4/9 + C*4/9 + D*1/9)*1/3
       =  A*8/27 + B*12/27 + C*6/27 + D*1/27
       =  E
 1234_ = (A*1/9 + B*4/9 + C*4/9)*1/3 + (B*1/9 + C*4/9 + D*4/9)*2/3
       =  A*1/27 + B*6/27 + C*12/27 + D*8/27
       =  F
 E*27  =  A*8    + B*12   + C*6     + D
 F*27  =  A      + B*6    + C*12    + D*8

Group the known values on one side:

 M       = E*27 - A*8 - D     = B*12 + C* 6
 N       = F*27 - A   - D*8   = B* 6 + C*12
 M*2 - N = B*18
 N*2 - M = C*18
 B       = (M*2 - N)/18
 C       = (N*2 - M)/18
 */

static double interp_cubic_coords(const double* src, double t) {
    double ab = SkDInterp(src[0], src[2], t);
    double bc = SkDInterp(src[2], src[4], t);
    double cd = SkDInterp(src[4], src[6], t);
    double abc = SkDInterp(ab, bc, t);
    double bcd = SkDInterp(bc, cd, t);
    double abcd = SkDInterp(abc, bcd, t);
    return abcd;
}

SkDCubic SkDCubic::subDivide(double t1, double t2) const {
    if (t1 == 0 || t2 == 1) {
        if (t1 == 0 && t2 == 1) {
            return *this;
        }
        SkDCubicPair pair = chopAt(t1 == 0 ? t2 : t1);
        SkDCubic dst = t1 == 0 ? pair.first() : pair.second();
        return dst;
    }
    SkDCubic dst;
    double ax = dst[0].fX = interp_cubic_coords(&fPts[0].fX, t1);
    double ay = dst[0].fY = interp_cubic_coords(&fPts[0].fY, t1);
    double ex = interp_cubic_coords(&fPts[0].fX, (t1*2+t2)/3);
    double ey = interp_cubic_coords(&fPts[0].fY, (t1*2+t2)/3);
    double fx = interp_cubic_coords(&fPts[0].fX, (t1+t2*2)/3);
    double fy = interp_cubic_coords(&fPts[0].fY, (t1+t2*2)/3);
    double dx = dst[3].fX = interp_cubic_coords(&fPts[0].fX, t2);
    double dy = dst[3].fY = interp_cubic_coords(&fPts[0].fY, t2);
    double mx = ex * 27 - ax * 8 - dx;
    double my = ey * 27 - ay * 8 - dy;
    double nx = fx * 27 - ax - dx * 8;
    double ny = fy * 27 - ay - dy * 8;
    /* bx = */ dst[1].fX = (mx * 2 - nx) / 18;
    /* by = */ dst[1].fY = (my * 2 - ny) / 18;
    /* cx = */ dst[2].fX = (nx * 2 - mx) / 18;
    /* cy = */ dst[2].fY = (ny * 2 - my) / 18;
    // FIXME: call align() ?
    return dst;
}

void SkDCubic::subDivide(const SkDPoint& a, const SkDPoint& d,
                         double t1, double t2, SkDPoint dst[2]) const {
    SkASSERT(t1 != t2);
    // this approach assumes that the control points computed directly are accurate enough
    SkDCubic sub = subDivide(t1, t2);
    dst[0] = sub[1] + (a - sub[0]);
    dst[1] = sub[2] + (d - sub[3]);
    if (t1 == 0 || t2 == 0) {
        align(0, 1, t1 == 0 ? &dst[0] : &dst[1]);
    }
    if (t1 == 1 || t2 == 1) {
        align(3, 2, t1 == 1 ? &dst[0] : &dst[1]);
    }
    if (AlmostBequalUlps(dst[0].fX, a.fX)) {
        dst[0].fX = a.fX;
    }
    if (AlmostBequalUlps(dst[0].fY, a.fY)) {
        dst[0].fY = a.fY;
    }
    if (AlmostBequalUlps(dst[1].fX, d.fX)) {
        dst[1].fX = d.fX;
    }
    if (AlmostBequalUlps(dst[1].fY, d.fY)) {
        dst[1].fY = d.fY;
    }
}

double SkDCubic::top(const SkDCubic& dCurve, double startT, double endT, SkDPoint*topPt) const {
    double extremeTs[2];
    double topT = -1;
    int roots = SkDCubic::FindExtrema(&fPts[0].fY, extremeTs);
    for (int index = 0; index < roots; ++index) {
        double t = startT + (endT - startT) * extremeTs[index];
        SkDPoint mid = dCurve.ptAtT(t);
        if (topPt->fY > mid.fY || (topPt->fY == mid.fY && topPt->fX > mid.fX)) {
            topT = t;
            *topPt = mid;
        }
    }
    return topT;
}
