| epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 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 |  */ | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 8 | #include "Test.h" | 
| tomhudson@google.com | 889bd8b | 2011-09-27 17:38:17 +0000 | [diff] [blame] | 9 | #include "SkMath.h" | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 10 | #include "SkMatrix.h" | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 11 | #include "SkMatrixUtils.h" | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 12 | #include "SkRandom.h" | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 13 |  | 
 | 14 | static bool nearly_equal_scalar(SkScalar a, SkScalar b) { | 
| epoger@google.com | 2047f00 | 2011-05-17 17:36:59 +0000 | [diff] [blame] | 15 |     // Note that we get more compounded error for multiple operations when | 
 | 16 |     // SK_SCALAR_IS_FIXED. | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 17 | #ifdef SK_SCALAR_IS_FLOAT | 
| epoger@google.com | 2047f00 | 2011-05-17 17:36:59 +0000 | [diff] [blame] | 18 |     const SkScalar tolerance = SK_Scalar1 / 200000; | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 19 | #else | 
| epoger@google.com | 2047f00 | 2011-05-17 17:36:59 +0000 | [diff] [blame] | 20 |     const SkScalar tolerance = SK_Scalar1 / 1024; | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 21 | #endif | 
 | 22 |  | 
 | 23 |     return SkScalarAbs(a - b) <= tolerance; | 
 | 24 | } | 
 | 25 |  | 
 | 26 | static bool nearly_equal(const SkMatrix& a, const SkMatrix& b) { | 
 | 27 |     for (int i = 0; i < 9; i++) { | 
 | 28 |         if (!nearly_equal_scalar(a[i], b[i])) { | 
| bungeman@google.com | fab44db | 2013-10-11 18:50:45 +0000 | [diff] [blame] | 29 |             SkDebugf("not equal %g %g\n", (float)a[i], (float)b[i]); | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 30 |             return false; | 
 | 31 |         } | 
 | 32 |     } | 
 | 33 |     return true; | 
 | 34 | } | 
 | 35 |  | 
| bsalomon@google.com | 8fe84b5 | 2012-03-26 15:24:27 +0000 | [diff] [blame] | 36 | static bool are_equal(skiatest::Reporter* reporter, | 
 | 37 |                       const SkMatrix& a, | 
 | 38 |                       const SkMatrix& b) { | 
 | 39 |     bool equal = a == b; | 
 | 40 |     bool cheapEqual = a.cheapEqualTo(b); | 
 | 41 |     if (equal != cheapEqual) { | 
| djsollen@google.com | 4bd2bdb | 2013-03-08 18:35:13 +0000 | [diff] [blame] | 42 | #ifdef SK_SCALAR_IS_FLOAT | 
| bsalomon@google.com | 39d4f3a | 2012-03-26 17:25:45 +0000 | [diff] [blame] | 43 |         if (equal) { | 
| bsalomon@google.com | 8fe84b5 | 2012-03-26 15:24:27 +0000 | [diff] [blame] | 44 |             bool foundZeroSignDiff = false; | 
 | 45 |             for (int i = 0; i < 9; ++i) { | 
 | 46 |                 float aVal = a.get(i); | 
 | 47 |                 float bVal = b.get(i); | 
| bsalomon@google.com | 373ebc6 | 2012-09-26 13:08:56 +0000 | [diff] [blame] | 48 |                 int aValI = *SkTCast<int*>(&aVal); | 
 | 49 |                 int bValI = *SkTCast<int*>(&bVal); | 
| bsalomon@google.com | 8fe84b5 | 2012-03-26 15:24:27 +0000 | [diff] [blame] | 50 |                 if (0 == aVal && 0 == bVal && aValI != bValI) { | 
 | 51 |                     foundZeroSignDiff = true; | 
 | 52 |                 } else { | 
 | 53 |                     REPORTER_ASSERT(reporter, aVal == bVal && aValI == aValI); | 
 | 54 |                 } | 
 | 55 |             } | 
 | 56 |             REPORTER_ASSERT(reporter, foundZeroSignDiff); | 
 | 57 |         } else { | 
 | 58 |             bool foundNaN = false; | 
 | 59 |             for (int i = 0; i < 9; ++i) { | 
 | 60 |                 float aVal = a.get(i); | 
 | 61 |                 float bVal = b.get(i); | 
| bsalomon@google.com | 373ebc6 | 2012-09-26 13:08:56 +0000 | [diff] [blame] | 62 |                 int aValI = *SkTCast<int*>(&aVal); | 
 | 63 |                 int bValI = *SkTCast<int*>(&bVal); | 
| bsalomon@google.com | 8fe84b5 | 2012-03-26 15:24:27 +0000 | [diff] [blame] | 64 |                 if (sk_float_isnan(aVal) && aValI == bValI) { | 
 | 65 |                     foundNaN = true; | 
 | 66 |                 } else { | 
 | 67 |                     REPORTER_ASSERT(reporter, aVal == bVal && aValI == bValI); | 
 | 68 |                 } | 
 | 69 |             } | 
 | 70 |             REPORTER_ASSERT(reporter, foundNaN); | 
 | 71 |         } | 
 | 72 | #else | 
 | 73 |         REPORTER_ASSERT(reporter, false); | 
 | 74 | #endif | 
 | 75 |     } | 
 | 76 |     return equal; | 
 | 77 | } | 
 | 78 |  | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 79 | static bool is_identity(const SkMatrix& m) { | 
 | 80 |     SkMatrix identity; | 
| reed@android.com | 80e39a7 | 2009-04-02 16:59:40 +0000 | [diff] [blame] | 81 |     identity.reset(); | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 82 |     return nearly_equal(m, identity); | 
 | 83 | } | 
 | 84 |  | 
| reed@google.com | 97cd69c | 2012-10-12 14:35:48 +0000 | [diff] [blame] | 85 | static void test_matrix_recttorect(skiatest::Reporter* reporter) { | 
 | 86 |     SkRect src, dst; | 
 | 87 |     SkMatrix matrix; | 
| skia.committer@gmail.com | f57c01b | 2012-10-13 02:01:56 +0000 | [diff] [blame] | 88 |  | 
| reed@google.com | 97cd69c | 2012-10-12 14:35:48 +0000 | [diff] [blame] | 89 |     src.set(0, 0, SK_Scalar1*10, SK_Scalar1*10); | 
 | 90 |     dst = src; | 
 | 91 |     matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit); | 
 | 92 |     REPORTER_ASSERT(reporter, SkMatrix::kIdentity_Mask == matrix.getType()); | 
 | 93 |     REPORTER_ASSERT(reporter, matrix.rectStaysRect()); | 
