| Index: src/core/SkMatrix.cpp
|
| diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
|
| index 13ec7ae322d0a3ff177a372557ace12382479ab1..7334b5bc552ac48a71557f981c6af5909515e93a 100644
|
| --- a/src/core/SkMatrix.cpp
|
| +++ b/src/core/SkMatrix.cpp
|
| @@ -240,6 +240,71 @@ bool SkMatrix::preservesRightAngles(SkScalar tol) const {
|
| SkScalarSquare(tol));
|
| }
|
|
|
| +bool SkMatrix::decomposeUpper2x2(SkScalar* rotation0,
|
| + SkScalar* xScale, SkScalar* yScale,
|
| + SkScalar* rotation1) const {
|
| +
|
| + // borrowed from Jim Blinn's article "Consider the Lowly 2x2 Matrix"
|
| + // Note: he uses row vectors, so we have to do some swapping of terms
|
| + SkScalar A = fMat[kMScaleX];
|
| + SkScalar B = fMat[kMSkewX];
|
| + SkScalar C = fMat[kMSkewY];
|
| + SkScalar D = fMat[kMScaleY];
|
| +
|
| + SkScalar E = SK_ScalarHalf*(A + D);
|
| + SkScalar F = SK_ScalarHalf*(A - D);
|
| + SkScalar G = SK_ScalarHalf*(C + B);
|
| + SkScalar H = SK_ScalarHalf*(C - B);
|
| +
|
| + SkScalar sqrt0 = SkScalarSqrt(E*E + H*H);
|
| + SkScalar sqrt1 = SkScalarSqrt(F*F + G*G);
|
| +
|
| + // can't have zero yScale, must be degenerate
|
| + if (SkScalarNearlyEqual(sqrt0, sqrt1)) {
|
| + return false;
|
| + }
|
| + if (NULL != xScale) {
|
| + *xScale = sqrt0 + sqrt1;
|
| + }
|
| + if (NULL != yScale) {
|
| + *yScale = sqrt0 - sqrt1;
|
| + }
|
| +
|
| + // uniformly scaled rotation
|
| + if (SkScalarNearlyZero(F) && SkScalarNearlyZero(G)) {
|
| + SkASSERT(!SkScalarNearlyZero(E));
|
| + if (NULL != rotation0) {
|
| + *rotation0 = SkScalarATan2(H, E);
|
| + }
|
| + if (NULL != rotation1) {
|
| + *rotation1 = 0;
|
| + }
|
| + // uniformly scaled reflection
|
| + } else if (SkScalarNearlyZero(E) && SkScalarNearlyZero(H)) {
|
| + SkASSERT(!SkScalarNearlyZero(F));
|
| + if (NULL != rotation0) {
|
| + *rotation0 = -SkScalarATan2(G, F);
|
| + }
|
| + if (NULL != rotation1) {
|
| + *rotation1 = 0;
|
| + }
|
| + } else {
|
| + SkASSERT(!SkScalarNearlyZero(E));
|
| + SkASSERT(!SkScalarNearlyZero(F));
|
| +
|
| + SkScalar arctan0 = SkScalarATan2(H, E);
|
| + SkScalar arctan1 = SkScalarATan2(G, F);
|
| + if (NULL != rotation0) {
|
| + *rotation0 = SK_ScalarHalf*(arctan0 - arctan1);
|
| + }
|
| + if (NULL != rotation1) {
|
| + *rotation1 = SK_ScalarHalf*(arctan0 + arctan1);
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| void SkMatrix::setTranslate(SkScalar dx, SkScalar dy) {
|
|
|