1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/utils/SkCubicInterval.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,67 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2011 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 +#include "SkCubicInterval.h" 1.12 + 1.13 +static SkScalar eval_cubic(SkScalar c1, SkScalar c2, SkScalar c3, 1.14 + SkScalar t) { 1.15 + return SkScalarMul(SkScalarMul(SkScalarMul(c3, t) + c2, t) + c1, t); 1.16 +} 1.17 + 1.18 +static SkScalar find_cubic_t(SkScalar c1, SkScalar c2, SkScalar c3, 1.19 + SkScalar targetX) { 1.20 + SkScalar minT = 0; 1.21 + SkScalar maxT = SK_Scalar1; 1.22 + SkScalar t; 1.23 + 1.24 + for (;;) { 1.25 + t = SkScalarAve(minT, maxT); 1.26 + SkScalar x = eval_cubic(c1, c2, c3, t); 1.27 + if (SkScalarNearlyZero(x - targetX)) { 1.28 + break; 1.29 + } 1.30 + // subdivide the range and try again 1.31 + if (x < targetX) { 1.32 + minT = t; 1.33 + } else { 1.34 + maxT = t; 1.35 + } 1.36 + } 1.37 + return t; 1.38 +} 1.39 + 1.40 +/* 1.41 + a(1-t)^3 + 3bt(1-t)^2 + 3ct^2(1-t) + dt^3 1.42 + a: [0, 0] 1.43 + d: [1, 1] 1.44 + 1.45 + 3bt - 6bt^2 + 3bt^3 + 3ct^2 - 3ct^3 + t^3 1.46 + C1 = t^1: 3b 1.47 + C2 = t^2: 3c - 6b 1.48 + C3 = t^3: 3b - 3c + 1 1.49 + 1.50 + ((C3*t + C2)*t + C1)*t 1.51 + */ 1.52 +SkScalar SkEvalCubicInterval(SkScalar x1, SkScalar y1, 1.53 + SkScalar x2, SkScalar y2, 1.54 + SkScalar unitX) { 1.55 + x1 = SkScalarPin(x1, 0, SK_Scalar1); 1.56 + x2 = SkScalarPin(x2, 0, SK_Scalar1); 1.57 + unitX = SkScalarPin(unitX, 0, SK_Scalar1); 1.58 + 1.59 + // First compute our coefficients in X 1.60 + x1 *= 3; 1.61 + x2 *= 3; 1.62 + 1.63 + // now search for t given unitX 1.64 + SkScalar t = find_cubic_t(x1, x2 - 2*x1, x1 - x2 + SK_Scalar1, unitX); 1.65 + 1.66 + // now evaluate the cubic in Y 1.67 + y1 *= 3; 1.68 + y2 *= 3; 1.69 + return eval_cubic(y1, y2 - 2*y1, y1 - y2 + SK_Scalar1, t); 1.70 +}