| skia.committer@gmail.com | f57c01b | 2012-10-13 02:01:56 +0000 | [diff] [blame] | 94 |  | 
| reed@google.com | 97cd69c | 2012-10-12 14:35:48 +0000 | [diff] [blame] | 95 |     dst.offset(SK_Scalar1, SK_Scalar1); | 
 | 96 |     matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit); | 
 | 97 |     REPORTER_ASSERT(reporter, SkMatrix::kTranslate_Mask == matrix.getType()); | 
 | 98 |     REPORTER_ASSERT(reporter, matrix.rectStaysRect()); | 
| skia.committer@gmail.com | f57c01b | 2012-10-13 02:01:56 +0000 | [diff] [blame] | 99 |  | 
| reed@google.com | 97cd69c | 2012-10-12 14:35:48 +0000 | [diff] [blame] | 100 |     dst.fRight += SK_Scalar1; | 
 | 101 |     matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit); | 
| skia.committer@gmail.com | e659c2e | 2012-12-04 02:01:25 +0000 | [diff] [blame] | 102 |     REPORTER_ASSERT(reporter, | 
| robertphillips@google.com | 93f0332 | 2012-12-03 17:35:19 +0000 | [diff] [blame] | 103 |                     (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask) == matrix.getType()); | 
| reed@google.com | 97cd69c | 2012-10-12 14:35:48 +0000 | [diff] [blame] | 104 |     REPORTER_ASSERT(reporter, matrix.rectStaysRect()); | 
 | 105 |  | 
 | 106 |     dst = src; | 
 | 107 |     dst.fRight = src.fRight * 2; | 
 | 108 |     matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit); | 
 | 109 |     REPORTER_ASSERT(reporter, SkMatrix::kScale_Mask == matrix.getType()); | 
 | 110 |     REPORTER_ASSERT(reporter, matrix.rectStaysRect()); | 
 | 111 | } | 
 | 112 |  | 
| reed@android.com | 4b7577b | 2009-06-29 16:14:41 +0000 | [diff] [blame] | 113 | static void test_flatten(skiatest::Reporter* reporter, const SkMatrix& m) { | 
 | 114 |     // add 100 in case we have a bug, I don't want to kill my stack in the test | 
| commit-bot@chromium.org | 4faa869 | 2013-11-05 15:46:56 +0000 | [diff] [blame] | 115 |     static const size_t kBufferSize = SkMatrix::kMaxFlattenSize + 100; | 
 | 116 |     char buffer[kBufferSize]; | 
 | 117 |     size_t size1 = m.writeToMemory(NULL); | 
 | 118 |     size_t size2 = m.writeToMemory(buffer); | 
| reed@android.com | 4b7577b | 2009-06-29 16:14:41 +0000 | [diff] [blame] | 119 |     REPORTER_ASSERT(reporter, size1 == size2); | 
 | 120 |     REPORTER_ASSERT(reporter, size1 <= SkMatrix::kMaxFlattenSize); | 
| rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 121 |  | 
| reed@android.com | 4b7577b | 2009-06-29 16:14:41 +0000 | [diff] [blame] | 122 |     SkMatrix m2; | 
| commit-bot@chromium.org | 4faa869 | 2013-11-05 15:46:56 +0000 | [diff] [blame] | 123 |     size_t size3 = m2.readFromMemory(buffer, kBufferSize); | 
| djsollen@google.com | 94e75ee | 2012-06-08 18:30:46 +0000 | [diff] [blame] | 124 |     REPORTER_ASSERT(reporter, size1 == size3); | 
| bsalomon@google.com | 8fe84b5 | 2012-03-26 15:24:27 +0000 | [diff] [blame] | 125 |     REPORTER_ASSERT(reporter, are_equal(reporter, m, m2)); | 
| rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 126 |  | 
| commit-bot@chromium.org | 4faa869 | 2013-11-05 15:46:56 +0000 | [diff] [blame] | 127 |     char buffer2[kBufferSize]; | 
| djsollen@google.com | 94e75ee | 2012-06-08 18:30:46 +0000 | [diff] [blame] | 128 |     size3 = m2.writeToMemory(buffer2); | 
 | 129 |     REPORTER_ASSERT(reporter, size1 == size3); | 
| reed@android.com | 4b7577b | 2009-06-29 16:14:41 +0000 | [diff] [blame] | 130 |     REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0); | 
 | 131 | } | 
 | 132 |  | 
