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

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

Powered by Google App Engine
This is Rietveld 408576698