MatrixTest.cpp revision 4b7577b042966657c776fd95c67f9363af57945f
1#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
30static 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
49void 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));
62    test_flatten(reporter, mat);
63
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));
68    test_flatten(reporter, mat);
69
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));
78    test_flatten(reporter, mat);
79    test_flatten(reporter, iden2);
80
81    // 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        };
105
106        for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) {
107            SkMatrix    m;
108
109            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
120#include "TestClassDef.h"
121DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix)
122