diff options
author | reed <reed@google.com> | 2015-03-20 06:01:08 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-20 06:01:08 -0700 |
commit | 40b7dd57ef1f4e91af72512d8ca57459b99d71bd (patch) | |
tree | afd50b4adccabef0ae0d3882f2c4c726c1dd5dee /src/core | |
parent | 26bf90e5d63024585a8261b224ea4387079e2751 (diff) |
use Sk2s for EvalQuadTangent and ChopQuadAt
cloned from https://codereview.chromium.org/1026633002/
BUG=skia:
Review URL: https://codereview.chromium.org/1024873003
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkGeometry.cpp | 42 | ||||
-rw-r--r-- | src/core/SkGeometry.h | 5 |
2 files changed, 44 insertions, 3 deletions
diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp index 6d14e4bb54..aea1fe5665 100644 --- a/src/core/SkGeometry.cpp +++ b/src/core/SkGeometry.cpp @@ -7,6 +7,7 @@ #include "SkGeometry.h" #include "SkMatrix.h" +#include "Sk2x.h" /** If defined, this makes eval_quad and eval_cubic do more setup (sometimes involving integer multiplies by 2 or 3, but fewer calls to SkScalarMul. @@ -127,8 +128,6 @@ void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tange } } -#include "Sk2x.h" - SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t) { SkASSERT(src); SkASSERT(t >= 0 && t <= SK_Scalar1); @@ -147,6 +146,23 @@ SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t) { return result; } +SkVector SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t) { + SkASSERT(src); + SkASSERT(t >= 0 && t <= SK_Scalar1); + + Sk2f P0 = Sk2f::Load(&src[0].fX); + Sk2f P1 = Sk2f::Load(&src[1].fX); + Sk2f P2 = Sk2f::Load(&src[2].fX); + + Sk2f B = P1 - P0; + Sk2f A = P2 - P1 - B; + Sk2f T = A * Sk2f(t) + B; + + SkVector result; + (T + T).store(&result.fX); + return result; +} + static void interp_quad_coords(const SkScalar* src, SkScalar* dst, SkScalar t) { SkScalar ab = SkScalarInterp(src[0], src[2], t); SkScalar bc = SkScalarInterp(src[2], src[4], t); @@ -165,6 +181,28 @@ void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t) { interp_quad_coords(&src[0].fY, &dst[0].fY, t); } +static inline Sk2s interp(const Sk2s& v0, const Sk2s& v1, const Sk2s& t) { + return v0 + (v1 - v0) * t; +} + +void SkChopQuadAt2(const SkPoint src[3], SkPoint dst[5], SkScalar t) { + SkASSERT(t > 0 && t < SK_Scalar1); + + Sk2s p0 = Sk2f::Load(&src[0].fX); + Sk2s p1 = Sk2f::Load(&src[1].fX); + Sk2s p2 = Sk2f::Load(&src[2].fX); + Sk2s tt = Sk2s(t); + + Sk2s p01 = interp(p0, p1, tt); + Sk2s p12 = interp(p1, p2, tt); + + p0.store(&dst[0].fX); + p01.store(&dst[1].fX); + interp(p01, p12, tt).store(&dst[2].fX); + p12.store(&dst[3].fX); + p2.store(&dst[4].fX); +} + void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]) { SkScalar x01 = SkScalarAve(src[0].fX, src[1].fX); SkScalar y01 = SkScalarAve(src[0].fY, src[1].fY); diff --git a/src/core/SkGeometry.h b/src/core/SkGeometry.h index ff863a2294..5f7aa5e7b3 100644 --- a/src/core/SkGeometry.h +++ b/src/core/SkGeometry.h @@ -17,11 +17,14 @@ int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]); /////////////////////////////////////////////////////////////////////////////// +SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t); +SkPoint SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t); +void SkChopQuadAt2(const SkPoint src[3], SkPoint dst[5], SkScalar t); + /** Set pt to the point on the src quadratic specified by t. t must be 0 <= t <= 1.0 */ void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tangent = NULL); -SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t); /** Given a src quadratic bezier, chop it at the specified t value, where 0 < t < 1, and return the two new quadratics in dst: |