MatrixTest.cpp revision ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976e
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "Test.h" 9ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "SkMatrix.h" 10ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 11ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic bool nearly_equal_scalar(SkScalar a, SkScalar b) { 122047f00e4698f83499ab91911999a65c21a951c9epoger@google.com // Note that we get more compounded error for multiple operations when 132047f00e4698f83499ab91911999a65c21a951c9epoger@google.com // SK_SCALAR_IS_FIXED. 14ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#ifdef SK_SCALAR_IS_FLOAT 152047f00e4698f83499ab91911999a65c21a951c9epoger@google.com const SkScalar tolerance = SK_Scalar1 / 200000; 16ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#else 172047f00e4698f83499ab91911999a65c21a951c9epoger@google.com const SkScalar tolerance = SK_Scalar1 / 1024; 18ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#endif 19ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 20ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com return SkScalarAbs(a - b) <= tolerance; 21ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com} 22ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 23ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic bool nearly_equal(const SkMatrix& a, const SkMatrix& b) { 24ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com for (int i = 0; i < 9; i++) { 25ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com if (!nearly_equal_scalar(a[i], b[i])) { 26d41344553163085bfcfaf7d5882c6028934f8e3breed@android.com printf("not equal %g %g\n", (float)a[i], (float)b[i]); 27ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com return false; 28ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 29ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 30ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com return true; 31ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com} 32ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 33ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic bool is_identity(const SkMatrix& m) { 34ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com SkMatrix identity; 3580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com identity.reset(); 36ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com return nearly_equal(m, identity); 37ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com} 38ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 394b7577b042966657c776fd95c67f9363af57945freed@android.comstatic void test_flatten(skiatest::Reporter* reporter, const SkMatrix& m) { 404b7577b042966657c776fd95c67f9363af57945freed@android.com // add 100 in case we have a bug, I don't want to kill my stack in the test 414b7577b042966657c776fd95c67f9363af57945freed@android.com char buffer[SkMatrix::kMaxFlattenSize + 100]; 424b7577b042966657c776fd95c67f9363af57945freed@android.com uint32_t size1 = m.flatten(NULL); 434b7577b042966657c776fd95c67f9363af57945freed@android.com uint32_t size2 = m.flatten(buffer); 444b7577b042966657c776fd95c67f9363af57945freed@android.com REPORTER_ASSERT(reporter, size1 == size2); 454b7577b042966657c776fd95c67f9363af57945freed@android.com REPORTER_ASSERT(reporter, size1 <= SkMatrix::kMaxFlattenSize); 464b7577b042966657c776fd95c67f9363af57945freed@android.com 474b7577b042966657c776fd95c67f9363af57945freed@android.com SkMatrix m2; 484b7577b042966657c776fd95c67f9363af57945freed@android.com uint32_t size3 = m2.unflatten(buffer); 494b7577b042966657c776fd95c67f9363af57945freed@android.com REPORTER_ASSERT(reporter, size1 == size2); 504b7577b042966657c776fd95c67f9363af57945freed@android.com REPORTER_ASSERT(reporter, m == m2); 514b7577b042966657c776fd95c67f9363af57945freed@android.com 524b7577b042966657c776fd95c67f9363af57945freed@android.com char buffer2[SkMatrix::kMaxFlattenSize + 100]; 534b7577b042966657c776fd95c67f9363af57945freed@android.com size3 = m2.flatten(buffer2); 544b7577b042966657c776fd95c67f9363af57945freed@android.com REPORTER_ASSERT(reporter, size1 == size2); 554b7577b042966657c776fd95c67f9363af57945freed@android.com REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0); 564b7577b042966657c776fd95c67f9363af57945freed@android.com} 574b7577b042966657c776fd95c67f9363af57945freed@android.com 58ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comvoid TestMatrix(skiatest::Reporter* reporter) { 59ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com SkMatrix mat, inverse, iden1, iden2; 60ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 61ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.reset(); 62ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.setTranslate(SK_Scalar1, SK_Scalar1); 63ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.invert(&inverse); 64ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com iden1.setConcat(mat, inverse); 65ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com REPORTER_ASSERT(reporter, is_identity(iden1)); 66ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 67ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.setScale(SkIntToScalar(2), SkIntToScalar(2)); 68ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.invert(&inverse); 69ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com iden1.setConcat(mat, inverse); 70ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com REPORTER_ASSERT(reporter, is_identity(iden1)); 714b7577b042966657c776fd95c67f9363af57945freed@android.com test_flatten(reporter, mat); 72ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 73ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.setScale(SK_Scalar1/2, SK_Scalar1/2); 74ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.invert(&inverse); 75ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com iden1.setConcat(mat, inverse); 76ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com REPORTER_ASSERT(reporter, is_identity(iden1)); 774b7577b042966657c776fd95c67f9363af57945freed@android.com test_flatten(reporter, mat); 78ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 79ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0); 80ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.postRotate(SkIntToScalar(25)); 81ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com REPORTER_ASSERT(reporter, mat.invert(NULL)); 82ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com mat.invert(&inverse); 83ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com iden1.setConcat(mat, inverse); 84ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com REPORTER_ASSERT(reporter, is_identity(iden1)); 85ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com iden2.setConcat(inverse, mat); 86ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com REPORTER_ASSERT(reporter, is_identity(iden2)); 874b7577b042966657c776fd95c67f9363af57945freed@android.com test_flatten(reporter, mat); 884b7577b042966657c776fd95c67f9363af57945freed@android.com test_flatten(reporter, iden2); 8980e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com 90ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com // rectStaysRect test 91ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { 92ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com static const struct { 93ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com SkScalar m00, m01, m10, m11; 94ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com bool mStaysRect; 95ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 96ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com gRectStaysRectSamples[] = { 97ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { 0, 0, 0, 0, false }, 98ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { 0, 0, 0, SK_Scalar1, false }, 99ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { 0, 0, SK_Scalar1, 0, false }, 100ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { 0, 0, SK_Scalar1, SK_Scalar1, false }, 101ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { 0, SK_Scalar1, 0, 0, false }, 102ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { 0, SK_Scalar1, 0, SK_Scalar1, false }, 103ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { 0, SK_Scalar1, SK_Scalar1, 0, true }, 104ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { 0, SK_Scalar1, SK_Scalar1, SK_Scalar1, false }, 105ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { SK_Scalar1, 0, 0, 0, false }, 106ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { SK_Scalar1, 0, 0, SK_Scalar1, true }, 107ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { SK_Scalar1, 0, SK_Scalar1, 0, false }, 108ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { SK_Scalar1, 0, SK_Scalar1, SK_Scalar1, false }, 109ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { SK_Scalar1, SK_Scalar1, 0, 0, false }, 110ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { SK_Scalar1, SK_Scalar1, 0, SK_Scalar1, false }, 111ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { SK_Scalar1, SK_Scalar1, SK_Scalar1, 0, false }, 112ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com { SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, false } 113ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com }; 11480e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com 115ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) { 116ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com SkMatrix m; 11780e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com 118ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com m.reset(); 119ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com m.set(SkMatrix::kMScaleX, gRectStaysRectSamples[i].m00); 120ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com m.set(SkMatrix::kMSkewX, gRectStaysRectSamples[i].m01); 121ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com m.set(SkMatrix::kMSkewY, gRectStaysRectSamples[i].m10); 122ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com m.set(SkMatrix::kMScaleY, gRectStaysRectSamples[i].m11); 123ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com REPORTER_ASSERT(reporter, 124ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect); 125ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 126ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com } 1271ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com 128ba7983e55ce15ddcd5534011935178760164fb9dbungeman@google.com mat.reset(); 1291ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com mat.set(SkMatrix::kMScaleX, SkIntToScalar(1)); 1301ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com mat.set(SkMatrix::kMSkewX, SkIntToScalar(2)); 1311ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com mat.set(SkMatrix::kMTransX, SkIntToScalar(3)); 1321ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com mat.set(SkMatrix::kMSkewY, SkIntToScalar(4)); 1331ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com mat.set(SkMatrix::kMScaleY, SkIntToScalar(5)); 1341ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com mat.set(SkMatrix::kMTransY, SkIntToScalar(6)); 1351ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com SkScalar affine[6]; 1361ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com REPORTER_ASSERT(reporter, mat.asAffine(affine)); 1371ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com 1381ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com #define affineEqual(e) affine[SkMatrix::kA##e] == mat.get(SkMatrix::kM##e) 1391ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com REPORTER_ASSERT(reporter, affineEqual(ScaleX)); 1401ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com REPORTER_ASSERT(reporter, affineEqual(SkewY)); 1411ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com REPORTER_ASSERT(reporter, affineEqual(SkewX)); 1421ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com REPORTER_ASSERT(reporter, affineEqual(ScaleY)); 1431ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com REPORTER_ASSERT(reporter, affineEqual(TransX)); 1441ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com REPORTER_ASSERT(reporter, affineEqual(TransY)); 1451ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com #undef affineEqual 1461ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com 1471ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com mat.set(SkMatrix::kMPersp1, SkIntToScalar(1)); 1481ddd7c39289b7dd18537fdac4b630e378cd78842bungeman@google.com REPORTER_ASSERT(reporter, !mat.asAffine(affine)); 149ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com} 150ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com 151d8730ea8b25d692c0656f8cf03f02aecfab2a17creed@android.com#include "TestClassDef.h" 152d8730ea8b25d692c0656f8cf03f02aecfab2a17creed@android.comDEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix) 153