| caryclark@google.com | 42639cd | 2012-06-06 12:03:39 +0000 | [diff] [blame] | 133 | static void test_matrix_max_stretch(skiatest::Reporter* reporter) { | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 134 |     SkMatrix identity; | 
 | 135 |     identity.reset(); | 
 | 136 |     REPORTER_ASSERT(reporter, SK_Scalar1 == identity.getMaxStretch()); | 
 | 137 |  | 
 | 138 |     SkMatrix scale; | 
 | 139 |     scale.setScale(SK_Scalar1 * 2, SK_Scalar1 * 4); | 
 | 140 |     REPORTER_ASSERT(reporter, SK_Scalar1 * 4 == scale.getMaxStretch()); | 
 | 141 |  | 
 | 142 |     SkMatrix rot90Scale; | 
 | 143 |     rot90Scale.setRotate(90 * SK_Scalar1); | 
 | 144 |     rot90Scale.postScale(SK_Scalar1 / 4, SK_Scalar1 / 2); | 
 | 145 |     REPORTER_ASSERT(reporter, SK_Scalar1 / 2 == rot90Scale.getMaxStretch()); | 
 | 146 |  | 
 | 147 |     SkMatrix rotate; | 
 | 148 |     rotate.setRotate(128 * SK_Scalar1); | 
 | 149 |     REPORTER_ASSERT(reporter, SkScalarAbs(SK_Scalar1 - rotate.getMaxStretch()) <= SK_ScalarNearlyZero); | 
 | 150 |  | 
 | 151 |     SkMatrix translate; | 
 | 152 |     translate.setTranslate(10 * SK_Scalar1, -5 * SK_Scalar1); | 
 | 153 |     REPORTER_ASSERT(reporter, SK_Scalar1 == translate.getMaxStretch()); | 
 | 154 |  | 
 | 155 |     SkMatrix perspX; | 
 | 156 |     perspX.reset(); | 
| bungeman@google.com | 07faed1 | 2011-10-07 21:55:56 +0000 | [diff] [blame] | 157 |     perspX.setPerspX(SkScalarToPersp(SK_Scalar1 / 1000)); | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 158 |     REPORTER_ASSERT(reporter, -SK_Scalar1 == perspX.getMaxStretch()); | 
 | 159 |  | 
 | 160 |     SkMatrix perspY; | 
 | 161 |     perspY.reset(); | 
| bungeman@google.com | 07faed1 | 2011-10-07 21:55:56 +0000 | [diff] [blame] | 162 |     perspY.setPerspX(SkScalarToPersp(-SK_Scalar1 / 500)); | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 163 |     REPORTER_ASSERT(reporter, -SK_Scalar1 == perspY.getMaxStretch()); | 
 | 164 |  | 
 | 165 |     SkMatrix baseMats[] = {scale, rot90Scale, rotate, | 
 | 166 |                            translate, perspX, perspY}; | 
 | 167 |     SkMatrix mats[2*SK_ARRAY_COUNT(baseMats)]; | 
| tomhudson@google.com | 83a4446 | 2011-10-27 15:27:51 +0000 | [diff] [blame] | 168 |     for (size_t i = 0; i < SK_ARRAY_COUNT(baseMats); ++i) { | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 169 |         mats[i] = baseMats[i]; | 
 | 170 |         bool invertable = mats[i].invert(&mats[i + SK_ARRAY_COUNT(baseMats)]); | 
 | 171 |         REPORTER_ASSERT(reporter, invertable); | 
 | 172 |     } | 
| commit-bot@chromium.org | e0e7cfe | 2013-09-09 20:09:12 +0000 | [diff] [blame] | 173 |     SkRandom rand; | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 174 |     for (int m = 0; m < 1000; ++m) { | 
 | 175 |         SkMatrix mat; | 
 | 176 |         mat.reset(); | 
 | 177 |         for (int i = 0; i < 4; ++i) { | 
 | 178 |             int x = rand.nextU() % SK_ARRAY_COUNT(mats); | 
 | 179 |             mat.postConcat(mats[x]); | 
 | 180 |         } | 
 | 181 |         SkScalar stretch = mat.getMaxStretch(); | 
| rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 182 |  | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 183 |         if ((stretch < 0) != mat.hasPerspective()) { | 
 | 184 |             stretch = mat.getMaxStretch(); | 
 | 185 |         } | 
 | 186 |  | 
 | 187 |         REPORTER_ASSERT(reporter, (stretch < 0) == mat.hasPerspective()); | 
 | 188 |  | 
 | 189 |         if (mat.hasPerspective()) { | 
 | 190 |             m -= 1; // try another non-persp matrix | 
 | 191 |             continue; | 
 | 192 |         } | 
 | 193 |  | 
 | 194 |         // test a bunch of vectors. None should be scaled by more than stretch | 
 | 195 |         // (modulo some error) and we should find a vector that is scaled by | 
 | 196 |         // almost stretch. | 
 | 197 |         static const SkScalar gStretchTol = (105 * SK_Scalar1) / 100; | 
 | 198 |         static const SkScalar gMaxStretchTol = (97 * SK_Scalar1) / 100; | 
 | 199 |         SkScalar max = 0; | 
 | 200 |         SkVector vectors[1000]; | 
| tomhudson@google.com | 83a4446 | 2011-10-27 15:27:51 +0000 | [diff] [blame] | 201 |         for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) { | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 202 |             vectors[i].fX = rand.nextSScalar1(); | 
 | 203 |             vectors[i].fY = rand.nextSScalar1(); | 
 | 204 |             if (!vectors[i].normalize()) { | 
 | 205 |                 i -= 1; | 
 | 206 |                 continue; | 
 | 207 |             } | 
 | 208 |         } | 
 | 209 |         mat.mapVectors(vectors, SK_ARRAY_COUNT(vectors)); | 
| tomhudson@google.com | 83a4446 | 2011-10-27 15:27:51 +0000 | [diff] [blame] | 210 |         for (size_t i = 0; i < SK_ARRAY_COUNT(vectors); ++i) { | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 211 |             SkScalar d = vectors[i].length(); | 
 | 212 |             REPORTER_ASSERT(reporter, SkScalarDiv(d, stretch) < gStretchTol); | 
 | 213 |             if (max < d) { | 
 | 214 |                 max = d; | 
 | 215 |             } | 
 | 216 |         } | 
 | 217 |         REPORTER_ASSERT(reporter, SkScalarDiv(max, stretch) >= gMaxStretchTol); | 
 | 218 |     } | 
 | 219 | } | 
 | 220 |  | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 221 | static void test_matrix_is_similarity(skiatest::Reporter* reporter) { | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 222 |     SkMatrix mat; | 
 | 223 |  | 
 | 224 |     // identity | 
 | 225 |     mat.setIdentity(); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 226 |     REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 227 |  | 
 | 228 |     // translation only | 
 | 229 |     mat.reset(); | 
 | 230 |     mat.setTranslate(SkIntToScalar(100), SkIntToScalar(100)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 231 |     REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 232 |  | 
 | 233 |     // scale with same size | 
 | 234 |     mat.reset(); | 
 | 235 |     mat.setScale(SkIntToScalar(15), SkIntToScalar(15)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 236 |     REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 237 |  | 
 | 238 |     // scale with one negative | 
 | 239 |     mat.reset(); | 
 | 240 |     mat.setScale(SkIntToScalar(-15), SkIntToScalar(15)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 241 |     REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 242 |  | 
 | 243 |     // scale with different size | 
 | 244 |     mat.reset(); | 
 | 245 |     mat.setScale(SkIntToScalar(15), SkIntToScalar(20)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 246 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 247 |  | 
 | 248 |     // scale with same size at a pivot point | 
 | 249 |     mat.reset(); | 
 | 250 |     mat.setScale(SkIntToScalar(15), SkIntToScalar(15), | 
 | 251 |                  SkIntToScalar(2), SkIntToScalar(2)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 252 |     REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 253 |  | 
 | 254 |     // scale with different size at a pivot point | 
 | 255 |     mat.reset(); | 
 | 256 |     mat.setScale(SkIntToScalar(15), SkIntToScalar(20), | 
 | 257 |                  SkIntToScalar(2), SkIntToScalar(2)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 258 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 259 |  | 
 | 260 |     // skew with same size | 
 | 261 |     mat.reset(); | 
 | 262 |     mat.setSkew(SkIntToScalar(15), SkIntToScalar(15)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 263 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 264 |  | 
 | 265 |     // skew with different size | 
 | 266 |     mat.reset(); | 
 | 267 |     mat.setSkew(SkIntToScalar(15), SkIntToScalar(20)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 268 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 269 |  | 
 | 270 |     // skew with same size at a pivot point | 
 | 271 |     mat.reset(); | 
 | 272 |     mat.setSkew(SkIntToScalar(15), SkIntToScalar(15), | 
 | 273 |                 SkIntToScalar(2), SkIntToScalar(2)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 274 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 275 |  | 
 | 276 |     // skew with different size at a pivot point | 
 | 277 |     mat.reset(); | 
 | 278 |     mat.setSkew(SkIntToScalar(15), SkIntToScalar(20), | 
 | 279 |                 SkIntToScalar(2), SkIntToScalar(2)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 280 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 281 |  | 
 | 282 |     // perspective x | 
 | 283 |     mat.reset(); | 
 | 284 |     mat.setPerspX(SkScalarToPersp(SK_Scalar1 / 2)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 285 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 286 |  | 
 | 287 |     // perspective y | 
 | 288 |     mat.reset(); | 
 | 289 |     mat.setPerspY(SkScalarToPersp(SK_Scalar1 / 2)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 290 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 291 |  | 
| djsollen@google.com | 4bd2bdb | 2013-03-08 18:35:13 +0000 | [diff] [blame] | 292 | #ifdef SK_SCALAR_IS_FLOAT | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 293 |     /* We bypass the following tests for SK_SCALAR_IS_FIXED build. | 
 | 294 |      * The long discussion can be found in this issue: | 
 | 295 |      *     http://codereview.appspot.com/5999050/ | 
 | 296 |      * In short, we haven't found a perfect way to fix the precision | 
 | 297 |      * issue, i.e. the way we use tolerance in isSimilarityTransformation | 
 | 298 |      * is incorrect. The situation becomes worse in fixed build, so | 
 | 299 |      * we disabled rotation related tests for fixed build. | 
 | 300 |      */ | 
 | 301 |  | 
 | 302 |     // rotate | 
 | 303 |     for (int angle = 0; angle < 360; ++angle) { | 
 | 304 |         mat.reset(); | 
 | 305 |         mat.setRotate(SkIntToScalar(angle)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 306 |         REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 307 |     } | 
 | 308 |  | 
 | 309 |     // see if there are any accumulated precision issues | 
 | 310 |     mat.reset(); | 
 | 311 |     for (int i = 1; i < 360; i++) { | 
 | 312 |         mat.postRotate(SkIntToScalar(1)); | 
 | 313 |     } | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 314 |     REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 315 |  | 
 | 316 |     // rotate + translate | 
 | 317 |     mat.reset(); | 
 | 318 |     mat.setRotate(SkIntToScalar(30)); | 
 | 319 |     mat.postTranslate(SkIntToScalar(10), SkIntToScalar(20)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 320 |     REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 321 |  | 
 | 322 |     // rotate + uniform scale | 
 | 323 |     mat.reset(); | 
 | 324 |     mat.setRotate(SkIntToScalar(30)); | 
 | 325 |     mat.postScale(SkIntToScalar(2), SkIntToScalar(2)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 326 |     REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 327 |  | 
 | 328 |     // rotate + non-uniform scale | 
 | 329 |     mat.reset(); | 
 | 330 |     mat.setRotate(SkIntToScalar(30)); | 
 | 331 |     mat.postScale(SkIntToScalar(3), SkIntToScalar(2)); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 332 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 333 | #endif | 
 | 334 |  | 
 | 335 |     // all zero | 
 | 336 |     mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, 0); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 337 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 338 |  | 
 | 339 |     // all zero except perspective | 
 | 340 |     mat.setAll(0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 341 |     REPORTER_ASSERT(reporter, !mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 342 |  | 
 | 343 |     // scales zero, only skews | 
 | 344 |     mat.setAll(0, SK_Scalar1, 0, | 
 | 345 |                SK_Scalar1, 0, 0, | 
 | 346 |                0, 0, SkMatrix::I()[8]); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 347 |     REPORTER_ASSERT(reporter, mat.isSimilarity()); | 
| bsalomon@google.com | 69afee1 | 2012-04-25 15:07:40 +0000 | [diff] [blame] | 348 | } | 
 | 349 |  | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 350 | // For test_matrix_decomposition, below. | 
| skia.committer@gmail.com | 5c561cb | 2013-07-25 07:01:00 +0000 | [diff] [blame] | 351 | static bool scalar_nearly_equal_relative(SkScalar a, SkScalar b, | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 352 |                                          SkScalar tolerance = SK_ScalarNearlyZero) { | 
 | 353 |     // from Bruce Dawson | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 354 |     // absolute check | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 355 |     SkScalar diff = SkScalarAbs(a - b); | 
 | 356 |     if (diff < tolerance) { | 
 | 357 |         return true; | 
 | 358 |     } | 
 | 359 |  | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 360 |     // relative check | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 361 |     a = SkScalarAbs(a); | 
 | 362 |     b = SkScalarAbs(b); | 
 | 363 |     SkScalar largest = (b > a) ? b : a; | 
 | 364 |  | 
 | 365 |     if (diff <= largest*tolerance) { | 
 | 366 |         return true; | 
 | 367 |     } | 
 | 368 |  | 
 | 369 |     return false; | 
 | 370 | } | 
 | 371 |  | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 372 | static bool check_matrix_recomposition(const SkMatrix& mat, | 
 | 373 |                                        const SkPoint& rotation1, | 
 | 374 |                                        const SkPoint& scale, | 
 | 375 |                                        const SkPoint& rotation2) { | 
 | 376 |     SkScalar c1 = rotation1.fX; | 
 | 377 |     SkScalar s1 = rotation1.fY; | 
 | 378 |     SkScalar scaleX = scale.fX; | 
 | 379 |     SkScalar scaleY = scale.fY; | 
 | 380 |     SkScalar c2 = rotation2.fX; | 
 | 381 |     SkScalar s2 = rotation2.fY; | 
| skia.committer@gmail.com | 85092f0 | 2013-09-04 07:01:39 +0000 | [diff] [blame] | 382 |  | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 383 |     // We do a relative check here because large scale factors cause problems with an absolute check | 
 | 384 |     bool result = scalar_nearly_equal_relative(mat[SkMatrix::kMScaleX], | 
 | 385 |                                                scaleX*c1*c2 - scaleY*s1*s2) && | 
 | 386 |                   scalar_nearly_equal_relative(mat[SkMatrix::kMSkewX], | 
 | 387 |                                                -scaleX*s1*c2 - scaleY*c1*s2) && | 
 | 388 |                   scalar_nearly_equal_relative(mat[SkMatrix::kMSkewY], | 
 | 389 |                                                scaleX*c1*s2 + scaleY*s1*c2) && | 
 | 390 |                   scalar_nearly_equal_relative(mat[SkMatrix::kMScaleY], | 
 | 391 |                                                -scaleX*s1*s2 + scaleY*c1*c2); | 
 | 392 |     return result; | 
 | 393 | } | 
 | 394 |  | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 395 | static void test_matrix_decomposition(skiatest::Reporter* reporter) { | 
 | 396 |     SkMatrix mat; | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 397 |     SkPoint rotation1, scale, rotation2; | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 398 |  | 
 | 399 |     const float kRotation0 = 15.5f; | 
 | 400 |     const float kRotation1 = -50.f; | 
 | 401 |     const float kScale0 = 5000.f; | 
 | 402 |     const float kScale1 = 0.001f; | 
 | 403 |  | 
 | 404 |     // identity | 
 | 405 |     mat.reset(); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 406 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 407 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 408 |     // make sure it doesn't crash if we pass in NULLs | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 409 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, NULL, NULL, NULL)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 410 |  | 
 | 411 |     // rotation only | 
 | 412 |     mat.setRotate(kRotation0); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 413 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 414 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 415 |  | 
 | 416 |     // uniform scale only | 
 | 417 |     mat.setScale(kScale0, kScale0); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 418 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 419 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 420 |  | 
 | 421 |     // anisotropic scale only | 
 | 422 |     mat.setScale(kScale1, kScale0); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 423 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 424 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 425 |  | 
 | 426 |     // rotation then uniform scale | 
 | 427 |     mat.setRotate(kRotation1); | 
 | 428 |     mat.postScale(kScale0, kScale0); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 429 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 430 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 431 |  | 
 | 432 |     // uniform scale then rotation | 
 | 433 |     mat.setScale(kScale0, kScale0); | 
 | 434 |     mat.postRotate(kRotation1); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 435 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 436 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 437 |  | 
 | 438 |     // rotation then uniform scale+reflection | 
 | 439 |     mat.setRotate(kRotation0); | 
 | 440 |     mat.postScale(kScale1, -kScale1); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 441 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 442 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 443 |  | 
 | 444 |     // uniform scale+reflection, then rotate | 
 | 445 |     mat.setScale(kScale0, -kScale0); | 
 | 446 |     mat.postRotate(kRotation1); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 447 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 448 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 449 |  | 
 | 450 |     // rotation then anisotropic scale | 
 | 451 |     mat.setRotate(kRotation1); | 
 | 452 |     mat.postScale(kScale1, kScale0); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 453 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 454 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 455 |  | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 456 |     // rotation then anisotropic scale | 
 | 457 |     mat.setRotate(90); | 
 | 458 |     mat.postScale(kScale1, kScale0); | 
 | 459 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 460 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| skia.committer@gmail.com | 85092f0 | 2013-09-04 07:01:39 +0000 | [diff] [blame] | 461 |  | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 462 |     // anisotropic scale then rotation | 
 | 463 |     mat.setScale(kScale1, kScale0); | 
 | 464 |     mat.postRotate(kRotation0); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 465 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 466 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| skia.committer@gmail.com | 85092f0 | 2013-09-04 07:01:39 +0000 | [diff] [blame] | 467 |  | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 468 |     // anisotropic scale then rotation | 
 | 469 |     mat.setScale(kScale1, kScale0); | 
 | 470 |     mat.postRotate(90); | 
 | 471 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 472 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 473 |  | 
 | 474 |     // rotation, uniform scale, then different rotation | 
 | 475 |     mat.setRotate(kRotation1); | 
 | 476 |     mat.postScale(kScale0, kScale0); | 
 | 477 |     mat.postRotate(kRotation0); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 478 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 479 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 480 |  | 
 | 481 |     // rotation, anisotropic scale, then different rotation | 
 | 482 |     mat.setRotate(kRotation0); | 
 | 483 |     mat.postScale(kScale1, kScale0); | 
 | 484 |     mat.postRotate(kRotation1); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 485 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 486 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| skia.committer@gmail.com | 85092f0 | 2013-09-04 07:01:39 +0000 | [diff] [blame] | 487 |  | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 488 |     // rotation, anisotropic scale + reflection, then different rotation | 
 | 489 |     mat.setRotate(kRotation0); | 
 | 490 |     mat.postScale(-kScale1, kScale0); | 
 | 491 |     mat.postRotate(kRotation1); | 
 | 492 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 493 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 494 |  | 
 | 495 |     // try some random matrices | 
| commit-bot@chromium.org | e0e7cfe | 2013-09-09 20:09:12 +0000 | [diff] [blame] | 496 |     SkRandom rand; | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 497 |     for (int m = 0; m < 1000; ++m) { | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 498 |         SkScalar rot0 = rand.nextRangeF(-180, 180); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 499 |         SkScalar sx = rand.nextRangeF(-3000.f, 3000.f); | 
 | 500 |         SkScalar sy = rand.nextRangeF(-3000.f, 3000.f); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 501 |         SkScalar rot1 = rand.nextRangeF(-180, 180); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 502 |         mat.setRotate(rot0); | 
 | 503 |         mat.postScale(sx, sy); | 
 | 504 |         mat.postRotate(rot1); | 
 | 505 |  | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 506 |         if (SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)) { | 
 | 507 |             REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 508 |         } else { | 
 | 509 |             // if the matrix is degenerate, the basis vectors should be near-parallel or near-zero | 
 | 510 |             SkScalar perpdot = mat[SkMatrix::kMScaleX]*mat[SkMatrix::kMScaleY] - | 
 | 511 |                                mat[SkMatrix::kMSkewX]*mat[SkMatrix::kMSkewY]; | 
 | 512 |             REPORTER_ASSERT(reporter, SkScalarNearlyZero(perpdot)); | 
 | 513 |         } | 
 | 514 |     } | 
 | 515 |  | 
 | 516 |     // translation shouldn't affect this | 
 | 517 |     mat.postTranslate(-1000.f, 1000.f); | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 518 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 519 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 520 |  | 
 | 521 |     // perspective shouldn't affect this | 
| jvanverth@google.com | 588f3d3 | 2013-07-24 18:44:10 +0000 | [diff] [blame] | 522 |     mat[SkMatrix::kMPersp0] = 12.f; | 
 | 523 |     mat[SkMatrix::kMPersp1] = 4.f; | 
 | 524 |     mat[SkMatrix::kMPersp2] = 1872.f; | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 525 |     REPORTER_ASSERT(reporter, SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
 | 526 |     REPORTER_ASSERT(reporter, check_matrix_recomposition(mat, rotation1, scale, rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 527 |  | 
 | 528 |     // degenerate matrices | 
 | 529 |     // mostly zero entries | 
 | 530 |     mat.reset(); | 
 | 531 |     mat[SkMatrix::kMScaleX] = 0.f; | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 532 |     REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 533 |     mat.reset(); | 
 | 534 |     mat[SkMatrix::kMScaleY] = 0.f; | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 535 |     REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 536 |     mat.reset(); | 
 | 537 |     // linearly dependent entries | 
 | 538 |     mat[SkMatrix::kMScaleX] = 1.f; | 
 | 539 |     mat[SkMatrix::kMSkewX] = 2.f; | 
 | 540 |     mat[SkMatrix::kMSkewY] = 4.f; | 
 | 541 |     mat[SkMatrix::kMScaleY] = 8.f; | 
| commit-bot@chromium.org | 5b2e264 | 2013-09-03 19:08:14 +0000 | [diff] [blame] | 542 |     REPORTER_ASSERT(reporter, !SkDecomposeUpper2x2(mat, &rotation1, &scale, &rotation2)); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 543 | } | 
 | 544 |  | 
| egdaniel@google.com | 259fbaf | 2013-08-15 21:12:11 +0000 | [diff] [blame] | 545 | // For test_matrix_homogeneous, below. | 
 | 546 | static bool scalar_array_nearly_equal_relative(const SkScalar a[], const SkScalar b[], int count) { | 
 | 547 |     for (int i = 0; i < count; ++i) { | 
 | 548 |         if (!scalar_nearly_equal_relative(a[i], b[i])) { | 
 | 549 |             return false; | 
 | 550 |         } | 
 | 551 |     } | 
 | 552 |     return true; | 
 | 553 | } | 
 | 554 |  | 
 | 555 | // For test_matrix_homogeneous, below. | 
 | 556 | // Maps a single triple in src using m and compares results to those in dst | 
 | 557 | static bool naive_homogeneous_mapping(const SkMatrix& m, const SkScalar src[3], | 
 | 558 |                                       const SkScalar dst[3]) { | 
 | 559 |     SkScalar res[3]; | 
 | 560 |     SkScalar ms[9] = {m[0], m[1], m[2], | 
 | 561 |                       m[3], m[4], m[5], | 
 | 562 |                       m[6], m[7], m[8]}; | 
 | 563 |     res[0] = src[0] * ms[0] + src[1] * ms[1] + src[2] * ms[2]; | 
 | 564 |     res[1] = src[0] * ms[3] + src[1] * ms[4] + src[2] * ms[5]; | 
 | 565 |     res[2] = src[0] * ms[6] + src[1] * ms[7] + src[2] * ms[8]; | 
 | 566 |     return scalar_array_nearly_equal_relative(res, dst, 3); | 
 | 567 | } | 
 | 568 |  | 
 | 569 | static void test_matrix_homogeneous(skiatest::Reporter* reporter) { | 
 | 570 |     SkMatrix mat; | 
 | 571 |  | 
 | 572 |     const float kRotation0 = 15.5f; | 
 | 573 |     const float kRotation1 = -50.f; | 
 | 574 |     const float kScale0 = 5000.f; | 
 | 575 |  | 
 | 576 |     const int kTripleCount = 1000; | 
 | 577 |     const int kMatrixCount = 1000; | 
| commit-bot@chromium.org | e0e7cfe | 2013-09-09 20:09:12 +0000 | [diff] [blame] | 578 |     SkRandom rand; | 
| egdaniel@google.com | 259fbaf | 2013-08-15 21:12:11 +0000 | [diff] [blame] | 579 |  | 
 | 580 |     SkScalar randTriples[3*kTripleCount]; | 
 | 581 |     for (int i = 0; i < 3*kTripleCount; ++i) { | 
 | 582 |         randTriples[i] = rand.nextRangeF(-3000.f, 3000.f); | 
 | 583 |     } | 
 | 584 |  | 
 | 585 |     SkMatrix mats[kMatrixCount]; | 
 | 586 |     for (int i = 0; i < kMatrixCount; ++i) { | 
 | 587 |         for (int j = 0; j < 9; ++j) { | 
 | 588 |             mats[i].set(j, rand.nextRangeF(-3000.f, 3000.f)); | 
 | 589 |         } | 
 | 590 |     } | 
 | 591 |  | 
 | 592 |     // identity | 
 | 593 |     { | 
 | 594 |     mat.reset(); | 
 | 595 |     SkScalar dst[3*kTripleCount]; | 
 | 596 |     mat.mapHomogeneousPoints(dst, randTriples, kTripleCount); | 
 | 597 |     REPORTER_ASSERT(reporter, scalar_array_nearly_equal_relative(randTriples, dst, kTripleCount*3)); | 
 | 598 |     } | 
 | 599 |  | 
 | 600 |     // zero matrix | 
 | 601 |     { | 
 | 602 |     mat.setAll(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f); | 
 | 603 |     SkScalar dst[3*kTripleCount]; | 
 | 604 |     mat.mapHomogeneousPoints(dst, randTriples, kTripleCount); | 
 | 605 |     SkScalar zeros[3] = {0.f, 0.f, 0.f}; | 
 | 606 |     for (int i = 0; i < kTripleCount; ++i) { | 
 | 607 |         REPORTER_ASSERT(reporter, scalar_array_nearly_equal_relative(&dst[i*3], zeros, 3)); | 
 | 608 |     } | 
 | 609 |     } | 
 | 610 |  | 
 | 611 |     // zero point | 
 | 612 |     { | 
 | 613 |     SkScalar zeros[3] = {0.f, 0.f, 0.f}; | 
 | 614 |     for (int i = 0; i < kMatrixCount; ++i) { | 
 | 615 |         SkScalar dst[3]; | 
 | 616 |         mats[i].mapHomogeneousPoints(dst, zeros, 1); | 
 | 617 |         REPORTER_ASSERT(reporter, scalar_array_nearly_equal_relative(dst, zeros, 3)); | 
 | 618 |     } | 
 | 619 |     } | 
 | 620 |  | 
 | 621 |     // doesn't crash with null dst, src, count == 0 | 
 | 622 |     { | 
 | 623 |     mats[0].mapHomogeneousPoints(NULL, NULL, 0); | 
 | 624 |     } | 
 | 625 |  | 
 | 626 |     // uniform scale of point | 
 | 627 |     { | 
 | 628 |     mat.setScale(kScale0, kScale0); | 
 | 629 |     SkScalar dst[3]; | 
 | 630 |     SkScalar src[3] = {randTriples[0], randTriples[1], 1.f}; | 
 | 631 |     SkPoint pnt; | 
 | 632 |     pnt.set(src[0], src[1]); | 
 | 633 |     mat.mapHomogeneousPoints(dst, src, 1); | 
 | 634 |     mat.mapPoints(&pnt, &pnt, 1); | 
 | 635 |     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[0], pnt.fX)); | 
 | 636 |     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[1], pnt.fY)); | 
 | 637 |     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[2], SK_Scalar1)); | 
 | 638 |     } | 
 | 639 |  | 
 | 640 |     // rotation of point | 
 | 641 |     { | 
 | 642 |     mat.setRotate(kRotation0); | 
 | 643 |     SkScalar dst[3]; | 
 | 644 |     SkScalar src[3] = {randTriples[0], randTriples[1], 1.f}; | 
 | 645 |     SkPoint pnt; | 
 | 646 |     pnt.set(src[0], src[1]); | 
 | 647 |     mat.mapHomogeneousPoints(dst, src, 1); | 
 | 648 |     mat.mapPoints(&pnt, &pnt, 1); | 
 | 649 |     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[0], pnt.fX)); | 
 | 650 |     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[1], pnt.fY)); | 
 | 651 |     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[2], SK_Scalar1)); | 
 | 652 |     } | 
 | 653 |  | 
 | 654 |     // rotation, scale, rotation of point | 
 | 655 |     { | 
 | 656 |     mat.setRotate(kRotation1); | 
 | 657 |     mat.postScale(kScale0, kScale0); | 
 | 658 |     mat.postRotate(kRotation0); | 
 | 659 |     SkScalar dst[3]; | 
 | 660 |     SkScalar src[3] = {randTriples[0], randTriples[1], 1.f}; | 
 | 661 |     SkPoint pnt; | 
 | 662 |     pnt.set(src[0], src[1]); | 
 | 663 |     mat.mapHomogeneousPoints(dst, src, 1); | 
 | 664 |     mat.mapPoints(&pnt, &pnt, 1); | 
 | 665 |     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[0], pnt.fX)); | 
 | 666 |     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[1], pnt.fY)); | 
 | 667 |     REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst[2], SK_Scalar1)); | 
 | 668 |     } | 
 | 669 |  | 
 | 670 |     // compare with naive approach | 
 | 671 |     { | 
 | 672 |     for (int i = 0; i < kMatrixCount; ++i) { | 
 | 673 |         for (int j = 0; j < kTripleCount; ++j) { | 
 | 674 |             SkScalar dst[3]; | 
 | 675 |             mats[i].mapHomogeneousPoints(dst, &randTriples[j*3], 1); | 
 | 676 |             REPORTER_ASSERT(reporter, naive_homogeneous_mapping(mats[i], &randTriples[j*3], dst)); | 
 | 677 |         } | 
 | 678 |     } | 
 | 679 |     } | 
 | 680 |  | 
 | 681 | } | 
 | 682 |  | 
