Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: ui/gfx/transform_unittest.cc

Issue 7044062: Use SkMatrix44 for the underlying implementation of ui::Transform (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Layer animator updates Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2006-2011 The Chromium Authors. All rights reserved.
tfarina 2011/06/25 00:19:19 nit: 2006-2011 -> 2011
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/basictypes.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7 #include "ui/gfx/transform.h"
8 #include "ui/gfx/point3.h"
9 #include <iostream>
sky 2011/06/24 20:58:19 The order of includes should match that of other f
10 #include <limits>
11
12 typedef testing::Test XFormTest;
tfarina 2011/06/25 00:19:19 If I'm not wrong, you don't need this typedef. You
13
14 namespace {
15
16 bool PointsAreNearlyEqual(const gfx::Point3f& lhs,
17 const gfx::Point3f& rhs) {
18 float epsilon = 0.0001f;
19 return lhs.SquaredDistanceTo(rhs) < epsilon;
20 }
21
22 } // anonymous namespace
tfarina 2011/06/25 00:19:19 Technically speaking this is not an anonymous name
23
24 TEST(XFormTest, Equality) {
tfarina 2011/06/25 00:19:19 Please, wrap the tests into an unnamed namespace a
25 ui::Transform lhs, rhs;
26 for (int i = 1; i < 360; ++i) {
27 lhs.SetRotate(i);
28 EXPECT_TRUE(lhs != rhs);
29 rhs.SetRotate(i - 360);
30 EXPECT_TRUE(lhs == rhs);
31 }
32 lhs = ui::Transform();
33 rhs = ui::Transform();
34 for (int i = 1; i < 100; ++i) {
35 lhs.SetTranslate(i, i);
36 rhs.SetTranslate(-i, -i);
37 EXPECT_TRUE(lhs != rhs);
38 rhs.ConcatTranslate(2*i, 2*i);
39 EXPECT_TRUE(lhs == rhs);
40 }
41 }
42
43 TEST(XFormTest, ConcatTranslate) {
44 static const struct TestCase {
45 int x1;
46 int y1;
47 float tx;
48 float ty;
49 int x2;
50 int y2;
51 } test_cases[] = {
52 { 0, 0, 10.0f, 20.0f, 10, 20 },
53 { 0, 0, -10.0f, -20.0f, 0, 0 },
54 { 0, 0, -10.0f, -20.0f, -10, -20 },
55 { 0, 0,
56 std::numeric_limits<float>::quiet_NaN(),
57 std::numeric_limits<float>::quiet_NaN(),
58 10, 20 },
59 };
60
61 ui::Transform xform;
62 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
63 const TestCase& value = test_cases[i];
64 xform.ConcatTranslate(value.tx, value.ty);
65 gfx::Point3f p1(value.x1, value.y1, 0);
66 gfx::Point3f p2(value.x2, value.y2, 0);
67 xform.TransformPoint(p1);
68 if (value.tx == value.tx &&
69 value.ty == value.ty) {
70 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
71 }
72 }
73 }
74
75 TEST(XFormTest, ConcatScale) {
76 static const struct TestCase {
77 int before;
78 float scale;
79 int after;
80 } test_cases[] = {
81 { 1, 10.0f, 10 },
82 { 1, .1f, 1 },
83 { 1, 100.0f, 100 },
84 { 1, -1.0f, -100 },
85 { 1, std::numeric_limits<float>::quiet_NaN(), 1 }
86 };
87
88 ui::Transform xform;
89 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
90 const TestCase& value = test_cases[i];
91 xform.ConcatScale(value.scale, value.scale);
92 gfx::Point3f p1(value.before, value.before, 0);
93 gfx::Point3f p2(value.after, value.after, 0);
94 xform.TransformPoint(p1);
95 if (value.scale == value.scale) {
96 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
97 }
98 }
99 }
100
101 TEST(XFormTest, ConcatRotate) {
102 static const struct TestCase {
103 int x1;
104 int y1;
105 float degrees;
106 int x2;
107 int y2;
108 } test_cases[] = {
109 { 1, 0, 90.0f, 0, 1 },
110 { 1, 0, -90.0f, 1, 0 },
111 { 1, 0, 90.0f, 0, 1 },
112 { 1, 0, 360.0f, 0, 1 },
113 { 1, 0, 0.0f, 0, 1 },
114 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0 }
115 };
116
117 ui::Transform xform;
118 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
119 const TestCase& value = test_cases[i];
120 xform.ConcatRotate(value.degrees);
121 gfx::Point3f p1(value.x1, value.y1, 0);
122 gfx::Point3f p2(value.x2, value.y2, 0);
123 xform.TransformPoint(p1);
124 if (value.degrees == value.degrees) {
125 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
126 }
127 }
128 }
129
130 TEST(XFormTest, SetTranslate) {
131 static const struct TestCase {
132 int x1; int y1;
133 float tx; float ty;
134 int x2; int y2;
135 } test_cases[] = {
136 { 0, 0, 10.0f, 20.0f, 10, 20 },
137 { 10, 20, 10.0f, 20.0f, 20, 40 },
138 { 10, 20, 0.0f, 0.0f, 10, 20 },
139 { 0, 0,
140 std::numeric_limits<float>::quiet_NaN(),
141 std::numeric_limits<float>::quiet_NaN(),
142 0, 0 }
143 };
144
145 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
146 const TestCase& value = test_cases[i];
147 for (int k = 0; k < 3; ++k) {
148 gfx::Point3f p0, p1, p2;
149 ui::Transform xform;
150 switch (k) {
151 case 0:
152 p1.SetPoint(value.x1, 0, 0);
153 p2.SetPoint(value.x2, 0, 0);
154 xform.SetTranslateX(value.tx);
155 break;
156 case 1:
157 p1.SetPoint(0, value.y1, 0);
158 p2.SetPoint(0, value.y2, 0);
159 xform.SetTranslateY(value.ty);
160 break;
161 case 2:
162 p1.SetPoint(value.x1, value.y1, 0);
163 p2.SetPoint(value.x2, value.y2, 0);
164 xform.SetTranslate(value.tx, value.ty);
165 break;
166 }
167 p0 = p1;
168 xform.TransformPoint(p1);
169 if (value.tx == value.tx &&
170 value.ty == value.ty) {
171 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
172 xform.TransformPointReverse(p1);
173 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0));
174 }
175 }
176 }
177 }
178
179 TEST(XFormTest, SetScale) {
180 static const struct TestCase {
181 int before;
182 float s;
183 int after;
184 } test_cases[] = {
185 { 1, 10.0f, 10 },
186 { 1, 1.0f, 1 },
187 { 1, 0.0f, 0 },
188 { 0, 10.0f, 0 },
189 { 1, std::numeric_limits<float>::quiet_NaN(), 0 },
190 };
191
192 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
193 const TestCase& value = test_cases[i];
194 for (int k = 0; k < 3; ++k) {
195 gfx::Point3f p0, p1, p2;
196 ui::Transform xform;
197 switch (k) {
198 case 0:
199 p1.SetPoint(value.before, 0, 0);
200 p2.SetPoint(value.after, 0, 0);
201 xform.SetScaleX(value.s);
202 break;
203 case 1:
204 p1.SetPoint(0, value.before, 0);
205 p2.SetPoint(0, value.after, 0);
206 xform.SetScaleY(value.s);
207 break;
208 case 2:
209 p1.SetPoint(value.before, value.before, 0);
210 p2.SetPoint(value.after, value.after, 0);
211 xform.SetScale(value.s, value.s);
212 break;
213 }
214 p0 = p1;
215 xform.TransformPoint(p1);
216 if (value.s == value.s) {
217 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
218 if (value.s != 0.0f) {
219 xform.TransformPointReverse(p1);
220 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0));
221 }
222 }
223 }
224 }
225 }
226
227 TEST(XFormTest, SetRotate) {
228 static const struct SetRotateCase {
229 int x;
230 int y;
231 float degree;
232 int xprime;
233 int yprime;
234 } set_rotate_cases[] = {
235 { 100, 0, 90.0f, 0, 100 },
236 { 0, 0, 90.0f, 0, 0 },
237 { 0, 100, 90.0f, -100, 0 },
238 { 0, 1, -90.0f, 1, 0 },
239 { 100, 0, 0.0f, 100, 0 },
240 { 0, 0, 0.0f, 0, 0 },
241 { 0, 0, std::numeric_limits<float>::quiet_NaN(), 0, 0 },
242 { 100, 0, 360.0f, 100, 0 }
243 };
244
245 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) {
246 const SetRotateCase& value = set_rotate_cases[i];
247 gfx::Point3f p0;
248 gfx::Point3f p1(value.x, value.y, 0);
249 gfx::Point3f p2(value.xprime, value.yprime, 0);
250 p0 = p1;
251 ui::Transform xform;
252 xform.SetRotate(value.degree);
253 // just want to make sure that we don't crash in the case of NaN.
254 if (value.degree == value.degree) {
255 xform.TransformPoint(p1);
256 EXPECT_TRUE(PointsAreNearlyEqual(p1, p2));
257 xform.TransformPointReverse(p1);
258 EXPECT_TRUE(PointsAreNearlyEqual(p1, p0));
259 }
260 }
261 }
262
263 // 2D tests
264 TEST(XFormTest, ConcatTranslate2D) {
265 static const struct TestCase {
266 int x1;
267 int y1;
268 float tx;
269 float ty;
270 int x2;
271 int y2;
272 } test_cases[] = {
273 { 0, 0, 10.0f, 20.0f, 10, 20},
274 { 0, 0, -10.0f, -20.0f, 0, 0},
275 { 0, 0, -10.0f, -20.0f, -10, -20},
276 { 0, 0,
277 std::numeric_limits<float>::quiet_NaN(),
278 std::numeric_limits<float>::quiet_NaN(),
279 10, 20},
280 };
281
282 ui::Transform xform;
283 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
284 const TestCase& value = test_cases[i];
285 xform.ConcatTranslate(value.tx, value.ty);
286 gfx::Point p1(value.x1, value.y1);
287 gfx::Point p2(value.x2, value.y2);
288 xform.TransformPoint(p1);
289 if (value.tx == value.tx &&
290 value.ty == value.ty) {
291 EXPECT_EQ(p1.x(), p2.x());
292 EXPECT_EQ(p1.y(), p2.y());
293 }
294 }
295 }
296
297 TEST(XFormTest, ConcatScale2D) {
298 static const struct TestCase {
299 int before;
300 float scale;
301 int after;
302 } test_cases[] = {
303 { 1, 10.0f, 10},
304 { 1, .1f, 1},
305 { 1, 100.0f, 100},
306 { 1, -1.0f, -100},
307 { 1, std::numeric_limits<float>::quiet_NaN(), 1}
308 };
309
310 ui::Transform xform;
311 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
312 const TestCase& value = test_cases[i];
313 xform.ConcatScale(value.scale, value.scale);
314 gfx::Point p1(value.before, value.before);
315 gfx::Point p2(value.after, value.after);
316 xform.TransformPoint(p1);
317 if (value.scale == value.scale) {
318 EXPECT_EQ(p1.x(), p2.x());
319 EXPECT_EQ(p1.y(), p2.y());
320 }
321 }
322 }
323
324 TEST(XFormTest, ConcatRotate2D) {
325 static const struct TestCase {
326 int x1;
327 int y1;
328 float degrees;
329 int x2;
330 int y2;
331 } test_cases[] = {
332 { 1, 0, 90.0f, 0, 1},
333 { 1, 0, -90.0f, 1, 0},
334 { 1, 0, 90.0f, 0, 1},
335 { 1, 0, 360.0f, 0, 1},
336 { 1, 0, 0.0f, 0, 1},
337 { 1, 0, std::numeric_limits<float>::quiet_NaN(), 1, 0}
338 };
339
340 ui::Transform xform;
341 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
342 const TestCase& value = test_cases[i];
343 xform.ConcatRotate(value.degrees);
344 gfx::Point p1(value.x1, value.y1);
345 gfx::Point p2(value.x2, value.y2);
346 xform.TransformPoint(p1);
347 if (value.degrees == value.degrees) {
348 EXPECT_EQ(p1.x(), p2.x());
349 EXPECT_EQ(p1.y(), p2.y());
350 }
351 }
352 }
353
354 TEST(XFormTest, SetTranslate2D) {
355 static const struct TestCase {
356 int x1; int y1;
357 float tx; float ty;
358 int x2; int y2;
359 } test_cases[] = {
360 { 0, 0, 10.0f, 20.0f, 10, 20},
361 { 10, 20, 10.0f, 20.0f, 20, 40},
362 { 10, 20, 0.0f, 0.0f, 10, 20},
363 { 0, 0,
364 std::numeric_limits<float>::quiet_NaN(),
365 std::numeric_limits<float>::quiet_NaN(),
366 0, 0}
367 };
368
369 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
370 const TestCase& value = test_cases[i];
371 for (int j = -1; j < 2; ++j) {
372 for (int k = 0; k < 3; ++k) {
373 float epsilon = 0.0001f;
374 gfx::Point p0, p1, p2;
375 ui::Transform xform;
376 switch (k) {
377 case 0:
378 p1.SetPoint(value.x1, 0);
379 p2.SetPoint(value.x2, 0);
380 xform.SetTranslateX(value.tx + j * epsilon);
381 break;
382 case 1:
383 p1.SetPoint(0, value.y1);
384 p2.SetPoint(0, value.y2);
385 xform.SetTranslateY(value.ty + j * epsilon);
386 break;
387 case 2:
388 p1.SetPoint(value.x1, value.y1);
389 p2.SetPoint(value.x2, value.y2);
390 xform.SetTranslate(value.tx + j * epsilon,
391 value.ty + j * epsilon);
392 break;
393 }
394 p0 = p1;
395 xform.TransformPoint(p1);
396 if (value.tx == value.tx &&
397 value.ty == value.ty) {
398 EXPECT_EQ(p1.x(), p2.x());
399 EXPECT_EQ(p1.y(), p2.y());
400 xform.TransformPointReverse(p1);
401 EXPECT_EQ(p1.x(), p0.x());
402 EXPECT_EQ(p1.y(), p0.y());
403 }
404 }
405 }
406 }
407 }
408
409 TEST(XFormTest, SetScale2D) {
410 static const struct TestCase {
411 int before;
412 float s;
413 int after;
414 } test_cases[] = {
415 { 1, 10.0f, 10},
416 { 1, 1.0f, 1},
417 { 1, 0.0f, 0},
418 { 0, 10.0f, 0},
419 { 1, std::numeric_limits<float>::quiet_NaN(), 0},
420 };
421
422 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
423 const TestCase& value = test_cases[i];
424 for (int j = -1; j < 2; ++j) {
425 for (int k = 0; k < 3; ++k) {
426 float epsilon = 0.0001f;
427 gfx::Point p0, p1, p2;
428 ui::Transform xform;
429 switch (k) {
430 case 0:
431 p1.SetPoint(value.before, 0);
432 p2.SetPoint(value.after, 0);
433 xform.SetScaleX(value.s + j * epsilon);
434 break;
435 case 1:
436 p1.SetPoint(0, value.before);
437 p2.SetPoint(0, value.after);
438 xform.SetScaleY(value.s + j * epsilon);
439 break;
440 case 2:
441 p1.SetPoint(value.before,
442 value.before);
443 p2.SetPoint(value.after,
444 value.after);
445 xform.SetScale(value.s + j * epsilon,
446 value.s + j * epsilon);
447 break;
448 }
449 p0 = p1;
450 xform.TransformPoint(p1);
451 if (value.s == value.s) {
452 EXPECT_EQ(p1.x(), p2.x());
453 EXPECT_EQ(p1.y(), p2.y());
454 if (value.s != 0.0f) {
455 xform.TransformPointReverse(p1);
456 EXPECT_EQ(p1.x(), p0.x());
457 EXPECT_EQ(p1.y(), p0.y());
458 }
459 }
460 }
461 }
462 }
463 }
464
465 TEST(XFormTest, SetRotate2D) {
466 static const struct SetRotateCase {
467 int x;
468 int y;
469 float degree;
470 int xprime;
471 int yprime;
472 } set_rotate_cases[] = {
473 { 100, 0, 90.0f, 0, 100},
474 { 0, 0, 90.0f, 0, 0},
475 { 0, 100, 90.0f, -100, 0},
476 { 0, 1, -90.0f, 1, 0},
477 { 100, 0, 0.0f, 100, 0},
478 { 0, 0, 0.0f, 0, 0},
479 { 0, 0, std::numeric_limits<float>::quiet_NaN(), 0, 0},
480 { 100, 0, 360.0f, 100, 0}
481 };
482
483 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(set_rotate_cases); ++i) {
484 const SetRotateCase& value = set_rotate_cases[i];
485 for (int j = 1; j >= -1; --j) {
486 float epsilon = 0.1f;
487 gfx::Point pt(value.x, value.y);
488 ui::Transform xform;
489 // should be invariant to small floating point errors.
490 xform.SetRotate(value.degree + j * epsilon);
491 // just want to make sure that we don't crash in the case of NaN.
492 if (value.degree == value.degree) {
493 xform.TransformPoint(pt);
494 EXPECT_EQ(value.xprime, pt.x());
495 EXPECT_EQ(value.yprime, pt.y());
496 xform.TransformPointReverse(pt);
497 EXPECT_EQ(pt.x(), value.x);
498 EXPECT_EQ(pt.y(), value.y);
499 }
500 }
501 }
502 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698