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:
parent
be61c05d89
commit
2fb96cc5d7
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user