| caryclark@google.com | 42639cd | 2012-06-06 12:03:39 +0000 | [diff] [blame] | 683 | static void TestMatrix(skiatest::Reporter* reporter) { | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 684 |     SkMatrix    mat, inverse, iden1, iden2; | 
 | 685 |  | 
 | 686 |     mat.reset(); | 
 | 687 |     mat.setTranslate(SK_Scalar1, SK_Scalar1); | 
| reed@google.com | 5bfa55b | 2012-04-19 18:59:25 +0000 | [diff] [blame] | 688 |     REPORTER_ASSERT(reporter, mat.invert(&inverse)); | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 689 |     iden1.setConcat(mat, inverse); | 
 | 690 |     REPORTER_ASSERT(reporter, is_identity(iden1)); | 
 | 691 |  | 
| reed@google.com | 2fb96cc | 2013-01-04 17:02:33 +0000 | [diff] [blame] | 692 |     mat.setScale(SkIntToScalar(2), SkIntToScalar(4)); | 
| reed@google.com | 5bfa55b | 2012-04-19 18:59:25 +0000 | [diff] [blame] | 693 |     REPORTER_ASSERT(reporter, mat.invert(&inverse)); | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 694 |     iden1.setConcat(mat, inverse); | 
 | 695 |     REPORTER_ASSERT(reporter, is_identity(iden1)); | 
| reed@android.com | 4b7577b | 2009-06-29 16:14:41 +0000 | [diff] [blame] | 696 |     test_flatten(reporter, mat); | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 697 |  | 
| reed@google.com | 2fb96cc | 2013-01-04 17:02:33 +0000 | [diff] [blame] | 698 |     mat.setScale(SK_Scalar1/2, SkIntToScalar(2)); | 
| reed@google.com | 5bfa55b | 2012-04-19 18:59:25 +0000 | [diff] [blame] | 699 |     REPORTER_ASSERT(reporter, mat.invert(&inverse)); | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 700 |     iden1.setConcat(mat, inverse); | 
 | 701 |     REPORTER_ASSERT(reporter, is_identity(iden1)); | 
| reed@android.com | 4b7577b | 2009-06-29 16:14:41 +0000 | [diff] [blame] | 702 |     test_flatten(reporter, mat); | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 703 |  | 
 | 704 |     mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0); | 
 | 705 |     mat.postRotate(SkIntToScalar(25)); | 
 | 706 |     REPORTER_ASSERT(reporter, mat.invert(NULL)); | 
