aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrPathUtils.cpp
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2014-12-12 09:11:23 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-12-12 09:11:24 -0800
commit8dd31cf69e24ff82865309781107dfab948b6a02 (patch)
treeed60702e6a075a3ec1eb992a9492a989b55b7c8e /src/gpu/GrPathUtils.cpp
parent09acfc8d1fd1723d01b7103f58a6f1502648f428 (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.cpp98
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);
}