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.
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"
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
, MatchTypesOrder
) {
143 TransformOperations mix_order_identity
;
144 mix_order_identity
.AppendTranslate(0, 0, 0);
145 mix_order_identity
.AppendScale(1, 1, 1);
146 mix_order_identity
.AppendTranslate(0, 0, 0);
148 TransformOperations mix_order_one
;
149 mix_order_one
.AppendTranslate(0, 1, 0);
150 mix_order_one
.AppendScale(2, 1, 3);
151 mix_order_one
.AppendTranslate(1, 0, 0);
153 TransformOperations mix_order_two
;
154 mix_order_two
.AppendTranslate(0, 1, 0);
155 mix_order_two
.AppendTranslate(1, 0, 0);
156 mix_order_two
.AppendScale(2, 1, 3);
158 EXPECT_TRUE(mix_order_identity
.MatchesTypes(mix_order_one
));
159 EXPECT_FALSE(mix_order_identity
.MatchesTypes(mix_order_two
));
160 EXPECT_FALSE(mix_order_one
.MatchesTypes(mix_order_two
));
163 TEST(TransformOperationTest
, NoneAlwaysMatches
) {
164 ScopedVector
<TransformOperations
> operations
;
165 GetIdentityOperations(&operations
);
167 TransformOperations none_operation
;
168 for (size_t i
= 0; i
< operations
.size(); ++i
)
169 EXPECT_TRUE(operations
[i
]->MatchesTypes(none_operation
));
172 TEST(TransformOperationTest
, ApplyTranslate
) {
176 TransformOperations operations
;
177 operations
.AppendTranslate(x
, y
, z
);
178 gfx::Transform expected
;
179 expected
.Translate3d(x
, y
, z
);
180 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
183 TEST(TransformOperationTest
, ApplyRotate
) {
187 SkMScalar degrees
= 80;
188 TransformOperations operations
;
189 operations
.AppendRotate(x
, y
, z
, degrees
);
190 gfx::Transform expected
;
191 expected
.RotateAbout(gfx::Vector3dF(x
, y
, z
), degrees
);
192 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
195 TEST(TransformOperationTest
, ApplyScale
) {
199 TransformOperations operations
;
200 operations
.AppendScale(x
, y
, z
);
201 gfx::Transform expected
;
202 expected
.Scale3d(x
, y
, z
);
203 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
206 TEST(TransformOperationTest
, ApplySkew
) {
209 TransformOperations operations
;
210 operations
.AppendSkew(x
, y
);
211 gfx::Transform expected
;
213 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
216 TEST(TransformOperationTest
, ApplyPerspective
) {
217 SkMScalar depth
= 800;
218 TransformOperations operations
;
219 operations
.AppendPerspective(depth
);
220 gfx::Transform expected
;
221 expected
.ApplyPerspectiveDepth(depth
);
222 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
, operations
.Apply());
225 TEST(TransformOperationTest
, ApplyMatrix
) {
229 gfx::Transform expected_matrix
;
230 expected_matrix
.Translate3d(dx
, dy
, dz
);
231 TransformOperations matrix_transform
;
232 matrix_transform
.AppendMatrix(expected_matrix
);
233 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_matrix
, matrix_transform
.Apply());
236 TEST(TransformOperationTest
, ApplyOrder
) {
245 TransformOperations operations
;
246 operations
.AppendScale(sx
, sy
, sz
);
247 operations
.AppendTranslate(dx
, dy
, dz
);
249 gfx::Transform expected_scale_matrix
;
250 expected_scale_matrix
.Scale3d(sx
, sy
, sz
);
252 gfx::Transform expected_translate_matrix
;
253 expected_translate_matrix
.Translate3d(dx
, dy
, dz
);
255 gfx::Transform expected_combined_matrix
= expected_scale_matrix
;
256 expected_combined_matrix
.PreconcatTransform(expected_translate_matrix
);
258 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_combined_matrix
, operations
.Apply());
261 TEST(TransformOperationTest
, BlendOrder
) {
278 TransformOperations operations_from
;
279 operations_from
.AppendScale(sx1
, sy1
, sz1
);
280 operations_from
.AppendTranslate(dx1
, dy1
, dz1
);
282 TransformOperations operations_to
;
283 operations_to
.AppendScale(sx2
, sy2
, sz2
);
284 operations_to
.AppendTranslate(dx2
, dy2
, dz2
);
286 gfx::Transform scale_from
;
287 scale_from
.Scale3d(sx1
, sy1
, sz1
);
288 gfx::Transform translate_from
;
289 translate_from
.Translate3d(dx1
, dy1
, dz1
);
291 gfx::Transform scale_to
;
292 scale_to
.Scale3d(sx2
, sy2
, sz2
);
293 gfx::Transform translate_to
;
294 translate_to
.Translate3d(dx2
, dy2
, dz2
);
296 SkMScalar progress
= 0.25f
;
298 gfx::Transform blended_scale
= scale_to
;
299 blended_scale
.Blend(scale_from
, progress
);
301 gfx::Transform blended_translate
= translate_to
;
302 blended_translate
.Blend(translate_from
, progress
);
304 gfx::Transform expected
= blended_scale
;
305 expected
.PreconcatTransform(blended_translate
);
307 EXPECT_TRANSFORMATION_MATRIX_EQ(
308 expected
, operations_to
.Blend(operations_from
, progress
));
311 static void CheckProgress(SkMScalar progress
,
312 const gfx::Transform
& from_matrix
,
313 const gfx::Transform
& to_matrix
,
314 const TransformOperations
& from_transform
,
315 const TransformOperations
& to_transform
) {
316 gfx::Transform expected_matrix
= to_matrix
;
317 expected_matrix
.Blend(from_matrix
, progress
);
318 EXPECT_TRANSFORMATION_MATRIX_EQ(
319 expected_matrix
, to_transform
.Blend(from_transform
, progress
));
322 TEST(TransformOperationTest
, BlendProgress
) {
326 TransformOperations operations_from
;
327 operations_from
.AppendScale(sx
, sy
, sz
);
329 gfx::Transform matrix_from
;
330 matrix_from
.Scale3d(sx
, sy
, sz
);
335 TransformOperations operations_to
;
336 operations_to
.AppendScale(sx
, sy
, sz
);
338 gfx::Transform matrix_to
;
339 matrix_to
.Scale3d(sx
, sy
, sz
);
341 CheckProgress(-1, matrix_from
, matrix_to
, operations_from
, operations_to
);
342 CheckProgress(0, matrix_from
, matrix_to
, operations_from
, operations_to
);
343 CheckProgress(0.25f
, matrix_from
, matrix_to
, operations_from
, operations_to
);
344 CheckProgress(0.5f
, matrix_from
, matrix_to
, operations_from
, operations_to
);
345 CheckProgress(1, matrix_from
, matrix_to
, operations_from
, operations_to
);
346 CheckProgress(2, matrix_from
, matrix_to
, operations_from
, operations_to
);
349 TEST(TransformOperationTest
, BlendWhenTypesDoNotMatch
) {
366 TransformOperations operations_from
;
367 operations_from
.AppendScale(sx1
, sy1
, sz1
);
368 operations_from
.AppendTranslate(dx1
, dy1
, dz1
);
370 TransformOperations operations_to
;
371 operations_to
.AppendTranslate(dx2
, dy2
, dz2
);
372 operations_to
.AppendScale(sx2
, sy2
, sz2
);
375 from
.Scale3d(sx1
, sy1
, sz1
);
376 from
.Translate3d(dx1
, dy1
, dz1
);
379 to
.Translate3d(dx2
, dy2
, dz2
);
380 to
.Scale3d(sx2
, sy2
, sz2
);
382 SkMScalar progress
= 0.25f
;
384 gfx::Transform expected
= to
;
385 expected
.Blend(from
, progress
);
387 EXPECT_TRANSFORMATION_MATRIX_EQ(
388 expected
, operations_to
.Blend(operations_from
, progress
));
391 TEST(TransformOperationTest
, LargeRotationsWithSameAxis
) {
392 TransformOperations operations_from
;
393 operations_from
.AppendRotate(0, 0, 1, 0);
395 TransformOperations operations_to
;
396 operations_to
.AppendRotate(0, 0, 2, 360);
398 SkMScalar progress
= 0.5f
;
400 gfx::Transform expected
;
401 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
403 EXPECT_TRANSFORMATION_MATRIX_EQ(
404 expected
, operations_to
.Blend(operations_from
, progress
));
407 TEST(TransformOperationTest
, LargeRotationsWithSameAxisInDifferentDirection
) {
408 TransformOperations operations_from
;
409 operations_from
.AppendRotate(0, 0, 1, 180);
411 TransformOperations operations_to
;
412 operations_to
.AppendRotate(0, 0, -1, 180);
414 SkMScalar progress
= 0.5f
;
416 gfx::Transform expected
;
418 EXPECT_TRANSFORMATION_MATRIX_EQ(
419 expected
, operations_to
.Blend(operations_from
, progress
));
422 TEST(TransformOperationTest
, LargeRotationsWithDifferentAxes
) {
423 TransformOperations operations_from
;
424 operations_from
.AppendRotate(0, 0, 1, 175);
426 TransformOperations operations_to
;
427 operations_to
.AppendRotate(0, 1, 0, 175);
429 SkMScalar progress
= 0.5f
;
430 gfx::Transform matrix_from
;
431 matrix_from
.RotateAbout(gfx::Vector3dF(0, 0, 1), 175);
433 gfx::Transform matrix_to
;
434 matrix_to
.RotateAbout(gfx::Vector3dF(0, 1, 0), 175);
436 gfx::Transform expected
= matrix_to
;
437 expected
.Blend(matrix_from
, progress
);
439 EXPECT_TRANSFORMATION_MATRIX_EQ(
440 expected
, operations_to
.Blend(operations_from
, progress
));
443 TEST(TransformOperationTest
, RotationFromZeroDegDifferentAxes
) {
444 TransformOperations operations_from
;
445 operations_from
.AppendRotate(0, 0, 1, 0);
447 TransformOperations operations_to
;
448 operations_to
.AppendRotate(0, 1, 0, 450);
450 SkMScalar progress
= 0.5f
;
451 gfx::Transform expected
;
452 expected
.RotateAbout(gfx::Vector3dF(0, 1, 0), 225);
453 EXPECT_TRANSFORMATION_MATRIX_EQ(
454 expected
, operations_to
.Blend(operations_from
, progress
));
457 TEST(TransformOperationTest
, RotationFromZeroDegSameAxes
) {
458 TransformOperations operations_from
;
459 operations_from
.AppendRotate(0, 0, 1, 0);
461 TransformOperations operations_to
;
462 operations_to
.AppendRotate(0, 0, 1, 450);
464 SkMScalar progress
= 0.5f
;
465 gfx::Transform expected
;
466 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 225);
467 EXPECT_TRANSFORMATION_MATRIX_EQ(
468 expected
, operations_to
.Blend(operations_from
, progress
));
471 TEST(TransformOperationTest
, RotationToZeroDegDifferentAxes
) {
472 TransformOperations operations_from
;
473 operations_from
.AppendRotate(0, 1, 0, 450);
475 TransformOperations operations_to
;
476 operations_to
.AppendRotate(0, 0, 1, 0);
478 SkMScalar progress
= 0.5f
;
479 gfx::Transform expected
;
480 expected
.RotateAbout(gfx::Vector3dF(0, 1, 0), 225);
481 EXPECT_TRANSFORMATION_MATRIX_EQ(
482 expected
, operations_to
.Blend(operations_from
, progress
));
485 TEST(TransformOperationTest
, RotationToZeroDegSameAxes
) {
486 TransformOperations operations_from
;
487 operations_from
.AppendRotate(0, 0, 1, 450);
489 TransformOperations operations_to
;
490 operations_to
.AppendRotate(0, 0, 1, 0);
492 SkMScalar progress
= 0.5f
;
493 gfx::Transform expected
;
494 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 225);
495 EXPECT_TRANSFORMATION_MATRIX_EQ(
496 expected
, operations_to
.Blend(operations_from
, progress
));
499 TEST(TransformOperationTest
, BlendRotationFromIdentity
) {
500 ScopedVector
<TransformOperations
> identity_operations
;
501 GetIdentityOperations(&identity_operations
);
503 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
504 TransformOperations operations
;
505 operations
.AppendRotate(0, 0, 1, 90);
507 SkMScalar progress
= 0.5f
;
509 gfx::Transform expected
;
510 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 45);
512 EXPECT_TRANSFORMATION_MATRIX_EQ(
513 expected
, operations
.Blend(*identity_operations
[i
], progress
));
517 expected
.MakeIdentity();
518 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), -45);
520 EXPECT_TRANSFORMATION_MATRIX_EQ(
521 expected
, operations
.Blend(*identity_operations
[i
], progress
));
525 expected
.MakeIdentity();
526 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 135);
528 EXPECT_TRANSFORMATION_MATRIX_EQ(
529 expected
, operations
.Blend(*identity_operations
[i
], progress
));
533 TEST(TransformOperationTest
, BlendTranslationFromIdentity
) {
534 ScopedVector
<TransformOperations
> identity_operations
;
535 GetIdentityOperations(&identity_operations
);
537 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
538 TransformOperations operations
;
539 operations
.AppendTranslate(2, 2, 2);
541 SkMScalar progress
= 0.5f
;
543 gfx::Transform expected
;
544 expected
.Translate3d(1, 1, 1);
546 EXPECT_TRANSFORMATION_MATRIX_EQ(
547 expected
, operations
.Blend(*identity_operations
[i
], progress
));
551 expected
.MakeIdentity();
552 expected
.Translate3d(-1, -1, -1);
554 EXPECT_TRANSFORMATION_MATRIX_EQ(
555 expected
, operations
.Blend(*identity_operations
[i
], progress
));
559 expected
.MakeIdentity();
560 expected
.Translate3d(3, 3, 3);
562 EXPECT_TRANSFORMATION_MATRIX_EQ(
563 expected
, operations
.Blend(*identity_operations
[i
], progress
));
567 TEST(TransformOperationTest
, BlendScaleFromIdentity
) {
568 ScopedVector
<TransformOperations
> identity_operations
;
569 GetIdentityOperations(&identity_operations
);
571 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
572 TransformOperations operations
;
573 operations
.AppendScale(3, 3, 3);
575 SkMScalar progress
= 0.5f
;
577 gfx::Transform expected
;
578 expected
.Scale3d(2, 2, 2);
580 EXPECT_TRANSFORMATION_MATRIX_EQ(
581 expected
, operations
.Blend(*identity_operations
[i
], progress
));
585 expected
.MakeIdentity();
586 expected
.Scale3d(0, 0, 0);
588 EXPECT_TRANSFORMATION_MATRIX_EQ(
589 expected
, operations
.Blend(*identity_operations
[i
], progress
));
593 expected
.MakeIdentity();
594 expected
.Scale3d(4, 4, 4);
596 EXPECT_TRANSFORMATION_MATRIX_EQ(
597 expected
, operations
.Blend(*identity_operations
[i
], progress
));
601 TEST(TransformOperationTest
, BlendSkewFromEmpty
) {
602 TransformOperations empty_operation
;
604 TransformOperations operations
;
605 operations
.AppendSkew(2, 2);
607 SkMScalar progress
= 0.5f
;
609 gfx::Transform expected
;
612 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
,
613 operations
.Blend(empty_operation
, progress
));
617 expected
.MakeIdentity();
618 expected
.Skew(-1, -1);
620 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
,
621 operations
.Blend(empty_operation
, progress
));
625 expected
.MakeIdentity();
628 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
,
629 operations
.Blend(empty_operation
, progress
));
632 TEST(TransformOperationTest
, BlendPerspectiveFromIdentity
) {
633 ScopedVector
<TransformOperations
> identity_operations
;
634 GetIdentityOperations(&identity_operations
);
636 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
637 TransformOperations operations
;
638 operations
.AppendPerspective(1000);
640 SkMScalar progress
= 0.5f
;
642 gfx::Transform expected
;
643 expected
.ApplyPerspectiveDepth(2000);
645 EXPECT_TRANSFORMATION_MATRIX_EQ(
646 expected
, operations
.Blend(*identity_operations
[i
], progress
));
650 TEST(TransformOperationTest
, BlendRotationToIdentity
) {
651 ScopedVector
<TransformOperations
> identity_operations
;
652 GetIdentityOperations(&identity_operations
);
654 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
655 TransformOperations operations
;
656 operations
.AppendRotate(0, 0, 1, 90);
658 SkMScalar progress
= 0.5f
;
660 gfx::Transform expected
;
661 expected
.RotateAbout(gfx::Vector3dF(0, 0, 1), 45);
663 EXPECT_TRANSFORMATION_MATRIX_EQ(
664 expected
, identity_operations
[i
]->Blend(operations
, progress
));
668 TEST(TransformOperationTest
, BlendTranslationToIdentity
) {
669 ScopedVector
<TransformOperations
> identity_operations
;
670 GetIdentityOperations(&identity_operations
);
672 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
673 TransformOperations operations
;
674 operations
.AppendTranslate(2, 2, 2);
676 SkMScalar progress
= 0.5f
;
678 gfx::Transform expected
;
679 expected
.Translate3d(1, 1, 1);
681 EXPECT_TRANSFORMATION_MATRIX_EQ(
682 expected
, identity_operations
[i
]->Blend(operations
, progress
));
686 TEST(TransformOperationTest
, BlendScaleToIdentity
) {
687 ScopedVector
<TransformOperations
> identity_operations
;
688 GetIdentityOperations(&identity_operations
);
690 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
691 TransformOperations operations
;
692 operations
.AppendScale(3, 3, 3);
694 SkMScalar progress
= 0.5f
;
696 gfx::Transform expected
;
697 expected
.Scale3d(2, 2, 2);
699 EXPECT_TRANSFORMATION_MATRIX_EQ(
700 expected
, identity_operations
[i
]->Blend(operations
, progress
));
704 TEST(TransformOperationTest
, BlendSkewToEmpty
) {
705 TransformOperations empty_operation
;
707 TransformOperations operations
;
708 operations
.AppendSkew(2, 2);
710 SkMScalar progress
= 0.5f
;
712 gfx::Transform expected
;
715 EXPECT_TRANSFORMATION_MATRIX_EQ(expected
,
716 empty_operation
.Blend(operations
, progress
));
719 TEST(TransformOperationTest
, BlendPerspectiveToIdentity
) {
720 ScopedVector
<TransformOperations
> identity_operations
;
721 GetIdentityOperations(&identity_operations
);
723 for (size_t i
= 0; i
< identity_operations
.size(); ++i
) {
724 TransformOperations operations
;
725 operations
.AppendPerspective(1000);
727 SkMScalar progress
= 0.5f
;
729 gfx::Transform expected
;
730 expected
.ApplyPerspectiveDepth(2000);
732 EXPECT_TRANSFORMATION_MATRIX_EQ(
733 expected
, identity_operations
[i
]->Blend(operations
, progress
));
737 TEST(TransformOperationTest
, ExtrapolatePerspectiveBlending
) {
738 TransformOperations operations1
;
739 operations1
.AppendPerspective(1000);
741 TransformOperations operations2
;
742 operations2
.AppendPerspective(500);
744 gfx::Transform expected
;
745 expected
.ApplyPerspectiveDepth(400);
747 EXPECT_TRANSFORMATION_MATRIX_EQ(
748 expected
, operations1
.Blend(operations2
, -0.5));
750 expected
.MakeIdentity();
751 expected
.ApplyPerspectiveDepth(2000);
753 EXPECT_TRANSFORMATION_MATRIX_EQ(
754 expected
, operations1
.Blend(operations2
, 1.5));
757 TEST(TransformOperationTest
, ExtrapolateMatrixBlending
) {
758 gfx::Transform transform1
;
759 transform1
.Translate3d(1, 1, 1);
760 TransformOperations operations1
;
761 operations1
.AppendMatrix(transform1
);
763 gfx::Transform transform2
;
764 transform2
.Translate3d(3, 3, 3);
765 TransformOperations operations2
;
766 operations2
.AppendMatrix(transform2
);
768 gfx::Transform expected
;
769 EXPECT_TRANSFORMATION_MATRIX_EQ(
770 expected
, operations1
.Blend(operations2
, 1.5));
772 expected
.Translate3d(4, 4, 4);
773 EXPECT_TRANSFORMATION_MATRIX_EQ(
774 expected
, operations1
.Blend(operations2
, -0.5));
777 TEST(TransformOperationTest
, BlendedBoundsWhenTypesDoNotMatch
) {
778 TransformOperations operations_from
;
779 operations_from
.AppendScale(2.0, 4.0, 8.0);
780 operations_from
.AppendTranslate(1.0, 2.0, 3.0);
782 TransformOperations operations_to
;
783 operations_to
.AppendTranslate(10.0, 20.0, 30.0);
784 operations_to
.AppendScale(4.0, 8.0, 16.0);
786 gfx::BoxF
box(1.f
, 1.f
, 1.f
);
789 SkMScalar min_progress
= 0.f
;
790 SkMScalar max_progress
= 1.f
;
792 EXPECT_FALSE(operations_to
.BlendedBoundsForBox(
793 box
, operations_from
, min_progress
, max_progress
, &bounds
));
796 TEST(TransformOperationTest
, BlendedBoundsForIdentity
) {
797 TransformOperations operations_from
;
798 operations_from
.AppendIdentity();
799 TransformOperations operations_to
;
800 operations_to
.AppendIdentity();
802 gfx::BoxF
box(1.f
, 2.f
, 3.f
);
805 SkMScalar min_progress
= 0.f
;
806 SkMScalar max_progress
= 1.f
;
808 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
809 box
, operations_from
, min_progress
, max_progress
, &bounds
));
810 EXPECT_EQ(box
.ToString(), bounds
.ToString());
813 TEST(TransformOperationTest
, BlendedBoundsForTranslate
) {
814 TransformOperations operations_from
;
815 operations_from
.AppendTranslate(3.0, -4.0, 2.0);
816 TransformOperations operations_to
;
817 operations_to
.AppendTranslate(7.0, 4.0, -2.0);
819 gfx::BoxF
box(1.f
, 2.f
, 3.f
, 4.f
, 4.f
, 4.f
);
822 SkMScalar min_progress
= -0.5f
;
823 SkMScalar max_progress
= 1.5f
;
824 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
825 box
, operations_from
, min_progress
, max_progress
, &bounds
));
826 EXPECT_EQ(gfx::BoxF(2.f
, -6.f
, -1.f
, 12.f
, 20.f
, 12.f
).ToString(),
831 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
832 box
, operations_from
, min_progress
, max_progress
, &bounds
));
833 EXPECT_EQ(gfx::BoxF(4.f
, -2.f
, 1.f
, 8.f
, 12.f
, 8.f
).ToString(),
836 TransformOperations identity
;
837 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
838 box
, identity
, min_progress
, max_progress
, &bounds
));
839 EXPECT_EQ(gfx::BoxF(1.f
, 2.f
, 1.f
, 11.f
, 8.f
, 6.f
).ToString(),
842 EXPECT_TRUE(identity
.BlendedBoundsForBox(
843 box
, operations_from
, min_progress
, max_progress
, &bounds
));
844 EXPECT_EQ(gfx::BoxF(1.f
, -2.f
, 3.f
, 7.f
, 8.f
, 6.f
).ToString(),
848 TEST(TransformOperationTest
, BlendedBoundsForScale
) {
849 TransformOperations operations_from
;
850 operations_from
.AppendScale(3.0, 0.5, 2.0);
851 TransformOperations operations_to
;
852 operations_to
.AppendScale(7.0, 4.0, -2.0);
854 gfx::BoxF
box(1.f
, 2.f
, 3.f
, 4.f
, 4.f
, 4.f
);
857 SkMScalar min_progress
= -0.5f
;
858 SkMScalar max_progress
= 1.5f
;
859 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
860 box
, operations_from
, min_progress
, max_progress
, &bounds
));
861 EXPECT_EQ(gfx::BoxF(1.f
, -7.5f
, -28.f
, 44.f
, 42.f
, 56.f
).ToString(),
866 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
867 box
, operations_from
, min_progress
, max_progress
, &bounds
));
868 EXPECT_EQ(gfx::BoxF(3.f
, 1.f
, -14.f
, 32.f
, 23.f
, 28.f
).ToString(),
871 TransformOperations identity
;
872 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
873 box
, identity
, min_progress
, max_progress
, &bounds
));
874 EXPECT_EQ(gfx::BoxF(1.f
, 2.f
, -14.f
, 34.f
, 22.f
, 21.f
).ToString(),
877 EXPECT_TRUE(identity
.BlendedBoundsForBox(
878 box
, operations_from
, min_progress
, max_progress
, &bounds
));
879 EXPECT_EQ(gfx::BoxF(1.f
, 1.f
, 3.f
, 14.f
, 5.f
, 11.f
).ToString(),
883 TEST(TransformOperationTest
, BlendedBoundsWithZeroScale
) {
884 TransformOperations zero_scale
;
885 zero_scale
.AppendScale(0.0, 0.0, 0.0);
886 TransformOperations non_zero_scale
;
887 non_zero_scale
.AppendScale(2.0, -4.0, 5.0);
889 gfx::BoxF
box(1.f
, 2.f
, 3.f
, 4.f
, 4.f
, 4.f
);
892 SkMScalar min_progress
= 0.f
;
893 SkMScalar max_progress
= 1.f
;
894 EXPECT_TRUE(zero_scale
.BlendedBoundsForBox(
895 box
, non_zero_scale
, min_progress
, max_progress
, &bounds
));
896 EXPECT_EQ(gfx::BoxF(0.f
, -24.f
, 0.f
, 10.f
, 24.f
, 35.f
).ToString(),
899 EXPECT_TRUE(non_zero_scale
.BlendedBoundsForBox(
900 box
, zero_scale
, min_progress
, max_progress
, &bounds
));
901 EXPECT_EQ(gfx::BoxF(0.f
, -24.f
, 0.f
, 10.f
, 24.f
, 35.f
).ToString(),
904 EXPECT_TRUE(zero_scale
.BlendedBoundsForBox(
905 box
, zero_scale
, min_progress
, max_progress
, &bounds
));
906 EXPECT_EQ(gfx::BoxF().ToString(), bounds
.ToString());
909 TEST(TransformOperationTest
, BlendedBoundsForRotationTrivial
) {
910 TransformOperations operations_from
;
911 operations_from
.AppendRotate(0.f
, 0.f
, 1.f
, 0.f
);
912 TransformOperations operations_to
;
913 operations_to
.AppendRotate(0.f
, 0.f
, 1.f
, 360.f
);
915 float sqrt_2
= sqrt(2.f
);
917 -sqrt_2
, -sqrt_2
, 0.f
, sqrt_2
, sqrt_2
, 0.f
);
920 // Since we're rotating 360 degrees, any box with dimensions between 0 and
921 // 2 * sqrt(2) should give the same result.
922 float sizes
[] = { 0.f
, 0.1f
, sqrt_2
, 2.f
* sqrt_2
};
923 for (size_t i
= 0; i
< arraysize(sizes
); ++i
) {
924 box
.set_size(sizes
[i
], sizes
[i
], 0.f
);
925 SkMScalar min_progress
= 0.f
;
926 SkMScalar max_progress
= 1.f
;
927 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
928 box
, operations_from
, min_progress
, max_progress
, &bounds
));
929 EXPECT_EQ(gfx::BoxF(-2.f
, -2.f
, 0.f
, 4.f
, 4.f
, 0.f
).ToString(),
934 TEST(TransformOperationTest
, BlendedBoundsForRotationAllExtrema
) {
935 // If the normal is out of the plane, we can have up to 6 extrema (a min/max
936 // in each dimension) between the endpoints of the arc. This test ensures that
937 // we consider all 6.
938 TransformOperations operations_from
;
939 operations_from
.AppendRotate(1.f
, 1.f
, 1.f
, 30.f
);
940 TransformOperations operations_to
;
941 operations_to
.AppendRotate(1.f
, 1.f
, 1.f
, 390.f
);
943 gfx::BoxF
box(1.f
, 0.f
, 0.f
, 0.f
, 0.f
, 0.f
);
946 float min
= -1.f
/ 3.f
;
948 float size
= max
- min
;
949 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
950 box
, operations_from
, 0.f
, 1.f
, &bounds
));
951 EXPECT_EQ(gfx::BoxF(min
, min
, min
, size
, size
, size
).ToString(),
955 TEST(TransformOperationTest
, BlendedBoundsForRotationDifferentAxes
) {
956 // We can handle rotations about a single axis. If the axes are different,
957 // we revert to matrix interpolation for which inflated bounds cannot be
959 TransformOperations operations_from
;
960 operations_from
.AppendRotate(1.f
, 1.f
, 1.f
, 30.f
);
961 TransformOperations operations_to_same
;
962 operations_to_same
.AppendRotate(1.f
, 1.f
, 1.f
, 390.f
);
963 TransformOperations operations_to_opposite
;
964 operations_to_opposite
.AppendRotate(-1.f
, -1.f
, -1.f
, 390.f
);
965 TransformOperations operations_to_different
;
966 operations_to_different
.AppendRotate(1.f
, 3.f
, 1.f
, 390.f
);
968 gfx::BoxF
box(1.f
, 0.f
, 0.f
, 0.f
, 0.f
, 0.f
);
971 EXPECT_TRUE(operations_to_same
.BlendedBoundsForBox(
972 box
, operations_from
, 0.f
, 1.f
, &bounds
));
973 EXPECT_TRUE(operations_to_opposite
.BlendedBoundsForBox(
974 box
, operations_from
, 0.f
, 1.f
, &bounds
));
975 EXPECT_FALSE(operations_to_different
.BlendedBoundsForBox(
976 box
, operations_from
, 0.f
, 1.f
, &bounds
));
979 TEST(TransformOperationTest
, BlendedBoundsForRotationPointOnAxis
) {
980 // Checks that if the point to rotate is sitting on the axis of rotation, that
981 // it does not get affected.
982 TransformOperations operations_from
;
983 operations_from
.AppendRotate(1.f
, 1.f
, 1.f
, 30.f
);
984 TransformOperations operations_to
;
985 operations_to
.AppendRotate(1.f
, 1.f
, 1.f
, 390.f
);
987 gfx::BoxF
box(1.f
, 1.f
, 1.f
, 0.f
, 0.f
, 0.f
);
990 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
991 box
, operations_from
, 0.f
, 1.f
, &bounds
));
992 EXPECT_EQ(box
.ToString(), bounds
.ToString());
995 TEST(TransformOperationTest
, BlendedBoundsForRotationProblematicAxes
) {
996 // Zeros in the components of the axis of rotation turned out to be tricky to
997 // deal with in practice. This function tests some potentially problematic
998 // axes to ensure sane behavior.
1000 // Some common values used in the expected boxes.
1001 float dim1
= 0.292893f
;
1002 float dim2
= sqrt(2.f
);
1003 float dim3
= 2.f
* dim2
;
1010 } tests
[] = {{0.f
, 0.f
, 0.f
, gfx::BoxF(1.f
, 1.f
, 1.f
, 0.f
, 0.f
, 0.f
)},
1011 {1.f
, 0.f
, 0.f
, gfx::BoxF(1.f
, -dim2
, -dim2
, 0.f
, dim3
, dim3
)},
1012 {0.f
, 1.f
, 0.f
, gfx::BoxF(-dim2
, 1.f
, -dim2
, dim3
, 0.f
, dim3
)},
1013 {0.f
, 0.f
, 1.f
, gfx::BoxF(-dim2
, -dim2
, 1.f
, dim3
, dim3
, 0.f
)},
1014 {1.f
, 1.f
, 0.f
, gfx::BoxF(dim1
, dim1
, -1.f
, dim2
, dim2
, 2.f
)},
1015 {0.f
, 1.f
, 1.f
, gfx::BoxF(-1.f
, dim1
, dim1
, 2.f
, dim2
, dim2
)},
1016 {1.f
, 0.f
, 1.f
, gfx::BoxF(dim1
, -1.f
, dim1
, dim2
, 2.f
, dim2
)}};
1018 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
1019 float x
= tests
[i
].x
;
1020 float y
= tests
[i
].y
;
1021 float z
= tests
[i
].z
;
1022 TransformOperations operations_from
;
1023 operations_from
.AppendRotate(x
, y
, z
, 0.f
);
1024 TransformOperations operations_to
;
1025 operations_to
.AppendRotate(x
, y
, z
, 360.f
);
1026 gfx::BoxF
box(1.f
, 1.f
, 1.f
, 0.f
, 0.f
, 0.f
);
1029 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
1030 box
, operations_from
, 0.f
, 1.f
, &bounds
));
1031 EXPECT_EQ(tests
[i
].expected
.ToString(), bounds
.ToString());
1035 static void ExpectBoxesApproximatelyEqual(const gfx::BoxF
& lhs
,
1036 const gfx::BoxF
& rhs
,
1038 EXPECT_NEAR(lhs
.x(), rhs
.x(), tolerance
);
1039 EXPECT_NEAR(lhs
.y(), rhs
.y(), tolerance
);
1040 EXPECT_NEAR(lhs
.z(), rhs
.z(), tolerance
);
1041 EXPECT_NEAR(lhs
.width(), rhs
.width(), tolerance
);
1042 EXPECT_NEAR(lhs
.height(), rhs
.height(), tolerance
);
1043 EXPECT_NEAR(lhs
.depth(), rhs
.depth(), tolerance
);
1046 static void EmpiricallyTestBounds(const TransformOperations
& from
,
1047 const TransformOperations
& to
,
1048 SkMScalar min_progress
,
1049 SkMScalar max_progress
,
1050 bool test_containment_only
) {
1051 gfx::BoxF
box(200.f
, 500.f
, 100.f
, 100.f
, 300.f
, 200.f
);
1054 to
.BlendedBoundsForBox(box
, from
, min_progress
, max_progress
, &bounds
));
1056 bool first_time
= true;
1057 gfx::BoxF empirical_bounds
;
1058 static const size_t kNumSteps
= 10;
1059 for (size_t step
= 0; step
< kNumSteps
; ++step
) {
1060 float t
= step
/ (kNumSteps
- 1.f
);
1061 t
= gfx::Tween::FloatValueBetween(t
, min_progress
, max_progress
);
1062 gfx::Transform partial_transform
= to
.Blend(from
, t
);
1063 gfx::BoxF transformed
= box
;
1064 partial_transform
.TransformBox(&transformed
);
1067 empirical_bounds
= transformed
;
1070 empirical_bounds
.Union(transformed
);
1074 if (test_containment_only
) {
1075 gfx::BoxF unified_bounds
= bounds
;
1076 unified_bounds
.Union(empirical_bounds
);
1077 // Convert to the screen space rects these boxes represent.
1078 gfx::Rect bounds_rect
= ToEnclosingRect(
1079 gfx::RectF(bounds
.x(), bounds
.y(), bounds
.width(), bounds
.height()));
1080 gfx::Rect unified_bounds_rect
=
1081 ToEnclosingRect(gfx::RectF(unified_bounds
.x(),
1083 unified_bounds
.width(),
1084 unified_bounds
.height()));
1085 EXPECT_EQ(bounds_rect
.ToString(), unified_bounds_rect
.ToString());
1087 // Our empirical estimate will be a little rough since we're only doing
1089 static const float kTolerance
= 1e-2f
;
1090 ExpectBoxesApproximatelyEqual(empirical_bounds
, bounds
, kTolerance
);
1094 static void EmpiricallyTestBoundsEquality(const TransformOperations
& from
,
1095 const TransformOperations
& to
,
1096 SkMScalar min_progress
,
1097 SkMScalar max_progress
) {
1098 EmpiricallyTestBounds(from
, to
, min_progress
, max_progress
, false);
1101 static void EmpiricallyTestBoundsContainment(const TransformOperations
& from
,
1102 const TransformOperations
& to
,
1103 SkMScalar min_progress
,
1104 SkMScalar max_progress
) {
1105 EmpiricallyTestBounds(from
, to
, min_progress
, max_progress
, true);
1108 TEST(TransformOperationTest
, BlendedBoundsForRotationEmpiricalTests
) {
1109 // Sets up various axis angle combinations, computes the bounding box and
1110 // empirically tests that the transformed bounds are indeed contained by the
1111 // computed bounding box.
1117 } axes
[] = {{1.f
, 1.f
, 1.f
},
1139 } angles
[] = {{5.f
, 10.f
},
1147 // We can go beyond the range [0, 1] (the bezier might slide out of this range
1148 // at either end), but since the first and last knots are at (0, 0) and (1, 1)
1149 // we will never go within it, so these tests are sufficient.
1154 {0.f
, 1.f
}, {-.25f
, 1.25f
},
1157 for (size_t i
= 0; i
< arraysize(axes
); ++i
) {
1158 for (size_t j
= 0; j
< arraysize(angles
); ++j
) {
1159 for (size_t k
= 0; k
< arraysize(progress
); ++k
) {
1160 float x
= axes
[i
].x
;
1161 float y
= axes
[i
].y
;
1162 float z
= axes
[i
].z
;
1163 TransformOperations operations_from
;
1164 operations_from
.AppendRotate(x
, y
, z
, angles
[j
].theta_from
);
1165 TransformOperations operations_to
;
1166 operations_to
.AppendRotate(x
, y
, z
, angles
[j
].theta_to
);
1167 EmpiricallyTestBoundsContainment(operations_from
,
1169 progress
[k
].min_progress
,
1170 progress
[k
].max_progress
);
1176 TEST(TransformOperationTest
, PerspectiveMatrixAndTransformBlendingEquivalency
) {
1177 TransformOperations from_operations
;
1178 from_operations
.AppendPerspective(200);
1180 TransformOperations to_operations
;
1181 to_operations
.AppendPerspective(1000);
1183 gfx::Transform from_transform
;
1184 from_transform
.ApplyPerspectiveDepth(200);
1186 gfx::Transform to_transform
;
1187 to_transform
.ApplyPerspectiveDepth(1000);
1189 static const int steps
= 20;
1190 for (int i
= 0; i
< steps
; ++i
) {
1191 double progress
= static_cast<double>(i
) / (steps
- 1);
1193 gfx::Transform blended_matrix
= to_transform
;
1194 EXPECT_TRUE(blended_matrix
.Blend(from_transform
, progress
));
1196 gfx::Transform blended_transform
=
1197 to_operations
.Blend(from_operations
, progress
);
1199 EXPECT_TRANSFORMATION_MATRIX_EQ(blended_matrix
, blended_transform
);
1203 TEST(TransformOperationTest
, BlendedBoundsForPerspective
) {
1207 } perspective_depths
[] = {
1210 {800.f
, std::numeric_limits
<float>::infinity()},
1217 {0.f
, 1.f
}, {-0.1f
, 1.1f
},
1220 for (size_t i
= 0; i
< arraysize(perspective_depths
); ++i
) {
1221 for (size_t j
= 0; j
< arraysize(progress
); ++j
) {
1222 TransformOperations operations_from
;
1223 operations_from
.AppendPerspective(perspective_depths
[i
].from_depth
);
1224 TransformOperations operations_to
;
1225 operations_to
.AppendPerspective(perspective_depths
[i
].to_depth
);
1226 EmpiricallyTestBoundsEquality(operations_from
,
1228 progress
[j
].min_progress
,
1229 progress
[j
].max_progress
);
1234 TEST(TransformOperationTest
, BlendedBoundsForSkew
) {
1241 {1.f
, 0.5f
, 0.5f
, 1.f
}, {2.f
, 1.f
, 0.5f
, 0.5f
},
1248 {0.f
, 1.f
}, {-0.1f
, 1.1f
},
1251 for (size_t i
= 0; i
< arraysize(skews
); ++i
) {
1252 for (size_t j
= 0; j
< arraysize(progress
); ++j
) {
1253 TransformOperations operations_from
;
1254 operations_from
.AppendSkew(skews
[i
].from_x
, skews
[i
].from_y
);
1255 TransformOperations operations_to
;
1256 operations_to
.AppendSkew(skews
[i
].to_x
, skews
[i
].to_y
);
1257 EmpiricallyTestBoundsEquality(operations_from
,
1259 progress
[j
].min_progress
,
1260 progress
[j
].max_progress
);
1265 TEST(TransformOperationTest
, NonCommutativeRotations
) {
1266 TransformOperations operations_from
;
1267 operations_from
.AppendRotate(1.0, 0.0, 0.0, 0.0);
1268 operations_from
.AppendRotate(0.0, 1.0, 0.0, 0.0);
1269 TransformOperations operations_to
;
1270 operations_to
.AppendRotate(1.0, 0.0, 0.0, 45.0);
1271 operations_to
.AppendRotate(0.0, 1.0, 0.0, 135.0);
1273 gfx::BoxF
box(0, 0, 0, 1, 1, 1);
1276 SkMScalar min_progress
= 0.0f
;
1277 SkMScalar max_progress
= 1.0f
;
1278 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
1279 box
, operations_from
, min_progress
, max_progress
, &bounds
));
1280 gfx::Transform blended_transform
=
1281 operations_to
.Blend(operations_from
, max_progress
);
1282 gfx::Point3F
blended_point(0.9f
, 0.9f
, 0.0f
);
1283 blended_transform
.TransformPoint(&blended_point
);
1284 gfx::BoxF expanded_bounds
= bounds
;
1285 expanded_bounds
.ExpandTo(blended_point
);
1286 EXPECT_EQ(bounds
.ToString(), expanded_bounds
.ToString());
1289 TEST(TransformOperationTest
, BlendedBoundsForSequence
) {
1290 TransformOperations operations_from
;
1291 operations_from
.AppendTranslate(1.0, -5.0, 1.0);
1292 operations_from
.AppendScale(-1.0, 2.0, 3.0);
1293 operations_from
.AppendTranslate(2.0, 4.0, -1.0);
1294 TransformOperations operations_to
;
1295 operations_to
.AppendTranslate(13.0, -1.0, 5.0);
1296 operations_to
.AppendScale(-3.0, -2.0, 5.0);
1297 operations_to
.AppendTranslate(6.0, -2.0, 3.0);
1299 gfx::BoxF
box(1.f
, 2.f
, 3.f
, 4.f
, 4.f
, 4.f
);
1302 SkMScalar min_progress
= -0.5f
;
1303 SkMScalar max_progress
= 1.5f
;
1304 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
1305 box
, operations_from
, min_progress
, max_progress
, &bounds
));
1306 EXPECT_EQ(gfx::BoxF(-57.f
, -59.f
, -1.f
, 76.f
, 112.f
, 80.f
).ToString(),
1311 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
1312 box
, operations_from
, min_progress
, max_progress
, &bounds
));
1313 EXPECT_EQ(gfx::BoxF(-32.f
, -25.f
, 7.f
, 42.f
, 44.f
, 48.f
).ToString(),
1316 TransformOperations identity
;
1317 EXPECT_TRUE(operations_to
.BlendedBoundsForBox(
1318 box
, identity
, min_progress
, max_progress
, &bounds
));
1319 EXPECT_EQ(gfx::BoxF(-33.f
, -13.f
, 3.f
, 57.f
, 19.f
, 52.f
).ToString(),
1322 EXPECT_TRUE(identity
.BlendedBoundsForBox(
1323 box
, operations_from
, min_progress
, max_progress
, &bounds
));
1324 EXPECT_EQ(gfx::BoxF(-7.f
, -3.f
, 2.f
, 15.f
, 23.f
, 20.f
).ToString(),
1328 TEST(TransformOperationTest
, AffectsScaleWithSingleOperation
) {
1329 TransformOperations empty_operations
;
1330 EXPECT_FALSE(empty_operations
.AffectsScale());
1332 TransformOperations identity
;
1333 identity
.AppendIdentity();
1334 EXPECT_FALSE(identity
.AffectsScale());
1336 TransformOperations translate
;
1337 translate
.AppendTranslate(1.f
, 2.f
, 3.f
);
1338 EXPECT_FALSE(translate
.AffectsScale());
1340 TransformOperations rotate
;
1341 rotate
.AppendRotate(1.f
, 2.f
, 3.f
, 4.f
);
1342 EXPECT_FALSE(rotate
.AffectsScale());
1344 TransformOperations scale
;
1345 scale
.AppendScale(1.f
, 2.f
, 3.f
);
1346 EXPECT_TRUE(scale
.AffectsScale());
1348 TransformOperations skew
;
1349 skew
.AppendSkew(1.f
, 2.f
);
1350 EXPECT_FALSE(skew
.AffectsScale());
1352 TransformOperations perspective
;
1353 perspective
.AppendPerspective(1.f
);
1354 EXPECT_FALSE(perspective
.AffectsScale());
1356 TransformOperations identity_matrix
;
1357 identity_matrix
.AppendMatrix(gfx::Transform());
1358 EXPECT_FALSE(identity_matrix
.AffectsScale());
1360 TransformOperations translation_matrix
;
1361 gfx::Transform translation_transform
;
1362 translation_transform
.Translate3d(1.f
, 2.f
, 3.f
);
1363 translation_matrix
.AppendMatrix(translation_transform
);
1364 EXPECT_FALSE(translation_matrix
.AffectsScale());
1366 TransformOperations scaling_matrix
;
1367 gfx::Transform scaling_transform
;
1368 scaling_transform
.Scale(2.f
, 2.f
);
1369 scaling_matrix
.AppendMatrix(scaling_transform
);
1370 EXPECT_TRUE(scaling_matrix
.AffectsScale());
1373 TEST(TransformOperationTest
, AffectsScaleWithMultipleOperations
) {
1374 TransformOperations operations1
;
1375 operations1
.AppendSkew(1.f
, 2.f
);
1376 operations1
.AppendTranslate(1.f
, 2.f
, 3.f
);
1377 operations1
.AppendIdentity();
1378 EXPECT_FALSE(operations1
.AffectsScale());
1380 TransformOperations operations2
;
1381 operations2
.AppendPerspective(2.f
);
1382 operations2
.AppendScale(1.f
, 2.f
, 3.f
);
1383 operations2
.AppendTranslate(3.f
, 2.f
, 1.f
);
1384 EXPECT_TRUE(operations2
.AffectsScale());
1387 TEST(TransformOperationTest
, IsTranslationWithSingleOperation
) {
1388 TransformOperations empty_operations
;
1389 EXPECT_TRUE(empty_operations
.IsTranslation());
1391 TransformOperations identity
;
1392 identity
.AppendIdentity();
1393 EXPECT_TRUE(identity
.IsTranslation());
1395 TransformOperations translate
;
1396 translate
.AppendTranslate(1.f
, 2.f
, 3.f
);
1397 EXPECT_TRUE(translate
.IsTranslation());
1399 TransformOperations rotate
;
1400 rotate
.AppendRotate(1.f
, 2.f
, 3.f
, 4.f
);
1401 EXPECT_FALSE(rotate
.IsTranslation());
1403 TransformOperations scale
;
1404 scale
.AppendScale(1.f
, 2.f
, 3.f
);
1405 EXPECT_FALSE(scale
.IsTranslation());
1407 TransformOperations skew
;
1408 skew
.AppendSkew(1.f
, 2.f
);
1409 EXPECT_FALSE(skew
.IsTranslation());
1411 TransformOperations perspective
;
1412 perspective
.AppendPerspective(1.f
);
1413 EXPECT_FALSE(perspective
.IsTranslation());
1415 TransformOperations identity_matrix
;
1416 identity_matrix
.AppendMatrix(gfx::Transform());
1417 EXPECT_TRUE(identity_matrix
.IsTranslation());
1419 TransformOperations translation_matrix
;
1420 gfx::Transform translation_transform
;
1421 translation_transform
.Translate3d(1.f
, 2.f
, 3.f
);
1422 translation_matrix
.AppendMatrix(translation_transform
);
1423 EXPECT_TRUE(translation_matrix
.IsTranslation());
1425 TransformOperations scaling_matrix
;
1426 gfx::Transform scaling_transform
;
1427 scaling_transform
.Scale(2.f
, 2.f
);
1428 scaling_matrix
.AppendMatrix(scaling_transform
);
1429 EXPECT_FALSE(scaling_matrix
.IsTranslation());
1432 TEST(TransformOperationTest
, IsTranslationWithMultipleOperations
) {
1433 TransformOperations operations1
;
1434 operations1
.AppendSkew(1.f
, 2.f
);
1435 operations1
.AppendTranslate(1.f
, 2.f
, 3.f
);
1436 operations1
.AppendIdentity();
1437 EXPECT_FALSE(operations1
.IsTranslation());
1439 TransformOperations operations2
;
1440 operations2
.AppendIdentity();
1441 operations2
.AppendTranslate(3.f
, 2.f
, 1.f
);
1442 gfx::Transform translation_transform
;
1443 translation_transform
.Translate3d(1.f
, 2.f
, 3.f
);
1444 operations2
.AppendMatrix(translation_transform
);
1445 EXPECT_TRUE(operations2
.IsTranslation());
1448 TEST(TransformOperationTest
, ScaleComponent
) {
1449 gfx::Vector3dF scale
;
1452 TransformOperations operations1
;
1453 operations1
.AppendScale(-3.f
, 2.f
, 5.f
);
1454 EXPECT_TRUE(operations1
.ScaleComponent(&scale
));
1455 EXPECT_EQ(gfx::Vector3dF(-3.f
, 2.f
, 5.f
), scale
);
1457 // Translate + Scale.
1458 TransformOperations operations5
;
1459 operations5
.AppendTranslate(1.f
, 2.f
, 3.f
);
1460 operations5
.AppendScale(2.f
, 5.f
, 4.f
);
1461 EXPECT_TRUE(operations5
.ScaleComponent(&scale
));
1462 EXPECT_EQ(gfx::Vector3dF(2.f
, 5.f
, 4.f
), scale
);
1464 // Translate + Scale + Matrix with translate.
1465 gfx::Transform translation_transform
;
1466 translation_transform
.Translate3d(1.f
, 2.f
, 3.f
);
1467 operations5
.AppendMatrix(translation_transform
);
1468 EXPECT_TRUE(operations5
.ScaleComponent(&scale
));
1469 EXPECT_EQ(gfx::Vector3dF(2.f
, 5.f
, 4.f
), scale
);
1472 TEST(TransformOperationTest
, ScaleComponentCannotBeComputed
) {
1473 gfx::Vector3dF scale
;
1476 TransformOperations operations1
;
1477 operations1
.AppendScale(2.f
, 2.f
, 2.f
);
1478 EXPECT_TRUE(operations1
.ScaleComponent(&scale
));
1479 EXPECT_EQ(gfx::Vector3dF(2.f
, 2.f
, 2.f
), scale
);
1482 TransformOperations operations2
;
1483 operations2
.AppendTranslate(1.f
, 2.f
, 3.f
);
1484 EXPECT_TRUE(operations2
.ScaleComponent(&scale
));
1485 EXPECT_EQ(gfx::Vector3dF(1.f
, 1.f
, 1.f
), scale
);
1487 // Scale + translate can.
1488 TransformOperations operations3
;
1489 operations3
.AppendScale(2.f
, 3.f
, 2.f
);
1490 operations3
.AppendTranslate(1.f
, 2.f
, 3.f
);
1491 EXPECT_TRUE(operations3
.ScaleComponent(&scale
));
1492 EXPECT_EQ(gfx::Vector3dF(2.f
, 3.f
, 2.f
), scale
);
1494 // Two Scales can't.
1495 TransformOperations operations4
;
1496 operations4
.AppendScale(2.f
, 3.f
, 2.f
);
1497 operations4
.AppendScale(3.f
, 2.f
, 3.f
);
1498 EXPECT_FALSE(operations4
.ScaleComponent(&scale
));
1501 TransformOperations operations5
;
1502 operations5
.AppendScale(2.f
, 2.f
, 2.f
);
1503 gfx::Transform scaling_transform
;
1504 scaling_transform
.Scale(2.f
, 2.f
);
1505 operations5
.AppendMatrix(scaling_transform
);
1506 EXPECT_FALSE(operations5
.ScaleComponent(&scale
));
1508 // Scale + Rotate can't.
1509 TransformOperations operations7
;
1510 operations7
.AppendScale(2.f
, 2.f
, 2.f
);
1511 operations7
.AppendRotate(1.f
, 2.f
, 3.f
, 4.f
);
1512 EXPECT_FALSE(operations7
.ScaleComponent(&scale
));
1514 // Scale + Skew can't.
1515 TransformOperations operations9
;
1516 operations9
.AppendScale(2.f
, 2.f
, 2.f
);
1517 operations9
.AppendSkew(1.f
, 2.f
);
1518 EXPECT_FALSE(operations9
.ScaleComponent(&scale
));
1520 // Scale + Perspective can't.
1521 TransformOperations operations11
;
1522 operations11
.AppendScale(2.f
, 2.f
, 2.f
);
1523 operations11
.AppendPerspective(1.f
);
1524 EXPECT_FALSE(operations11
.ScaleComponent(&scale
));