| reed@google.com | 5bfa55b | 2012-04-19 18:59:25 +0000 | [diff] [blame] | 707 |     REPORTER_ASSERT(reporter, mat.invert(&inverse)); | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 708 |     iden1.setConcat(mat, inverse); | 
 | 709 |     REPORTER_ASSERT(reporter, is_identity(iden1)); | 
 | 710 |     iden2.setConcat(inverse, mat); | 
 | 711 |     REPORTER_ASSERT(reporter, is_identity(iden2)); | 
| reed@android.com | 4b7577b | 2009-06-29 16:14:41 +0000 | [diff] [blame] | 712 |     test_flatten(reporter, mat); | 
 | 713 |     test_flatten(reporter, iden2); | 
| reed@android.com | 80e39a7 | 2009-04-02 16:59:40 +0000 | [diff] [blame] | 714 |  | 
| reed@google.com | 2fb96cc | 2013-01-04 17:02:33 +0000 | [diff] [blame] | 715 |     mat.setScale(0, SK_Scalar1); | 
| reed@google.com | e40591d | 2013-01-30 15:47:42 +0000 | [diff] [blame] | 716 |     REPORTER_ASSERT(reporter, !mat.invert(NULL)); | 
| reed@google.com | 2fb96cc | 2013-01-04 17:02:33 +0000 | [diff] [blame] | 717 |     REPORTER_ASSERT(reporter, !mat.invert(&inverse)); | 
 | 718 |     mat.setScale(SK_Scalar1, 0); | 
