| Index: src/core/SkMatrix.cpp
|
| diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
|
| index 64edd67e8796a8c9ddf3c92fd55b144dd8e2980a..52ed0143b92107c32adb64b4750dbcf940bb4688 100644
|
| --- a/src/core/SkMatrix.cpp
|
| +++ b/src/core/SkMatrix.cpp
|
| @@ -170,6 +170,15 @@ bool operator==(const SkMatrix& a, const SkMatrix& b) {
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| +// helper function to determine if upper-left 2x2 of matrix is degenerate
|
| +static inline bool is_degenerate_2x2(SkScalar scaleX, SkScalar skewX,
|
| + SkScalar skewY, SkScalar scaleY) {
|
| + SkScalar perp_dot = scaleX*scaleY - skewX*skewY;
|
| + return SkScalarNearlyZero(perp_dot, SK_ScalarNearlyZero*SK_ScalarNearlyZero);
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| bool SkMatrix::isSimilarity(SkScalar tol) const {
|
| // if identity or translate matrix
|
| TypeMask mask = this->getType();
|
| @@ -189,10 +198,7 @@ bool SkMatrix::isSimilarity(SkScalar tol) const {
|
| SkScalar sx = fMat[kMSkewX];
|
| SkScalar sy = fMat[kMSkewY];
|
|
|
| - // TODO: I (rphillips) think there should be an || in here (see preservesRightAngles)
|
| - // degenerate matrix, non-similarity
|
| - if (SkScalarNearlyZero(mx) && SkScalarNearlyZero(my)
|
| - && SkScalarNearlyZero(sx) && SkScalarNearlyZero(sy)) {
|
| + if (is_degenerate_2x2(mx, sx, sy, my)) {
|
| return false;
|
| }
|
|
|
| @@ -224,9 +230,7 @@ bool SkMatrix::preservesRightAngles(SkScalar tol) const {
|
| SkScalar sx = fMat[kMSkewX];
|
| SkScalar sy = fMat[kMSkewY];
|
|
|
| - if ((SkScalarNearlyZero(mx) && SkScalarNearlyZero(sx)) ||
|
| - (SkScalarNearlyZero(my) && SkScalarNearlyZero(sy))) {
|
| - // degenerate matrix
|
| + if (is_degenerate_2x2(mx, sx, sy, my)) {
|
| return false;
|
| }
|
|
|
| @@ -1979,6 +1983,10 @@ bool SkDecomposeUpper2x2(const SkMatrix& matrix,
|
| SkScalar C = matrix[SkMatrix::kMSkewY];
|
| SkScalar D = matrix[SkMatrix::kMScaleY];
|
|
|
| + if (is_degenerate_2x2(A, B, C, D)) {
|
| + return false;
|
| + }
|
| +
|
| SkScalar E = SK_ScalarHalf*(A + D);
|
| SkScalar F = SK_ScalarHalf*(A - D);
|
| SkScalar G = SK_ScalarHalf*(C + B);
|
| @@ -1989,26 +1997,24 @@ bool SkDecomposeUpper2x2(const SkMatrix& matrix,
|
|
|
| SkScalar xs, ys, r0, r1;
|
|
|
| - // can't have zero yScale, must be degenerate
|
| - if (SkScalarNearlyEqual(sqrt0, sqrt1)) {
|
| - return false;
|
| - }
|
| xs = sqrt0 + sqrt1;
|
| ys = sqrt0 - sqrt1;
|
| + // can't have zero yScale, must be degenerate
|
| + SkASSERT(!SkScalarNearlyZero(ys));
|
|
|
| // uniformly scaled rotation
|
| if (SkScalarNearlyZero(F) && SkScalarNearlyZero(G)) {
|
| - SkASSERT(!SkScalarNearlyZero(E));
|
| + SkASSERT(!SkScalarNearlyZero(E) || !SkScalarNearlyZero(H));
|
| r0 = SkScalarATan2(H, E);
|
| r1 = 0;
|
| // uniformly scaled reflection
|
| } else if (SkScalarNearlyZero(E) && SkScalarNearlyZero(H)) {
|
| - SkASSERT(!SkScalarNearlyZero(F));
|
| + SkASSERT(!SkScalarNearlyZero(F) || !SkScalarNearlyZero(G));
|
| r0 = -SkScalarATan2(G, F);
|
| r1 = 0;
|
| } else {
|
| - SkASSERT(!SkScalarNearlyZero(E));
|
| - SkASSERT(!SkScalarNearlyZero(F));
|
| + SkASSERT(!SkScalarNearlyZero(E) || !SkScalarNearlyZero(H));
|
| + SkASSERT(!SkScalarNearlyZero(F) || !SkScalarNearlyZero(G));
|
|
|
| SkScalar arctan0 = SkScalarATan2(H, E);
|
| SkScalar arctan1 = SkScalarATan2(G, F);
|
|
|