|  | // Copyright (c) 2012 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/transform_util.h" | 
|  |  | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  | #include "ui/gfx/point.h" | 
|  | #include "ui/gfx/point3_f.h" | 
|  | #include "ui/gfx/rect.h" | 
|  |  | 
|  | namespace gfx { | 
|  | namespace { | 
|  |  | 
|  | TEST(TransformUtilTest, GetScaleTransform) { | 
|  | const Point kAnchor(20, 40); | 
|  | const float kScale = 0.5f; | 
|  |  | 
|  | Transform scale = GetScaleTransform(kAnchor, kScale); | 
|  |  | 
|  | const int kOffset = 10; | 
|  | for (int sign_x = -1; sign_x <= 1; ++sign_x) { | 
|  | for (int sign_y = -1; sign_y <= 1; ++sign_y) { | 
|  | Point test(kAnchor.x() + sign_x * kOffset, | 
|  | kAnchor.y() + sign_y * kOffset); | 
|  | scale.TransformPoint(&test); | 
|  |  | 
|  | EXPECT_EQ(Point(kAnchor.x() + sign_x * kOffset * kScale, | 
|  | kAnchor.y() + sign_y * kOffset * kScale), | 
|  | test); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST(TransformUtilTest, SnapRotation) { | 
|  | Transform result(Transform::kSkipInitialization); | 
|  | Transform transform; | 
|  | transform.RotateAboutZAxis(89.99); | 
|  |  | 
|  | Rect viewport(1920, 1200); | 
|  | bool snapped = SnapTransform(&result, transform, viewport); | 
|  |  | 
|  | EXPECT_TRUE(snapped) << "Viewport should snap for this rotation."; | 
|  | } | 
|  |  | 
|  | TEST(TransformUtilTest, SnapRotationDistantViewport) { | 
|  | const int kOffset = 5000; | 
|  | Transform result(Transform::kSkipInitialization); | 
|  | Transform transform; | 
|  |  | 
|  | transform.RotateAboutZAxis(89.99); | 
|  |  | 
|  | Rect viewport(kOffset, kOffset, 1920, 1200); | 
|  | bool snapped = SnapTransform(&result, transform, viewport); | 
|  |  | 
|  | EXPECT_FALSE(snapped) << "Distant viewport shouldn't snap by more than 1px."; | 
|  | } | 
|  |  | 
|  | TEST(TransformUtilTest, NoSnapRotation) { | 
|  | Transform result(Transform::kSkipInitialization); | 
|  | Transform transform; | 
|  | const int kOffset = 5000; | 
|  |  | 
|  | transform.RotateAboutZAxis(89.9); | 
|  |  | 
|  | Rect viewport(kOffset, kOffset, 1920, 1200); | 
|  | bool snapped = SnapTransform(&result, transform, viewport); | 
|  |  | 
|  | EXPECT_FALSE(snapped) << "Viewport should not snap for this rotation."; | 
|  | } | 
|  |  | 
|  | // Translations should always be snappable, the most we would move is 0.5 | 
|  | // pixels towards either direction to the nearest value in each component. | 
|  | TEST(TransformUtilTest, SnapTranslation) { | 
|  | Transform result(Transform::kSkipInitialization); | 
|  | Transform transform; | 
|  |  | 
|  | transform.Translate3d( | 
|  | SkDoubleToMScalar(1.01), SkDoubleToMScalar(1.99), SkDoubleToMScalar(3.0)); | 
|  |  | 
|  | Rect viewport(1920, 1200); | 
|  | bool snapped = SnapTransform(&result, transform, viewport); | 
|  |  | 
|  | EXPECT_TRUE(snapped) << "Viewport should snap for this translation."; | 
|  | } | 
|  |  | 
|  | TEST(TransformUtilTest, SnapTranslationDistantViewport) { | 
|  | Transform result(Transform::kSkipInitialization); | 
|  | Transform transform; | 
|  | const int kOffset = 5000; | 
|  |  | 
|  | transform.Translate3d( | 
|  | SkDoubleToMScalar(1.01), SkDoubleToMScalar(1.99), SkDoubleToMScalar(3.0)); | 
|  |  | 
|  | Rect viewport(kOffset, kOffset, 1920, 1200); | 
|  | bool snapped = SnapTransform(&result, transform, viewport); | 
|  |  | 
|  | EXPECT_TRUE(snapped) | 
|  | << "Distant viewport should still snap by less than 1px."; | 
|  | } | 
|  |  | 
|  | TEST(TransformUtilTest, SnapScale) { | 
|  | Transform result(Transform::kSkipInitialization); | 
|  | Transform transform; | 
|  |  | 
|  | transform.Scale3d(SkDoubleToMScalar(5.0), | 
|  | SkDoubleToMScalar(2.00001), | 
|  | SkDoubleToMScalar(1.0)); | 
|  | Rect viewport(1920, 1200); | 
|  | bool snapped = SnapTransform(&result, transform, viewport); | 
|  |  | 
|  | EXPECT_TRUE(snapped) << "Viewport should snap for this scaling."; | 
|  | } | 
|  |  | 
|  | TEST(TransformUtilTest, NoSnapScale) { | 
|  | Transform result(Transform::kSkipInitialization); | 
|  | Transform transform; | 
|  |  | 
|  | transform.Scale3d( | 
|  | SkDoubleToMScalar(5.0), SkDoubleToMScalar(2.1), SkDoubleToMScalar(1.0)); | 
|  | Rect viewport(1920, 1200); | 
|  | bool snapped = SnapTransform(&result, transform, viewport); | 
|  |  | 
|  | EXPECT_FALSE(snapped) << "Viewport shouldn't snap for this scaling."; | 
|  | } | 
|  |  | 
|  | TEST(TransformUtilTest, SnapCompositeTransform) { | 
|  | Transform result(Transform::kSkipInitialization); | 
|  | Transform transform; | 
|  |  | 
|  | transform.Translate3d(SkDoubleToMScalar(30.5), SkDoubleToMScalar(20.0), | 
|  | SkDoubleToMScalar(10.1)); | 
|  | transform.RotateAboutZAxis(89.99); | 
|  | transform.Scale3d(SkDoubleToMScalar(1.0), | 
|  | SkDoubleToMScalar(3.00001), | 
|  | SkDoubleToMScalar(2.0)); | 
|  |  | 
|  | Rect viewport(1920, 1200); | 
|  | bool snapped = SnapTransform(&result, transform, viewport); | 
|  | ASSERT_TRUE(snapped) << "Viewport should snap all components."; | 
|  |  | 
|  | Point3F point; | 
|  |  | 
|  | point = Point3F(viewport.origin()); | 
|  | result.TransformPoint(&point); | 
|  | EXPECT_EQ(Point3F(31.f, 20.f, 10.f), point) << "Transformed origin"; | 
|  |  | 
|  | point = Point3F(viewport.top_right()); | 
|  | result.TransformPoint(&point); | 
|  | EXPECT_EQ(Point3F(31.f, 1940.f, 10.f), point) << "Transformed top-right"; | 
|  |  | 
|  | point = Point3F(viewport.bottom_left()); | 
|  | result.TransformPoint(&point); | 
|  | EXPECT_EQ(Point3F(-3569.f, 20.f, 10.f), point) << "Transformed bottom-left"; | 
|  |  | 
|  | point = Point3F(viewport.bottom_right()); | 
|  | result.TransformPoint(&point); | 
|  | EXPECT_EQ(Point3F(-3569.f, 1940.f, 10.f), point) | 
|  | << "Transformed bottom-right"; | 
|  | } | 
|  |  | 
|  | TEST(TransformUtilTest, NoSnapSkewedCompositeTransform) { | 
|  | Transform result(Transform::kSkipInitialization); | 
|  | Transform transform; | 
|  |  | 
|  |  | 
|  | transform.RotateAboutZAxis(89.99); | 
|  | transform.Scale3d(SkDoubleToMScalar(1.0), | 
|  | SkDoubleToMScalar(3.00001), | 
|  | SkDoubleToMScalar(2.0)); | 
|  | transform.Translate3d(SkDoubleToMScalar(30.5), SkDoubleToMScalar(20.0), | 
|  | SkDoubleToMScalar(10.1)); | 
|  | transform.SkewX(20.0); | 
|  | Rect viewport(1920, 1200); | 
|  | bool snapped = SnapTransform(&result, transform, viewport); | 
|  | EXPECT_FALSE(snapped) << "Skewed viewport should not snap."; | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  | }  // namespace gfx |