| reed@google.com | e40591d | 2013-01-30 15:47:42 +0000 | [diff] [blame] | 719 |     REPORTER_ASSERT(reporter, !mat.invert(NULL)); | 
| reed@google.com | 2fb96cc | 2013-01-04 17:02:33 +0000 | [diff] [blame] | 720 |     REPORTER_ASSERT(reporter, !mat.invert(&inverse)); | 
 | 721 |  | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 722 |     // rectStaysRect test | 
 | 723 |     { | 
 | 724 |         static const struct { | 
 | 725 |             SkScalar    m00, m01, m10, m11; | 
 | 726 |             bool        mStaysRect; | 
 | 727 |         } | 
 | 728 |         gRectStaysRectSamples[] = { | 
 | 729 |             {          0,          0,          0,           0, false }, | 
 | 730 |             {          0,          0,          0,  SK_Scalar1, false }, | 
 | 731 |             {          0,          0, SK_Scalar1,           0, false }, | 
 | 732 |             {          0,          0, SK_Scalar1,  SK_Scalar1, false }, | 
 | 733 |             {          0, SK_Scalar1,          0,           0, false }, | 
 | 734 |             {          0, SK_Scalar1,          0,  SK_Scalar1, false }, | 
 | 735 |             {          0, SK_Scalar1, SK_Scalar1,           0, true }, | 
 | 736 |             {          0, SK_Scalar1, SK_Scalar1,  SK_Scalar1, false }, | 
 | 737 |             { SK_Scalar1,          0,          0,           0, false }, | 
 | 738 |             { SK_Scalar1,          0,          0,  SK_Scalar1, true }, | 
 | 739 |             { SK_Scalar1,          0, SK_Scalar1,           0, false }, | 
 | 740 |             { SK_Scalar1,          0, SK_Scalar1,  SK_Scalar1, false }, | 
 | 741 |             { SK_Scalar1, SK_Scalar1,          0,           0, false }, | 
 | 742 |             { SK_Scalar1, SK_Scalar1,          0,  SK_Scalar1, false }, | 
 | 743 |             { SK_Scalar1, SK_Scalar1, SK_Scalar1,           0, false }, | 
 | 744 |             { SK_Scalar1, SK_Scalar1, SK_Scalar1,  SK_Scalar1, false } | 
 | 745 |         }; | 
| reed@android.com | 80e39a7 | 2009-04-02 16:59:40 +0000 | [diff] [blame] | 746 |  | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 747 |         for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) { | 
 | 748 |             SkMatrix    m; | 
| reed@android.com | 80e39a7 | 2009-04-02 16:59:40 +0000 | [diff] [blame] | 749 |  | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 750 |             m.reset(); | 
 | 751 |             m.set(SkMatrix::kMScaleX, gRectStaysRectSamples[i].m00); | 
 | 752 |             m.set(SkMatrix::kMSkewX,  gRectStaysRectSamples[i].m01); | 
 | 753 |             m.set(SkMatrix::kMSkewY,  gRectStaysRectSamples[i].m10); | 
 | 754 |             m.set(SkMatrix::kMScaleY, gRectStaysRectSamples[i].m11); | 
 | 755 |             REPORTER_ASSERT(reporter, | 
 | 756 |                     m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect); | 
 | 757 |         } | 
 | 758 |     } | 
