blob: 76847a674a9f59ff04e34541d4034c3912c84ece [file] [log] [blame]
[email protected]665e2b72012-03-14 17:06:591// Copyright (c) 2012 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.
4
5#include "ui/gfx/transform_util.h"
6
[email protected]665e2b72012-03-14 17:06:597#include "testing/gtest/include/gtest/gtest.h"
tfarina655f81d2014-12-23 02:38:508#include "ui/gfx/geometry/point.h"
9#include "ui/gfx/geometry/point3_f.h"
tfarina3b0452d2014-12-31 15:20:0910#include "ui/gfx/geometry/rect.h"
[email protected]665e2b72012-03-14 17:06:5911
[email protected]db06cc12012-11-10 05:19:5212namespace gfx {
13namespace {
14
[email protected]665e2b72012-03-14 17:06:5915TEST(TransformUtilTest, GetScaleTransform) {
[email protected]db06cc12012-11-10 05:19:5216 const Point kAnchor(20, 40);
[email protected]665e2b72012-03-14 17:06:5917 const float kScale = 0.5f;
18
[email protected]db06cc12012-11-10 05:19:5219 Transform scale = GetScaleTransform(kAnchor, kScale);
[email protected]665e2b72012-03-14 17:06:5920
21 const int kOffset = 10;
22 for (int sign_x = -1; sign_x <= 1; ++sign_x) {
23 for (int sign_y = -1; sign_y <= 1; ++sign_y) {
[email protected]db06cc12012-11-10 05:19:5224 Point test(kAnchor.x() + sign_x * kOffset,
25 kAnchor.y() + sign_y * kOffset);
[email protected]26d7ece2013-09-12 20:59:4726 scale.TransformPoint(&test);
[email protected]665e2b72012-03-14 17:06:5927
[email protected]db06cc12012-11-10 05:19:5228 EXPECT_EQ(Point(kAnchor.x() + sign_x * kOffset * kScale,
29 kAnchor.y() + sign_y * kOffset * kScale),
[email protected]665e2b72012-03-14 17:06:5930 test);
31 }
32 }
33}
[email protected]db06cc12012-11-10 05:19:5234
[email protected]dd31d492013-10-24 22:33:2535TEST(TransformUtilTest, SnapRotation) {
36 Transform result(Transform::kSkipInitialization);
37 Transform transform;
38 transform.RotateAboutZAxis(89.99);
39
40 Rect viewport(1920, 1200);
41 bool snapped = SnapTransform(&result, transform, viewport);
42
43 EXPECT_TRUE(snapped) << "Viewport should snap for this rotation.";
44}
45
46TEST(TransformUtilTest, SnapRotationDistantViewport) {
47 const int kOffset = 5000;
48 Transform result(Transform::kSkipInitialization);
49 Transform transform;
50
51 transform.RotateAboutZAxis(89.99);
52
53 Rect viewport(kOffset, kOffset, 1920, 1200);
54 bool snapped = SnapTransform(&result, transform, viewport);
55
56 EXPECT_FALSE(snapped) << "Distant viewport shouldn't snap by more than 1px.";
57}
58
59TEST(TransformUtilTest, NoSnapRotation) {
60 Transform result(Transform::kSkipInitialization);
61 Transform transform;
62 const int kOffset = 5000;
63
64 transform.RotateAboutZAxis(89.9);
65
66 Rect viewport(kOffset, kOffset, 1920, 1200);
67 bool snapped = SnapTransform(&result, transform, viewport);
68
69 EXPECT_FALSE(snapped) << "Viewport should not snap for this rotation.";
70}
71
72// Translations should always be snappable, the most we would move is 0.5
73// pixels towards either direction to the nearest value in each component.
74TEST(TransformUtilTest, SnapTranslation) {
75 Transform result(Transform::kSkipInitialization);
76 Transform transform;
77
78 transform.Translate3d(
79 SkDoubleToMScalar(1.01), SkDoubleToMScalar(1.99), SkDoubleToMScalar(3.0));
80
81 Rect viewport(1920, 1200);
82 bool snapped = SnapTransform(&result, transform, viewport);
83
84 EXPECT_TRUE(snapped) << "Viewport should snap for this translation.";
85}
86
87TEST(TransformUtilTest, SnapTranslationDistantViewport) {
88 Transform result(Transform::kSkipInitialization);
89 Transform transform;
90 const int kOffset = 5000;
91
92 transform.Translate3d(
93 SkDoubleToMScalar(1.01), SkDoubleToMScalar(1.99), SkDoubleToMScalar(3.0));
94
95 Rect viewport(kOffset, kOffset, 1920, 1200);
96 bool snapped = SnapTransform(&result, transform, viewport);
97
98 EXPECT_TRUE(snapped)
99 << "Distant viewport should still snap by less than 1px.";
100}
101
102TEST(TransformUtilTest, SnapScale) {
103 Transform result(Transform::kSkipInitialization);
104 Transform transform;
105
106 transform.Scale3d(SkDoubleToMScalar(5.0),
107 SkDoubleToMScalar(2.00001),
108 SkDoubleToMScalar(1.0));
109 Rect viewport(1920, 1200);
110 bool snapped = SnapTransform(&result, transform, viewport);
111
112 EXPECT_TRUE(snapped) << "Viewport should snap for this scaling.";
113}
114
115TEST(TransformUtilTest, NoSnapScale) {
116 Transform result(Transform::kSkipInitialization);
117 Transform transform;
118
119 transform.Scale3d(
120 SkDoubleToMScalar(5.0), SkDoubleToMScalar(2.1), SkDoubleToMScalar(1.0));
121 Rect viewport(1920, 1200);
122 bool snapped = SnapTransform(&result, transform, viewport);
123
124 EXPECT_FALSE(snapped) << "Viewport shouldn't snap for this scaling.";
125}
126
127TEST(TransformUtilTest, SnapCompositeTransform) {
128 Transform result(Transform::kSkipInitialization);
129 Transform transform;
130
131 transform.Translate3d(SkDoubleToMScalar(30.5), SkDoubleToMScalar(20.0),
132 SkDoubleToMScalar(10.1));
133 transform.RotateAboutZAxis(89.99);
134 transform.Scale3d(SkDoubleToMScalar(1.0),
135 SkDoubleToMScalar(3.00001),
136 SkDoubleToMScalar(2.0));
137
138 Rect viewport(1920, 1200);
139 bool snapped = SnapTransform(&result, transform, viewport);
140 ASSERT_TRUE(snapped) << "Viewport should snap all components.";
141
142 Point3F point;
143
danakj1d478ea02015-10-21 17:53:41144 point = Point3F(PointF(viewport.origin()));
[email protected]dd31d492013-10-24 22:33:25145 result.TransformPoint(&point);
146 EXPECT_EQ(Point3F(31.f, 20.f, 10.f), point) << "Transformed origin";
147
danakj1d478ea02015-10-21 17:53:41148 point = Point3F(PointF(viewport.top_right()));
[email protected]dd31d492013-10-24 22:33:25149 result.TransformPoint(&point);
150 EXPECT_EQ(Point3F(31.f, 1940.f, 10.f), point) << "Transformed top-right";
151
danakj1d478ea02015-10-21 17:53:41152 point = Point3F(PointF(viewport.bottom_left()));
[email protected]dd31d492013-10-24 22:33:25153 result.TransformPoint(&point);
154 EXPECT_EQ(Point3F(-3569.f, 20.f, 10.f), point) << "Transformed bottom-left";
155
danakj1d478ea02015-10-21 17:53:41156 point = Point3F(PointF(viewport.bottom_right()));
[email protected]dd31d492013-10-24 22:33:25157 result.TransformPoint(&point);
158 EXPECT_EQ(Point3F(-3569.f, 1940.f, 10.f), point)
159 << "Transformed bottom-right";
160}
161
162TEST(TransformUtilTest, NoSnapSkewedCompositeTransform) {
163 Transform result(Transform::kSkipInitialization);
164 Transform transform;
165
166
167 transform.RotateAboutZAxis(89.99);
168 transform.Scale3d(SkDoubleToMScalar(1.0),
169 SkDoubleToMScalar(3.00001),
170 SkDoubleToMScalar(2.0));
171 transform.Translate3d(SkDoubleToMScalar(30.5), SkDoubleToMScalar(20.0),
172 SkDoubleToMScalar(10.1));
nainar8ca8ee62015-09-03 01:04:10173 transform.Skew(20.0, 0.0);
[email protected]dd31d492013-10-24 22:33:25174 Rect viewport(1920, 1200);
175 bool snapped = SnapTransform(&result, transform, viewport);
176 EXPECT_FALSE(snapped) << "Skewed viewport should not snap.";
177}
178
bruthig8a260732014-11-24 23:32:02179TEST(TransformUtilTest, TransformAboutPivot) {
180 Transform transform;
181 transform.Scale(3, 4);
182 transform = TransformAboutPivot(Point(7, 8), transform);
183
184 Point point;
185
186 point = Point(0, 0);
187 transform.TransformPoint(&point);
188 EXPECT_EQ(Point(-14, -24).ToString(), point.ToString());
189
190 point = Point(1, 1);
191 transform.TransformPoint(&point);
192 EXPECT_EQ(Point(-11, -20).ToString(), point.ToString());
193}
194
vmpstrb1442372015-07-08 19:29:08195TEST(TransformUtilTest, BlendOppositeQuaternions) {
196 DecomposedTransform first;
197 DecomposedTransform second;
198 second.quaternion[3] = -second.quaternion[3];
199
200 DecomposedTransform result;
201 BlendDecomposedTransforms(&result, first, second, 0.25);
202 for (size_t i = 0; i < 4; ++i) {
203 EXPECT_TRUE(std::isfinite(result.quaternion[i]));
204 EXPECT_FALSE(std::isnan(result.quaternion[i]));
205 }
206}
207
[email protected]db06cc12012-11-10 05:19:52208} // namespace
209} // namespace gfx