aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-29 14:43:31 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-29 14:43:31 +0000
commit4dcd062803fef457899add1df56e9defb667ce8d (patch)
tree8bc10eae836f4a4f01fea4a115281cf654041d57 /src/core
parent81152f4d5b040dee6b12ecff7a831616220810ec (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.cpp36
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);