| bungeman@google.com | 1ddd7c3 | 2011-07-13 19:41:55 +0000 | [diff] [blame] | 759 |  | 
| bungeman@google.com | ba7983e | 2011-07-13 20:18:16 +0000 | [diff] [blame] | 760 |     mat.reset(); | 
| bungeman@google.com | 1ddd7c3 | 2011-07-13 19:41:55 +0000 | [diff] [blame] | 761 |     mat.set(SkMatrix::kMScaleX, SkIntToScalar(1)); | 
 | 762 |     mat.set(SkMatrix::kMSkewX,  SkIntToScalar(2)); | 
 | 763 |     mat.set(SkMatrix::kMTransX, SkIntToScalar(3)); | 
 | 764 |     mat.set(SkMatrix::kMSkewY,  SkIntToScalar(4)); | 
 | 765 |     mat.set(SkMatrix::kMScaleY, SkIntToScalar(5)); | 
 | 766 |     mat.set(SkMatrix::kMTransY, SkIntToScalar(6)); | 
| bungeman@google.com | 1ddd7c3 | 2011-07-13 19:41:55 +0000 | [diff] [blame] | 767 |     SkScalar affine[6]; | 
 | 768 |     REPORTER_ASSERT(reporter, mat.asAffine(affine)); | 
 | 769 |  | 
 | 770 |     #define affineEqual(e) affine[SkMatrix::kA##e] == mat.get(SkMatrix::kM##e) | 
 | 771 |     REPORTER_ASSERT(reporter, affineEqual(ScaleX)); | 
 | 772 |     REPORTER_ASSERT(reporter, affineEqual(SkewY)); | 
 | 773 |     REPORTER_ASSERT(reporter, affineEqual(SkewX)); | 
 | 774 |     REPORTER_ASSERT(reporter, affineEqual(ScaleY)); | 
 | 775 |     REPORTER_ASSERT(reporter, affineEqual(TransX)); | 
 | 776 |     REPORTER_ASSERT(reporter, affineEqual(TransY)); | 
 | 777 |     #undef affineEqual | 
 | 778 |  | 
