1#include "Test.h"
2#include "SkMatrix44.h"
3
4static 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
16static bool nearly_equal(const SkMatrix44& a, const SkMatrix44& b) {
17    for (int i = 0; i < 4; ++i) {
18        for (int j = 0; j < 4; ++j) {
19            if (!nearly_equal_scalar(a.get(i, j), b.get(i, j))) {
20                printf("not equal %g %g\n", (float)a.get(i, j), (float)b.get(i, j));
21                return false;
22            }
23        }
24    }
25    return true;
26}
27
28static bool is_identity(const SkMatrix44& m) {
29    SkMatrix44 identity;
30    identity.reset();
31    return nearly_equal(m, identity);
32}
33
34
35void TestMatrix44(skiatest::Reporter* reporter) {
36    SkMatrix44 mat, inverse, iden1, iden2, rot;
37
38    mat.reset();
39    mat.setTranslate(SK_Scalar1, SK_Scalar1, SK_Scalar1);
40    mat.invert(&inverse);
41    iden1.setConcat(mat, inverse);
42    REPORTER_ASSERT(reporter, is_identity(iden1));
43
44    mat.setScale(SkIntToScalar(2), SkIntToScalar(2), SkIntToScalar(2));
45    mat.invert(&inverse);
46    iden1.setConcat(mat, inverse);
47    REPORTER_ASSERT(reporter, is_identity(iden1));
48
49    mat.setScale(SK_Scalar1/2, SK_Scalar1/2, SK_Scalar1/2);
50    mat.invert(&inverse);
51    iden1.setConcat(mat, inverse);
52    REPORTER_ASSERT(reporter, is_identity(iden1));
53
54    mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20));
55    rot.setRotateDegreesAbout(
56        SkIntToScalar(0),
57        SkIntToScalar(0),
58        SkIntToScalar(-1),
59        SkIntToScalar(90));
60    mat.postConcat(rot);
61    REPORTER_ASSERT(reporter, mat.invert(NULL));
62    mat.invert(&inverse);
63    iden1.setConcat(mat, inverse);
64    REPORTER_ASSERT(reporter, is_identity(iden1));
65    iden2.setConcat(inverse, mat);
66    REPORTER_ASSERT(reporter, is_identity(iden2));
67}
68
69#include "TestClassDef.h"
70DEFINE_TESTCLASS("Matrix44", Matrix44TestClass, TestMatrix44)
71