123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ui/gfx/geometry/transform_operations.h"
- #include <stddef.h>
- #include <limits>
- #include <utility>
- #include <vector>
- #include "base/cxx17_backports.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "ui/gfx/animation/tween.h"
- #include "ui/gfx/geometry/box_f.h"
- #include "ui/gfx/geometry/rect_conversions.h"
- #include "ui/gfx/geometry/test/geometry_util.h"
- #include "ui/gfx/geometry/vector3d_f.h"
- namespace gfx {
- namespace {
- void ExpectTransformOperationEqual(const TransformOperation& lhs,
- const TransformOperation& rhs) {
- EXPECT_EQ(lhs.type, rhs.type);
- EXPECT_TRANSFORM_EQ(lhs.matrix, rhs.matrix);
- switch (lhs.type) {
- case TransformOperation::TRANSFORM_OPERATION_TRANSLATE:
- EXPECT_FLOAT_EQ(lhs.translate.x, rhs.translate.x);
- EXPECT_FLOAT_EQ(lhs.translate.y, rhs.translate.y);
- EXPECT_FLOAT_EQ(lhs.translate.z, rhs.translate.z);
- break;
- case TransformOperation::TRANSFORM_OPERATION_ROTATE:
- EXPECT_FLOAT_EQ(lhs.rotate.axis.x, rhs.rotate.axis.x);
- EXPECT_FLOAT_EQ(lhs.rotate.axis.y, rhs.rotate.axis.y);
- EXPECT_FLOAT_EQ(lhs.rotate.axis.z, rhs.rotate.axis.z);
- EXPECT_FLOAT_EQ(lhs.rotate.angle, rhs.rotate.angle);
- break;
- case TransformOperation::TRANSFORM_OPERATION_SCALE:
- EXPECT_FLOAT_EQ(lhs.scale.x, rhs.scale.x);
- EXPECT_FLOAT_EQ(lhs.scale.y, rhs.scale.y);
- EXPECT_FLOAT_EQ(lhs.scale.z, rhs.scale.z);
- break;
- case TransformOperation::TRANSFORM_OPERATION_SKEWX:
- case TransformOperation::TRANSFORM_OPERATION_SKEWY:
- case TransformOperation::TRANSFORM_OPERATION_SKEW:
- EXPECT_FLOAT_EQ(lhs.skew.x, rhs.skew.x);
- EXPECT_FLOAT_EQ(lhs.skew.y, rhs.skew.y);
- break;
- case TransformOperation::TRANSFORM_OPERATION_PERSPECTIVE:
- EXPECT_FLOAT_EQ(lhs.perspective_m43, rhs.perspective_m43);
- break;
- case TransformOperation::TRANSFORM_OPERATION_MATRIX:
- case TransformOperation::TRANSFORM_OPERATION_IDENTITY:
- break;
- }
- }
- TEST(TransformOperationTest, TransformTypesAreUnique) {
- std::vector<std::unique_ptr<TransformOperations>> transforms;
- std::unique_ptr<TransformOperations> to_add(
- std::make_unique<TransformOperations>());
- to_add->AppendTranslate(1, 0, 0);
- transforms.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendRotate(0, 0, 1, 2);
- transforms.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendScale(2, 2, 2);
- transforms.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendSkew(1, 0);
- transforms.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendPerspective(800);
- transforms.push_back(std::move(to_add));
- for (size_t i = 0; i < transforms.size(); ++i) {
- for (size_t j = 0; j < transforms.size(); ++j) {
- bool matches_type = transforms[i]->MatchesTypes(*transforms[j]);
- EXPECT_TRUE((i == j && matches_type) || !matches_type);
- }
- }
- }
- TEST(TransformOperationTest, MatchingPrefixSameLength) {
- TransformOperations translates;
- translates.AppendTranslate(1, 0, 0);
- translates.AppendTranslate(1, 0, 0);
- translates.AppendTranslate(1, 0, 0);
- TransformOperations skews;
- skews.AppendSkew(0, 2);
- skews.AppendSkew(0, 2);
- skews.AppendSkew(0, 2);
- TransformOperations translates2;
- translates2.AppendTranslate(0, 2, 0);
- translates2.AppendTranslate(0, 2, 0);
- translates2.AppendTranslate(0, 2, 0);
- TransformOperations mixed;
- mixed.AppendTranslate(0, 2, 0);
- mixed.AppendScale(2, 1, 1);
- mixed.AppendSkew(0, 2);
- TransformOperations translates3 = translates2;
- EXPECT_EQ(0UL, translates.MatchingPrefixLength(skews));
- EXPECT_EQ(3UL, translates.MatchingPrefixLength(translates2));
- EXPECT_EQ(3UL, translates.MatchingPrefixLength(translates3));
- EXPECT_EQ(1UL, translates.MatchingPrefixLength(mixed));
- }
- TEST(TransformOperationTest, MatchingPrefixDifferentLength) {
- TransformOperations translates;
- translates.AppendTranslate(1, 0, 0);
- translates.AppendTranslate(1, 0, 0);
- translates.AppendTranslate(1, 0, 0);
- TransformOperations skews;
- skews.AppendSkew(2, 0);
- skews.AppendSkew(2, 0);
- TransformOperations translates2;
- translates2.AppendTranslate(0, 2, 0);
- translates2.AppendTranslate(0, 2, 0);
- TransformOperations none;
- EXPECT_EQ(0UL, translates.MatchingPrefixLength(skews));
- // Pad the length of the shorter list provided all previous operation-
- // pairs match per spec
- // (https://drafts.csswg.org/css-transforms/#interpolation-of-transforms).
- EXPECT_EQ(3UL, translates.MatchingPrefixLength(translates2));
- EXPECT_EQ(3UL, translates.MatchingPrefixLength(none));
- }
- std::vector<std::unique_ptr<TransformOperations>> GetIdentityOperations() {
- std::vector<std::unique_ptr<TransformOperations>> operations;
- std::unique_ptr<TransformOperations> to_add(
- std::make_unique<TransformOperations>());
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendTranslate(0, 0, 0);
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendTranslate(0, 0, 0);
- to_add->AppendTranslate(0, 0, 0);
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendScale(1, 1, 1);
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendScale(1, 1, 1);
- to_add->AppendScale(1, 1, 1);
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendSkew(0, 0);
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendSkew(0, 0);
- to_add->AppendSkew(0, 0);
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendRotate(0, 0, 1, 0);
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendRotate(0, 0, 1, 0);
- to_add->AppendRotate(0, 0, 1, 0);
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendMatrix(gfx::Transform());
- operations.push_back(std::move(to_add));
- to_add = std::make_unique<TransformOperations>();
- to_add->AppendMatrix(gfx::Transform());
- to_add->AppendMatrix(gfx::Transform());
- operations.push_back(std::move(to_add));
- return operations;
- }
- TEST(TransformOperationTest, MatchingPrefixLengthOrder) {
- TransformOperations mix_order_identity;
- mix_order_identity.AppendTranslate(0, 0, 0);
- mix_order_identity.AppendScale(1, 1, 1);
- mix_order_identity.AppendTranslate(0, 0, 0);
- TransformOperations mix_order_one;
- mix_order_one.AppendTranslate(0, 1, 0);
- mix_order_one.AppendScale(2, 1, 3);
- mix_order_one.AppendTranslate(1, 0, 0);
- TransformOperations mix_order_two;
- mix_order_two.AppendTranslate(0, 1, 0);
- mix_order_two.AppendTranslate(1, 0, 0);
- mix_order_two.AppendScale(2, 1, 3);
- EXPECT_EQ(3UL, mix_order_identity.MatchingPrefixLength(mix_order_one));
- EXPECT_EQ(1UL, mix_order_identity.MatchingPrefixLength(mix_order_two));
- EXPECT_EQ(1UL, mix_order_one.MatchingPrefixLength(mix_order_two));
- }
- TEST(TransformOperationTest, NoneAlwaysMatches) {
- std::vector<std::unique_ptr<TransformOperations>> operations =
- GetIdentityOperations();
- TransformOperations none_operation;
- for (const auto& operation : operations) {
- EXPECT_EQ(operation->size(),
- operation->MatchingPrefixLength(none_operation));
- }
- }
- TEST(TransformOperationTest, ApplyTranslate) {
- SkScalar x = 1;
- SkScalar y = 2;
- SkScalar z = 3;
- TransformOperations operations;
- operations.AppendTranslate(x, y, z);
- gfx::Transform expected;
- expected.Translate3d(x, y, z);
- EXPECT_TRANSFORM_EQ(expected, operations.Apply());
- }
- TEST(TransformOperationTest, ApplyRotate) {
- SkScalar x = 1;
- SkScalar y = 2;
- SkScalar z = 3;
- SkScalar degrees = 80;
- TransformOperations operations;
- operations.AppendRotate(x, y, z, degrees);
- gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(x, y, z), degrees);
- EXPECT_TRANSFORM_EQ(expected, operations.Apply());
- }
- TEST(TransformOperationTest, ApplyScale) {
- SkScalar x = 1;
- SkScalar y = 2;
- SkScalar z = 3;
- TransformOperations operations;
- operations.AppendScale(x, y, z);
- gfx::Transform expected;
- expected.Scale3d(x, y, z);
- EXPECT_TRANSFORM_EQ(expected, operations.Apply());
- }
- TEST(TransformOperationTest, ApplySkew) {
- SkScalar x = 1;
- SkScalar y = 2;
- TransformOperations operations;
- operations.AppendSkew(x, y);
- gfx::Transform expected;
- expected.Skew(x, y);
- EXPECT_TRANSFORM_EQ(expected, operations.Apply());
- }
- TEST(TransformOperationTest, ApplyPerspective) {
- SkScalar depth = 800;
- TransformOperations operations;
- operations.AppendPerspective(depth);
- gfx::Transform expected;
- expected.ApplyPerspectiveDepth(depth);
- EXPECT_TRANSFORM_EQ(expected, operations.Apply());
- }
- TEST(TransformOperationTest, ApplyMatrix) {
- SkScalar dx = 1;
- SkScalar dy = 2;
- SkScalar dz = 3;
- gfx::Transform expected_matrix;
- expected_matrix.Translate3d(dx, dy, dz);
- TransformOperations matrix_transform;
- matrix_transform.AppendMatrix(expected_matrix);
- EXPECT_TRANSFORM_EQ(expected_matrix, matrix_transform.Apply());
- }
- TEST(TransformOperationTest, ApplyOrder) {
- SkScalar sx = 2;
- SkScalar sy = 4;
- SkScalar sz = 8;
- SkScalar dx = 1;
- SkScalar dy = 2;
- SkScalar dz = 3;
- TransformOperations operations;
- operations.AppendScale(sx, sy, sz);
- operations.AppendTranslate(dx, dy, dz);
- gfx::Transform expected_scale_matrix;
- expected_scale_matrix.Scale3d(sx, sy, sz);
- gfx::Transform expected_translate_matrix;
- expected_translate_matrix.Translate3d(dx, dy, dz);
- gfx::Transform expected_combined_matrix = expected_scale_matrix;
- expected_combined_matrix.PreconcatTransform(expected_translate_matrix);
- EXPECT_TRANSFORM_EQ(expected_combined_matrix, operations.Apply());
- }
- TEST(TransformOperationTest, BlendOrder) {
- SkScalar sx1 = 2;
- SkScalar sy1 = 4;
- SkScalar sz1 = 8;
- SkScalar dx1 = 1;
- SkScalar dy1 = 2;
- SkScalar dz1 = 3;
- SkScalar sx2 = 4;
- SkScalar sy2 = 8;
- SkScalar sz2 = 16;
- SkScalar dx2 = 10;
- SkScalar dy2 = 20;
- SkScalar dz2 = 30;
- SkScalar sx3 = 2;
- SkScalar sy3 = 1;
- SkScalar sz3 = 1;
- TransformOperations operations_from;
- operations_from.AppendScale(sx1, sy1, sz1);
- operations_from.AppendTranslate(dx1, dy1, dz1);
- TransformOperations operations_to;
- operations_to.AppendScale(sx2, sy2, sz2);
- operations_to.AppendTranslate(dx2, dy2, dz2);
- gfx::Transform scale_from;
- scale_from.Scale3d(sx1, sy1, sz1);
- gfx::Transform translate_from;
- translate_from.Translate3d(dx1, dy1, dz1);
- gfx::Transform scale_to;
- scale_to.Scale3d(sx2, sy2, sz2);
- gfx::Transform translate_to;
- translate_to.Translate3d(dx2, dy2, dz2);
- SkScalar progress = 0.25f;
- TransformOperations operations_expected;
- operations_expected.AppendScale(
- gfx::Tween::FloatValueBetween(progress, sx1, sx2),
- gfx::Tween::FloatValueBetween(progress, sy1, sy2),
- gfx::Tween::FloatValueBetween(progress, sz1, sz2));
- operations_expected.AppendTranslate(
- gfx::Tween::FloatValueBetween(progress, dx1, dx2),
- gfx::Tween::FloatValueBetween(progress, dy1, dy2),
- gfx::Tween::FloatValueBetween(progress, dz1, dz2));
- gfx::Transform blended_scale = scale_to;
- blended_scale.Blend(scale_from, progress);
- gfx::Transform blended_translate = translate_to;
- blended_translate.Blend(translate_from, progress);
- gfx::Transform expected = blended_scale;
- expected.PreconcatTransform(blended_translate);
- TransformOperations blended = operations_to.Blend(operations_from, progress);
- EXPECT_TRANSFORM_EQ(expected, blended.Apply());
- EXPECT_TRANSFORM_EQ(operations_expected.Apply(), blended.Apply());
- EXPECT_EQ(operations_expected.size(), blended.size());
- for (size_t i = 0; i < operations_expected.size(); ++i) {
- TransformOperation expected_op = operations_expected.at(i);
- TransformOperation blended_op = blended.at(i);
- SCOPED_TRACE(i);
- ExpectTransformOperationEqual(expected_op, blended_op);
- }
- TransformOperations base_operations_expected = operations_expected;
- // Create a mismatch in number of operations. Pairwise interpolation is still
- // used when the operations match up to the length of the shorter list.
- operations_to.AppendScale(sx3, sy3, sz3);
- gfx::Transform appended_scale;
- appended_scale.Scale3d(sx3, sy3, sz3);
- gfx::Transform blended_append_scale = appended_scale;
- blended_append_scale.Blend(gfx::Transform(), progress);
- expected.PreconcatTransform(blended_append_scale);
- operations_expected.AppendScale(
- gfx::Tween::FloatValueBetween(progress, 1, sx3),
- gfx::Tween::FloatValueBetween(progress, 1, sy3),
- gfx::Tween::FloatValueBetween(progress, 1, sz3));
- blended = operations_to.Blend(operations_from, progress);
- EXPECT_TRANSFORM_EQ(expected, blended.Apply());
- EXPECT_TRANSFORM_EQ(operations_expected.Apply(), blended.Apply());
- EXPECT_EQ(operations_expected.size(), blended.size());
- for (size_t i = 0; i < operations_expected.size(); ++i) {
- TransformOperation expected_op = operations_expected.at(i);
- TransformOperation blended_op = blended.at(i);
- SCOPED_TRACE(i);
- ExpectTransformOperationEqual(expected_op, blended_op);
- }
- // Create a mismatch, forcing matrix interpolation for the last operator pair.
- operations_from.AppendRotate(0, 0, 1, 90);
- blended = operations_to.Blend(operations_from, progress);
- gfx::Transform transform_from;
- transform_from.RotateAboutZAxis(90);
- gfx::Transform transform_to;
- transform_to.Scale3d(sx3, sy3, sz3);
- gfx::Transform blended_matrix = transform_to;
- blended_matrix.Blend(transform_from, progress);
- expected = blended_scale;
- expected.PreconcatTransform(blended_translate);
- expected.PreconcatTransform(blended_matrix);
- operations_expected = base_operations_expected;
- operations_expected.AppendMatrix(blended_matrix);
- EXPECT_TRANSFORM_EQ(expected, blended.Apply());
- EXPECT_TRANSFORM_EQ(operations_expected.Apply(), blended.Apply());
- EXPECT_EQ(operations_expected.size(), blended.size());
- for (size_t i = 0; i < operations_expected.size(); ++i) {
- TransformOperation expected_op = operations_expected.at(i);
- TransformOperation blended_op = blended.at(i);
- SCOPED_TRACE(i);
- ExpectTransformOperationEqual(expected_op, blended_op);
- }
- }
- static void CheckProgress(SkScalar progress,
- const gfx::Transform& from_matrix,
- const gfx::Transform& to_matrix,
- const TransformOperations& from_transform,
- const TransformOperations& to_transform) {
- gfx::Transform expected_matrix = to_matrix;
- expected_matrix.Blend(from_matrix, progress);
- EXPECT_TRANSFORM_EQ(expected_matrix,
- to_transform.Blend(from_transform, progress).Apply());
- }
- TEST(TransformOperationTest, BlendProgress) {
- SkScalar sx = 2;
- SkScalar sy = 4;
- SkScalar sz = 8;
- TransformOperations operations_from;
- operations_from.AppendScale(sx, sy, sz);
- gfx::Transform matrix_from;
- matrix_from.Scale3d(sx, sy, sz);
- sx = 4;
- sy = 8;
- sz = 16;
- TransformOperations operations_to;
- operations_to.AppendScale(sx, sy, sz);
- gfx::Transform matrix_to;
- matrix_to.Scale3d(sx, sy, sz);
- CheckProgress(-1, matrix_from, matrix_to, operations_from, operations_to);
- CheckProgress(0, matrix_from, matrix_to, operations_from, operations_to);
- CheckProgress(0.25f, matrix_from, matrix_to, operations_from, operations_to);
- CheckProgress(0.5f, matrix_from, matrix_to, operations_from, operations_to);
- CheckProgress(1, matrix_from, matrix_to, operations_from, operations_to);
- CheckProgress(2, matrix_from, matrix_to, operations_from, operations_to);
- }
- TEST(TransformOperationTest, BlendWhenTypesDoNotMatch) {
- SkScalar sx1 = 2;
- SkScalar sy1 = 4;
- SkScalar sz1 = 8;
- SkScalar dx1 = 1;
- SkScalar dy1 = 2;
- SkScalar dz1 = 3;
- SkScalar sx2 = 4;
- SkScalar sy2 = 8;
- SkScalar sz2 = 16;
- SkScalar dx2 = 10;
- SkScalar dy2 = 20;
- SkScalar dz2 = 30;
- TransformOperations operations_from;
- operations_from.AppendScale(sx1, sy1, sz1);
- operations_from.AppendTranslate(dx1, dy1, dz1);
- TransformOperations operations_to;
- operations_to.AppendTranslate(dx2, dy2, dz2);
- operations_to.AppendScale(sx2, sy2, sz2);
- gfx::Transform from;
- from.Scale3d(sx1, sy1, sz1);
- from.Translate3d(dx1, dy1, dz1);
- gfx::Transform to;
- to.Translate3d(dx2, dy2, dz2);
- to.Scale3d(sx2, sy2, sz2);
- SkScalar progress = 0.25f;
- gfx::Transform expected = to;
- expected.Blend(from, progress);
- EXPECT_TRANSFORM_EQ(expected,
- operations_to.Blend(operations_from, progress).Apply());
- }
- TEST(TransformOperationTest, LargeRotationsWithSameAxis) {
- TransformOperations operations_from;
- operations_from.AppendRotate(0, 0, 1, 0);
- TransformOperations operations_to;
- operations_to.AppendRotate(0, 0, 2, 360);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 180);
- EXPECT_TRANSFORM_EQ(expected,
- operations_to.Blend(operations_from, progress).Apply());
- }
- TEST(TransformOperationTest, LargeRotationsWithSameAxisInDifferentDirection) {
- TransformOperations operations_from;
- operations_from.AppendRotate(0, 0, 1, 180);
- TransformOperations operations_to;
- operations_to.AppendRotate(0, 0, -1, 180);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- EXPECT_TRANSFORM_EQ(expected,
- operations_to.Blend(operations_from, progress).Apply());
- }
- TEST(TransformOperationTest, LargeRotationsWithDifferentAxes) {
- TransformOperations operations_from;
- operations_from.AppendRotate(0, 0, 1, 175);
- TransformOperations operations_to;
- operations_to.AppendRotate(0, 1, 0, 175);
- SkScalar progress = 0.5f;
- gfx::Transform matrix_from;
- matrix_from.RotateAbout(gfx::Vector3dF(0, 0, 1), 175);
- gfx::Transform matrix_to;
- matrix_to.RotateAbout(gfx::Vector3dF(0, 1, 0), 175);
- gfx::Transform expected = matrix_to;
- expected.Blend(matrix_from, progress);
- EXPECT_TRANSFORM_EQ(expected,
- operations_to.Blend(operations_from, progress).Apply());
- }
- TEST(TransformOperationTest, RotationFromZeroDegDifferentAxes) {
- TransformOperations operations_from;
- operations_from.AppendRotate(0, 0, 1, 0);
- TransformOperations operations_to;
- operations_to.AppendRotate(0, 1, 0, 450);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(0, 1, 0), 225);
- EXPECT_TRANSFORM_EQ(expected,
- operations_to.Blend(operations_from, progress).Apply());
- }
- TEST(TransformOperationTest, RotationFromZeroDegSameAxes) {
- TransformOperations operations_from;
- operations_from.AppendRotate(0, 0, 1, 0);
- TransformOperations operations_to;
- operations_to.AppendRotate(0, 0, 1, 450);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 225);
- EXPECT_TRANSFORM_EQ(expected,
- operations_to.Blend(operations_from, progress).Apply());
- }
- TEST(TransformOperationTest, RotationToZeroDegDifferentAxes) {
- TransformOperations operations_from;
- operations_from.AppendRotate(0, 1, 0, 450);
- TransformOperations operations_to;
- operations_to.AppendRotate(0, 0, 1, 0);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(0, 1, 0), 225);
- EXPECT_TRANSFORM_EQ(expected,
- operations_to.Blend(operations_from, progress).Apply());
- }
- TEST(TransformOperationTest, RotationToZeroDegSameAxes) {
- TransformOperations operations_from;
- operations_from.AppendRotate(0, 0, 1, 450);
- TransformOperations operations_to;
- operations_to.AppendRotate(0, 0, 1, 0);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 225);
- EXPECT_TRANSFORM_EQ(expected,
- operations_to.Blend(operations_from, progress).Apply());
- }
- TEST(TransformOperationTest, BlendRotationFromIdentity) {
- std::vector<std::unique_ptr<TransformOperations>> identity_operations =
- GetIdentityOperations();
- for (const auto& identity_operation : identity_operations) {
- TransformOperations operations;
- operations.AppendRotate(0, 0, 1, 90);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 45);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- progress = -0.5f;
- expected.MakeIdentity();
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), -45);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- progress = 1.5f;
- expected.MakeIdentity();
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 135);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- }
- }
- TEST(TransformOperationTest, BlendTranslationFromIdentity) {
- std::vector<std::unique_ptr<TransformOperations>> identity_operations =
- GetIdentityOperations();
- for (const auto& identity_operation : identity_operations) {
- TransformOperations operations;
- operations.AppendTranslate(2, 2, 2);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.Translate3d(1, 1, 1);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- progress = -0.5f;
- expected.MakeIdentity();
- expected.Translate3d(-1, -1, -1);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- progress = 1.5f;
- expected.MakeIdentity();
- expected.Translate3d(3, 3, 3);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- }
- }
- TEST(TransformOperationTest, BlendScaleFromIdentity) {
- std::vector<std::unique_ptr<TransformOperations>> identity_operations =
- GetIdentityOperations();
- for (const auto& identity_operation : identity_operations) {
- TransformOperations operations;
- operations.AppendScale(3, 3, 3);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.Scale3d(2, 2, 2);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- progress = -0.5f;
- expected.MakeIdentity();
- expected.Scale3d(0, 0, 0);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- progress = 1.5f;
- expected.MakeIdentity();
- expected.Scale3d(4, 4, 4);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- }
- }
- TEST(TransformOperationTest, BlendSkewFromEmpty) {
- TransformOperations empty_operation;
- TransformOperations operations;
- operations.AppendSkew(2, 2);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.Skew(1, 1);
- EXPECT_TRANSFORM_EQ(expected,
- operations.Blend(empty_operation, progress).Apply());
- progress = -0.5f;
- expected.MakeIdentity();
- expected.Skew(-1, -1);
- EXPECT_TRANSFORM_EQ(expected,
- operations.Blend(empty_operation, progress).Apply());
- progress = 1.5f;
- expected.MakeIdentity();
- expected.Skew(3, 3);
- EXPECT_TRANSFORM_EQ(expected,
- operations.Blend(empty_operation, progress).Apply());
- }
- TEST(TransformOperationTest, BlendPerspectiveFromIdentity) {
- std::vector<std::unique_ptr<TransformOperations>> identity_operations =
- GetIdentityOperations();
- for (const auto& identity_operation : identity_operations) {
- TransformOperations operations;
- operations.AppendPerspective(1000);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.ApplyPerspectiveDepth(2000);
- EXPECT_TRANSFORM_EQ(
- expected, operations.Blend(*identity_operation, progress).Apply());
- }
- }
- TEST(TransformOperationTest, BlendRotationToIdentity) {
- std::vector<std::unique_ptr<TransformOperations>> identity_operations =
- GetIdentityOperations();
- for (const auto& identity_operation : identity_operations) {
- TransformOperations operations;
- operations.AppendRotate(0, 0, 1, 90);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.RotateAbout(gfx::Vector3dF(0, 0, 1), 45);
- EXPECT_TRANSFORM_EQ(
- expected, identity_operation->Blend(operations, progress).Apply());
- }
- }
- TEST(TransformOperationTest, BlendTranslationToIdentity) {
- std::vector<std::unique_ptr<TransformOperations>> identity_operations =
- GetIdentityOperations();
- for (const auto& identity_operation : identity_operations) {
- TransformOperations operations;
- operations.AppendTranslate(2, 2, 2);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.Translate3d(1, 1, 1);
- EXPECT_TRANSFORM_EQ(
- expected, identity_operation->Blend(operations, progress).Apply());
- }
- }
- TEST(TransformOperationTest, BlendScaleToIdentity) {
- std::vector<std::unique_ptr<TransformOperations>> identity_operations =
- GetIdentityOperations();
- for (const auto& identity_operation : identity_operations) {
- TransformOperations operations;
- operations.AppendScale(3, 3, 3);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.Scale3d(2, 2, 2);
- EXPECT_TRANSFORM_EQ(
- expected, identity_operation->Blend(operations, progress).Apply());
- }
- }
- TEST(TransformOperationTest, BlendSkewToEmpty) {
- TransformOperations empty_operation;
- TransformOperations operations;
- operations.AppendSkew(2, 2);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.Skew(1, 1);
- EXPECT_TRANSFORM_EQ(expected,
- empty_operation.Blend(operations, progress).Apply());
- }
- TEST(TransformOperationTest, BlendPerspectiveToIdentity) {
- std::vector<std::unique_ptr<TransformOperations>> identity_operations =
- GetIdentityOperations();
- for (const auto& identity_operation : identity_operations) {
- TransformOperations operations;
- operations.AppendPerspective(1000);
- SkScalar progress = 0.5f;
- gfx::Transform expected;
- expected.ApplyPerspectiveDepth(2000);
- EXPECT_TRANSFORM_EQ(
- expected, identity_operation->Blend(operations, progress).Apply());
- }
- }
- TEST(TransformOperationTest, ExtrapolatePerspectiveBlending) {
- TransformOperations operations1;
- operations1.AppendPerspective(1000);
- TransformOperations operations2;
- operations2.AppendPerspective(500);
- gfx::Transform expected;
- expected.ApplyPerspectiveDepth(400);
- EXPECT_TRANSFORM_EQ(expected, operations1.Blend(operations2, -0.5).Apply());
- expected.MakeIdentity();
- expected.ApplyPerspectiveDepth(2000);
- EXPECT_TRANSFORM_EQ(expected, operations1.Blend(operations2, 1.5).Apply());
- }
- TEST(TransformOperationTest, ExtrapolateMatrixBlending) {
- gfx::Transform transform1;
- transform1.Translate3d(1, 1, 1);
- TransformOperations operations1;
- operations1.AppendMatrix(transform1);
- gfx::Transform transform2;
- transform2.Translate3d(3, 3, 3);
- TransformOperations operations2;
- operations2.AppendMatrix(transform2);
- gfx::Transform expected;
- EXPECT_TRANSFORM_EQ(expected, operations1.Blend(operations2, 1.5).Apply());
- expected.Translate3d(4, 4, 4);
- EXPECT_TRANSFORM_EQ(expected, operations1.Blend(operations2, -0.5).Apply());
- }
- TEST(TransformOperationTest, NonDecomposableBlend) {
- TransformOperations non_decomposible_transform;
- gfx::Transform non_decomposible_matrix(0, 0, 0, 0, 0, 0);
- non_decomposible_transform.AppendMatrix(non_decomposible_matrix);
- TransformOperations identity_transform;
- gfx::Transform identity_matrix;
- identity_transform.AppendMatrix(identity_matrix);
- // Before the half-way point, we should return the 'from' matrix.
- EXPECT_TRANSFORM_EQ(
- non_decomposible_matrix,
- identity_transform.Blend(non_decomposible_transform, 0.0f).Apply());
- EXPECT_TRANSFORM_EQ(
- non_decomposible_matrix,
- identity_transform.Blend(non_decomposible_transform, 0.49f).Apply());
- // After the half-way point, we should return the 'to' matrix.
- EXPECT_TRANSFORM_EQ(
- identity_matrix,
- identity_transform.Blend(non_decomposible_transform, 0.5f).Apply());
- EXPECT_TRANSFORM_EQ(
- identity_matrix,
- identity_transform.Blend(non_decomposible_transform, 1.0f).Apply());
- }
- TEST(TransformOperationTest, BlendedBoundsWhenTypesDoNotMatch) {
- TransformOperations operations_from;
- operations_from.AppendScale(2.0, 4.0, 8.0);
- operations_from.AppendTranslate(1.0, 2.0, 3.0);
- TransformOperations operations_to;
- operations_to.AppendTranslate(10.0, 20.0, 30.0);
- operations_to.AppendScale(4.0, 8.0, 16.0);
- gfx::BoxF box(1.f, 1.f, 1.f);
- gfx::BoxF bounds;
- SkScalar min_progress = 0.f;
- SkScalar max_progress = 1.f;
- EXPECT_FALSE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- }
- TEST(TransformOperationTest, BlendedBoundsForIdentity) {
- TransformOperations operations_from;
- operations_from.AppendIdentity();
- TransformOperations operations_to;
- operations_to.AppendIdentity();
- gfx::BoxF box(1.f, 2.f, 3.f);
- gfx::BoxF bounds;
- SkScalar min_progress = 0.f;
- SkScalar max_progress = 1.f;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- EXPECT_EQ(box.ToString(), bounds.ToString());
- }
- TEST(TransformOperationTest, BlendedBoundsForTranslate) {
- TransformOperations operations_from;
- operations_from.AppendTranslate(3.0, -4.0, 2.0);
- TransformOperations operations_to;
- operations_to.AppendTranslate(7.0, 4.0, -2.0);
- gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
- gfx::BoxF bounds;
- SkScalar min_progress = -0.5f;
- SkScalar max_progress = 1.5f;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(2.f, -6.f, -1.f, 12.f, 20.f, 12.f).ToString(),
- bounds.ToString());
- min_progress = 0.f;
- max_progress = 1.f;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(4.f, -2.f, 1.f, 8.f, 12.f, 8.f).ToString(),
- bounds.ToString());
- TransformOperations identity;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(box, identity, min_progress,
- max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(1.f, 2.f, 1.f, 11.f, 8.f, 6.f).ToString(),
- bounds.ToString());
- EXPECT_TRUE(identity.BlendedBoundsForBox(box, operations_from, min_progress,
- max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(1.f, -2.f, 3.f, 7.f, 8.f, 6.f).ToString(),
- bounds.ToString());
- }
- TEST(TransformOperationTest, BlendedBoundsForScale) {
- TransformOperations operations_from;
- operations_from.AppendScale(3.0, 0.5, 2.0);
- TransformOperations operations_to;
- operations_to.AppendScale(7.0, 4.0, -2.0);
- gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
- gfx::BoxF bounds;
- SkScalar min_progress = -0.5f;
- SkScalar max_progress = 1.5f;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(1.f, -7.5f, -28.f, 44.f, 42.f, 56.f).ToString(),
- bounds.ToString());
- min_progress = 0.f;
- max_progress = 1.f;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(3.f, 1.f, -14.f, 32.f, 23.f, 28.f).ToString(),
- bounds.ToString());
- TransformOperations identity;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(box, identity, min_progress,
- max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(1.f, 2.f, -14.f, 34.f, 22.f, 21.f).ToString(),
- bounds.ToString());
- EXPECT_TRUE(identity.BlendedBoundsForBox(box, operations_from, min_progress,
- max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(1.f, 1.f, 3.f, 14.f, 5.f, 11.f).ToString(),
- bounds.ToString());
- }
- TEST(TransformOperationTest, BlendedBoundsWithZeroScale) {
- TransformOperations zero_scale;
- zero_scale.AppendScale(0.0, 0.0, 0.0);
- TransformOperations non_zero_scale;
- non_zero_scale.AppendScale(2.0, -4.0, 5.0);
- gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
- gfx::BoxF bounds;
- SkScalar min_progress = 0.f;
- SkScalar max_progress = 1.f;
- EXPECT_TRUE(zero_scale.BlendedBoundsForBox(box, non_zero_scale, min_progress,
- max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(0.f, -24.f, 0.f, 10.f, 24.f, 35.f).ToString(),
- bounds.ToString());
- EXPECT_TRUE(non_zero_scale.BlendedBoundsForBox(box, zero_scale, min_progress,
- max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(0.f, -24.f, 0.f, 10.f, 24.f, 35.f).ToString(),
- bounds.ToString());
- EXPECT_TRUE(zero_scale.BlendedBoundsForBox(box, zero_scale, min_progress,
- max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF().ToString(), bounds.ToString());
- }
- TEST(TransformOperationTest, BlendedBoundsForRotationTrivial) {
- TransformOperations operations_from;
- operations_from.AppendRotate(0.f, 0.f, 1.f, 0.f);
- TransformOperations operations_to;
- operations_to.AppendRotate(0.f, 0.f, 1.f, 360.f);
- float sqrt_2 = sqrt(2.f);
- gfx::BoxF box(-sqrt_2, -sqrt_2, 0.f, sqrt_2, sqrt_2, 0.f);
- gfx::BoxF bounds;
- // Since we're rotating 360 degrees, any box with dimensions between 0 and
- // 2 * sqrt(2) should give the same result.
- float sizes[] = {0.f, 0.1f, sqrt_2, 2.f * sqrt_2};
- for (float size : sizes) {
- box.set_size(size, size, 0.f);
- SkScalar min_progress = 0.f;
- SkScalar max_progress = 1.f;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(-2.f, -2.f, 0.f, 4.f, 4.f, 0.f).ToString(),
- bounds.ToString());
- }
- }
- TEST(TransformOperationTest, BlendedBoundsForRotationAllExtrema) {
- // If the normal is out of the plane, we can have up to 6 extrema (a min/max
- // in each dimension) between the endpoints of the arc. This test ensures that
- // we consider all 6.
- TransformOperations operations_from;
- operations_from.AppendRotate(1.f, 1.f, 1.f, 30.f);
- TransformOperations operations_to;
- operations_to.AppendRotate(1.f, 1.f, 1.f, 390.f);
- gfx::BoxF box(1.f, 0.f, 0.f, 0.f, 0.f, 0.f);
- gfx::BoxF bounds;
- float min = -1.f / 3.f;
- float max = 1.f;
- float size = max - min;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(box, operations_from, 0.f, 1.f,
- &bounds));
- EXPECT_EQ(gfx::BoxF(min, min, min, size, size, size).ToString(),
- bounds.ToString());
- }
- TEST(TransformOperationTest, BlendedBoundsForRotationDifferentAxes) {
- // We can handle rotations about a single axis. If the axes are different,
- // we revert to matrix interpolation for which inflated bounds cannot be
- // computed.
- TransformOperations operations_from;
- operations_from.AppendRotate(1.f, 1.f, 1.f, 30.f);
- TransformOperations operations_to_same;
- operations_to_same.AppendRotate(1.f, 1.f, 1.f, 390.f);
- TransformOperations operations_to_opposite;
- operations_to_opposite.AppendRotate(-1.f, -1.f, -1.f, 390.f);
- TransformOperations operations_to_different;
- operations_to_different.AppendRotate(1.f, 3.f, 1.f, 390.f);
- gfx::BoxF box(1.f, 0.f, 0.f, 0.f, 0.f, 0.f);
- gfx::BoxF bounds;
- EXPECT_TRUE(operations_to_same.BlendedBoundsForBox(box, operations_from, 0.f,
- 1.f, &bounds));
- EXPECT_TRUE(operations_to_opposite.BlendedBoundsForBox(box, operations_from,
- 0.f, 1.f, &bounds));
- EXPECT_FALSE(operations_to_different.BlendedBoundsForBox(box, operations_from,
- 0.f, 1.f, &bounds));
- }
- TEST(TransformOperationTest, BlendedBoundsForRotationPointOnAxis) {
- // Checks that if the point to rotate is sitting on the axis of rotation, that
- // it does not get affected.
- TransformOperations operations_from;
- operations_from.AppendRotate(1.f, 1.f, 1.f, 30.f);
- TransformOperations operations_to;
- operations_to.AppendRotate(1.f, 1.f, 1.f, 390.f);
- gfx::BoxF box(1.f, 1.f, 1.f, 0.f, 0.f, 0.f);
- gfx::BoxF bounds;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(box, operations_from, 0.f, 1.f,
- &bounds));
- EXPECT_EQ(box.ToString(), bounds.ToString());
- }
- TEST(TransformOperationTest, BlendedBoundsForRotationProblematicAxes) {
- // Zeros in the components of the axis of rotation turned out to be tricky to
- // deal with in practice. This function tests some potentially problematic
- // axes to ensure sane behavior.
- // Some common values used in the expected boxes.
- float dim1 = 0.292893f;
- float dim2 = sqrt(2.f);
- float dim3 = 2.f * dim2;
- struct {
- float x;
- float y;
- float z;
- gfx::BoxF expected;
- } tests[] = {{0.f, 0.f, 0.f, gfx::BoxF(1.f, 1.f, 1.f, 0.f, 0.f, 0.f)},
- {1.f, 0.f, 0.f, gfx::BoxF(1.f, -dim2, -dim2, 0.f, dim3, dim3)},
- {0.f, 1.f, 0.f, gfx::BoxF(-dim2, 1.f, -dim2, dim3, 0.f, dim3)},
- {0.f, 0.f, 1.f, gfx::BoxF(-dim2, -dim2, 1.f, dim3, dim3, 0.f)},
- {1.f, 1.f, 0.f, gfx::BoxF(dim1, dim1, -1.f, dim2, dim2, 2.f)},
- {0.f, 1.f, 1.f, gfx::BoxF(-1.f, dim1, dim1, 2.f, dim2, dim2)},
- {1.f, 0.f, 1.f, gfx::BoxF(dim1, -1.f, dim1, dim2, 2.f, dim2)}};
- for (const auto& test : tests) {
- float x = test.x;
- float y = test.y;
- float z = test.z;
- TransformOperations operations_from;
- operations_from.AppendRotate(x, y, z, 0.f);
- TransformOperations operations_to;
- operations_to.AppendRotate(x, y, z, 360.f);
- gfx::BoxF box(1.f, 1.f, 1.f, 0.f, 0.f, 0.f);
- gfx::BoxF bounds;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(box, operations_from, 0.f,
- 1.f, &bounds));
- EXPECT_EQ(test.expected.ToString(), bounds.ToString());
- }
- }
- static void ExpectBoxesApproximatelyEqual(const gfx::BoxF& lhs,
- const gfx::BoxF& rhs,
- float tolerance) {
- EXPECT_NEAR(lhs.x(), rhs.x(), tolerance);
- EXPECT_NEAR(lhs.y(), rhs.y(), tolerance);
- EXPECT_NEAR(lhs.z(), rhs.z(), tolerance);
- EXPECT_NEAR(lhs.width(), rhs.width(), tolerance);
- EXPECT_NEAR(lhs.height(), rhs.height(), tolerance);
- EXPECT_NEAR(lhs.depth(), rhs.depth(), tolerance);
- }
- static void EmpiricallyTestBounds(const TransformOperations& from,
- const TransformOperations& to,
- SkScalar min_progress,
- SkScalar max_progress,
- bool test_containment_only) {
- gfx::BoxF box(200.f, 500.f, 100.f, 100.f, 300.f, 200.f);
- gfx::BoxF bounds;
- EXPECT_TRUE(
- to.BlendedBoundsForBox(box, from, min_progress, max_progress, &bounds));
- bool first_time = true;
- gfx::BoxF empirical_bounds;
- static const size_t kNumSteps = 10;
- for (size_t step = 0; step < kNumSteps; ++step) {
- float t = step / (kNumSteps - 1.f);
- t = gfx::Tween::FloatValueBetween(t, min_progress, max_progress);
- gfx::Transform partial_transform = to.Blend(from, t).Apply();
- gfx::BoxF transformed = box;
- partial_transform.TransformBox(&transformed);
- if (first_time) {
- empirical_bounds = transformed;
- first_time = false;
- } else {
- empirical_bounds.Union(transformed);
- }
- }
- if (test_containment_only) {
- gfx::BoxF unified_bounds = bounds;
- unified_bounds.Union(empirical_bounds);
- // Convert to the screen space rects these boxes represent.
- gfx::Rect bounds_rect = ToEnclosingRect(
- gfx::RectF(bounds.x(), bounds.y(), bounds.width(), bounds.height()));
- gfx::Rect unified_bounds_rect = ToEnclosingRect(
- gfx::RectF(unified_bounds.x(), unified_bounds.y(),
- unified_bounds.width(), unified_bounds.height()));
- EXPECT_EQ(bounds_rect.ToString(), unified_bounds_rect.ToString());
- } else {
- // Our empirical estimate will be a little rough since we're only doing
- // 100 samples.
- static const float kTolerance = 1e-2f;
- ExpectBoxesApproximatelyEqual(empirical_bounds, bounds, kTolerance);
- }
- }
- static void EmpiricallyTestBoundsEquality(const TransformOperations& from,
- const TransformOperations& to,
- SkScalar min_progress,
- SkScalar max_progress) {
- EmpiricallyTestBounds(from, to, min_progress, max_progress, false);
- }
- static void EmpiricallyTestBoundsContainment(const TransformOperations& from,
- const TransformOperations& to,
- SkScalar min_progress,
- SkScalar max_progress) {
- EmpiricallyTestBounds(from, to, min_progress, max_progress, true);
- }
- TEST(TransformOperationTest, BlendedBoundsForRotationEmpiricalTests) {
- // Sets up various axis angle combinations, computes the bounding box and
- // empirically tests that the transformed bounds are indeed contained by the
- // computed bounding box.
- struct {
- float x;
- float y;
- float z;
- } axes[] = {{1.f, 1.f, 1.f}, {-1.f, -1.f, -1.f}, {-1.f, 2.f, 3.f},
- {1.f, -2.f, 3.f}, {1.f, 2.f, -3.f}, {0.f, 0.f, 0.f},
- {1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f},
- {1.f, 1.f, 0.f}, {0.f, 1.f, 1.f}, {1.f, 0.f, 1.f},
- {-1.f, 0.f, 0.f}, {0.f, -1.f, 0.f}, {0.f, 0.f, -1.f},
- {-1.f, -1.f, 0.f}, {0.f, -1.f, -1.f}, {-1.f, 0.f, -1.f}};
- struct {
- float theta_from;
- float theta_to;
- } angles[] = {{5.f, 10.f}, {10.f, 5.f}, {0.f, 360.f}, {20.f, 180.f},
- {-20.f, -180.f}, {180.f, -220.f}, {220.f, 320.f}};
- // We can go beyond the range [0, 1] (the bezier might slide out of this range
- // at either end), but since the first and last knots are at (0, 0) and (1, 1)
- // we will never go within it, so these tests are sufficient.
- struct {
- float min_progress;
- float max_progress;
- } progresses[] = {
- {0.f, 1.f},
- {-.25f, 1.25f},
- };
- for (const auto& axis : axes) {
- for (const auto& angle : angles) {
- for (const auto& progress : progresses) {
- float x = axis.x;
- float y = axis.y;
- float z = axis.z;
- TransformOperations operations_from;
- operations_from.AppendRotate(x, y, z, angle.theta_from);
- TransformOperations operations_to;
- operations_to.AppendRotate(x, y, z, angle.theta_to);
- EmpiricallyTestBoundsContainment(operations_from, operations_to,
- progress.min_progress,
- progress.max_progress);
- }
- }
- }
- }
- TEST(TransformOperationTest, PerspectiveMatrixAndTransformBlendingEquivalency) {
- TransformOperations from_operations;
- from_operations.AppendPerspective(200);
- TransformOperations to_operations;
- to_operations.AppendPerspective(1000);
- gfx::Transform from_transform;
- from_transform.ApplyPerspectiveDepth(200);
- gfx::Transform to_transform;
- to_transform.ApplyPerspectiveDepth(1000);
- static const int steps = 20;
- for (int i = 0; i < steps; ++i) {
- double progress = static_cast<double>(i) / (steps - 1);
- gfx::Transform blended_matrix = to_transform;
- EXPECT_TRUE(blended_matrix.Blend(from_transform, progress));
- gfx::Transform blended_transform =
- to_operations.Blend(from_operations, progress).Apply();
- EXPECT_TRANSFORM_EQ(blended_matrix, blended_transform);
- }
- }
- TEST(TransformOperationTest, BlendedBoundsForPerspective) {
- struct {
- float from_depth;
- float to_depth;
- } perspective_depths[] = {
- {600.f, 400.f},
- {800.f, 1000.f},
- {800.f, std::numeric_limits<float>::infinity()},
- };
- struct {
- float min_progress;
- float max_progress;
- } progresses[] = {
- {0.f, 1.f},
- {-0.1f, 1.1f},
- };
- for (const auto& perspective_depth : perspective_depths) {
- for (const auto& progress : progresses) {
- TransformOperations operations_from;
- operations_from.AppendPerspective(perspective_depth.from_depth);
- TransformOperations operations_to;
- operations_to.AppendPerspective(perspective_depth.to_depth);
- EmpiricallyTestBoundsEquality(operations_from, operations_to,
- progress.min_progress,
- progress.max_progress);
- }
- }
- }
- TEST(TransformOperationTest, BlendedBoundsForSkew) {
- struct {
- float from_x;
- float from_y;
- float to_x;
- float to_y;
- } skews[] = {
- {1.f, 0.5f, 0.5f, 1.f},
- {2.f, 1.f, 0.5f, 0.5f},
- };
- struct {
- float min_progress;
- float max_progress;
- } progresses[] = {
- {0.f, 1.f},
- {-0.1f, 1.1f},
- };
- for (const auto& skew : skews) {
- for (const auto& progress : progresses) {
- TransformOperations operations_from;
- operations_from.AppendSkew(skew.from_x, skew.from_y);
- TransformOperations operations_to;
- operations_to.AppendSkew(skew.to_x, skew.to_y);
- EmpiricallyTestBoundsEquality(operations_from, operations_to,
- progress.min_progress,
- progress.max_progress);
- }
- }
- }
- TEST(TransformOperationTest, NonCommutativeRotations) {
- TransformOperations operations_from;
- operations_from.AppendRotate(1.0, 0.0, 0.0, 0.0);
- operations_from.AppendRotate(0.0, 1.0, 0.0, 0.0);
- TransformOperations operations_to;
- operations_to.AppendRotate(1.0, 0.0, 0.0, 45.0);
- operations_to.AppendRotate(0.0, 1.0, 0.0, 135.0);
- gfx::BoxF box(0, 0, 0, 1, 1, 1);
- gfx::BoxF bounds;
- SkScalar min_progress = 0.0f;
- SkScalar max_progress = 1.0f;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- gfx::Transform blended_transform =
- operations_to.Blend(operations_from, max_progress).Apply();
- gfx::Point3F blended_point(0.9f, 0.9f, 0.0f);
- blended_transform.TransformPoint(&blended_point);
- gfx::BoxF expanded_bounds = bounds;
- expanded_bounds.ExpandTo(blended_point);
- EXPECT_EQ(bounds.ToString(), expanded_bounds.ToString());
- }
- TEST(TransformOperationTest, BlendedBoundsForSequence) {
- TransformOperations operations_from;
- operations_from.AppendTranslate(1.0, -5.0, 1.0);
- operations_from.AppendScale(-1.0, 2.0, 3.0);
- operations_from.AppendTranslate(2.0, 4.0, -1.0);
- TransformOperations operations_to;
- operations_to.AppendTranslate(13.0, -1.0, 5.0);
- operations_to.AppendScale(-3.0, -2.0, 5.0);
- operations_to.AppendTranslate(6.0, -2.0, 3.0);
- gfx::BoxF box(1.f, 2.f, 3.f, 4.f, 4.f, 4.f);
- gfx::BoxF bounds;
- SkScalar min_progress = -0.5f;
- SkScalar max_progress = 1.5f;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(-57.f, -59.f, -1.f, 76.f, 112.f, 80.f).ToString(),
- bounds.ToString());
- min_progress = 0.f;
- max_progress = 1.f;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(
- box, operations_from, min_progress, max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(-32.f, -25.f, 7.f, 42.f, 44.f, 48.f).ToString(),
- bounds.ToString());
- TransformOperations identity;
- EXPECT_TRUE(operations_to.BlendedBoundsForBox(box, identity, min_progress,
- max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(-33.f, -13.f, 3.f, 57.f, 19.f, 52.f).ToString(),
- bounds.ToString());
- EXPECT_TRUE(identity.BlendedBoundsForBox(box, operations_from, min_progress,
- max_progress, &bounds));
- EXPECT_EQ(gfx::BoxF(-7.f, -3.f, 2.f, 15.f, 23.f, 20.f).ToString(),
- bounds.ToString());
- }
- TEST(TransformOperationTest, IsTranslationWithSingleOperation) {
- TransformOperations empty_operations;
- EXPECT_TRUE(empty_operations.IsTranslation());
- TransformOperations identity;
- identity.AppendIdentity();
- EXPECT_TRUE(identity.IsTranslation());
- TransformOperations translate;
- translate.AppendTranslate(1.f, 2.f, 3.f);
- EXPECT_TRUE(translate.IsTranslation());
- TransformOperations rotate;
- rotate.AppendRotate(1.f, 2.f, 3.f, 4.f);
- EXPECT_FALSE(rotate.IsTranslation());
- TransformOperations scale;
- scale.AppendScale(1.f, 2.f, 3.f);
- EXPECT_FALSE(scale.IsTranslation());
- TransformOperations skew;
- skew.AppendSkew(1.f, 2.f);
- EXPECT_FALSE(skew.IsTranslation());
- TransformOperations perspective;
- perspective.AppendPerspective(1.f);
- EXPECT_FALSE(perspective.IsTranslation());
- TransformOperations identity_matrix;
- identity_matrix.AppendMatrix(gfx::Transform());
- EXPECT_TRUE(identity_matrix.IsTranslation());
- TransformOperations translation_matrix;
- gfx::Transform translation_transform;
- translation_transform.Translate3d(1.f, 2.f, 3.f);
- translation_matrix.AppendMatrix(translation_transform);
- EXPECT_TRUE(translation_matrix.IsTranslation());
- TransformOperations scaling_matrix;
- gfx::Transform scaling_transform;
- scaling_transform.Scale(2.f, 2.f);
- scaling_matrix.AppendMatrix(scaling_transform);
- EXPECT_FALSE(scaling_matrix.IsTranslation());
- }
- TEST(TransformOperationTest, IsTranslationWithMultipleOperations) {
- TransformOperations operations1;
- operations1.AppendSkew(1.f, 2.f);
- operations1.AppendTranslate(1.f, 2.f, 3.f);
- operations1.AppendIdentity();
- EXPECT_FALSE(operations1.IsTranslation());
- TransformOperations operations2;
- operations2.AppendIdentity();
- operations2.AppendTranslate(3.f, 2.f, 1.f);
- gfx::Transform translation_transform;
- translation_transform.Translate3d(1.f, 2.f, 3.f);
- operations2.AppendMatrix(translation_transform);
- EXPECT_TRUE(operations2.IsTranslation());
- }
- TEST(TransformOperationTest, ScaleComponent) {
- SkScalar scale;
- // Scale.
- TransformOperations operations1;
- operations1.AppendScale(-3.f, 2.f, 5.f);
- EXPECT_TRUE(operations1.ScaleComponent(&scale));
- EXPECT_EQ(5.f, scale);
- // Translate.
- TransformOperations operations2;
- operations2.AppendTranslate(1.f, 2.f, 3.f);
- EXPECT_TRUE(operations2.ScaleComponent(&scale));
- EXPECT_EQ(1.f, scale);
- // Rotate.
- TransformOperations operations3;
- operations3.AppendRotate(1.f, 2.f, 3.f, 4.f);
- EXPECT_TRUE(operations3.ScaleComponent(&scale));
- EXPECT_EQ(1.f, scale);
- // Matrix that's only a translation.
- TransformOperations operations4;
- gfx::Transform translation_transform;
- translation_transform.Translate3d(1.f, 2.f, 3.f);
- operations4.AppendMatrix(translation_transform);
- EXPECT_TRUE(operations4.ScaleComponent(&scale));
- EXPECT_EQ(1.f, scale);
- // Matrix that includes scale.
- TransformOperations operations5;
- gfx::Transform matrix;
- matrix.RotateAboutZAxis(30.0);
- matrix.Scale(-7.f, 6.f);
- matrix.Translate3d(gfx::Vector3dF(3.f, 7.f, 1.f));
- operations5.AppendMatrix(matrix);
- EXPECT_TRUE(operations5.ScaleComponent(&scale));
- EXPECT_EQ(7.f, scale);
- // Matrix with perspective.
- TransformOperations operations6;
- matrix.ApplyPerspectiveDepth(2000.f);
- operations6.AppendMatrix(matrix);
- EXPECT_FALSE(operations6.ScaleComponent(&scale));
- // Skew.
- TransformOperations operations7;
- operations7.AppendSkew(30.f, 60.f);
- EXPECT_TRUE(operations7.ScaleComponent(&scale));
- EXPECT_EQ(2.f, scale);
- // Perspective.
- TransformOperations operations8;
- operations8.AppendPerspective(500.f);
- EXPECT_FALSE(operations8.ScaleComponent(&scale));
- // Translate + Scale.
- TransformOperations operations9;
- operations9.AppendTranslate(1.f, 2.f, 3.f);
- operations9.AppendScale(2.f, 5.f, 4.f);
- EXPECT_TRUE(operations9.ScaleComponent(&scale));
- EXPECT_EQ(5.f, scale);
- // Translate + Scale + Matrix with translate.
- operations9.AppendMatrix(translation_transform);
- EXPECT_TRUE(operations9.ScaleComponent(&scale));
- EXPECT_EQ(5.f, scale);
- // Scale + translate.
- TransformOperations operations10;
- operations10.AppendScale(2.f, 3.f, 2.f);
- operations10.AppendTranslate(1.f, 2.f, 3.f);
- EXPECT_TRUE(operations10.ScaleComponent(&scale));
- EXPECT_EQ(3.f, scale);
- // Two Scales.
- TransformOperations operations11;
- operations11.AppendScale(2.f, 3.f, 2.f);
- operations11.AppendScale(-3.f, -2.f, -3.f);
- EXPECT_TRUE(operations11.ScaleComponent(&scale));
- EXPECT_EQ(9.f, scale);
- // Scale + Matrix.
- TransformOperations operations12;
- operations12.AppendScale(2.f, 2.f, 2.f);
- gfx::Transform scaling_transform;
- scaling_transform.Scale(2.f, 2.f);
- operations12.AppendMatrix(scaling_transform);
- EXPECT_TRUE(operations12.ScaleComponent(&scale));
- EXPECT_EQ(4.f, scale);
- // Scale + Rotate.
- TransformOperations operations13;
- operations13.AppendScale(2.f, 2.f, 2.f);
- operations13.AppendRotate(1.f, 2.f, 3.f, 4.f);
- EXPECT_TRUE(operations13.ScaleComponent(&scale));
- EXPECT_EQ(2.f, scale);
- // Scale + Skew.
- TransformOperations operations14;
- operations14.AppendScale(2.f, 2.f, 2.f);
- operations14.AppendSkew(60.f, 45.f);
- EXPECT_TRUE(operations14.ScaleComponent(&scale));
- EXPECT_EQ(4.f, scale);
- // Scale + Perspective.
- TransformOperations operations15;
- operations15.AppendScale(2.f, 2.f, 2.f);
- operations15.AppendPerspective(1.f);
- EXPECT_FALSE(operations15.ScaleComponent(&scale));
- // Matrix with skew.
- TransformOperations operations16;
- gfx::Transform skew_transform;
- skew_transform.Skew(50.f, 60.f);
- operations16.AppendMatrix(skew_transform);
- EXPECT_TRUE(operations16.ScaleComponent(&scale));
- EXPECT_EQ(2.f, scale);
- }
- TEST(TransformOperationsTest, ApproximateEquality) {
- float noise = 1e-7f;
- float tolerance = 1e-5f;
- TransformOperations lhs;
- TransformOperations rhs;
- // Empty lists of operations are trivially equal.
- EXPECT_TRUE(lhs.ApproximatelyEqual(rhs, tolerance));
- rhs.AppendIdentity();
- rhs.AppendTranslate(0, 0, 0);
- rhs.AppendRotate(1, 0, 0, 0);
- rhs.AppendScale(1, 1, 1);
- rhs.AppendSkew(0, 0);
- rhs.AppendMatrix(gfx::Transform());
- // Even though both lists operations are effectively the identity matrix, rhs
- // has a different number of operations and is therefore different.
- EXPECT_FALSE(lhs.ApproximatelyEqual(rhs, tolerance));
- rhs.AppendPerspective(800);
- // Assignment should produce equal lists of operations.
- lhs = rhs;
- EXPECT_TRUE(lhs.ApproximatelyEqual(rhs, tolerance));
- // Cannot affect identity operations.
- lhs.at(0).translate.x = 1;
- EXPECT_TRUE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs.at(1).translate.x += noise;
- EXPECT_TRUE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs.at(1).translate.x += 1;
- EXPECT_FALSE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs = rhs;
- lhs.at(2).rotate.angle += noise;
- EXPECT_TRUE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs.at(2).rotate.angle = 1;
- EXPECT_FALSE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs = rhs;
- lhs.at(3).scale.x += noise;
- EXPECT_TRUE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs.at(3).scale.x += 1;
- EXPECT_FALSE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs = rhs;
- lhs.at(4).skew.x += noise;
- EXPECT_TRUE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs.at(4).skew.x = 2;
- EXPECT_FALSE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs = rhs;
- lhs.at(5).matrix.Translate3d(noise, 0, 0);
- EXPECT_TRUE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs.at(5).matrix.Translate3d(1, 1, 1);
- EXPECT_FALSE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs = rhs;
- lhs.at(6).perspective_m43 += noise;
- EXPECT_TRUE(lhs.ApproximatelyEqual(rhs, tolerance));
- lhs.at(6).perspective_m43 = -1.0f / 810;
- EXPECT_FALSE(lhs.ApproximatelyEqual(rhs, tolerance));
- }
- } // namespace
- // This test is intentionally outside the anonymous namespace for visibility as
- // it needs to be friend of TransformOperations.
- TEST(TransformOperationsTest, TestDecompositionCache) {
- TransformOperations transforms;
- EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
- EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
- // Reset cache when appending a scale transform.
- transforms.AppendScale(2.f, 2.f, 2.f);
- EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(1));
- EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(1));
- EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
- EXPECT_EQ(2UL, transforms.decomposed_transforms_.size());
- // Reset cache when appending a rotation transform.
- transforms.AppendRotate(1, 0, 0, 45);
- EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
- EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
- // Reset cache when appending a translation transform.
- transforms.AppendTranslate(1, 1, 1);
- EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
- EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
- // Reset cache when appending a skew transform.
- transforms.AppendSkew(1, 0);
- EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
- EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
- // Reset cache when appending a perspective transform.
- transforms.AppendPerspective(800);
- EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
- EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
- // Reset cache when appending a matrix transform.
- transforms.AppendMatrix(gfx::Transform());
- EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
- EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
- // Reset cache when appending a generic transform operation.
- transforms.Append(TransformOperation());
- EXPECT_EQ(0UL, transforms.decomposed_transforms_.size());
- EXPECT_TRUE(transforms.ComputeDecomposedTransform(0));
- EXPECT_EQ(1UL, transforms.decomposed_transforms_.size());
- }
- TEST(TransformOperationTest, BlendSkewMismatch) {
- TransformOperations from_ops, to_ops, expected_ops;
- from_ops.AppendSkewX(0);
- from_ops.AppendRotate(0, 0, 1, 0);
- to_ops.AppendSkewY(0);
- to_ops.AppendRotate(0, 0, 1, 360);
- // Skew types do not match so use matrix interpolation
- expected_ops.AppendMatrix(gfx::Transform());
- TransformOperations blended_ops = to_ops.Blend(from_ops, 0.5);
- ASSERT_EQ(blended_ops.size(), 1u);
- ExpectTransformOperationEqual(blended_ops.at(0), expected_ops.at(0));
- }
- TEST(TransformOperationTest, BlendSkewMatch) {
- TransformOperations from_ops, to_ops, expected_ops;
- from_ops.AppendSkew(30, 0);
- from_ops.AppendRotate(0, 0, 1, 0);
- to_ops.AppendSkew(0, 30);
- to_ops.AppendRotate(0, 0, 1, 360);
- // Skew types match so interpolate as a function.
- expected_ops.AppendSkew(15, 15);
- expected_ops.AppendRotate(0, 0, 1, 180);
- TransformOperations blended_ops = to_ops.Blend(from_ops, 0.5);
- ASSERT_EQ(blended_ops.size(), 2u);
- ExpectTransformOperationEqual(blended_ops.at(0), expected_ops.at(0));
- ExpectTransformOperationEqual(blended_ops.at(1), expected_ops.at(1));
- }
- } // namespace gfx
|