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
This commit is contained in:
reed@google.com 2013-01-04 17:02:33 +00:00
parent be61c05d89
commit 2fb96cc5d7
2 changed files with 43 additions and 3 deletions

View File

@ -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);

View File

@ -384,13 +384,13 @@ static void TestMatrix(skiatest::Reporter* reporter) {
iden1.setConcat(mat, inverse);
REPORTER_ASSERT(reporter, is_identity(iden1));
mat.setScale(SkIntToScalar(2), SkIntToScalar(2));
mat.setScale(SkIntToScalar(2), SkIntToScalar(4));
REPORTER_ASSERT(reporter, mat.invert(&inverse));
iden1.setConcat(mat, inverse);
REPORTER_ASSERT(reporter, is_identity(iden1));
test_flatten(reporter, mat);
mat.setScale(SK_Scalar1/2, SK_Scalar1/2);
mat.setScale(SK_Scalar1/2, SkIntToScalar(2));
REPORTER_ASSERT(reporter, mat.invert(&inverse));
iden1.setConcat(mat, inverse);
REPORTER_ASSERT(reporter, is_identity(iden1));
@ -407,6 +407,11 @@ static void TestMatrix(skiatest::Reporter* reporter) {
test_flatten(reporter, mat);
test_flatten(reporter, iden2);
mat.setScale(0, SK_Scalar1);
REPORTER_ASSERT(reporter, !mat.invert(&inverse));
mat.setScale(SK_Scalar1, 0);
REPORTER_ASSERT(reporter, !mat.invert(&inverse));
// rectStaysRect test
{
static const struct {