• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "Test.h"
2 #include "SkMatrix.h"
3 
nearly_equal_scalar(SkScalar a,SkScalar b)4 static bool nearly_equal_scalar(SkScalar a, SkScalar b) {
5     // Note that we get more compounded error for multiple operations when
6     // SK_SCALAR_IS_FIXED.
7 #ifdef SK_SCALAR_IS_FLOAT
8     const SkScalar tolerance = SK_Scalar1 / 200000;
9 #else
10     const SkScalar tolerance = SK_Scalar1 / 1024;
11 #endif
12 
13     return SkScalarAbs(a - b) <= tolerance;
14 }
15 
nearly_equal(const SkMatrix & a,const SkMatrix & b)16 static bool nearly_equal(const SkMatrix& a, const SkMatrix& b) {
17     for (int i = 0; i < 9; i++) {
18         if (!nearly_equal_scalar(a[i], b[i])) {
19             printf("not equal %g %g\n", (float)a[i], (float)b[i]);
20             return false;
21         }
22     }
23     return true;
24 }
25 
is_identity(const SkMatrix & m)26 static bool is_identity(const SkMatrix& m) {
27     SkMatrix identity;
28     identity.reset();
29     return nearly_equal(m, identity);
30 }
31 
test_flatten(skiatest::Reporter * reporter,const SkMatrix & m)32 static void test_flatten(skiatest::Reporter* reporter, const SkMatrix& m) {
33     // add 100 in case we have a bug, I don't want to kill my stack in the test
34     char buffer[SkMatrix::kMaxFlattenSize + 100];
35     uint32_t size1 = m.flatten(NULL);
36     uint32_t size2 = m.flatten(buffer);
37     REPORTER_ASSERT(reporter, size1 == size2);
38     REPORTER_ASSERT(reporter, size1 <= SkMatrix::kMaxFlattenSize);
39 
40     SkMatrix m2;
41     uint32_t size3 = m2.unflatten(buffer);
42     REPORTER_ASSERT(reporter, size1 == size2);
43     REPORTER_ASSERT(reporter, m == m2);
44 
45     char buffer2[SkMatrix::kMaxFlattenSize + 100];
46     size3 = m2.flatten(buffer2);
47     REPORTER_ASSERT(reporter, size1 == size2);
48     REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0);
49 }
50 
TestMatrix(skiatest::Reporter * reporter)51 void TestMatrix(skiatest::Reporter* reporter) {
52     SkMatrix    mat, inverse, iden1, iden2;
53 
54     mat.reset();
55     mat.setTranslate(SK_Scalar1, SK_Scalar1);
56     mat.invert(&inverse);
57     iden1.setConcat(mat, inverse);
58     REPORTER_ASSERT(reporter, is_identity(iden1));
59 
60     mat.setScale(SkIntToScalar(2), SkIntToScalar(2));
61     mat.invert(&inverse);
62     iden1.setConcat(mat, inverse);
63     REPORTER_ASSERT(reporter, is_identity(iden1));
64     test_flatten(reporter, mat);
65 
66     mat.setScale(SK_Scalar1/2, SK_Scalar1/2);
67     mat.invert(&inverse);
68     iden1.setConcat(mat, inverse);
69     REPORTER_ASSERT(reporter, is_identity(iden1));
70     test_flatten(reporter, mat);
71 
72     mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0);
73     mat.postRotate(SkIntToScalar(25));
74     REPORTER_ASSERT(reporter, mat.invert(NULL));
75     mat.invert(&inverse);
76     iden1.setConcat(mat, inverse);
77     REPORTER_ASSERT(reporter, is_identity(iden1));
78     iden2.setConcat(inverse, mat);
79     REPORTER_ASSERT(reporter, is_identity(iden2));
80     test_flatten(reporter, mat);
81     test_flatten(reporter, iden2);
82 
83     // rectStaysRect test
84     {
85         static const struct {
86             SkScalar    m00, m01, m10, m11;
87             bool        mStaysRect;
88         }
89         gRectStaysRectSamples[] = {
90             {          0,          0,          0,           0, false },
91             {          0,          0,          0,  SK_Scalar1, false },
92             {          0,          0, SK_Scalar1,           0, false },
93             {          0,          0, SK_Scalar1,  SK_Scalar1, false },
94             {          0, SK_Scalar1,          0,           0, false },
95             {          0, SK_Scalar1,          0,  SK_Scalar1, false },
96             {          0, SK_Scalar1, SK_Scalar1,           0, true },
97             {          0, SK_Scalar1, SK_Scalar1,  SK_Scalar1, false },
98             { SK_Scalar1,          0,          0,           0, false },
99             { SK_Scalar1,          0,          0,  SK_Scalar1, true },
100             { SK_Scalar1,          0, SK_Scalar1,           0, false },
101             { SK_Scalar1,          0, SK_Scalar1,  SK_Scalar1, false },
102             { SK_Scalar1, SK_Scalar1,          0,           0, false },
103             { SK_Scalar1, SK_Scalar1,          0,  SK_Scalar1, false },
104             { SK_Scalar1, SK_Scalar1, SK_Scalar1,           0, false },
105             { SK_Scalar1, SK_Scalar1, SK_Scalar1,  SK_Scalar1, false }
106         };
107 
108         for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) {
109             SkMatrix    m;
110 
111             m.reset();
112             m.set(SkMatrix::kMScaleX, gRectStaysRectSamples[i].m00);
113             m.set(SkMatrix::kMSkewX,  gRectStaysRectSamples[i].m01);
114             m.set(SkMatrix::kMSkewY,  gRectStaysRectSamples[i].m10);
115             m.set(SkMatrix::kMScaleY, gRectStaysRectSamples[i].m11);
116             REPORTER_ASSERT(reporter,
117                     m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect);
118         }
119     }
120 }
121 
122 #include "TestClassDef.h"
123 DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix)
124