base: Use more specific CHECK macros for comparisons.
[chromium-blink-merge.git] / cc / animation / transform_operations_unittest.cc
blob7aae696db4c15d8ba3bba8c549d7c8ca59a02b92
1 // Copyright 2013 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.
5 #include <limits>
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_vector.h"
9 #include "cc/animation/transform_operations.h"
10 #include "cc/test/geometry_test_utils.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gfx/animation/tween.h"
13 #include "ui/gfx/geometry/box_f.h"
14 #include "ui/gfx/geometry/rect_conversions.h"
15 #include "ui/gfx/geometry/vector3d_f.h"
17 namespace cc {
18 namespace {
20 TEST(TransformOperationTest, TransformTypesAreUnique) {
21 ScopedVector<TransformOperations> transforms;
23 TransformOperations* to_add = new TransformOperations();
24 to_add->AppendTranslate(1, 0, 0);
25 transforms.push_back(to_add);
27 to_add = new TransformOperations();
28 to_add->AppendRotate(0, 0, 1, 2);
29 transforms.push_back(to_add);
31 to_add = new TransformOperations();
32 to_add->AppendScale(2, 2, 2);
33 transforms.push_back(to_add);
35 to_add = new TransformOperations();
36 to_add->AppendSkew(1, 0);
37 transforms.push_back(to_add);
39 to_add = new TransformOperations();
40 to_add->AppendPerspective(800);
41 transforms.push_back(to_add);
43 for (size_t i = 0; i < transforms.size(); ++i) {
44 for (size_t j = 0; j < transforms.size(); ++j) {
45 bool matches_type = transforms[i]->MatchesTypes(*transforms[j]);
46 EXPECT_TRUE((i == j && matches_type) || !matches_type);
51 TEST(TransformOperationTest, MatchTypesSameLength) {
52 TransformOperations translates;
53 translates.AppendTranslate(1, 0, 0);
54 translates.AppendTranslate(1, 0, 0);
55 translates.AppendTranslate(1, 0, 0);
57 TransformOperations skews;
58 skews.AppendSkew(0, 2);
59 skews.AppendSkew(0, 2);
60 skews.AppendSkew(0, 2);
62 TransformOperations translates2;
63 translates2.AppendTranslate(0, 2, 0);
64 translates2.AppendTranslate(0, 2, 0);
65 translates2.AppendTranslate(0, 2, 0);
67 TransformOperations translates3 = translates2;
69 EXPECT_FALSE(translates.MatchesTypes(skews));
70 EXPECT_TRUE(translates.MatchesTypes(translates2));
71 EXPECT_TRUE(translates.MatchesTypes(translates3));
74 TEST(TransformOperationTest, MatchTypesDifferentLength) {
75 TransformOperations translates;
76 translates.AppendTranslate(1, 0, 0);
77 translates.AppendTranslate(1, 0, 0);
78 translates.AppendTranslate(1, 0, 0);
80 TransformOperations skews;
81 skews.AppendSkew(2, 0);
82 skews.AppendSkew(2, 0);
84 TransformOperations translates2;
85 translates2.AppendTranslate(0, 2, 0);
86 translates2.AppendTranslate(0, 2, 0);
88 EXPECT_FALSE(translates.MatchesTypes(skews));
89 EXPECT_FALSE(translates.MatchesTypes(translates2));
92 void GetIdentityOperations(ScopedVector<TransformOperations>* operations) {
93 TransformOperations* to_add = new TransformOperations();
94 operations->push_back(to_add);
96 to_add = new TransformOperations();
97 to_add->AppendTranslate(0, 0, 0);
98 operations->push_back(to_add);
100 to_add = new TransformOperations();
101 to_add->AppendTranslate(0, 0, 0);
102 to_add->AppendTranslate(0, 0, 0);
103 operations->push_back(to_add);
105 to_add = new TransformOperations();
106 to_add->AppendScale(1, 1, 1);
107 operations->push_back(to_add);
109 to_add = new TransformOperations();
110 to_add->AppendScale(1, 1, 1);
111 to_add->AppendScale(1, 1, 1);
112 operations->push_back(to_add);
114 to_add = new TransformOperations();
115 to_add->AppendSkew(0, 0);
116 operations->push_back(to_add);
118 to_add = new TransformOperations();
119 to_add->AppendSkew(0, 0);
120 to_add->AppendSkew(0, 0);
121 operations->push_back(to_add);
123 to_add = new TransformOperations();
124 to_add->AppendRotate(0, 0, 1, 0);
125 operations->push_back(to_add);
127 to_add = new TransformOperations();
128 to_add->AppendRotate(0, 0, 1, 0);
129 to_add->AppendRotate(0, 0, 1, 0);
130 operations->push_back(to_add);
132 to_add = new TransformOperations();
133 to_add->AppendMatrix(gfx::Transform());
134 operations->push_back(to_add);
136 to_add = new TransformOperations();
137 to_add->AppendMatrix(gfx::Transform());
138 to_add->AppendMatrix(gfx::Transform());
139 operations->push_back(to_add);
142 TEST(TransformOperationTest, IdentityAlwaysMatches) {
143 ScopedVector<TransformOperations> operations;
144 GetIdentityOperations(&operations);
146 for (size_t i = 0; i < operations.size(); ++i) {
147 for (size_t j = 0; j < operations.size(); ++j)
148 EXPECT_TRUE(operations[i]->MatchesTypes(*operations[j]));
152 TEST(TransformOperationTest, ApplyTranslate) {
153 SkMScalar x = 1;
154 SkMScalar y = 2;
155 SkMScalar z = 3;
156 TransformOperations operations;
157 operations.AppendTranslate(x, y, z);
158 gfx::Transform expected;
159 expected.Translate3d(x, y, z);
160 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
163 TEST(TransformOperationTest, ApplyRotate) {
164 SkMScalar x = 1;
165 SkMScalar y = 2;
166 SkMScalar z = 3;
167 SkMScalar degrees = 80;
168 TransformOperations operations;
169 operations.AppendRotate(x, y, z, degrees);
170 gfx::Transform expected;
171 expected.RotateAbout(gfx::Vector3dF(x, y, z), degrees);
172 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
175 TEST(TransformOperationTest, ApplyScale) {
176 SkMScalar x = 1;
177 SkMScalar y = 2;
178 SkMScalar z = 3;
179 TransformOperations operations;
180 operations.AppendScale(x, y, z);
181 gfx::Transform expected;
182 expected.Scale3d(x, y, z);
183 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
186 TEST(TransformOperationTest, ApplySkew) {
187 SkMScalar x = 1;
188 SkMScalar y = 2;
189 TransformOperations operations;
190 operations.AppendSkew(x, y);
191 gfx::Transform expected;
192 expected.SkewX(x);
193 expected.SkewY(y);
194 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
197 TEST(TransformOperationTest, ApplyPerspective) {
198 SkMScalar depth = 800;
199 TransformOperations operations;
200 operations.AppendPerspective(depth);
201 gfx::Transform expected;
202 expected.ApplyPerspectiveDepth(depth);
203 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, operations.Apply());
206 TEST(TransformOperationTest, ApplyMatrix) {
207 SkMScalar dx = 1;
208 SkMScalar dy = 2;
209 SkMScalar dz = 3;
210 gfx::Transform expected_matrix;
211 expected_matrix.Translate3d(dx, dy, dz);
212 TransformOperations matrix_transform;
213 matrix_transform.AppendMatrix(expected_matrix);
214 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_matrix, matrix_transform.Apply());
217 TEST(TransformOperationTest, ApplyOrder) {
218 SkMScalar sx = 2;
219 SkMScalar sy = 4;
220 SkMScalar sz = 8;
222 SkMScalar dx = 1;
223 SkMScalar dy = 2;
224 SkMScalar dz = 3;
226 TransformOperations operations;
227 operations.AppendScale(sx, sy, sz);
228 operations.AppendTranslate(dx, dy, dz);
230 gfx::Transform expected_scale_matrix;
231 expected_scale_matrix.Scale3d(sx, sy, sz);
233 gfx::Transform expected_translate_matrix;
234 expected_translate_matrix.Translate3d(dx, dy, dz);
236 gfx::Transform expected_combined_matrix = expected_scale_matrix;
237 expected_combined_matrix.PreconcatTransform(expected_translate_matrix);
239 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_combined_matrix, operations.Apply());
242 TEST(TransformOperationTest, BlendOrder) {
243 SkMScalar sx1 = 2;
244 SkMScalar sy1 = 4;
245 SkMScalar sz1 = 8;
247 SkMScalar dx1 = 1;
248 SkMScalar dy1 = 2;
249 SkMScalar dz1 = 3;
251 SkMScalar sx2 = 4;
252 SkMScalar sy2 = 8;
253 SkMScalar sz2 = 16;
255 SkMScalar dx2 = 10;
256 SkMScalar dy2 = 20;
257 SkMScalar dz2 = 30;
259 TransformOperations operations_from;
260 operations_from.AppendScale(sx1, sy1, sz1);
261 operations_from.AppendTranslate(dx1, dy1, dz1);
263 TransformOperations operations_to;
264 operations_to.AppendScale(sx2, sy2, sz2);
265 operations_to.AppendTranslate(dx2, dy2, dz2);
267 gfx::Transform scale_from;
268 scale_from.Scale3d(sx1, sy1, sz1);
269 gfx::Transform translate_from;
270 translate_from.Translate3d(dx1, dy1, dz1);
272 gfx::Transform scale_to;
273 scale_to.Scale3d(sx2, sy2, sz2);
274 gfx::Transform translate_to;
275 translate_to.Translate3d(dx2, dy2, dz2);
277 SkMScalar progress = 0.25f;
279 gfx::Transform blended_scale = scale_to;
280 blended_scale.Blend(scale_from, progress);
282 gfx::Transform blended_translate = translate_to;
283 blended_translate.Blend(translate_from, progress);
285 gfx::Transform expected = blended_scale;
286 expected.PreconcatTransform(blended_translate);
288 EXPECT_TRANSFORMATION_MATRIX_EQ(
289 expected, operations_to.Blend(operations_from, progress));
292 static void CheckProgress(SkMScalar progress,
293 const gfx::Transform& from_matrix,
294 const gfx::Transform& to_matrix,
295 const TransformOperations& from_transform,
296 const TransformOperations& to_transform) {
297 gfx::Transform expected_matrix = to_matrix;
298 expected_matrix.Blend(from_matrix, progress);
299 EXPECT_TRANSFORMATION_MATRIX_EQ(
300 expected_matrix, to_transform.Blend(from_transform, progress));
303 TEST(TransformOperationTest, BlendProgress) {
304 SkMScalar sx = 2;
305 SkMScalar sy = 4;
306 SkMScalar sz = 8;
307 TransformOperations operations_from;
308 operations_from.AppendScale(sx, sy, sz);
310 gfx::Transform matrix_from;
311 matrix_from.Scale3d(sx, sy, sz);
313 sx = 4;
314 sy = 8;
315 sz = 16;
316 TransformOperations operations_to;
317 operations_to.AppendScale(sx, sy, sz);
319 gfx::Transform matrix_to;
320 matrix_to.Scale3d(sx, sy, sz);
322 CheckProgress(-1, matrix_from, matrix_to, operations_from, operations_to);
323 CheckProgress(0, matrix_from, matrix_to, operations_from, operations_to);
324 CheckProgress(0.25f, matrix_from, matrix_to, operations_from, operations_to);
325 CheckProgress(0.5f, matrix_from, matrix_to, operations_from, operations_to);
326 CheckProgress(1, matrix_from, matrix_to, operations_from, operations_to);
327 CheckProgress(2, matrix_from, matrix_to, operations_from, operations_to);
330 TEST(TransformOperationTest, BlendWhenTypesDoNotMatch) {
331 SkMScalar sx1 = 2;
332 SkMScalar sy1 = 4;
333 SkMScalar sz1 = 8;
335 SkMScalar dx1 = 1;
336 SkMScalar dy1 = 2;
337 SkMScalar dz1 = 3;
339 SkMScalar sx2 = 4;
340 SkMScalar sy2 = 8;
341 SkMScalar sz2 = 16;
343 SkMScalar dx2 = 10;
344 SkMScalar dy2 = 20;
345 SkMScalar dz2 = 30;
347 TransformOperations operations_from;
348 operations_from.AppendScale(sx1, sy1, sz1);
349 operations_from.AppendTranslate(dx1, dy1, dz1);
351 TransformOperations operations_to;
352 operations_to.AppendTranslate(dx2, dy2, dz2);
353 operations_to.AppendScale(sx2, sy2, sz2);
355 gfx::Transform from;
356 from.Scale3d(sx1, sy1, sz1);
357 from.Translate3d(dx1, dy1, dz1);
359 gfx::Transform to;
360 to.Translate3d(dx2, dy2, dz2);
361 to.Scale3d(sx2, sy2, sz2);
363 SkMScalar progress = 0.25f;
365 gfx::Transform expected = to;
366 expected.Blend(from, progress);
368 EXPECT_TRANSFORMATION_MATRIX_EQ(
369 expected, operations_to.Blend(operations_from, progress));
372 TEST(TransformOperationTest, LargeRotationsWithSameAxis) {
373 TransformOperations operations_from;
374 operations_from.AppendRotate(0, 0, 1, 0);
376 TransformOperations operations_to;
377 operations_to.AppendRotate(0, 0, 2, 360);
379 SkMScalar progress = 0.5f;
381 gfx::Transform expected;
382 expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
384 EXPECT_TRANSFORMATION_MATRIX_EQ(
385 expected, operations_to.Blend(operations_from, progress));
388 TEST(TransformOperationTest, LargeRotationsWithSameAxisInDifferentDirection) {
389 TransformOperations operations_from;
390 operations_from.AppendRotate(0, 0, 1, 180);
392 TransformOperations operations_to;
393 operations_to.AppendRotate(0, 0, -1, 180);
395 SkMScalar progress = 0.5f;
397 gfx::Transform expected;
399 EXPECT_TRANSFORMATION_MATRIX_EQ(
400 expected, operations_to.Blend(operations_from, progress));
403 TEST(TransformOperationTest, LargeRotationsWithDifferentAxes) {
404 TransformOperations operations_from;
405 operations_from.AppendRotate(0, 0, 1, 175);
407 TransformOperations operations_to;
408 operations_to.AppendRotate(0, 1, 0, 175);
410 SkMScalar progress = 0.5f;
411 gfx::Transform matrix_from;
412 matrix_from.RotateAbout(gfx::Vector3dF(0, 0, 1), 175);
414 gfx::Transform matrix_to;
415 matrix_to.RotateAbout(gfx::Vector3dF(0, 1, 0), 175);
417 gfx::Transform expected = matrix_to;
418 expected.Blend(matrix_from, progress);
420 EXPECT_TRANSFORMATION_MATRIX_EQ(
421 expected, operations_to.Blend(operations_from, progress));
424 TEST(TransformOperationTest, BlendRotationFromIdentity) {
425 ScopedVector<TransformOperations> identity_operations;
426 GetIdentityOperations(&identity_operations);
428 for (size_t i = 0; i < identity_operations.size(); ++i) {
429 TransformOperations operations;
430 operations.AppendRotate(0, 0, 1, 360);
432 SkMScalar progress = 0.5f;
434 gfx::Transform expected;
435 expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
437 EXPECT_TRANSFORMATION_MATRIX_EQ(
438 expected, operations.Blend(*identity_operations[i], progress));
440 progress = -0.5f;
442 expected.MakeIdentity();
443 expected.RotateAbout(gfx::Vector3dF(0, 0, 1), -180);
445 EXPECT_TRANSFORMATION_MATRIX_EQ(
446 expected, operations.Blend(*identity_operations[i], progress));
448 progress = 1.5f;
450 expected.MakeIdentity();
451 expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 540);
453 EXPECT_TRANSFORMATION_MATRIX_EQ(
454 expected, operations.Blend(*identity_operations[i], progress));
458 TEST(TransformOperationTest, BlendTranslationFromIdentity) {
459 ScopedVector<TransformOperations> identity_operations;
460 GetIdentityOperations(&identity_operations);
462 for (size_t i = 0; i < identity_operations.size(); ++i) {
463 TransformOperations operations;
464 operations.AppendTranslate(2, 2, 2);
466 SkMScalar progress = 0.5f;
468 gfx::Transform expected;
469 expected.Translate3d(1, 1, 1);
471 EXPECT_TRANSFORMATION_MATRIX_EQ(
472 expected, operations.Blend(*identity_operations[i], progress));
474 progress = -0.5f;
476 expected.MakeIdentity();
477 expected.Translate3d(-1, -1, -1);
479 EXPECT_TRANSFORMATION_MATRIX_EQ(
480 expected, operations.Blend(*identity_operations[i], progress));
482 progress = 1.5f;
484 expected.MakeIdentity();
485 expected.Translate3d(3, 3, 3);
487 EXPECT_TRANSFORMATION_MATRIX_EQ(
488 expected, operations.Blend(*identity_operations[i], progress));
492 TEST(TransformOperationTest, BlendScaleFromIdentity) {
493 ScopedVector<TransformOperations> identity_operations;
494 GetIdentityOperations(&identity_operations);
496 for (size_t i = 0; i < identity_operations.size(); ++i) {
497 TransformOperations operations;
498 operations.AppendScale(3, 3, 3);
500 SkMScalar progress = 0.5f;
502 gfx::Transform expected;
503 expected.Scale3d(2, 2, 2);
505 EXPECT_TRANSFORMATION_MATRIX_EQ(
506 expected, operations.Blend(*identity_operations[i], progress));
508 progress = -0.5f;
510 expected.MakeIdentity();
511 expected.Scale3d(0, 0, 0);
513 EXPECT_TRANSFORMATION_MATRIX_EQ(
514 expected, operations.Blend(*identity_operations[i], progress));
516 progress = 1.5f;
518 expected.MakeIdentity();
519 expected.Scale3d(4, 4, 4);
521 EXPECT_TRANSFORMATION_MATRIX_EQ(
522 expected, operations.Blend(*identity_operations[i], progress));
526 TEST(TransformOperationTest, BlendSkewFromIdentity) {
527 ScopedVector<TransformOperations> identity_operations;
528 GetIdentityOperations(&identity_operations);
530 for (size_t i = 0; i < identity_operations.size(); ++i) {
531 TransformOperations operations;
532 operations.AppendSkew(2, 2);
534 SkMScalar progress = 0.5f;
536 gfx::Transform expected;
537 expected.SkewX(1);
538 expected.SkewY(1);
540 EXPECT_TRANSFORMATION_MATRIX_EQ(
541 expected, operations.Blend(*identity_operations[i], progress));
543 progress = -0.5f;
545 expected.MakeIdentity();
546 expected.SkewX(-1);
547 expected.SkewY(-1);
549 EXPECT_TRANSFORMATION_MATRIX_EQ(
550 expected, operations.Blend(*identity_operations[i], progress));
552 progress = 1.5f;
554 expected.MakeIdentity();
555 expected.SkewX(3);
556 expected.SkewY(3);
558 EXPECT_TRANSFORMATION_MATRIX_EQ(
559 expected, operations.Blend(*identity_operations[i], progress));
563 TEST(TransformOperationTest, BlendPerspectiveFromIdentity) {
564 ScopedVector<TransformOperations> identity_operations;
565 GetIdentityOperations(&identity_operations);
567 for (size_t i = 0; i < identity_operations.size(); ++i) {
568 TransformOperations operations;
569 operations.AppendPerspective(1000);
571 SkMScalar progress = 0.5f;
573 gfx::Transform expected;
574 expected.ApplyPerspectiveDepth(2000);
576 EXPECT_TRANSFORMATION_MATRIX_EQ(
577 expected, operations.Blend(*identity_operations[i], progress));
581 TEST(TransformOperationTest, BlendRotationToIdentity) {
582 ScopedVector<TransformOperations> identity_operations;
583 GetIdentityOperations(&identity_operations);
585 for (size_t i = 0; i < identity_operations.size(); ++i) {
586 TransformOperations operations;
587 operations.AppendRotate(0, 0, 1, 360);
589 SkMScalar progress = 0.5f;
591 gfx::Transform expected;
592 expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
594 EXPECT_TRANSFORMATION_MATRIX_EQ(
595 expected, identity_operations[i]->Blend(operations, progress));
599 TEST(TransformOperationTest, BlendTranslationToIdentity) {
600 ScopedVector<TransformOperations> identity_operations;
601 GetIdentityOperations(&identity_operations);
603 for (size_t i = 0; i < identity_operations.size(); ++i) {
604 TransformOperations operations;
605 operations.AppendTranslate(2, 2, 2);
607 SkMScalar progress = 0.5f;
609 gfx::Transform expected;
610 expected.Translate3d(1, 1, 1);
612 EXPECT_TRANSFORMATION_MATRIX_EQ(
613 expected, identity_operations[i]->Blend(operations, progress));
617 TEST(TransformOperationTest, BlendScaleToIdentity) {
618 ScopedVector<TransformOperations> identity_operations;
619 GetIdentityOperations(&identity_operations);
621 for (size_t i = 0; i < identity_operations.size(); ++i) {
622 TransformOperations operations;
623 operations.AppendScale(3, 3, 3);
625 SkMScalar progress = 0.5f;
627 gfx::Transform expected;
628 expected.Scale3d(2, 2, 2);
630 EXPECT_TRANSFORMATION_MATRIX_EQ(
631 expected, identity_operations[i]->Blend(operations, progress));
635 TEST(TransformOperationTest, BlendSkewToIdentity) {
636 ScopedVector<TransformOperations> identity_operations;
637 GetIdentityOperations(&identity_operations);
639 for (size_t i = 0; i < identity_operations.size(); ++i) {
640 TransformOperations operations;
641 operations.AppendSkew(2, 2);
643 SkMScalar progress = 0.5f;
645 gfx::Transform expected;
646 expected.SkewX(1);
647 expected.SkewY(1);
649 EXPECT_TRANSFORMATION_MATRIX_EQ(
650 expected, identity_operations[i]->Blend(operations, progress));
654 TEST(TransformOperationTest, BlendPerspectiveToIdentity) {
655 ScopedVector<TransformOperations> identity_operations;
656 GetIdentityOperations(&identity_operations);
658 for (size_t i = 0; i < identity_operations.size(); ++i) {
659 TransformOperations operations;
660 operations.AppendPerspective(1000);
662 SkMScalar progress = 0.5f;
664 gfx::Transform expected;
665 expected.ApplyPerspectiveDepth(2000);
667 EXPECT_TRANSFORMATION_MATRIX_EQ(
668 expected, identity_operations[i]->Blend(operations, progress));
672 TEST(TransformOperationTest, ExtrapolatePerspectiveBlending) {
673 TransformOperations operations1;
674 operations1.AppendPerspective(1000);
676 TransformOperations operations2;
677 operations2.AppendPerspective(500);
679 gfx::Transform expected;
680 expected.ApplyPerspectiveDepth(400);
682 EXPECT_TRANSFORMATION_MATRIX_EQ(
683 expected, operations1.Blend(operations2, -0.5));
685 expected.MakeIdentity();
686 expected.ApplyPerspectiveDepth(2000);
688 EXPECT_TRANSFORMATION_MATRIX_EQ(
689 expected, operations1.Blend(operations2, 1.5));
692 TEST(TransformOperationTest, ExtrapolateMatrixBlending) {
693 gfx::Transform transform1;
694 transform1.Translate3d(1, 1, 1);
695 TransformOperations operations1;
696 operations1.AppendMatrix(transform1);
698 gfx::Transform transform2;
699 transform2.Translate3d(3, 3, 3);
700 TransformOperations operations2;
701 operations2.AppendMatrix(transform2);
703 gfx::Transform expected;
704 EXPECT_TRANSFORMATION_MATRIX_EQ(
705 expected, operations1.Blend(operations2, 1.5));
707 expected.Translate3d(4, 4, 4);
708 EXPECT_TRANSFORMATION_MATRIX_EQ(
709 expected, operations1.Blend(operations2, -0.5));
712 TEST(TransformOperationTest, BlendedBoundsWhenTypesDoNotMatch) {
713 TransformOperations operations_from;
714 operations_from.AppendScale(2.0, 4.0, 8.0);
715 operations_from.AppendTranslate(1.0, 2.0, 3.0);
717 TransformOperations operations_to;
718 operations_to.AppendTranslate(10.0, 20.0, 30.0);
719 operations_to.AppendScale(4.0, 8.0, 16.0);
721 gfx::BoxF box(1.f, 1.f, 1.f);
722 gfx::BoxF bounds;
724 SkMScalar min_progress = 0.f;
725 SkMScalar max_progress = 1.f;
727 EXPECT_FALSE(operations_to.BlendedBoundsForBox(
728 box, operations_from, min_progress, max_progress, &bounds));
731 TEST(TransformOperationTest, BlendedBoundsForIdentity) {
732 TransformOperations operations_from;
733 operations_from.AppendIdentity();
734 TransformOperations operations_to;
735 operations_to.AppendIdentity();
737 gfx::BoxF box(1.f, 2.f, 3.f);
738 gfx::BoxF bounds;
740 SkMScalar min_progress = 0.f;
741 SkMScalar max_progress = 1.f;
743 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
744 box, operations_from, min_progress, max_progress, &bounds));
745 EXPECT_EQ(box.ToString(), bounds.ToString());
748 TEST(TransformOperationTest, BlendedBoundsForTranslate) {
749 TransformOperations operations_from;
750 operations_from.AppendTranslate(3.0, -4.0, 2.0);
751 TransformOperations operations_to;
752 operations_to.AppendTranslate(7.0, 4.0, -2.0);
754 gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
755 gfx::BoxF bounds;
757 SkMScalar min_progress = -0.5f;
758 SkMScalar max_progress = 1.5f;
759 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
760 box, operations_from, min_progress, max_progress, &bounds));
761 EXPECT_EQ(gfx::BoxF(2.f, -6.f, -1.f, 12.f, 20.f, 12.f).ToString(),
762 bounds.ToString());
764 min_progress = 0.f;
765 max_progress = 1.f;
766 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
767 box, operations_from, min_progress, max_progress, &bounds));
768 EXPECT_EQ(gfx::BoxF(4.f, -2.f, 1.f, 8.f, 12.f, 8.f).ToString(),
769 bounds.ToString());
771 TransformOperations identity;
772 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
773 box, identity, min_progress, max_progress, &bounds));
774 EXPECT_EQ(gfx::BoxF(1.f, 2.f, 1.f, 11.f, 8.f, 6.f).ToString(),
775 bounds.ToString());
777 EXPECT_TRUE(identity.BlendedBoundsForBox(
778 box, operations_from, min_progress, max_progress, &bounds));
779 EXPECT_EQ(gfx::BoxF(1.f, -2.f, 3.f, 7.f, 8.f, 6.f).ToString(),
780 bounds.ToString());
783 TEST(TransformOperationTest, BlendedBoundsForScale) {
784 TransformOperations operations_from;
785 operations_from.AppendScale(3.0, 0.5, 2.0);
786 TransformOperations operations_to;
787 operations_to.AppendScale(7.0, 4.0, -2.0);
789 gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
790 gfx::BoxF bounds;
792 SkMScalar min_progress = -0.5f;
793 SkMScalar max_progress = 1.5f;
794 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
795 box, operations_from, min_progress, max_progress, &bounds));
796 EXPECT_EQ(gfx::BoxF(1.f, -7.5f, -28.f, 44.f, 42.f, 56.f).ToString(),
797 bounds.ToString());
799 min_progress = 0.f;
800 max_progress = 1.f;
801 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
802 box, operations_from, min_progress, max_progress, &bounds));
803 EXPECT_EQ(gfx::BoxF(3.f, 1.f, -14.f, 32.f, 23.f, 28.f).ToString(),
804 bounds.ToString());
806 TransformOperations identity;
807 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
808 box, identity, min_progress, max_progress, &bounds));
809 EXPECT_EQ(gfx::BoxF(1.f, 2.f, -14.f, 34.f, 22.f, 21.f).ToString(),
810 bounds.ToString());
812 EXPECT_TRUE(identity.BlendedBoundsForBox(
813 box, operations_from, min_progress, max_progress, &bounds));
814 EXPECT_EQ(gfx::BoxF(1.f, 1.f, 3.f, 14.f, 5.f, 11.f).ToString(),
815 bounds.ToString());
818 TEST(TransformOperationTest, BlendedBoundsWithZeroScale) {
819 TransformOperations zero_scale;
820 zero_scale.AppendScale(0.0, 0.0, 0.0);
821 TransformOperations non_zero_scale;
822 non_zero_scale.AppendScale(2.0, -4.0, 5.0);
824 gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
825 gfx::BoxF bounds;
827 SkMScalar min_progress = 0.f;
828 SkMScalar max_progress = 1.f;
829 EXPECT_TRUE(zero_scale.BlendedBoundsForBox(
830 box, non_zero_scale, min_progress, max_progress, &bounds));
831 EXPECT_EQ(gfx::BoxF(0.f, -24.f, 0.f, 10.f, 24.f, 35.f).ToString(),
832 bounds.ToString());
834 EXPECT_TRUE(non_zero_scale.BlendedBoundsForBox(
835 box, zero_scale, min_progress, max_progress, &bounds));
836 EXPECT_EQ(gfx::BoxF(0.f, -24.f, 0.f, 10.f, 24.f, 35.f).ToString(),
837 bounds.ToString());
839 EXPECT_TRUE(zero_scale.BlendedBoundsForBox(
840 box, zero_scale, min_progress, max_progress, &bounds));
841 EXPECT_EQ(gfx::BoxF().ToString(), bounds.ToString());
844 TEST(TransformOperationTest, BlendedBoundsForRotationTrivial) {
845 TransformOperations operations_from;
846 operations_from.AppendRotate(0.f, 0.f, 1.f, 0.f);
847 TransformOperations operations_to;
848 operations_to.AppendRotate(0.f, 0.f, 1.f, 360.f);
850 float sqrt_2 = sqrt(2.f);
851 gfx::BoxF box(
852 -sqrt_2, -sqrt_2, 0.f, sqrt_2, sqrt_2, 0.f);
853 gfx::BoxF bounds;
855 // Since we're rotating 360 degrees, any box with dimensions between 0 and
856 // 2 * sqrt(2) should give the same result.
857 float sizes[] = { 0.f, 0.1f, sqrt_2, 2.f * sqrt_2 };
858 for (size_t i = 0; i < arraysize(sizes); ++i) {
859 box.set_size(sizes[i], sizes[i], 0.f);
860 SkMScalar min_progress = 0.f;
861 SkMScalar max_progress = 1.f;
862 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
863 box, operations_from, min_progress, max_progress, &bounds));
864 EXPECT_EQ(gfx::BoxF(-2.f, -2.f, 0.f, 4.f, 4.f, 0.f).ToString(),
865 bounds.ToString());
869 TEST(TransformOperationTest, BlendedBoundsForRotationAllExtrema) {
870 // If the normal is out of the plane, we can have up to 6 extrema (a min/max
871 // in each dimension) between the endpoints of the arc. This test ensures that
872 // we consider all 6.
873 TransformOperations operations_from;
874 operations_from.AppendRotate(1.f, 1.f, 1.f, 30.f);
875 TransformOperations operations_to;
876 operations_to.AppendRotate(1.f, 1.f, 1.f, 390.f);
878 gfx::BoxF box(1.f, 0.f, 0.f, 0.f, 0.f, 0.f);
879 gfx::BoxF bounds;
881 float min = -1.f / 3.f;
882 float max = 1.f;
883 float size = max - min;
884 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
885 box, operations_from, 0.f, 1.f, &bounds));
886 EXPECT_EQ(gfx::BoxF(min, min, min, size, size, size).ToString(),
887 bounds.ToString());
890 TEST(TransformOperationTest, BlendedBoundsForRotationDifferentAxes) {
891 // We can handle rotations about a single axis. If the axes are different,
892 // we revert to matrix interpolation for which inflated bounds cannot be
893 // computed.
894 TransformOperations operations_from;
895 operations_from.AppendRotate(1.f, 1.f, 1.f, 30.f);
896 TransformOperations operations_to_same;
897 operations_to_same.AppendRotate(1.f, 1.f, 1.f, 390.f);
898 TransformOperations operations_to_opposite;
899 operations_to_opposite.AppendRotate(-1.f, -1.f, -1.f, 390.f);
900 TransformOperations operations_to_different;
901 operations_to_different.AppendRotate(1.f, 3.f, 1.f, 390.f);
903 gfx::BoxF box(1.f, 0.f, 0.f, 0.f, 0.f, 0.f);
904 gfx::BoxF bounds;
906 EXPECT_TRUE(operations_to_same.BlendedBoundsForBox(
907 box, operations_from, 0.f, 1.f, &bounds));
908 EXPECT_TRUE(operations_to_opposite.BlendedBoundsForBox(
909 box, operations_from, 0.f, 1.f, &bounds));
910 EXPECT_FALSE(operations_to_different.BlendedBoundsForBox(
911 box, operations_from, 0.f, 1.f, &bounds));
914 TEST(TransformOperationTest, BlendedBoundsForRotationPointOnAxis) {
915 // Checks that if the point to rotate is sitting on the axis of rotation, that
916 // it does not get affected.
917 TransformOperations operations_from;
918 operations_from.AppendRotate(1.f, 1.f, 1.f, 30.f);
919 TransformOperations operations_to;
920 operations_to.AppendRotate(1.f, 1.f, 1.f, 390.f);
922 gfx::BoxF box(1.f, 1.f, 1.f, 0.f, 0.f, 0.f);
923 gfx::BoxF bounds;
925 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
926 box, operations_from, 0.f, 1.f, &bounds));
927 EXPECT_EQ(box.ToString(), bounds.ToString());
930 TEST(TransformOperationTest, BlendedBoundsForRotationProblematicAxes) {
931 // Zeros in the components of the axis of rotation turned out to be tricky to
932 // deal with in practice. This function tests some potentially problematic
933 // axes to ensure sane behavior.
935 // Some common values used in the expected boxes.
936 float dim1 = 0.292893f;
937 float dim2 = sqrt(2.f);
938 float dim3 = 2.f * dim2;
940 struct {
941 float x;
942 float y;
943 float z;
944 gfx::BoxF expected;
945 } tests[] = {{0.f, 0.f, 0.f, gfx::BoxF(1.f, 1.f, 1.f, 0.f, 0.f, 0.f)},
946 {1.f, 0.f, 0.f, gfx::BoxF(1.f, -dim2, -dim2, 0.f, dim3, dim3)},
947 {0.f, 1.f, 0.f, gfx::BoxF(-dim2, 1.f, -dim2, dim3, 0.f, dim3)},
948 {0.f, 0.f, 1.f, gfx::BoxF(-dim2, -dim2, 1.f, dim3, dim3, 0.f)},
949 {1.f, 1.f, 0.f, gfx::BoxF(dim1, dim1, -1.f, dim2, dim2, 2.f)},
950 {0.f, 1.f, 1.f, gfx::BoxF(-1.f, dim1, dim1, 2.f, dim2, dim2)},
951 {1.f, 0.f, 1.f, gfx::BoxF(dim1, -1.f, dim1, dim2, 2.f, dim2)}};
953 for (size_t i = 0; i < arraysize(tests); ++i) {
954 float x = tests[i].x;
955 float y = tests[i].y;
956 float z = tests[i].z;
957 TransformOperations operations_from;
958 operations_from.AppendRotate(x, y, z, 0.f);
959 TransformOperations operations_to;
960 operations_to.AppendRotate(x, y, z, 360.f);
961 gfx::BoxF box(1.f, 1.f, 1.f, 0.f, 0.f, 0.f);
962 gfx::BoxF bounds;
964 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
965 box, operations_from, 0.f, 1.f, &bounds));
966 EXPECT_EQ(tests[i].expected.ToString(), bounds.ToString());
970 static void ExpectBoxesApproximatelyEqual(const gfx::BoxF& lhs,
971 const gfx::BoxF& rhs,
972 float tolerance) {
973 EXPECT_NEAR(lhs.x(), rhs.x(), tolerance);
974 EXPECT_NEAR(lhs.y(), rhs.y(), tolerance);
975 EXPECT_NEAR(lhs.z(), rhs.z(), tolerance);
976 EXPECT_NEAR(lhs.width(), rhs.width(), tolerance);
977 EXPECT_NEAR(lhs.height(), rhs.height(), tolerance);
978 EXPECT_NEAR(lhs.depth(), rhs.depth(), tolerance);
981 static void EmpiricallyTestBounds(const TransformOperations& from,
982 const TransformOperations& to,
983 SkMScalar min_progress,
984 SkMScalar max_progress,
985 bool test_containment_only) {
986 gfx::BoxF box(200.f, 500.f, 100.f, 100.f, 300.f, 200.f);
987 gfx::BoxF bounds;
988 EXPECT_TRUE(
989 to.BlendedBoundsForBox(box, from, min_progress, max_progress, &bounds));
991 bool first_time = true;
992 gfx::BoxF empirical_bounds;
993 static const size_t kNumSteps = 10;
994 for (size_t step = 0; step < kNumSteps; ++step) {
995 float t = step / (kNumSteps - 1.f);
996 t = gfx::Tween::FloatValueBetween(t, min_progress, max_progress);
997 gfx::Transform partial_transform = to.Blend(from, t);
998 gfx::BoxF transformed = box;
999 partial_transform.TransformBox(&transformed);
1001 if (first_time) {
1002 empirical_bounds = transformed;
1003 first_time = false;
1004 } else {
1005 empirical_bounds.Union(transformed);
1009 if (test_containment_only) {
1010 gfx::BoxF unified_bounds = bounds;
1011 unified_bounds.Union(empirical_bounds);
1012 // Convert to the screen space rects these boxes represent.
1013 gfx::Rect bounds_rect = ToEnclosingRect(
1014 gfx::RectF(bounds.x(), bounds.y(), bounds.width(), bounds.height()));
1015 gfx::Rect unified_bounds_rect =
1016 ToEnclosingRect(gfx::RectF(unified_bounds.x(),
1017 unified_bounds.y(),
1018 unified_bounds.width(),
1019 unified_bounds.height()));
1020 EXPECT_EQ(bounds_rect.ToString(), unified_bounds_rect.ToString());
1021 } else {
1022 // Our empirical estimate will be a little rough since we're only doing
1023 // 100 samples.
1024 static const float kTolerance = 1e-2f;
1025 ExpectBoxesApproximatelyEqual(empirical_bounds, bounds, kTolerance);
1029 static void EmpiricallyTestBoundsEquality(const TransformOperations& from,
1030 const TransformOperations& to,
1031 SkMScalar min_progress,
1032 SkMScalar max_progress) {
1033 EmpiricallyTestBounds(from, to, min_progress, max_progress, false);
1036 static void EmpiricallyTestBoundsContainment(const TransformOperations& from,
1037 const TransformOperations& to,
1038 SkMScalar min_progress,
1039 SkMScalar max_progress) {
1040 EmpiricallyTestBounds(from, to, min_progress, max_progress, true);
1043 TEST(TransformOperationTest, BlendedBoundsForRotationEmpiricalTests) {
1044 // Sets up various axis angle combinations, computes the bounding box and
1045 // empirically tests that the transformed bounds are indeed contained by the
1046 // computed bounding box.
1048 struct {
1049 float x;
1050 float y;
1051 float z;
1052 } axes[] = {{1.f, 1.f, 1.f},
1053 {-1.f, -1.f, -1.f},
1054 {-1.f, 2.f, 3.f},
1055 {1.f, -2.f, 3.f},
1056 {1.f, 2.f, -3.f},
1057 {0.f, 0.f, 0.f},
1058 {1.f, 0.f, 0.f},
1059 {0.f, 1.f, 0.f},
1060 {0.f, 0.f, 1.f},
1061 {1.f, 1.f, 0.f},
1062 {0.f, 1.f, 1.f},
1063 {1.f, 0.f, 1.f},
1064 {-1.f, 0.f, 0.f},
1065 {0.f, -1.f, 0.f},
1066 {0.f, 0.f, -1.f},
1067 {-1.f, -1.f, 0.f},
1068 {0.f, -1.f, -1.f},
1069 {-1.f, 0.f, -1.f}};
1071 struct {
1072 float theta_from;
1073 float theta_to;
1074 } angles[] = {{5.f, 10.f},
1075 {10.f, 5.f},
1076 {0.f, 360.f},
1077 {20.f, 180.f},
1078 {-20.f, -180.f},
1079 {180.f, -220.f},
1080 {220.f, 320.f}};
1082 // We can go beyond the range [0, 1] (the bezier might slide out of this range
1083 // at either end), but since the first and last knots are at (0, 0) and (1, 1)
1084 // we will never go within it, so these tests are sufficient.
1085 struct {
1086 float min_progress;
1087 float max_progress;
1088 } progress[] = {
1089 {0.f, 1.f}, {-.25f, 1.25f},
1092 for (size_t i = 0; i < arraysize(axes); ++i) {
1093 for (size_t j = 0; j < arraysize(angles); ++j) {
1094 for (size_t k = 0; k < arraysize(progress); ++k) {
1095 float x = axes[i].x;
1096 float y = axes[i].y;
1097 float z = axes[i].z;
1098 TransformOperations operations_from;
1099 operations_from.AppendRotate(x, y, z, angles[j].theta_from);
1100 TransformOperations operations_to;
1101 operations_to.AppendRotate(x, y, z, angles[j].theta_to);
1102 EmpiricallyTestBoundsContainment(operations_from,
1103 operations_to,
1104 progress[k].min_progress,
1105 progress[k].max_progress);
1111 TEST(TransformOperationTest, PerspectiveMatrixAndTransformBlendingEquivalency) {
1112 TransformOperations from_operations;
1113 from_operations.AppendPerspective(200);
1115 TransformOperations to_operations;
1116 to_operations.AppendPerspective(1000);
1118 gfx::Transform from_transform;
1119 from_transform.ApplyPerspectiveDepth(200);
1121 gfx::Transform to_transform;
1122 to_transform.ApplyPerspectiveDepth(1000);
1124 static const int steps = 20;
1125 for (int i = 0; i < steps; ++i) {
1126 double progress = static_cast<double>(i) / (steps - 1);
1128 gfx::Transform blended_matrix = to_transform;
1129 EXPECT_TRUE(blended_matrix.Blend(from_transform, progress));
1131 gfx::Transform blended_transform =
1132 to_operations.Blend(from_operations, progress);
1134 EXPECT_TRANSFORMATION_MATRIX_EQ(blended_matrix, blended_transform);
1138 TEST(TransformOperationTest, BlendedBoundsForPerspective) {
1139 struct {
1140 float from_depth;
1141 float to_depth;
1142 } perspective_depths[] = {
1143 {600.f, 400.f},
1144 {800.f, 1000.f},
1145 {800.f, std::numeric_limits<float>::infinity()},
1148 struct {
1149 float min_progress;
1150 float max_progress;
1151 } progress[] = {
1152 {0.f, 1.f}, {-0.1f, 1.1f},
1155 for (size_t i = 0; i < arraysize(perspective_depths); ++i) {
1156 for (size_t j = 0; j < arraysize(progress); ++j) {
1157 TransformOperations operations_from;
1158 operations_from.AppendPerspective(perspective_depths[i].from_depth);
1159 TransformOperations operations_to;
1160 operations_to.AppendPerspective(perspective_depths[i].to_depth);
1161 EmpiricallyTestBoundsEquality(operations_from,
1162 operations_to,
1163 progress[j].min_progress,
1164 progress[j].max_progress);
1169 TEST(TransformOperationTest, BlendedBoundsForSkew) {
1170 struct {
1171 float from_x;
1172 float from_y;
1173 float to_x;
1174 float to_y;
1175 } skews[] = {
1176 {1.f, 0.5f, 0.5f, 1.f}, {2.f, 1.f, 0.5f, 0.5f},
1179 struct {
1180 float min_progress;
1181 float max_progress;
1182 } progress[] = {
1183 {0.f, 1.f}, {-0.1f, 1.1f},
1186 for (size_t i = 0; i < arraysize(skews); ++i) {
1187 for (size_t j = 0; j < arraysize(progress); ++j) {
1188 TransformOperations operations_from;
1189 operations_from.AppendSkew(skews[i].from_x, skews[i].from_y);
1190 TransformOperations operations_to;
1191 operations_to.AppendSkew(skews[i].to_x, skews[i].to_y);
1192 EmpiricallyTestBoundsEquality(operations_from,
1193 operations_to,
1194 progress[j].min_progress,
1195 progress[j].max_progress);
1200 TEST(TransformOperationTest, NonCommutativeRotations) {
1201 TransformOperations operations_from;
1202 operations_from.AppendRotate(1.0, 0.0, 0.0, 0.0);
1203 operations_from.AppendRotate(0.0, 1.0, 0.0, 0.0);
1204 TransformOperations operations_to;
1205 operations_to.AppendRotate(1.0, 0.0, 0.0, 45.0);
1206 operations_to.AppendRotate(0.0, 1.0, 0.0, 135.0);
1208 gfx::BoxF box(0, 0, 0, 1, 1, 1);
1209 gfx::BoxF bounds;
1211 SkMScalar min_progress = 0.0f;
1212 SkMScalar max_progress = 1.0f;
1213 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
1214 box, operations_from, min_progress, max_progress, &bounds));
1215 gfx::Transform blended_transform =
1216 operations_to.Blend(operations_from, max_progress);
1217 gfx::Point3F blended_point(0.9f, 0.9f, 0.0f);
1218 blended_transform.TransformPoint(&blended_point);
1219 gfx::BoxF expanded_bounds = bounds;
1220 expanded_bounds.ExpandTo(blended_point);
1221 EXPECT_EQ(bounds.ToString(), expanded_bounds.ToString());
1224 TEST(TransformOperationTest, BlendedBoundsForSequence) {
1225 TransformOperations operations_from;
1226 operations_from.AppendTranslate(1.0, -5.0, 1.0);
1227 operations_from.AppendScale(-1.0, 2.0, 3.0);
1228 operations_from.AppendTranslate(2.0, 4.0, -1.0);
1229 TransformOperations operations_to;
1230 operations_to.AppendTranslate(13.0, -1.0, 5.0);
1231 operations_to.AppendScale(-3.0, -2.0, 5.0);
1232 operations_to.AppendTranslate(6.0, -2.0, 3.0);
1234 gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
1235 gfx::BoxF bounds;
1237 SkMScalar min_progress = -0.5f;
1238 SkMScalar max_progress = 1.5f;
1239 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
1240 box, operations_from, min_progress, max_progress, &bounds));
1241 EXPECT_EQ(gfx::BoxF(-57.f, -59.f, -1.f, 76.f, 112.f, 80.f).ToString(),
1242 bounds.ToString());
1244 min_progress = 0.f;
1245 max_progress = 1.f;
1246 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
1247 box, operations_from, min_progress, max_progress, &bounds));
1248 EXPECT_EQ(gfx::BoxF(-32.f, -25.f, 7.f, 42.f, 44.f, 48.f).ToString(),
1249 bounds.ToString());
1251 TransformOperations identity;
1252 EXPECT_TRUE(operations_to.BlendedBoundsForBox(
1253 box, identity, min_progress, max_progress, &bounds));
1254 EXPECT_EQ(gfx::BoxF(-33.f, -13.f, 3.f, 57.f, 19.f, 52.f).ToString(),
1255 bounds.ToString());
1257 EXPECT_TRUE(identity.BlendedBoundsForBox(
1258 box, operations_from, min_progress, max_progress, &bounds));
1259 EXPECT_EQ(gfx::BoxF(-7.f, -3.f, 2.f, 15.f, 23.f, 20.f).ToString(),
1260 bounds.ToString());
1263 TEST(TransformOperationTest, AffectsScaleWithSingleOperation) {
1264 TransformOperations empty_operations;
1265 EXPECT_FALSE(empty_operations.AffectsScale());
1267 TransformOperations identity;
1268 identity.AppendIdentity();
1269 EXPECT_FALSE(identity.AffectsScale());
1271 TransformOperations translate;
1272 translate.AppendTranslate(1.f, 2.f, 3.f);
1273 EXPECT_FALSE(translate.AffectsScale());
1275 TransformOperations rotate;
1276 rotate.AppendRotate(1.f, 2.f, 3.f, 4.f);
1277 EXPECT_FALSE(rotate.AffectsScale());
1279 TransformOperations scale;
1280 scale.AppendScale(1.f, 2.f, 3.f);
1281 EXPECT_TRUE(scale.AffectsScale());
1283 TransformOperations skew;
1284 skew.AppendSkew(1.f, 2.f);
1285 EXPECT_FALSE(skew.AffectsScale());
1287 TransformOperations perspective;
1288 perspective.AppendPerspective(1.f);
1289 EXPECT_FALSE(perspective.AffectsScale());
1291 TransformOperations identity_matrix;
1292 identity_matrix.AppendMatrix(gfx::Transform());
1293 EXPECT_FALSE(identity_matrix.AffectsScale());
1295 TransformOperations translation_matrix;
1296 gfx::Transform translation_transform;
1297 translation_transform.Translate3d(1.f, 2.f, 3.f);
1298 translation_matrix.AppendMatrix(translation_transform);
1299 EXPECT_FALSE(translation_matrix.AffectsScale());
1301 TransformOperations scaling_matrix;
1302 gfx::Transform scaling_transform;
1303 scaling_transform.Scale(2.f, 2.f);
1304 scaling_matrix.AppendMatrix(scaling_transform);
1305 EXPECT_TRUE(scaling_matrix.AffectsScale());
1308 TEST(TransformOperationTest, AffectsScaleWithMultipleOperations) {
1309 TransformOperations operations1;
1310 operations1.AppendSkew(1.f, 2.f);
1311 operations1.AppendTranslate(1.f, 2.f, 3.f);
1312 operations1.AppendIdentity();
1313 EXPECT_FALSE(operations1.AffectsScale());
1315 TransformOperations operations2;
1316 operations2.AppendPerspective(2.f);
1317 operations2.AppendScale(1.f, 2.f, 3.f);
1318 operations2.AppendTranslate(3.f, 2.f, 1.f);
1319 EXPECT_TRUE(operations2.AffectsScale());
1322 TEST(TransformOperationTest, IsTranslationWithSingleOperation) {
1323 TransformOperations empty_operations;
1324 EXPECT_TRUE(empty_operations.IsTranslation());
1326 TransformOperations identity;
1327 identity.AppendIdentity();
1328 EXPECT_TRUE(identity.IsTranslation());
1330 TransformOperations translate;
1331 translate.AppendTranslate(1.f, 2.f, 3.f);
1332 EXPECT_TRUE(translate.IsTranslation());
1334 TransformOperations rotate;
1335 rotate.AppendRotate(1.f, 2.f, 3.f, 4.f);
1336 EXPECT_FALSE(rotate.IsTranslation());
1338 TransformOperations scale;
1339 scale.AppendScale(1.f, 2.f, 3.f);
1340 EXPECT_FALSE(scale.IsTranslation());
1342 TransformOperations skew;
1343 skew.AppendSkew(1.f, 2.f);
1344 EXPECT_FALSE(skew.IsTranslation());
1346 TransformOperations perspective;
1347 perspective.AppendPerspective(1.f);
1348 EXPECT_FALSE(perspective.IsTranslation());
1350 TransformOperations identity_matrix;
1351 identity_matrix.AppendMatrix(gfx::Transform());
1352 EXPECT_TRUE(identity_matrix.IsTranslation());
1354 TransformOperations translation_matrix;
1355 gfx::Transform translation_transform;
1356 translation_transform.Translate3d(1.f, 2.f, 3.f);
1357 translation_matrix.AppendMatrix(translation_transform);
1358 EXPECT_TRUE(translation_matrix.IsTranslation());
1360 TransformOperations scaling_matrix;
1361 gfx::Transform scaling_transform;
1362 scaling_transform.Scale(2.f, 2.f);
1363 scaling_matrix.AppendMatrix(scaling_transform);
1364 EXPECT_FALSE(scaling_matrix.IsTranslation());
1367 TEST(TransformOperationTest, IsTranslationWithMultipleOperations) {
1368 TransformOperations operations1;
1369 operations1.AppendSkew(1.f, 2.f);
1370 operations1.AppendTranslate(1.f, 2.f, 3.f);
1371 operations1.AppendIdentity();
1372 EXPECT_FALSE(operations1.IsTranslation());
1374 TransformOperations operations2;
1375 operations2.AppendIdentity();
1376 operations2.AppendTranslate(3.f, 2.f, 1.f);
1377 gfx::Transform translation_transform;
1378 translation_transform.Translate3d(1.f, 2.f, 3.f);
1379 operations2.AppendMatrix(translation_transform);
1380 EXPECT_TRUE(operations2.IsTranslation());
1383 TEST(TransformOperationTest, ScaleComponent) {
1384 gfx::Vector3dF scale;
1386 // Scale.
1387 TransformOperations operations1;
1388 operations1.AppendScale(-3.f, 2.f, 5.f);
1389 EXPECT_TRUE(operations1.ScaleComponent(&scale));
1390 EXPECT_EQ(gfx::Vector3dF(-3.f, 2.f, 5.f), scale);
1392 // Translate + Scale.
1393 TransformOperations operations5;
1394 operations5.AppendTranslate(1.f, 2.f, 3.f);
1395 operations5.AppendScale(2.f, 5.f, 4.f);
1396 EXPECT_TRUE(operations5.ScaleComponent(&scale));
1397 EXPECT_EQ(gfx::Vector3dF(2.f, 5.f, 4.f), scale);
1399 // Translate + Scale + Matrix with translate.
1400 gfx::Transform translation_transform;
1401 translation_transform.Translate3d(1.f, 2.f, 3.f);
1402 operations5.AppendMatrix(translation_transform);
1403 EXPECT_TRUE(operations5.ScaleComponent(&scale));
1404 EXPECT_EQ(gfx::Vector3dF(2.f, 5.f, 4.f), scale);
1407 TEST(TransformOperationTest, ScaleComponentCannotBeComputed) {
1408 gfx::Vector3dF scale;
1410 // Scale can.
1411 TransformOperations operations1;
1412 operations1.AppendScale(2.f, 2.f, 2.f);
1413 EXPECT_TRUE(operations1.ScaleComponent(&scale));
1414 EXPECT_EQ(gfx::Vector3dF(2.f, 2.f, 2.f), scale);
1416 // Translate can.
1417 TransformOperations operations2;
1418 operations2.AppendTranslate(1.f, 2.f, 3.f);
1419 EXPECT_TRUE(operations2.ScaleComponent(&scale));
1420 EXPECT_EQ(gfx::Vector3dF(1.f, 1.f, 1.f), scale);
1422 // Scale + translate can.
1423 TransformOperations operations3;
1424 operations3.AppendScale(2.f, 3.f, 2.f);
1425 operations3.AppendTranslate(1.f, 2.f, 3.f);
1426 EXPECT_TRUE(operations3.ScaleComponent(&scale));
1427 EXPECT_EQ(gfx::Vector3dF(2.f, 3.f, 2.f), scale);
1429 // Two Scales can't.
1430 TransformOperations operations4;
1431 operations4.AppendScale(2.f, 3.f, 2.f);
1432 operations4.AppendScale(3.f, 2.f, 3.f);
1433 EXPECT_FALSE(operations4.ScaleComponent(&scale));
1435 // Matrix can't.
1436 TransformOperations operations5;
1437 operations5.AppendScale(2.f, 2.f, 2.f);
1438 gfx::Transform scaling_transform;
1439 scaling_transform.Scale(2.f, 2.f);
1440 operations5.AppendMatrix(scaling_transform);
1441 EXPECT_FALSE(operations5.ScaleComponent(&scale));
1443 // Scale + Rotate can't.
1444 TransformOperations operations7;
1445 operations7.AppendScale(2.f, 2.f, 2.f);
1446 operations7.AppendRotate(1.f, 2.f, 3.f, 4.f);
1447 EXPECT_FALSE(operations7.ScaleComponent(&scale));
1449 // Scale + Skew can't.
1450 TransformOperations operations9;
1451 operations9.AppendScale(2.f, 2.f, 2.f);
1452 operations9.AppendSkew(1.f, 2.f);
1453 EXPECT_FALSE(operations9.ScaleComponent(&scale));
1455 // Scale + Perspective can't.
1456 TransformOperations operations11;
1457 operations11.AppendScale(2.f, 2.f, 2.f);
1458 operations11.AppendPerspective(1.f);
1459 EXPECT_FALSE(operations11.ScaleComponent(&scale));
1462 } // namespace
1463 } // namespace cc