Home | History | Annotate | Download | only in tests
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "Test.h"
      9 #include "SkMatrix44.h"
     10 
     11 static bool nearly_equal_scalar(SkMScalar a, SkMScalar b) {
     12     // Note that we get more compounded error for multiple operations when
     13     // SK_SCALAR_IS_FIXED.
     14 #ifdef SK_SCALAR_IS_FLOAT
     15     const SkScalar tolerance = SK_Scalar1 / 200000;
     16 #else
     17     const SkScalar tolerance = SK_Scalar1 / 1024;
     18 #endif
     19 
     20     return SkScalarAbs(a - b) <= tolerance;
     21 }
     22 
     23 template <typename T> void assert16(skiatest::Reporter* reporter, const T data[],
     24                                     T m0,  T m1,  T m2,  T m3,
     25                                     T m4,  T m5,  T m6,  T m7,
     26                                     T m8,  T m9,  T m10, T m11,
     27                                     T m12, T m13, T m14, T m15) {
     28     REPORTER_ASSERT(reporter, data[0] == m0);
     29     REPORTER_ASSERT(reporter, data[1] == m1);
     30     REPORTER_ASSERT(reporter, data[2] == m2);
     31     REPORTER_ASSERT(reporter, data[3] == m3);
     32 
     33     REPORTER_ASSERT(reporter, data[4] == m4);
     34     REPORTER_ASSERT(reporter, data[5] == m5);
     35     REPORTER_ASSERT(reporter, data[6] == m6);
     36     REPORTER_ASSERT(reporter, data[7] == m7);
     37 
     38     REPORTER_ASSERT(reporter, data[8] == m8);
     39     REPORTER_ASSERT(reporter, data[9] == m9);
     40     REPORTER_ASSERT(reporter, data[10] == m10);
     41     REPORTER_ASSERT(reporter, data[11] == m11);
     42 
     43     REPORTER_ASSERT(reporter, data[12] == m12);
     44     REPORTER_ASSERT(reporter, data[13] == m13);
     45     REPORTER_ASSERT(reporter, data[14] == m14);
     46     REPORTER_ASSERT(reporter, data[15] == m15);
     47 }
     48 
     49 static bool nearly_equal(const SkMatrix44& a, const SkMatrix44& b) {
     50     for (int i = 0; i < 4; ++i) {
     51         for (int j = 0; j < 4; ++j) {
     52             if (!nearly_equal_scalar(a.get(i, j), b.get(i, j))) {
     53                 printf("not equal %g %g\n", a.get(i, j), b.get(i, j));
     54                 return false;
     55             }
     56         }
     57     }
     58     return true;
     59 }
     60 
     61 static bool is_identity(const SkMatrix44& m) {
     62     SkMatrix44 identity;
     63     identity.reset();
     64     return nearly_equal(m, identity);
     65 }
     66 
     67 static void test_common_angles(skiatest::Reporter* reporter) {
     68     SkMatrix44 rot;
     69     // Test precision of rotation in common cases
     70     int common_angles[] = { 0, 90, -90, 180, -180, 270, -270, 360, -360 };
     71     for (int i = 0; i < 9; ++i) {
     72         rot.setRotateDegreesAbout(0, 0, -1, common_angles[i]);
     73 
     74         SkMatrix rot3x3 = rot;
     75         REPORTER_ASSERT(reporter, rot3x3.rectStaysRect());
     76     }
     77 }
     78 
     79 void TestMatrix44(skiatest::Reporter* reporter) {
     80 #ifdef SK_SCALAR_IS_FLOAT
     81     SkMatrix44 mat, inverse, iden1, iden2, rot;
     82 
     83     mat.reset();
     84     mat.setTranslate(SK_Scalar1, SK_Scalar1, SK_Scalar1);
     85     mat.invert(&inverse);
     86     iden1.setConcat(mat, inverse);
     87     REPORTER_ASSERT(reporter, is_identity(iden1));
     88 
     89     mat.setScale(SkIntToScalar(2), SkIntToScalar(2), SkIntToScalar(2));
     90     mat.invert(&inverse);
     91     iden1.setConcat(mat, inverse);
     92     REPORTER_ASSERT(reporter, is_identity(iden1));
     93 
     94     mat.setScale(SK_Scalar1/2, SK_Scalar1/2, SK_Scalar1/2);
     95     mat.invert(&inverse);
     96     iden1.setConcat(mat, inverse);
     97     REPORTER_ASSERT(reporter, is_identity(iden1));
     98 
     99     mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20));
    100     rot.setRotateDegreesAbout(
    101         SkIntToScalar(0),
    102         SkIntToScalar(0),
    103         SkIntToScalar(-1),
    104         SkIntToScalar(90));
    105     mat.postConcat(rot);
    106     REPORTER_ASSERT(reporter, mat.invert(NULL));
    107     mat.invert(&inverse);
    108     iden1.setConcat(mat, inverse);
    109     REPORTER_ASSERT(reporter, is_identity(iden1));
    110     iden2.setConcat(inverse, mat);
    111     REPORTER_ASSERT(reporter, is_identity(iden2));
    112 
    113     // test rol/col Major getters
    114     {
    115         mat.setTranslate(2, 3, 4);
    116         float dataf[16];
    117         double datad[16];
    118 
    119         mat.asColMajorf(dataf);
    120         assert16<float>(reporter, dataf,
    121                  1, 0, 0, 0,
    122                  0, 1, 0, 0,
    123                  0, 0, 1, 0,
    124                  2, 3, 4, 1);
    125         mat.asColMajord(datad);
    126         assert16<double>(reporter, datad, 1, 0, 0, 0,
    127                         0, 1, 0, 0,
    128                         0, 0, 1, 0,
    129                         2, 3, 4, 1);
    130         mat.asRowMajorf(dataf);
    131         assert16<float>(reporter, dataf, 1, 0, 0, 2,
    132                         0, 1, 0, 3,
    133                         0, 0, 1, 4,
    134                         0, 0, 0, 1);
    135         mat.asRowMajord(datad);
    136         assert16<double>(reporter, datad, 1, 0, 0, 2,
    137                         0, 1, 0, 3,
    138                         0, 0, 1, 4,
    139                         0, 0, 0, 1);
    140     }
    141 
    142 #if 0   // working on making this pass
    143     test_common_angles(reporter);
    144 #endif
    145 #endif
    146 }
    147 
    148 #include "TestClassDef.h"
    149 DEFINE_TESTCLASS("Matrix44", Matrix44TestClass, TestMatrix44)
    150