| bungeman@google.com | 07faed1 | 2011-10-07 21:55:56 +0000 | [diff] [blame] | 779 |     mat.set(SkMatrix::kMPersp1, SkScalarToPersp(SK_Scalar1 / 2)); | 
| bungeman@google.com | 1ddd7c3 | 2011-07-13 19:41:55 +0000 | [diff] [blame] | 780 |     REPORTER_ASSERT(reporter, !mat.asAffine(affine)); | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 781 |  | 
| bsalomon@google.com | 8fe84b5 | 2012-03-26 15:24:27 +0000 | [diff] [blame] | 782 |     SkMatrix mat2; | 
 | 783 |     mat2.reset(); | 
 | 784 |     mat.reset(); | 
 | 785 |     SkScalar zero = 0; | 
 | 786 |     mat.set(SkMatrix::kMSkewX, -zero); | 
 | 787 |     REPORTER_ASSERT(reporter, are_equal(reporter, mat, mat2)); | 
 | 788 |  | 
 | 789 |     mat2.reset(); | 
 | 790 |     mat.reset(); | 
 | 791 |     mat.set(SkMatrix::kMSkewX, SK_ScalarNaN); | 
 | 792 |     mat2.set(SkMatrix::kMSkewX, SK_ScalarNaN); | 
| bsalomon@google.com | 9ed2ecd | 2012-03-26 15:57:37 +0000 | [diff] [blame] | 793 |     // fixed pt doesn't have the property that NaN does not equal itself. | 
 | 794 | #ifdef SK_SCALAR_IS_FIXED | 
 | 795 |     REPORTER_ASSERT(reporter, are_equal(reporter, mat, mat2)); | 
 | 796 | #else | 
| bsalomon@google.com | 8fe84b5 | 2012-03-26 15:24:27 +0000 | [diff] [blame] | 797 |     REPORTER_ASSERT(reporter, !are_equal(reporter, mat, mat2)); | 
| bsalomon@google.com | 9ed2ecd | 2012-03-26 15:57:37 +0000 | [diff] [blame] | 798 | #endif | 
| bsalomon@google.com | 8fe84b5 | 2012-03-26 15:24:27 +0000 | [diff] [blame] | 799 |  | 
| bsalomon@google.com | 3839632 | 2011-09-09 19:32:04 +0000 | [diff] [blame] | 800 |     test_matrix_max_stretch(reporter); | 
| jvanverth@google.com | 46d3d39 | 2013-01-22 13:34:01 +0000 | [diff] [blame] | 801 |     test_matrix_is_similarity(reporter); | 
| reed@google.com | 97cd69c | 2012-10-12 14:35:48 +0000 | [diff] [blame] | 802 |     test_matrix_recttorect(reporter); | 
| commit-bot@chromium.org | 08284e4 | 2013-07-24 18:08:08 +0000 | [diff] [blame] | 803 |     test_matrix_decomposition(reporter); | 
| egdaniel@google.com | 259fbaf | 2013-08-15 21:12:11 +0000 | [diff] [blame] | 804 |     test_matrix_homogeneous(reporter); | 
| reed@android.com | ed67331 | 2009-02-27 16:24:51 +0000 | [diff] [blame] | 805 | } | 
 | 806 |  | 
| reed@android.com | d8730ea | 2009-02-27 22:06:06 +0000 | [diff] [blame] | 807 | #include "TestClassDef.h" | 
 | 808 | DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix) |