diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-01-04 17:02:33 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-01-04 17:02:33 +0000 |
commit | 2fb96cc5d713451216bd63d5dc8d19abc8550730 (patch) | |
tree | d97411a5a61648e62f2e23e6139982681b9fa6d1 /src | |
parent | be61c05d897bef024fde7a9f9d7b6c35855bb982 (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')
-rw-r--r-- | src/core/SkMatrix.cpp | 37 |
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); |