diff options
author | caryclark <caryclark@google.com> | 2014-12-12 09:11:23 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-12 09:11:24 -0800 |
commit | 8dd31cf69e24ff82865309781107dfab948b6a02 (patch) | |
tree | ed60702e6a075a3ec1eb992a9492a989b55b7c8e /src/gpu/GrPathUtils.cpp | |
parent | 09acfc8d1fd1723d01b7103f58a6f1502648f428 (diff) |
Extract cubic classification from gpu into geometry
Move code from the GPU path utilities into geometry so that
path ops can share.
Review URL: https://codereview.chromium.org/787763007
Diffstat (limited to 'src/gpu/GrPathUtils.cpp')
-rw-r--r-- | src/gpu/GrPathUtils.cpp | 98 |
1 files changed, 11 insertions, 87 deletions
diff --git a/src/gpu/GrPathUtils.cpp b/src/gpu/GrPathUtils.cpp index 464231a8dc..81dc103e02 100644 --- a/src/gpu/GrPathUtils.cpp +++ b/src/gpu/GrPathUtils.cpp @@ -547,50 +547,6 @@ void GrPathUtils::convertCubicToQuads(const SkPoint p[4], //////////////////////////////////////////////////////////////////////////////// -enum CubicType { - kSerpentine_CubicType, - kCusp_CubicType, - kLoop_CubicType, - kQuadratic_CubicType, - kLine_CubicType, - kPoint_CubicType -}; - -// discr(I) = d0^2 * (3*d1^2 - 4*d0*d2) -// Classification: -// discr(I) > 0 Serpentine -// discr(I) = 0 Cusp -// discr(I) < 0 Loop -// d0 = d1 = 0 Quadratic -// d0 = d1 = d2 = 0 Line -// p0 = p1 = p2 = p3 Point -static CubicType classify_cubic(const SkPoint p[4], const SkScalar d[3]) { - if (p[0] == p[1] && p[0] == p[2] && p[0] == p[3]) { - return kPoint_CubicType; - } - const SkScalar discr = d[0] * d[0] * (3.f * d[1] * d[1] - 4.f * d[0] * d[2]); - if (discr > SK_ScalarNearlyZero) { - return kSerpentine_CubicType; - } else if (discr < -SK_ScalarNearlyZero) { - return kLoop_CubicType; - } else { - if (0.f == d[0] && 0.f == d[1]) { - return (0.f == d[2] ? kLine_CubicType : kQuadratic_CubicType); - } else { - return kCusp_CubicType; - } - } -} - -// Assumes the third component of points is 1. -// Calcs p0 . (p1 x p2) -static SkScalar calc_dot_cross_cubic(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2) { - const SkScalar xComp = p0.fX * (p1.fY - p2.fY); - const SkScalar yComp = p0.fY * (p2.fX - p1.fX); - const SkScalar wComp = p1.fX * p2.fY - p1.fY * p2.fX; - return (xComp + yComp + wComp); -} - // Solves linear system to extract klm // P.K = k (similarly for l, m) // Where P is matrix of control points @@ -735,34 +691,6 @@ static void set_quadratic_klm(const SkScalar d[3], SkScalar k[4], SkScalar l[4], } } -// Calc coefficients of I(s,t) where roots of I are inflection points of curve -// I(s,t) = t*(3*d0*s^2 - 3*d1*s*t + d2*t^2) -// d0 = a1 - 2*a2+3*a3 -// d1 = -a2 + 3*a3 -// d2 = 3*a3 -// a1 = p0 . (p3 x p2) -// a2 = p1 . (p0 x p3) -// a3 = p2 . (p1 x p0) -// Places the values of d1, d2, d3 in array d passed in -static void calc_cubic_inflection_func(const SkPoint p[4], SkScalar d[3]) { - SkScalar a1 = calc_dot_cross_cubic(p[0], p[3], p[2]); - SkScalar a2 = calc_dot_cross_cubic(p[1], p[0], p[3]); - SkScalar a3 = calc_dot_cross_cubic(p[2], p[1], p[0]); - - // need to scale a's or values in later calculations will grow to high - SkScalar max = SkScalarAbs(a1); - max = SkMaxScalar(max, SkScalarAbs(a2)); - max = SkMaxScalar(max, SkScalarAbs(a3)); - max = 1.f/max; - a1 = a1 * max; - a2 = a2 * max; - a3 = a3 * max; - - d[2] = 3.f * a3; - d[1] = d[2] - a2; - d[0] = d[1] - a2 + a1; -} - int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[10], SkScalar klm[9], SkScalar klm_rev[3]) { // Variable to store the two parametric values at the loop double point @@ -770,12 +698,10 @@ int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[1 SkScalar largeS = 0.f; SkScalar d[3]; - calc_cubic_inflection_func(src, d); - - CubicType cType = classify_cubic(src, d); + SkCubicType cType = SkClassifyCubic(src, d); int chop_count = 0; - if (kLoop_CubicType == cType) { + if (kLoop_SkCubicType == cType) { 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]; @@ -834,14 +760,14 @@ int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[1 SkScalar controlL[4]; SkScalar controlM[4]; - if (kSerpentine_CubicType == cType || (kCusp_CubicType == cType && 0.f != d[0])) { + if (kSerpentine_SkCubicType == cType || (kCusp_SkCubicType == cType && 0.f != d[0])) { set_serp_klm(d, controlK, controlL, controlM); - } else if (kLoop_CubicType == cType) { + } else if (kLoop_SkCubicType == cType) { set_loop_klm(d, controlK, controlL, controlM); - } else if (kCusp_CubicType == cType) { + } else if (kCusp_SkCubicType == cType) { SkASSERT(0.f == d[0]); set_cusp_klm(d, controlK, controlL, controlM); - } else if (kQuadratic_CubicType == cType) { + } else if (kQuadratic_SkCubicType == cType) { set_quadratic_klm(d, controlK, controlL, controlM); } @@ -852,22 +778,20 @@ int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[1 void GrPathUtils::getCubicKLM(const SkPoint p[4], SkScalar klm[9]) { SkScalar d[3]; - calc_cubic_inflection_func(p, d); - - CubicType cType = classify_cubic(p, d); + SkCubicType cType = SkClassifyCubic(p, d); SkScalar controlK[4]; SkScalar controlL[4]; SkScalar controlM[4]; - if (kSerpentine_CubicType == cType || (kCusp_CubicType == cType && 0.f != d[0])) { + if (kSerpentine_SkCubicType == cType || (kCusp_SkCubicType == cType && 0.f != d[0])) { set_serp_klm(d, controlK, controlL, controlM); - } else if (kLoop_CubicType == cType) { + } else if (kLoop_SkCubicType == cType) { set_loop_klm(d, controlK, controlL, controlM); - } else if (kCusp_CubicType == cType) { + } else if (kCusp_SkCubicType == cType) { SkASSERT(0.f == d[0]); set_cusp_klm(d, controlK, controlL, controlM); - } else if (kQuadratic_CubicType == cType) { + } else if (kQuadratic_SkCubicType == cType) { set_quadratic_klm(d, controlK, controlL, controlM); } |