diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/utils/SkCubicInterval.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/utils/SkCubicInterval.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,67 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SkCubicInterval.h" + +static SkScalar eval_cubic(SkScalar c1, SkScalar c2, SkScalar c3, + SkScalar t) { + return SkScalarMul(SkScalarMul(SkScalarMul(c3, t) + c2, t) + c1, t); +} + +static SkScalar find_cubic_t(SkScalar c1, SkScalar c2, SkScalar c3, + SkScalar targetX) { + SkScalar minT = 0; + SkScalar maxT = SK_Scalar1; + SkScalar t; + + for (;;) { + t = SkScalarAve(minT, maxT); + SkScalar x = eval_cubic(c1, c2, c3, t); + if (SkScalarNearlyZero(x - targetX)) { + break; + } + // subdivide the range and try again + if (x < targetX) { + minT = t; + } else { + maxT = t; + } + } + return t; +} + +/* + a(1-t)^3 + 3bt(1-t)^2 + 3ct^2(1-t) + dt^3 + a: [0, 0] + d: [1, 1] + + 3bt - 6bt^2 + 3bt^3 + 3ct^2 - 3ct^3 + t^3 + C1 = t^1: 3b + C2 = t^2: 3c - 6b + C3 = t^3: 3b - 3c + 1 + + ((C3*t + C2)*t + C1)*t + */ +SkScalar SkEvalCubicInterval(SkScalar x1, SkScalar y1, + SkScalar x2, SkScalar y2, + SkScalar unitX) { + x1 = SkScalarPin(x1, 0, SK_Scalar1); + x2 = SkScalarPin(x2, 0, SK_Scalar1); + unitX = SkScalarPin(unitX, 0, SK_Scalar1); + + // First compute our coefficients in X + x1 *= 3; + x2 *= 3; + + // now search for t given unitX + SkScalar t = find_cubic_t(x1, x2 - 2*x1, x1 - x2 + SK_Scalar1, unitX); + + // now evaluate the cubic in Y + y1 *= 3; + y2 *= 3; + return eval_cubic(y1, y2 - 2*y1, y1 - y2 + SK_Scalar1, t); +}