blob: 052687da341f80b04552ae455c06dec5afea47fe [file] [log] [blame]
reed@android.comed673312009-02-27 16:24:51 +00001#include "Test.h"
2#include "SkMatrix.h"
3
4static bool nearly_equal_scalar(SkScalar a, SkScalar b) {
5#ifdef SK_SCALAR_IS_FLOAT
6 const float tolerance = 0.000005f;
7#else
8 const int32_t tolerance = 3;
9#endif
10
11 return SkScalarAbs(a - b) <= tolerance;
12}
13
14static bool nearly_equal(const SkMatrix& a, const SkMatrix& b) {
15 for (int i = 0; i < 9; i++) {
16 if (!nearly_equal_scalar(a[i], b[i])) {
17 printf("not equal %g %g\n", a[i], b[i]);
18 return false;
19 }
20 }
21 return true;
22}
23
24static bool is_identity(const SkMatrix& m) {
25 SkMatrix identity;
reed@android.com80e39a72009-04-02 16:59:40 +000026 identity.reset();
reed@android.comed673312009-02-27 16:24:51 +000027 return nearly_equal(m, identity);
28}
29
reed@android.com4b7577b2009-06-29 16:14:41 +000030static void test_flatten(skiatest::Reporter* reporter, const SkMatrix& m) {
31 // add 100 in case we have a bug, I don't want to kill my stack in the test
32 char buffer[SkMatrix::kMaxFlattenSize + 100];
33 uint32_t size1 = m.flatten(NULL);
34 uint32_t size2 = m.flatten(buffer);
35 REPORTER_ASSERT(reporter, size1 == size2);
36 REPORTER_ASSERT(reporter, size1 <= SkMatrix::kMaxFlattenSize);
37
38 SkMatrix m2;
39 uint32_t size3 = m2.unflatten(buffer);
40 REPORTER_ASSERT(reporter, size1 == size2);
41 REPORTER_ASSERT(reporter, m == m2);
42
43 char buffer2[SkMatrix::kMaxFlattenSize + 100];
44 size3 = m2.flatten(buffer2);
45 REPORTER_ASSERT(reporter, size1 == size2);
46 REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0);
47}
48
reed@android.comed673312009-02-27 16:24:51 +000049void TestMatrix(skiatest::Reporter* reporter) {
50 SkMatrix mat, inverse, iden1, iden2;
51
52 mat.reset();
53 mat.setTranslate(SK_Scalar1, SK_Scalar1);
54 mat.invert(&inverse);
55 iden1.setConcat(mat, inverse);
56 REPORTER_ASSERT(reporter, is_identity(iden1));
57
58 mat.setScale(SkIntToScalar(2), SkIntToScalar(2));
59 mat.invert(&inverse);
60 iden1.setConcat(mat, inverse);
61 REPORTER_ASSERT(reporter, is_identity(iden1));
reed@android.com4b7577b2009-06-29 16:14:41 +000062 test_flatten(reporter, mat);
reed@android.comed673312009-02-27 16:24:51 +000063
64 mat.setScale(SK_Scalar1/2, SK_Scalar1/2);
65 mat.invert(&inverse);
66 iden1.setConcat(mat, inverse);
67 REPORTER_ASSERT(reporter, is_identity(iden1));
reed@android.com4b7577b2009-06-29 16:14:41 +000068 test_flatten(reporter, mat);
reed@android.comed673312009-02-27 16:24:51 +000069
70 mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0);
71 mat.postRotate(SkIntToScalar(25));
72 REPORTER_ASSERT(reporter, mat.invert(NULL));
73 mat.invert(&inverse);
74 iden1.setConcat(mat, inverse);
75 REPORTER_ASSERT(reporter, is_identity(iden1));
76 iden2.setConcat(inverse, mat);
77 REPORTER_ASSERT(reporter, is_identity(iden2));
reed@android.com4b7577b2009-06-29 16:14:41 +000078 test_flatten(reporter, mat);
79 test_flatten(reporter, iden2);
reed@android.com80e39a72009-04-02 16:59:40 +000080
reed@android.comed673312009-02-27 16:24:51 +000081 // rectStaysRect test
82 {
83 static const struct {
84 SkScalar m00, m01, m10, m11;
85 bool mStaysRect;
86 }
87 gRectStaysRectSamples[] = {
88 { 0, 0, 0, 0, false },
89 { 0, 0, 0, SK_Scalar1, false },
90 { 0, 0, SK_Scalar1, 0, false },
91 { 0, 0, SK_Scalar1, SK_Scalar1, false },
92 { 0, SK_Scalar1, 0, 0, false },
93 { 0, SK_Scalar1, 0, SK_Scalar1, false },
94 { 0, SK_Scalar1, SK_Scalar1, 0, true },
95 { 0, SK_Scalar1, SK_Scalar1, SK_Scalar1, false },
96 { SK_Scalar1, 0, 0, 0, false },
97 { SK_Scalar1, 0, 0, SK_Scalar1, true },
98 { SK_Scalar1, 0, SK_Scalar1, 0, false },
99 { SK_Scalar1, 0, SK_Scalar1, SK_Scalar1, false },
100 { SK_Scalar1, SK_Scalar1, 0, 0, false },
101 { SK_Scalar1, SK_Scalar1, 0, SK_Scalar1, false },
102 { SK_Scalar1, SK_Scalar1, SK_Scalar1, 0, false },
103 { SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, false }
104 };
reed@android.com80e39a72009-04-02 16:59:40 +0000105
reed@android.comed673312009-02-27 16:24:51 +0000106 for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) {
107 SkMatrix m;
reed@android.com80e39a72009-04-02 16:59:40 +0000108
reed@android.comed673312009-02-27 16:24:51 +0000109 m.reset();
110 m.set(SkMatrix::kMScaleX, gRectStaysRectSamples[i].m00);
111 m.set(SkMatrix::kMSkewX, gRectStaysRectSamples[i].m01);
112 m.set(SkMatrix::kMSkewY, gRectStaysRectSamples[i].m10);
113 m.set(SkMatrix::kMScaleY, gRectStaysRectSamples[i].m11);
114 REPORTER_ASSERT(reporter,
115 m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect);
116 }
117 }
118}
119
reed@android.comd8730ea2009-02-27 22:06:06 +0000120#include "TestClassDef.h"
121DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix)