aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkMatrix.cpp
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-04 17:02:33 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-04 17:02:33 +0000
commit2fb96cc5d713451216bd63d5dc8d19abc8550730 (patch)
treed97411a5a61648e62f2e23e6139982681b9fa6d1 /src/core/SkMatrix.cpp
parentbe61c05d897bef024fde7a9f9d7b6c35855bb982 (diff)
special-case matrix invert for translate and scale
update unittest to use diff scale-x and scale-y values, and tests for non-invertible scale matrices Review URL: https://codereview.appspot.com/7027055 git-svn-id: http://skia.googlecode.com/svn/trunk@7019 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkMatrix.cpp')
-rw-r--r--src/core/SkMatrix.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
index 5c9547e8a7..6cccc39ece 100644
--- a/src/core/SkMatrix.cpp
+++ b/src/core/SkMatrix.cpp
@@ -850,7 +850,42 @@ bool SkMatrix::asAffine(SkScalar affine[6]) const {
bool SkMatrix::invertNonIdentity(SkMatrix* inv) const {
SkASSERT(!this->isIdentity());
- int isPersp = this->hasPerspective();
+
+ TypeMask mask = this->getType();
+
+ if (0 == (mask & ~(kScale_Mask | kTranslate_Mask))) {
+ if (inv) {
+ if (mask & kScale_Mask) {
+ SkScalar invX = fMat[kMScaleX];
+ SkScalar invY = fMat[kMScaleY];
+ if (0 == invX || 0 == invY) {
+ return false;
+ }
+ invX = SkScalarInvert(invX);
+ invY = SkScalarInvert(invY);
+
+ // Must be careful when writing to inv, since it may be the
+ // same memory as this.
+
+ inv->fMat[kMSkewX] = inv->fMat[kMSkewY] =
+ inv->fMat[kMPersp0] = inv->fMat[kMPersp1] = 0;
+
+ inv->fMat[kMScaleX] = invX;
+ inv->fMat[kMScaleY] = invY;
+ inv->fMat[kMPersp2] = kMatrix22Elem;
+ inv->fMat[kMTransX] = -SkScalarMul(fMat[kMTransX], invX);
+ inv->fMat[kMTransY] = -SkScalarMul(fMat[kMTransY], invY);
+
+ inv->setTypeMask(mask | kRectStaysRect_Mask);
+ } else {
+ // translate only
+ inv->setTranslate(-fMat[kMTransX], -fMat[kMTransY]);
+ }
+ }
+ return true;
+ }
+
+ int isPersp = mask & kPerspective_Mask;
int shift;
SkDetScalar scale = sk_inv_determinant(fMat, isPersp, &shift);