MatrixTest.cpp revision 4b7577b042966657c776fd95c67f9363af57945f
1ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "Test.h"
2ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "SkMatrix.h"
3ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
4ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic bool nearly_equal_scalar(SkScalar a, SkScalar b) {
5ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#ifdef SK_SCALAR_IS_FLOAT
6ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    const float tolerance = 0.000005f;
7ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#else
8ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    const int32_t tolerance = 3;
9ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#endif
10ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
11ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return SkScalarAbs(a - b) <= tolerance;
12ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
13ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
14ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic bool nearly_equal(const SkMatrix& a, const SkMatrix& b) {
15ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    for (int i = 0; i < 9; i++) {
16ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        if (!nearly_equal_scalar(a[i], b[i])) {
17ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            printf("not equal %g %g\n", a[i], b[i]);
18ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            return false;
19ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
20ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
21ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return true;
22ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
23ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
24ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic bool is_identity(const SkMatrix& m) {
25ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkMatrix identity;
2680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com    identity.reset();
27ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return nearly_equal(m, identity);
28ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
29ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
304b7577b042966657c776fd95c67f9363af57945freed@android.comstatic void test_flatten(skiatest::Reporter* reporter, const SkMatrix& m) {
314b7577b042966657c776fd95c67f9363af57945freed@android.com    // add 100 in case we have a bug, I don't want to kill my stack in the test
324b7577b042966657c776fd95c67f9363af57945freed@android.com    char buffer[SkMatrix::kMaxFlattenSize + 100];
334b7577b042966657c776fd95c67f9363af57945freed@android.com    uint32_t size1 = m.flatten(NULL);
344b7577b042966657c776fd95c67f9363af57945freed@android.com    uint32_t size2 = m.flatten(buffer);
354b7577b042966657c776fd95c67f9363af57945freed@android.com    REPORTER_ASSERT(reporter, size1 == size2);
364b7577b042966657c776fd95c67f9363af57945freed@android.com    REPORTER_ASSERT(reporter, size1 <= SkMatrix::kMaxFlattenSize);
374b7577b042966657c776fd95c67f9363af57945freed@android.com
384b7577b042966657c776fd95c67f9363af57945freed@android.com    SkMatrix m2;
394b7577b042966657c776fd95c67f9363af57945freed@android.com    uint32_t size3 = m2.unflatten(buffer);
404b7577b042966657c776fd95c67f9363af57945freed@android.com    REPORTER_ASSERT(reporter, size1 == size2);
414b7577b042966657c776fd95c67f9363af57945freed@android.com    REPORTER_ASSERT(reporter, m == m2);
424b7577b042966657c776fd95c67f9363af57945freed@android.com
434b7577b042966657c776fd95c67f9363af57945freed@android.com    char buffer2[SkMatrix::kMaxFlattenSize + 100];
444b7577b042966657c776fd95c67f9363af57945freed@android.com    size3 = m2.flatten(buffer2);
454b7577b042966657c776fd95c67f9363af57945freed@android.com    REPORTER_ASSERT(reporter, size1 == size2);
464b7577b042966657c776fd95c67f9363af57945freed@android.com    REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0);
474b7577b042966657c776fd95c67f9363af57945freed@android.com}
484b7577b042966657c776fd95c67f9363af57945freed@android.com
49ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comvoid TestMatrix(skiatest::Reporter* reporter) {
50ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    SkMatrix    mat, inverse, iden1, iden2;
51ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
52ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.reset();
53ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.setTranslate(SK_Scalar1, SK_Scalar1);
54ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.invert(&inverse);
55ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    iden1.setConcat(mat, inverse);
56ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, is_identity(iden1));
57ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
58ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.setScale(SkIntToScalar(2), SkIntToScalar(2));
59ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.invert(&inverse);
60ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    iden1.setConcat(mat, inverse);
61ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, is_identity(iden1));
624b7577b042966657c776fd95c67f9363af57945freed@android.com    test_flatten(reporter, mat);
63ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
64ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.setScale(SK_Scalar1/2, SK_Scalar1/2);
65ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.invert(&inverse);
66ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    iden1.setConcat(mat, inverse);
67ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, is_identity(iden1));
684b7577b042966657c776fd95c67f9363af57945freed@android.com    test_flatten(reporter, mat);
69ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
70ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0);
71ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.postRotate(SkIntToScalar(25));
72ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, mat.invert(NULL));
73ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    mat.invert(&inverse);
74ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    iden1.setConcat(mat, inverse);
75ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, is_identity(iden1));
76ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    iden2.setConcat(inverse, mat);
77ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    REPORTER_ASSERT(reporter, is_identity(iden2));
784b7577b042966657c776fd95c67f9363af57945freed@android.com    test_flatten(reporter, mat);
794b7577b042966657c776fd95c67f9363af57945freed@android.com    test_flatten(reporter, iden2);
8080e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
81ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    // rectStaysRect test
82ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    {
83ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        static const struct {
84ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            SkScalar    m00, m01, m10, m11;
85ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            bool        mStaysRect;
86ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
87ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        gRectStaysRectSamples[] = {
88ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            {          0,          0,          0,           0, false },
89ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            {          0,          0,          0,  SK_Scalar1, false },
90ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            {          0,          0, SK_Scalar1,           0, false },
91ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            {          0,          0, SK_Scalar1,  SK_Scalar1, false },
92ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            {          0, SK_Scalar1,          0,           0, false },
93ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            {          0, SK_Scalar1,          0,  SK_Scalar1, false },
94ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            {          0, SK_Scalar1, SK_Scalar1,           0, true },
95ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            {          0, SK_Scalar1, SK_Scalar1,  SK_Scalar1, false },
96ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            { SK_Scalar1,          0,          0,           0, false },
97ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            { SK_Scalar1,          0,          0,  SK_Scalar1, true },
98ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            { SK_Scalar1,          0, SK_Scalar1,           0, false },
99ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            { SK_Scalar1,          0, SK_Scalar1,  SK_Scalar1, false },
100ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            { SK_Scalar1, SK_Scalar1,          0,           0, false },
101ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            { SK_Scalar1, SK_Scalar1,          0,  SK_Scalar1, false },
102ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            { SK_Scalar1, SK_Scalar1, SK_Scalar1,           0, false },
103ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            { SK_Scalar1, SK_Scalar1, SK_Scalar1,  SK_Scalar1, false }
104ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        };
10580e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
106ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) {
107ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            SkMatrix    m;
10880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
109ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            m.reset();
110ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            m.set(SkMatrix::kMScaleX, gRectStaysRectSamples[i].m00);
111ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            m.set(SkMatrix::kMSkewX,  gRectStaysRectSamples[i].m01);
112ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            m.set(SkMatrix::kMSkewY,  gRectStaysRectSamples[i].m10);
113ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            m.set(SkMatrix::kMScaleY, gRectStaysRectSamples[i].m11);
114ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            REPORTER_ASSERT(reporter,
115ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com                    m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect);
116ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
117ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
118ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
119ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
120d8730ea8b25d692c0656f8cf03f02aecfab2a17creed@android.com#include "TestClassDef.h"
121d8730ea8b25d692c0656f8cf03f02aecfab2a17creed@android.comDEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix)
122