aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-03-20 06:01:08 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-03-20 06:01:08 -0700
commit40b7dd57ef1f4e91af72512d8ca57459b99d71bd (patch)
treeafd50b4adccabef0ae0d3882f2c4c726c1dd5dee /src/core
parent26bf90e5d63024585a8261b224ea4387079e2751 (diff)
use Sk2s for EvalQuadTangent and ChopQuadAt
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkGeometry.cpp42
-rw-r--r--src/core/SkGeometry.h5
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: