| Index: src/core/SkGeometry.cpp
|
| diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp
|
| index 04e396c37741d8d13d5a925e36ef0f42bb988c88..5d017981d99baa57384592a5651aeef9f1178e19 100644
|
| --- a/src/core/SkGeometry.cpp
|
| +++ b/src/core/SkGeometry.cpp
|
| @@ -950,180 +950,6 @@ bool SkChopMonoCubicAtX(SkPoint src[4], SkScalar x, SkPoint dst[7]) {
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -#ifdef SK_SUPPORT_LEGACY_ARCTO
|
| -/* Find t value for quadratic [a, b, c] = d.
|
| - Return 0 if there is no solution within [0, 1)
|
| -*/
|
| -static SkScalar quad_solve(SkScalar a, SkScalar b, SkScalar c, SkScalar d) {
|
| - // At^2 + Bt + C = d
|
| - SkScalar A = a - 2 * b + c;
|
| - SkScalar B = 2 * (b - a);
|
| - SkScalar C = a - d;
|
| -
|
| - SkScalar roots[2];
|
| - int count = SkFindUnitQuadRoots(A, B, C, roots);
|
| -
|
| - SkASSERT(count <= 1);
|
| - return count == 1 ? roots[0] : 0;
|
| -}
|
| -
|
| -/* given a quad-curve and a point (x,y), chop the quad at that point and place
|
| - the new off-curve point and endpoint into 'dest'.
|
| - Should only return false if the computed pos is the start of the curve
|
| - (i.e. root == 0)
|
| -*/
|
| -static bool truncate_last_curve(const SkPoint quad[3], SkScalar x, SkScalar y,
|
| - SkPoint* dest) {
|
| - const SkScalar* base;
|
| - SkScalar value;
|
| -
|
| - if (SkScalarAbs(x) < SkScalarAbs(y)) {
|
| - base = &quad[0].fX;
|
| - value = x;
|
| - } else {
|
| - base = &quad[0].fY;
|
| - value = y;
|
| - }
|
| -
|
| - // note: this returns 0 if it thinks value is out of range, meaning the
|
| - // root might return something outside of [0, 1)
|
| - SkScalar t = quad_solve(base[0], base[2], base[4], value);
|
| -
|
| - if (t > 0) {
|
| - SkPoint tmp[5];
|
| - SkChopQuadAt(quad, tmp, t);
|
| - dest[0] = tmp[1];
|
| - dest[1].set(x, y);
|
| - return true;
|
| - } else {
|
| - /* t == 0 means either the value triggered a root outside of [0, 1)
|
| - For our purposes, we can ignore the <= 0 roots, but we want to
|
| - catch the >= 1 roots (which given our caller, will basically mean
|
| - a root of 1, give-or-take numerical instability). If we are in the
|
| - >= 1 case, return the existing offCurve point.
|
| -
|
| - The test below checks to see if we are close to the "end" of the
|
| - curve (near base[4]). Rather than specifying a tolerance, I just
|
| - check to see if value is on to the right/left of the middle point
|
| - (depending on the direction/sign of the end points).
|
| - */
|
| - if ((base[0] < base[4] && value > base[2]) ||
|
| - (base[0] > base[4] && value < base[2])) // should root have been 1
|
| - {
|
| - dest[0] = quad[1];
|
| - dest[1].set(x, y);
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -static const SkPoint gQuadCirclePts[kSkBuildQuadArcStorage] = {
|
| -// The mid point of the quadratic arc approximation is half way between the two
|
| -// control points. The float epsilon adjustment moves the on curve point out by
|
| -// two bits, distributing the convex test error between the round rect
|
| -// approximation and the convex cross product sign equality test.
|
| -#define SK_MID_RRECT_OFFSET \
|
| - (SK_Scalar1 + SK_ScalarTanPIOver8 + FLT_EPSILON * 4) / 2
|
| - { SK_Scalar1, 0 },
|
| - { SK_Scalar1, SK_ScalarTanPIOver8 },
|
| - { SK_MID_RRECT_OFFSET, SK_MID_RRECT_OFFSET },
|
| - { SK_ScalarTanPIOver8, SK_Scalar1 },
|
| -
|
| - { 0, SK_Scalar1 },
|
| - { -SK_ScalarTanPIOver8, SK_Scalar1 },
|
| - { -SK_MID_RRECT_OFFSET, SK_MID_RRECT_OFFSET },
|
| - { -SK_Scalar1, SK_ScalarTanPIOver8 },
|
| -
|
| - { -SK_Scalar1, 0 },
|
| - { -SK_Scalar1, -SK_ScalarTanPIOver8 },
|
| - { -SK_MID_RRECT_OFFSET, -SK_MID_RRECT_OFFSET },
|
| - { -SK_ScalarTanPIOver8, -SK_Scalar1 },
|
| -
|
| - { 0, -SK_Scalar1 },
|
| - { SK_ScalarTanPIOver8, -SK_Scalar1 },
|
| - { SK_MID_RRECT_OFFSET, -SK_MID_RRECT_OFFSET },
|
| - { SK_Scalar1, -SK_ScalarTanPIOver8 },
|
| -
|
| - { SK_Scalar1, 0 }
|
| -#undef SK_MID_RRECT_OFFSET
|
| -};
|
| -
|
| -int SkBuildQuadArc(const SkVector& uStart, const SkVector& uStop,
|
| - SkRotationDirection dir, const SkMatrix* userMatrix,
|
| - SkPoint quadPoints[]) {
|
| - // rotate by x,y so that uStart is (1.0)
|
| - SkScalar x = SkPoint::DotProduct(uStart, uStop);
|
| - SkScalar y = SkPoint::CrossProduct(uStart, uStop);
|
| -
|
| - SkScalar absX = SkScalarAbs(x);
|
| - SkScalar absY = SkScalarAbs(y);
|
| -
|
| - int pointCount;
|
| -
|
| - // check for (effectively) coincident vectors
|
| - // this can happen if our angle is nearly 0 or nearly 180 (y == 0)
|
| - // ... we use the dot-prod to distinguish between 0 and 180 (x > 0)
|
| - if (absY <= SK_ScalarNearlyZero && x > 0 &&
|
| - ((y >= 0 && kCW_SkRotationDirection == dir) ||
|
| - (y <= 0 && kCCW_SkRotationDirection == dir))) {
|
| -
|
| - // just return the start-point
|
| - quadPoints[0].set(SK_Scalar1, 0);
|
| - pointCount = 1;
|
| - } else {
|
| - if (dir == kCCW_SkRotationDirection) {
|
| - y = -y;
|
| - }
|
| - // what octant (quadratic curve) is [xy] in?
|
| - int oct = 0;
|
| - bool sameSign = true;
|
| -
|
| - if (0 == y) {
|
| - oct = 4; // 180
|
| - SkASSERT(SkScalarAbs(x + SK_Scalar1) <= SK_ScalarNearlyZero);
|
| - } else if (0 == x) {
|
| - SkASSERT(absY - SK_Scalar1 <= SK_ScalarNearlyZero);
|
| - oct = y > 0 ? 2 : 6; // 90 : 270
|
| - } else {
|
| - if (y < 0) {
|
| - oct += 4;
|
| - }
|
| - if ((x < 0) != (y < 0)) {
|
| - oct += 2;
|
| - sameSign = false;
|
| - }
|
| - if ((absX < absY) == sameSign) {
|
| - oct += 1;
|
| - }
|
| - }
|
| -
|
| - int wholeCount = oct << 1;
|
| - memcpy(quadPoints, gQuadCirclePts, (wholeCount + 1) * sizeof(SkPoint));
|
| -
|
| - const SkPoint* arc = &gQuadCirclePts[wholeCount];
|
| - if (truncate_last_curve(arc, x, y, &quadPoints[wholeCount + 1])) {
|
| - wholeCount += 2;
|
| - }
|
| - pointCount = wholeCount + 1;
|
| - }
|
| -
|
| - // now handle counter-clockwise and the initial unitStart rotation
|
| - SkMatrix matrix;
|
| - matrix.setSinCos(uStart.fY, uStart.fX);
|
| - if (dir == kCCW_SkRotationDirection) {
|
| - matrix.preScale(SK_Scalar1, -SK_Scalar1);
|
| - }
|
| - if (userMatrix) {
|
| - matrix.postConcat(*userMatrix);
|
| - }
|
| - matrix.mapPoints(quadPoints, pointCount);
|
| - return pointCount;
|
| -}
|
| -#endif
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| //
|
| // NURB representation for conics. Helpful explanations at:
|
| //
|
|
|