From 2fb96cc5d713451216bd63d5dc8d19abc8550730 Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Fri, 4 Jan 2013 17:02:33 +0000 Subject: 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 --- src/core/SkMatrix.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'src/core/SkMatrix.cpp') 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); -- cgit v1.2.3