1/* 2 * Copyright (C) 2014 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25#include "config.h" 26#include "platform/transforms/TransformOperations.h" 27 28#include "platform/geometry/FloatBox.h" 29#include "platform/geometry/FloatBoxTestHelpers.h" 30#include "platform/transforms/IdentityTransformOperation.h" 31#include "platform/transforms/Matrix3DTransformOperation.h" 32#include "platform/transforms/MatrixTransformOperation.h" 33#include "platform/transforms/PerspectiveTransformOperation.h" 34#include "platform/transforms/RotateTransformOperation.h" 35#include "platform/transforms/ScaleTransformOperation.h" 36#include "platform/transforms/SkewTransformOperation.h" 37#include "platform/transforms/TranslateTransformOperation.h" 38 39#include <gtest/gtest.h> 40 41using namespace blink; 42namespace { 43 44static const TransformOperations identityOperations; 45 46static void EmpiricallyTestBounds(const TransformOperations& from, 47 const TransformOperations& to, 48 const double& minProgress, 49 const double& maxProgress) 50{ 51 FloatBox box(200, 500, 100, 100, 300, 200); 52 FloatBox bounds; 53 54 EXPECT_TRUE(to.blendedBoundsForBox(box, from, minProgress, maxProgress, &bounds)); 55 bool firstTime = true; 56 57 FloatBox empiricalBounds; 58 static const size_t numSteps = 10; 59 for (size_t step = 0; step < numSteps; ++step) { 60 float t = step / (numSteps - 1); 61 t = minProgress + (maxProgress - minProgress) * t; 62 TransformOperations operations = from.blend(to, t); 63 TransformationMatrix matrix; 64 operations.apply(FloatSize(0, 0), matrix); 65 FloatBox transformed = box; 66 matrix.transformBox(transformed); 67 68 if (firstTime) 69 empiricalBounds = transformed; 70 else 71 empiricalBounds.unionBounds(transformed); 72 firstTime = false; 73 } 74 75 ASSERT_PRED_FORMAT2(FloatBoxTest::AssertContains, bounds, empiricalBounds); 76} 77 78TEST(TransformOperationsTest, AbsoluteAnimatedTranslatedBoundsTest) 79{ 80 TransformOperations fromOps; 81 TransformOperations toOps; 82 fromOps.operations().append(TranslateTransformOperation::create(Length(-30, blink::Fixed), Length(20, blink::Fixed), 15, TransformOperation::Translate3D)); 83 toOps.operations().append(TranslateTransformOperation::create(Length(10, blink::Fixed), Length(10, blink::Fixed), 200, TransformOperation::Translate3D)); 84 FloatBox box(0, 0, 0, 10, 10, 10); 85 FloatBox bounds; 86 87 EXPECT_TRUE(toOps.blendedBoundsForBox(box, identityOperations, 0, 1, &bounds)); 88 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(0, 0, 0, 20, 20, 210), bounds); 89 90 EXPECT_TRUE(identityOperations.blendedBoundsForBox(box, toOps, 0, 1, &bounds)); 91 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(0, 0, 0, 20, 20, 210), bounds); 92 93 EXPECT_TRUE(identityOperations.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 94 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-30, 0, 0, 40, 30, 25), bounds); 95 96 EXPECT_TRUE(toOps.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 97 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-30, 10, 15, 50, 20, 195), bounds); 98 99 EXPECT_TRUE(toOps.blendedBoundsForBox(box, fromOps, -0.5, 1.25, &bounds)); 100 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-50, 7.5, -77.5, 80, 27.5, 333.75), bounds); 101} 102 103TEST(TransformOperationsTest, EmpiricalAnimatedTranslatedBoundsTest) 104{ 105 float testTransforms[][2][3] = { 106 { { 0, 0, 0 }, { 10, 10, 0 } } , 107 { { -100, 202.5, -32.6 }, { 43.2, 56.1, 89.75 } }, 108 { { 43.2, 56.1, 89.75 }, { -100, 202.5, -32.6 } } 109 }; 110 111 // All progressions for animations start and end at 0, 1 respectively, 112 // we can go outside of these bounds, but will always at least contain 113 // [0,1]. 114 float progress[][2] = { 115 { 0, 1 }, 116 { -.25, 1.25 } 117 }; 118 119 for (size_t i = 0; i < WTF_ARRAY_LENGTH(testTransforms); ++i) { 120 for (size_t j = 0; j < WTF_ARRAY_LENGTH(progress); ++j) { 121 TransformOperations fromOps; 122 TransformOperations toOps; 123 fromOps.operations().append(TranslateTransformOperation::create(Length(testTransforms[i][0][0], blink::Fixed), Length(testTransforms[i][0][1], blink::Fixed), testTransforms[i][0][2], TransformOperation::Translate3D)); 124 toOps.operations().append(TranslateTransformOperation::create(Length(testTransforms[i][1][0], blink::Fixed), Length(testTransforms[i][1][1], blink::Fixed), testTransforms[i][1][2], TransformOperation::Translate3D)); 125 EmpiricallyTestBounds(fromOps, toOps, 0, 1); 126 } 127 } 128} 129 130TEST(TransformOperationsTest, AbsoluteAnimatedScaleBoundsTest) 131{ 132 TransformOperations fromOps; 133 TransformOperations toOps; 134 fromOps.operations().append(ScaleTransformOperation::create(4, -3, TransformOperation::Scale)); 135 toOps.operations().append(ScaleTransformOperation::create(5, 2, TransformOperation::Scale)); 136 137 FloatBox box(0, 0, 0, 10, 10, 10); 138 FloatBox bounds; 139 140 EXPECT_TRUE(toOps.blendedBoundsForBox(box, identityOperations, 0, 1, &bounds)); 141 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(0, 0, 0, 50, 20, 10), bounds); 142 143 EXPECT_TRUE(identityOperations.blendedBoundsForBox(box, toOps, 0, 1, &bounds)); 144 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(0, 0, 0, 50, 20, 10), bounds); 145 146 EXPECT_TRUE(identityOperations.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 147 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(0, -30, 0, 40, 40, 10), bounds); 148 149 EXPECT_TRUE(toOps.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 150 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(0, -30, 0, 50, 50, 10), bounds); 151 152 EXPECT_TRUE(toOps.blendedBoundsForBox(box, fromOps, -0.5, 1.25, &bounds)); 153 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(0, -55, 0, 52.5, 87.5, 10), bounds); 154} 155 156TEST(TransformOperationsTest, EmpiricalAnimatedScaleBoundsTest) 157{ 158 159 float testTransforms[][2][3] = { 160 { { 1, 1, 1 }, { 10, 10, -32}}, 161 { { 1, 2, 5 }, { -1, -2, -4}}, 162 { { 0, 0, 0 }, { 1, 2, 3}}, 163 { { 0, 0, 0 }, { 0, 0, 0}} 164 }; 165 166 // All progressions for animations start and end at 0, 1 respectively, 167 // we can go outside of these bounds, but will always at least contain 168 // [0,1]. 169 float progress[][2] = { 170 { 0, 1 }, 171 { -.25f, 1.25f } 172 }; 173 174 for (size_t i = 0; i < WTF_ARRAY_LENGTH(testTransforms); ++i) { 175 for (size_t j = 0; j < WTF_ARRAY_LENGTH(progress); ++j) { 176 TransformOperations fromOps; 177 TransformOperations toOps; 178 fromOps.operations().append(TranslateTransformOperation::create(Length(testTransforms[i][0][0], blink::Fixed), Length(testTransforms[i][0][1], blink::Fixed), testTransforms[i][0][2], TransformOperation::Translate3D)); 179 toOps.operations().append(TranslateTransformOperation::create(Length(testTransforms[i][1][0], blink::Fixed), Length(testTransforms[i][1][1], blink::Fixed), testTransforms[i][1][2], TransformOperation::Translate3D)); 180 EmpiricallyTestBounds(fromOps, toOps, 0, 1); 181 } 182 } 183} 184 185TEST(TransformOperationsTest, AbsoluteAnimatedRotationBounds) 186{ 187 TransformOperations fromOps; 188 TransformOperations toOps; 189 fromOps.operations().append(RotateTransformOperation::create(0, TransformOperation::Rotate)); 190 toOps.operations().append(RotateTransformOperation::create(360, TransformOperation::Rotate)); 191 float sqrt2 = sqrt(2.0f); 192 FloatBox box(-sqrt2, -sqrt2, 0, sqrt2, sqrt2, 0); 193 FloatBox bounds; 194 195 // Since we're rotating 360 degrees, any box with dimensions between 0 and 196 // 2 * sqrt(2) should give the same result. 197 float sizes[] = { 0, 0.1f, sqrt2, 2*sqrt2 }; 198 toOps.blendedBoundsForBox(box, fromOps, 0, 1, &bounds); 199 for (size_t i = 0; i < WTF_ARRAY_LENGTH(sizes); ++i) { 200 box.setSize(FloatPoint3D(sizes[i], sizes[i], 0)); 201 202 EXPECT_TRUE(toOps.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 203 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-2, -2, 0, 4, 4, 0), bounds); 204 } 205} 206 207TEST(TransformOperationsTest, AbsoluteAnimatedExtremeRotationBounds) 208{ 209 // If the normal is off-plane, we can have up to 6 exrema (min/max in each 210 // dimension between) the endpoints of the arg. This makes sure we are 211 // catching all 6. 212 TransformOperations fromOps; 213 TransformOperations toOps; 214 fromOps.operations().append(RotateTransformOperation::create(1, 1, 1, 30, TransformOperation::Rotate3D)); 215 toOps.operations().append(RotateTransformOperation::create(1, 1, 1, 390, TransformOperation::Rotate3D)); 216 217 FloatBox box(1, 0, 0, 0, 0, 0); 218 FloatBox bounds; 219 float min = -1 / 3.0f; 220 float max = 1; 221 float size = max - min; 222 EXPECT_TRUE(toOps.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 223 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(min, min, min, size, size, size), bounds); 224} 225 226TEST(TransformOperationsTest, AbsoluteAnimatedAxisRotationBounds) 227{ 228 // We can handle rotations about a single axis. If the axes are different, 229 // we revert to matrix interpolation for which inflated bounds cannot be 230 // computed. 231 TransformOperations fromOps; 232 TransformOperations toSame; 233 TransformOperations toOpposite; 234 TransformOperations toDifferent; 235 fromOps.operations().append(RotateTransformOperation::create(1, 1, 1, 30, TransformOperation::Rotate3D)); 236 toSame.operations().append(RotateTransformOperation::create(1, 1, 1, 390, TransformOperation::Rotate3D)); 237 toOpposite.operations().append(RotateTransformOperation::create(-1, -1, -1, 390, TransformOperation::Rotate3D)); 238 toDifferent.operations().append(RotateTransformOperation::create(1, 3, 1, 390, TransformOperation::Rotate3D)); 239 240 FloatBox box(1, 0, 0, 0, 0, 0); 241 FloatBox bounds; 242 EXPECT_TRUE(toSame.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 243 EXPECT_TRUE(toOpposite.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 244 EXPECT_FALSE(toDifferent.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 245} 246 247TEST(TransformOperationsTest, AbsoluteAnimatedOnAxisRotationBounds) 248{ 249 // If we rotate a point that is on the axis of rotation, the box should not 250 // change at all. 251 TransformOperations fromOps; 252 TransformOperations toOps; 253 fromOps.operations().append(RotateTransformOperation::create(1, 1, 1, 30, TransformOperation::Rotate3D)); 254 toOps.operations().append(RotateTransformOperation::create(1, 1, 1, 390, TransformOperation::Rotate3D)); 255 256 FloatBox box(1, 1, 1, 0, 0, 0); 257 FloatBox bounds; 258 259 EXPECT_TRUE(toOps.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 260 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, box, bounds); 261} 262 263// This would have been best as anonymous structs, but |WTF_ARRAY_LENGTH| 264// does not get along with anonymous structs once we support C++11 265// WTF_ARRAY_LENGTH will automatically support anonymous structs. 266 267struct ProblematicAxisTest { 268 double x; 269 double y; 270 double z; 271 FloatBox expected; 272}; 273 274TEST(TransformOperationsTest, AbsoluteAnimatedProblematicAxisRotationBounds) 275{ 276 // Zeros in the components of the axis osf rotation turned out to be tricky to 277 // deal with in practice. This function tests some potentially problematic 278 // axes to ensure sane behavior. 279 280 // Some common values used in the expected boxes. 281 float dim1 = 0.292893f; 282 float dim2 = sqrt(2.0f); 283 float dim3 = 2 * dim2; 284 285 ProblematicAxisTest tests[] = { 286 { 0, 0, 0, FloatBox(1, 1, 1, 0, 0, 0) }, 287 { 1, 0, 0, FloatBox(1, -dim2, -dim2, 0, dim3, dim3) }, 288 { 0, 1, 0, FloatBox(-dim2, 1, -dim2, dim3, 0, dim3) }, 289 { 0, 0, 1, FloatBox(-dim2, -dim2, 1, dim3, dim3, 0) }, 290 { 1, 1, 0, FloatBox(dim1, dim1, -1, dim2, dim2, 2) }, 291 { 0, 1, 1, FloatBox(-1, dim1, dim1, 2, dim2, dim2) }, 292 { 1, 0, 1, FloatBox(dim1, -1, dim1, dim2, 2, dim2) } 293 }; 294 295 for (size_t i = 0; i < WTF_ARRAY_LENGTH(tests); ++i) { 296 float x = tests[i].x; 297 float y = tests[i].y; 298 float z = tests[i].z; 299 TransformOperations fromOps; 300 fromOps.operations().append(RotateTransformOperation::create(x, y, z, 0, TransformOperation::Rotate3D)); 301 TransformOperations toOps; 302 toOps.operations().append(RotateTransformOperation::create(x, y, z, 360, TransformOperation::Rotate3D)); 303 FloatBox box(1, 1, 1, 0, 0, 0); 304 FloatBox bounds; 305 306 EXPECT_TRUE(toOps.blendedBoundsForBox( 307 box, fromOps, 0, 1, &bounds)); 308 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, tests[i].expected, bounds); 309 } 310} 311 312 313TEST(TransformOperationsTest, BlendedBoundsForRotationEmpiricalTests) 314{ 315 float axes[][3] = { 316 { 1, 1, 1 }, 317 { -1, -1, -1 }, 318 { -1, 2, 3 }, 319 { 1, -2, 3 }, 320 { 0, 0, 0 }, 321 { 1, 0, 0 }, 322 { 0, 1, 0 }, 323 { 0, 0, 1 }, 324 { 1, 1, 0 }, 325 { 0, 1, 1 }, 326 { 1, 0, 1 }, 327 { -1, 0, 0 }, 328 { 0, -1, 0 }, 329 { 0, 0, -1 }, 330 { -1, -1, 0 }, 331 { 0, -1, -1 }, 332 { -1, 0, -1 } 333 }; 334 335 float angles[][2] = { 336 { 5, 100 }, 337 { 10, 5 }, 338 { 0, 360 }, 339 { 20, 180 }, 340 { -20, -180 }, 341 { 180, -220 }, 342 { 220, 320 }, 343 { 1020, 1120 }, 344 {-3200, 120 }, 345 {-9000, -9050 } 346 }; 347 348 float progress[][2] = { 349 { 0, 1 }, 350 { -0.25f, 1.25f } 351 }; 352 353 for (size_t i = 0; i < WTF_ARRAY_LENGTH(axes); ++i) { 354 for (size_t j = 0; j < WTF_ARRAY_LENGTH(angles); ++j) { 355 for (size_t k = 0; k < WTF_ARRAY_LENGTH(progress); ++k) { 356 float x = axes[i][0]; 357 float y = axes[i][1]; 358 float z = axes[i][2]; 359 360 TransformOperations fromOps; 361 TransformOperations toOps; 362 363 fromOps.operations().append(RotateTransformOperation::create(x, y, z, angles[j][0], TransformOperation::Rotate3D)); 364 toOps.operations().append(RotateTransformOperation::create(x, y, z, angles[j][1], TransformOperation::Rotate3D)); 365 EmpiricallyTestBounds(fromOps, toOps, progress[k][0], progress[k][1]); 366 } 367 } 368 } 369} 370 371TEST(TransformOperationsTest, AbsoluteAnimatedPerspectiveBoundsTest) 372{ 373 TransformOperations fromOps; 374 TransformOperations toOps; 375 fromOps.operations().append(PerspectiveTransformOperation::create(10)); 376 toOps.operations().append(PerspectiveTransformOperation::create(30)); 377 FloatBox box(0, 0, 0, 10, 10, 10); 378 FloatBox bounds; 379 toOps.blendedBoundsForBox(box, fromOps, 0, 1, &bounds); 380 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(0, 0, 0, 15, 15, 15), bounds); 381 382 fromOps.blendedBoundsForBox(box, toOps, -0.25, 1.25, &bounds); 383 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-40, -40, -40, 52, 52, 52), bounds); 384} 385 386TEST(TransformOperationsTest, EmpiricalAnimatedPerspectiveBoundsTest) 387{ 388 float depths[][2] = { 389 { 600, 400 }, 390 { 800, 1000 }, 391 { 800, std::numeric_limits<float>::infinity() } 392 }; 393 394 float progress[][2] = { 395 { 0, 1 }, 396 {-0.1f, 1.1f } 397 }; 398 399 for (size_t i = 0; i < WTF_ARRAY_LENGTH(depths); ++i) { 400 for (size_t j = 0; j < WTF_ARRAY_LENGTH(progress); ++j) { 401 TransformOperations fromOps; 402 TransformOperations toOps; 403 404 fromOps.operations().append(PerspectiveTransformOperation::create(depths[i][0])); 405 toOps.operations().append(PerspectiveTransformOperation::create(depths[i][1])); 406 407 EmpiricallyTestBounds(fromOps, toOps, progress[j][0], progress[j][1]); 408 } 409 } 410} 411 412 413TEST(TransformOperationsTest, AnimatedSkewBoundsTest) 414{ 415 TransformOperations fromOps; 416 TransformOperations toOps; 417 fromOps.operations().append(SkewTransformOperation::create(-45, 0, TransformOperation::Skew)); 418 toOps.operations().append(SkewTransformOperation::create(0, 45, TransformOperation::Skew)); 419 FloatBox box(0, 0, 0, 10, 10, 10); 420 FloatBox bounds; 421 422 toOps.blendedBoundsForBox(box, identityOperations, 0, 1, &bounds); 423 ASSERT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(0, 0, 0, 10, 20, 10), bounds); 424 425 identityOperations.blendedBoundsForBox(box, fromOps, 0, 1, &bounds); 426 ASSERT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-10, 0, 0, 20, 10, 10), bounds); 427 428 toOps.blendedBoundsForBox(box, fromOps, 0, 1, &bounds); 429 ASSERT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-10, 0, 0, 20, 20, 10), bounds); 430 431 fromOps.blendedBoundsForBox(box, toOps, 0, 1, &bounds); 432 ASSERT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-10, 0, 0, 20, 20, 10), bounds); 433} 434 435TEST(TransformOperationsTest, NonCommutativeRotations) 436{ 437 TransformOperations fromOps; 438 fromOps.operations().append(RotateTransformOperation::create(1, 0, 0, 0, TransformOperation::Rotate3D)); 439 fromOps.operations().append(RotateTransformOperation::create(0, 1, 0, 0, TransformOperation::Rotate3D)); 440 TransformOperations toOps; 441 toOps.operations().append(RotateTransformOperation::create(1, 0, 0, 45, TransformOperation::Rotate3D)); 442 toOps.operations().append(RotateTransformOperation::create(0, 1, 0, 135, TransformOperation::Rotate3D)); 443 444 FloatBox box(0, 0, 0, 1, 1, 1); 445 FloatBox bounds; 446 447 double minProgress = 0; 448 double maxProgress = 1; 449 EXPECT_TRUE(toOps.blendedBoundsForBox( 450 box, fromOps, minProgress, maxProgress, &bounds)); 451 452 TransformOperations operations = toOps.blend(fromOps, maxProgress); 453 TransformationMatrix blendedTransform; 454 operations.apply(FloatSize(0, 0), blendedTransform); 455 456 FloatPoint3D blendedPoint(0.9f, 0.9f, 0); 457 blendedPoint = blendedTransform.mapPoint(blendedPoint); 458 FloatBox expandedBounds = bounds; 459 expandedBounds.expandTo(blendedPoint); 460 461 ASSERT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, bounds, expandedBounds); 462} 463 464TEST(TransformOperationsTest, AbsoluteSequenceBoundsTest) 465{ 466 TransformOperations fromOps; 467 TransformOperations toOps; 468 469 fromOps.operations().append(TranslateTransformOperation::create(Length(1, Fixed), Length(-5, Fixed), 1, TransformOperation::Translate3D)); 470 fromOps.operations().append(ScaleTransformOperation::create(-1, 2, 3, TransformOperation::Scale3D)); 471 fromOps.operations().append(TranslateTransformOperation::create(Length(2, Fixed), Length(4, Fixed), -1, TransformOperation::Translate3D)); 472 473 toOps.operations().append(TranslateTransformOperation::create(Length(13, Fixed), Length(-1, Fixed), 5, TransformOperation::Translate3D)); 474 toOps.operations().append(ScaleTransformOperation::create(-3, -2, 5, TransformOperation::Scale3D)); 475 toOps.operations().append(TranslateTransformOperation::create(Length(6, Fixed), Length(-2, Fixed), 3, TransformOperation::Translate3D)); 476 477 FloatBox box(1, 2, 3, 4, 4, 4); 478 FloatBox bounds; 479 480 EXPECT_TRUE(toOps.blendedBoundsForBox(box, fromOps, -0.5, 1.5, &bounds)); 481 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-57, -59, -1, 76, 112, 80), bounds); 482 483 EXPECT_TRUE(toOps.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 484 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-32, -25, 7, 42, 44, 48), bounds); 485 486 EXPECT_TRUE(toOps.blendedBoundsForBox(box, identityOperations, 0, 1, &bounds)); 487 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-33, -13, 3, 57, 19, 52), bounds); 488 489 EXPECT_TRUE(identityOperations.blendedBoundsForBox(box, fromOps, 0, 1, &bounds)); 490 EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, FloatBox(-7, -3, 2, 15, 23, 20), bounds); 491} 492 493} // namespace 494