diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-04-25 15:07:40 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-04-25 15:07:40 +0000 |
commit | 69afee1c8fd22affc873890cfcf766d6f5cfdcc2 (patch) | |
tree | 9434d6e0c77614aec9457cfccb8df78543a0f1cb | |
parent | 1df888bc3a502279eb46e6a71fbf257e1de940ed (diff) |
add isSimilarityTransform() and some tests
Committed on behalf of Guanqun.Lu@gmail.com
Review URL: http://codereview.appspot.com/5999050/
git-svn-id: http://skia.googlecode.com/svn/trunk@3762 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | tests/MatrixTest.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp index c188d5542f..6cf900612e 100644 --- a/tests/MatrixTest.cpp +++ b/tests/MatrixTest.cpp @@ -188,6 +188,165 @@ void test_matrix_max_stretch(skiatest::Reporter* reporter) { } } +// This function is extracted from src/gpu/SkGpuDevice.cpp, +// in order to make sure this function works correctly. +static bool isSimilarityTransformation(const SkMatrix& matrix, + SkScalar tol = SK_ScalarNearlyZero) { + if (matrix.isIdentity() || matrix.getType() == SkMatrix::kTranslate_Mask) { + return true; + } + if (matrix.hasPerspective()) { + return false; + } + + SkScalar mx = matrix.get(SkMatrix::kMScaleX); + SkScalar sx = matrix.get(SkMatrix::kMSkewX); + SkScalar my = matrix.get(SkMatrix::kMScaleY); + SkScalar sy = matrix.get(SkMatrix::kMSkewY); + + if (mx == 0 && sx == 0 && my == 0 && sy == 0) { + return false; + } + + // it has scales or skews, but it could also be rotation, check it out. + SkVector vec[2]; + vec[0].set(mx, sx); + vec[1].set(sy, my); + + return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) && + SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(), + SkScalarSquare(tol)); +} + +void test_matrix_is_similarity_transform(skiatest::Reporter* reporter) { + SkMatrix mat; + + // identity + mat.setIdentity(); + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); + + // translation only + mat.reset(); + mat.setTranslate(SkIntToScalar(100), SkIntToScalar(100)); + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); + + // scale with same size + mat.reset(); + mat.setScale(SkIntToScalar(15), SkIntToScalar(15)); + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); + + // scale with one negative + mat.reset(); + mat.setScale(SkIntToScalar(-15), SkIntToScalar(15)); + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); + + // scale with different size + mat.reset(); + mat.setScale(SkIntToScalar(15), SkIntToScalar(20)); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + + // scale with same size at a pivot point + mat.reset(); + mat.setScale(SkIntToScalar(15), SkIntToScalar(15), + SkIntToScalar(2), SkIntToScalar(2)); + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); + + // scale with different size at a pivot point + mat.reset(); + mat.setScale(SkIntToScalar(15), SkIntToScalar(20), + SkIntToScalar(2), SkIntToScalar(2)); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + + // skew with same size + mat.reset(); + mat.setSkew(SkIntToScalar(15), SkIntToScalar(15)); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + + // skew with different size + mat.reset(); + mat.setSkew(SkIntToScalar(15), SkIntToScalar(20)); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + + // skew with same size at a pivot point + mat.reset(); + mat.setSkew(SkIntToScalar(15), SkIntToScalar(15), + SkIntToScalar(2), SkIntToScalar(2)); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + + // skew with different size at a pivot point + mat.reset(); + mat.setSkew(SkIntToScalar(15), SkIntToScalar(20), + SkIntToScalar(2), SkIntToScalar(2)); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + + // perspective x + mat.reset(); + mat.setPerspX(SkScalarToPersp(SK_Scalar1 / 2)); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + + // perspective y + mat.reset(); + mat.setPerspY(SkScalarToPersp(SK_Scalar1 / 2)); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + +#if SK_SCALAR_IS_FLOAT + /* We bypass the following tests for SK_SCALAR_IS_FIXED build. + * The long discussion can be found in this issue: + * http://codereview.appspot.com/5999050/ + * In short, we haven't found a perfect way to fix the precision + * issue, i.e. the way we use tolerance in isSimilarityTransformation + * is incorrect. The situation becomes worse in fixed build, so + * we disabled rotation related tests for fixed build. + */ + + // rotate + for (int angle = 0; angle < 360; ++angle) { + mat.reset(); + mat.setRotate(SkIntToScalar(angle)); + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); + } + + // see if there are any accumulated precision issues + mat.reset(); + for (int i = 1; i < 360; i++) { + mat.postRotate(SkIntToScalar(1)); + } + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); + + // rotate + translate + mat.reset(); + mat.setRotate(SkIntToScalar(30)); + mat.postTranslate(SkIntToScalar(10), SkIntToScalar(20)); + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); + + // rotate + uniform scale + mat.reset(); + mat.setRotate(SkIntToScalar(30)); + mat.postScale(SkIntToScalar(2), SkIntToScalar(2)); + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); + + // rotate + non-uniform scale + mat.reset(); + mat.setRotate(SkIntToScalar(30)); + mat.postScale(SkIntToScalar(3), SkIntToScalar(2)); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); +#endif + + // all zero + mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + + // all zero except perspective + mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1); + REPORTER_ASSERT(reporter, !isSimilarityTransformation(mat)); + + // scales zero, only skews + mat.setAll(0, SK_Scalar1, 0, + SK_Scalar1, 0, 0, + 0, 0, SkMatrix::I()[8]); + REPORTER_ASSERT(reporter, isSimilarityTransformation(mat)); +} + void TestMatrix(skiatest::Reporter* reporter) { SkMatrix mat, inverse, iden1, iden2; @@ -299,6 +458,7 @@ void TestMatrix(skiatest::Reporter* reporter) { #endif test_matrix_max_stretch(reporter); + test_matrix_is_similarity_transform(reporter); } #include "TestClassDef.h" |