diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-07-29 14:43:31 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-07-29 14:43:31 +0000 |
commit | 4dcd062803fef457899add1df56e9defb667ce8d (patch) | |
tree | 8bc10eae836f4a4f01fea4a115281cf654041d57 /src/core | |
parent | 81152f4d5b040dee6b12ecff7a831616220810ec (diff) |
Matrix decomposition cleanup: Add is_degenerate_2x2(), and fix some asserts
(atan2 can take a zero x value, but both x == 0 and y == 0 is undefined).
R=reed@google.com, robertphillips@google.com
Author: jvanverth@google.com
Review URL: https://chromiumcodereview.appspot.com/20303003
git-svn-id: http://skia.googlecode.com/svn/trunk@10410 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkMatrix.cpp | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index 64edd67e87..52ed0143b9 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); |