blob: 1e4e341f2bc85dd7f8525e538b658567bffb62c0 [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;
26 identity.reset();
27 return nearly_equal(m, identity);
28}
29
30void TestMatrix(skiatest::Reporter* reporter) {
31 SkMatrix mat, inverse, iden1, iden2;
32
33 mat.reset();
34 mat.setTranslate(SK_Scalar1, SK_Scalar1);
35 mat.invert(&inverse);
36 iden1.setConcat(mat, inverse);
37 REPORTER_ASSERT(reporter, is_identity(iden1));
38
39 mat.setScale(SkIntToScalar(2), SkIntToScalar(2));
40 mat.invert(&inverse);
41 iden1.setConcat(mat, inverse);
42 REPORTER_ASSERT(reporter, is_identity(iden1));
43
44 mat.setScale(SK_Scalar1/2, SK_Scalar1/2);
45 mat.invert(&inverse);
46 iden1.setConcat(mat, inverse);
47 REPORTER_ASSERT(reporter, is_identity(iden1));
48
49 mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0);
50 mat.postRotate(SkIntToScalar(25));
51 REPORTER_ASSERT(reporter, mat.invert(NULL));
52 mat.invert(&inverse);
53 iden1.setConcat(mat, inverse);
54 REPORTER_ASSERT(reporter, is_identity(iden1));
55 iden2.setConcat(inverse, mat);
56 REPORTER_ASSERT(reporter, is_identity(iden2));
57
58 // rectStaysRect test
59 {
60 static const struct {
61 SkScalar m00, m01, m10, m11;
62 bool mStaysRect;
63 }
64 gRectStaysRectSamples[] = {
65 { 0, 0, 0, 0, false },
66 { 0, 0, 0, SK_Scalar1, false },
67 { 0, 0, SK_Scalar1, 0, false },
68 { 0, 0, SK_Scalar1, SK_Scalar1, false },
69 { 0, SK_Scalar1, 0, 0, false },
70 { 0, SK_Scalar1, 0, SK_Scalar1, false },
71 { 0, SK_Scalar1, SK_Scalar1, 0, true },
72 { 0, SK_Scalar1, SK_Scalar1, SK_Scalar1, false },
73 { SK_Scalar1, 0, 0, 0, false },
74 { SK_Scalar1, 0, 0, SK_Scalar1, true },
75 { SK_Scalar1, 0, SK_Scalar1, 0, false },
76 { SK_Scalar1, 0, SK_Scalar1, SK_Scalar1, false },
77 { SK_Scalar1, SK_Scalar1, 0, 0, false },
78 { SK_Scalar1, SK_Scalar1, 0, SK_Scalar1, false },
79 { SK_Scalar1, SK_Scalar1, SK_Scalar1, 0, false },
80 { SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, false }
81 };
82
83 for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) {
84 SkMatrix m;
85
86 m.reset();
87 m.set(SkMatrix::kMScaleX, gRectStaysRectSamples[i].m00);
88 m.set(SkMatrix::kMSkewX, gRectStaysRectSamples[i].m01);
89 m.set(SkMatrix::kMSkewY, gRectStaysRectSamples[i].m10);
90 m.set(SkMatrix::kMScaleY, gRectStaysRectSamples[i].m11);
91 REPORTER_ASSERT(reporter,
92 m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect);
93 }
94 }
95}
96
97///////////////////////////////////////////////////////////////////////////////
98
99namespace skiatest {
100
101 class MatrixTest : public Test {
102 public:
103 static Test* Factory(void*) {
104 return SkNEW(MatrixTest);
105 }
106
107 protected:
108 virtual void onGetName(SkString* name) {
109 name->set("Matrix");
110 }
111
112 virtual void onRun(Reporter* reporter) {
113 TestMatrix(reporter);
114 }
115 };
116
117 static TestRegistry gReg(MatrixTest::Factory);
118}
119