1 // 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.
5 #include "ui/wm/core/image_grid.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/skia/include/core/SkBitmap.h"
9 #include "ui/aura/test/aura_test_base.h"
10 #include "ui/gfx/image/image.h"
11 #include "ui/gfx/image/image_skia.h"
17 // Creates a gfx::Image with the requested dimensions.
18 gfx::Image
* CreateImage(const gfx::Size
& size
) {
20 bitmap
.setInfo(SkImageInfo::MakeN32Premul(size
.width(), size
.height()));
21 return new gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(bitmap
));
26 typedef aura::test::AuraTestBase ImageGridTest
;
28 // Test that an ImageGrid's layers are transformed correctly when SetSize() is
30 TEST_F(ImageGridTest
, Basic
) {
31 // Size of the images around the grid's border.
32 const int kBorder
= 2;
34 scoped_ptr
<gfx::Image
> image_1x1(CreateImage(gfx::Size(1, 1)));
35 scoped_ptr
<gfx::Image
> image_1xB(CreateImage(gfx::Size(1, kBorder
)));
36 scoped_ptr
<gfx::Image
> image_Bx1(CreateImage(gfx::Size(kBorder
, 1)));
37 scoped_ptr
<gfx::Image
> image_BxB(CreateImage(gfx::Size(kBorder
, kBorder
)));
40 grid
.SetImages(image_BxB
.get(), image_1xB
.get(), image_BxB
.get(),
41 image_Bx1
.get(), image_1x1
.get(), image_Bx1
.get(),
42 image_BxB
.get(), image_1xB
.get(), image_BxB
.get());
44 ImageGrid::TestAPI
test_api(&grid
);
45 ASSERT_TRUE(grid
.top_left_layer() != NULL
);
46 ASSERT_TRUE(grid
.top_layer() != NULL
);
47 ASSERT_TRUE(grid
.top_right_layer() != NULL
);
48 ASSERT_TRUE(grid
.left_layer() != NULL
);
49 ASSERT_TRUE(grid
.center_layer() != NULL
);
50 ASSERT_TRUE(grid
.right_layer() != NULL
);
51 ASSERT_TRUE(grid
.bottom_left_layer() != NULL
);
52 ASSERT_TRUE(grid
.bottom_layer() != NULL
);
53 ASSERT_TRUE(grid
.bottom_right_layer() != NULL
);
55 const gfx::Size
size(20, 30);
58 // The top-left layer should be flush with the top-left corner and unscaled.
59 EXPECT_EQ(gfx::RectF(0, 0, kBorder
, kBorder
).ToString(),
60 test_api
.GetTransformedLayerBounds(
61 *grid
.top_left_layer()).ToString());
63 // The top layer should be flush with the top edge and stretched horizontally
64 // between the two top corners.
66 kBorder
, 0, size
.width() - 2 * kBorder
, kBorder
).ToString(),
67 test_api
.GetTransformedLayerBounds(
68 *grid
.top_layer()).ToString());
70 // The top-right layer should be flush with the top-right corner and unscaled.
71 EXPECT_EQ(gfx::RectF(size
.width() - kBorder
, 0, kBorder
, kBorder
).ToString(),
72 test_api
.GetTransformedLayerBounds(
73 *grid
.top_right_layer()).ToString());
75 // The left layer should be flush with the left edge and stretched vertically
76 // between the two left corners.
78 0, kBorder
, kBorder
, size
.height() - 2 * kBorder
).ToString(),
79 test_api
.GetTransformedLayerBounds(
80 *grid
.left_layer()).ToString());
82 // The center layer should fill the space in the middle of the grid.
84 kBorder
, kBorder
, size
.width() - 2 * kBorder
,
85 size
.height() - 2 * kBorder
).ToString(),
86 test_api
.GetTransformedLayerBounds(
87 *grid
.center_layer()).ToString());
89 // The right layer should be flush with the right edge and stretched
90 // vertically between the two right corners.
92 size
.width() - kBorder
, kBorder
,
93 kBorder
, size
.height() - 2 * kBorder
).ToString(),
94 test_api
.GetTransformedLayerBounds(
95 *grid
.right_layer()).ToString());
97 // The bottom-left layer should be flush with the bottom-left corner and
99 EXPECT_EQ(gfx::RectF(0, size
.height() - kBorder
, kBorder
, kBorder
).ToString(),
100 test_api
.GetTransformedLayerBounds(
101 *grid
.bottom_left_layer()).ToString());
103 // The bottom layer should be flush with the bottom edge and stretched
104 // horizontally between the two bottom corners.
105 EXPECT_EQ(gfx::RectF(
106 kBorder
, size
.height() - kBorder
,
107 size
.width() - 2 * kBorder
, kBorder
).ToString(),
108 test_api
.GetTransformedLayerBounds(
109 *grid
.bottom_layer()).ToString());
111 // The bottom-right layer should be flush with the bottom-right corner and
113 EXPECT_EQ(gfx::RectF(
114 size
.width() - kBorder
, size
.height() - kBorder
,
115 kBorder
, kBorder
).ToString(),
116 test_api
.GetTransformedLayerBounds(
117 *grid
.bottom_right_layer()).ToString());
120 // Test that an ImageGrid's layers are transformed correctly when
121 // SetContentBounds() is called.
122 TEST_F(ImageGridTest
, SetContentBounds
) {
123 // Size of the images around the grid's border.
124 const int kBorder
= 2;
126 scoped_ptr
<gfx::Image
> image_1x1(CreateImage(gfx::Size(1, 1)));
127 scoped_ptr
<gfx::Image
> image_1xB(CreateImage(gfx::Size(1, kBorder
)));
128 scoped_ptr
<gfx::Image
> image_Bx1(CreateImage(gfx::Size(kBorder
, 1)));
129 scoped_ptr
<gfx::Image
> image_BxB(CreateImage(gfx::Size(kBorder
, kBorder
)));
132 grid
.SetImages(image_BxB
.get(), image_1xB
.get(), image_BxB
.get(),
133 image_Bx1
.get(), image_1x1
.get(), image_Bx1
.get(),
134 image_BxB
.get(), image_1xB
.get(), image_BxB
.get());
136 ImageGrid::TestAPI
test_api(&grid
);
138 const gfx::Point
origin(5, 10);
139 const gfx::Size
size(20, 30);
140 grid
.SetContentBounds(gfx::Rect(origin
, size
));
142 // The master layer is positioned above the top-left corner of the content
143 // bounds and has height/width that contain the grid and bounds.
144 EXPECT_EQ(gfx::RectF(origin
.x() - kBorder
,
145 origin
.y() - kBorder
,
146 size
.width() + 2 * kBorder
,
147 size
.height() + 2 * kBorder
).ToString(),
148 test_api
.GetTransformedLayerBounds(*grid
.layer()).ToString());
151 // Check that we don't crash if only a single image is supplied.
152 TEST_F(ImageGridTest
, SingleImage
) {
153 const int kBorder
= 1;
154 scoped_ptr
<gfx::Image
> image(CreateImage(gfx::Size(kBorder
, kBorder
)));
157 grid
.SetImages(NULL
, image
.get(), NULL
,
161 ImageGrid::TestAPI
test_api(&grid
);
162 EXPECT_TRUE(grid
.top_left_layer() == NULL
);
163 ASSERT_TRUE(grid
.top_layer() != NULL
);
164 EXPECT_TRUE(grid
.top_right_layer() == NULL
);
165 EXPECT_TRUE(grid
.left_layer() == NULL
);
166 EXPECT_TRUE(grid
.center_layer() == NULL
);
167 EXPECT_TRUE(grid
.right_layer() == NULL
);
168 EXPECT_TRUE(grid
.bottom_left_layer() == NULL
);
169 EXPECT_TRUE(grid
.bottom_layer() == NULL
);
170 EXPECT_TRUE(grid
.bottom_right_layer() == NULL
);
172 const gfx::Size
kSize(10, 10);
175 // The top layer should be scaled horizontally across the entire width, but it
176 // shouldn't be scaled vertically.
177 EXPECT_EQ(gfx::RectF(0, 0, kSize
.width(), kBorder
).ToString(),
178 test_api
.GetTransformedLayerBounds(
179 *grid
.top_layer()).ToString());
182 // Check that we don't crash when we reset existing images to NULL and
183 // reset NULL images to new ones.
184 TEST_F(ImageGridTest
, ResetImages
) {
185 const int kBorder
= 1;
186 scoped_ptr
<gfx::Image
> image(CreateImage(gfx::Size(kBorder
, kBorder
)));
189 grid
.SetImages(NULL
, image
.get(), NULL
,
193 // Only the top edge has a layer.
194 ImageGrid::TestAPI
test_api(&grid
);
195 ASSERT_TRUE(grid
.top_left_layer() == NULL
);
196 ASSERT_FALSE(grid
.top_layer() == NULL
);
197 ASSERT_TRUE(grid
.top_right_layer() == NULL
);
198 ASSERT_TRUE(grid
.left_layer() == NULL
);
199 ASSERT_TRUE(grid
.center_layer() == NULL
);
200 ASSERT_TRUE(grid
.right_layer() == NULL
);
201 ASSERT_TRUE(grid
.bottom_left_layer() == NULL
);
202 ASSERT_TRUE(grid
.bottom_layer() == NULL
);
203 ASSERT_TRUE(grid
.bottom_right_layer() == NULL
);
205 grid
.SetImages(NULL
, NULL
, NULL
,
207 NULL
, image
.get(), NULL
);
209 // Now only the bottom edge has a layer.
210 ASSERT_TRUE(grid
.top_left_layer() == NULL
);
211 ASSERT_TRUE(grid
.top_layer() == NULL
);
212 ASSERT_TRUE(grid
.top_right_layer() == NULL
);
213 ASSERT_TRUE(grid
.left_layer() == NULL
);
214 ASSERT_TRUE(grid
.center_layer() == NULL
);
215 ASSERT_TRUE(grid
.right_layer() == NULL
);
216 ASSERT_TRUE(grid
.bottom_left_layer() == NULL
);
217 ASSERT_FALSE(grid
.bottom_layer() == NULL
);
218 ASSERT_TRUE(grid
.bottom_right_layer() == NULL
);
221 // Test that side (top, left, right, bottom) layers that are narrower than their
222 // adjacent corner layers stay pinned to the outside edges instead of getting
223 // moved inwards or scaled. This exercises the scenario used for shadows.
224 TEST_F(ImageGridTest
, SmallerSides
) {
225 const int kCorner
= 2;
228 scoped_ptr
<gfx::Image
> top_left_image(
229 CreateImage(gfx::Size(kCorner
, kCorner
)));
230 scoped_ptr
<gfx::Image
> top_image(CreateImage(gfx::Size(kEdge
, kEdge
)));
231 scoped_ptr
<gfx::Image
> top_right_image(
232 CreateImage(gfx::Size(kCorner
, kCorner
)));
233 scoped_ptr
<gfx::Image
> left_image(CreateImage(gfx::Size(kEdge
, kEdge
)));
234 scoped_ptr
<gfx::Image
> right_image(CreateImage(gfx::Size(kEdge
, kEdge
)));
237 grid
.SetImages(top_left_image
.get(), top_image
.get(), top_right_image
.get(),
238 left_image
.get(), NULL
, right_image
.get(),
240 ImageGrid::TestAPI
test_api(&grid
);
242 const gfx::Size
kSize(20, 30);
245 // The top layer should be flush with the top edge and stretched horizontally
246 // between the two top corners.
247 EXPECT_EQ(gfx::RectF(
248 kCorner
, 0, kSize
.width() - 2 * kCorner
, kEdge
).ToString(),
249 test_api
.GetTransformedLayerBounds(
250 *grid
.top_layer()).ToString());
252 // The left layer should be flush with the left edge and stretched vertically
253 // between the top left corner and the bottom.
254 EXPECT_EQ(gfx::RectF(
255 0, kCorner
, kEdge
, kSize
.height() - kCorner
).ToString(),
256 test_api
.GetTransformedLayerBounds(
257 *grid
.left_layer()).ToString());
259 // The right layer should be flush with the right edge and stretched
260 // vertically between the top right corner and the bottom.
261 EXPECT_EQ(gfx::RectF(
262 kSize
.width() - kEdge
, kCorner
,
263 kEdge
, kSize
.height() - kCorner
).ToString(),
264 test_api
.GetTransformedLayerBounds(
265 *grid
.right_layer()).ToString());
268 // Test that we hide or clip layers as needed when the grid is assigned a small
270 TEST_F(ImageGridTest
, TooSmall
) {
271 const int kCorner
= 5;
272 const int kCenter
= 3;
275 scoped_ptr
<gfx::Image
> top_left_image(
276 CreateImage(gfx::Size(kCorner
, kCorner
)));
277 scoped_ptr
<gfx::Image
> top_image(CreateImage(gfx::Size(kEdge
, kEdge
)));
278 scoped_ptr
<gfx::Image
> top_right_image(
279 CreateImage(gfx::Size(kCorner
, kCorner
)));
280 scoped_ptr
<gfx::Image
> left_image(CreateImage(gfx::Size(kEdge
, kEdge
)));
281 scoped_ptr
<gfx::Image
> center_image(CreateImage(gfx::Size(kCenter
, kCenter
)));
282 scoped_ptr
<gfx::Image
> right_image(CreateImage(gfx::Size(kEdge
, kEdge
)));
283 scoped_ptr
<gfx::Image
> bottom_left_image(
284 CreateImage(gfx::Size(kCorner
, kCorner
)));
285 scoped_ptr
<gfx::Image
> bottom_image(CreateImage(gfx::Size(kEdge
, kEdge
)));
286 scoped_ptr
<gfx::Image
> bottom_right_image(
287 CreateImage(gfx::Size(kCorner
, kCorner
)));
291 top_left_image
.get(), top_image
.get(), top_right_image
.get(),
292 left_image
.get(), center_image
.get(), right_image
.get(),
293 bottom_left_image
.get(), bottom_image
.get(), bottom_right_image
.get());
294 ImageGrid::TestAPI
test_api(&grid
);
296 // Set a size that's smaller than the combined (unscaled) corner images.
297 const gfx::Size
kSmallSize(kCorner
+ kCorner
- 3, kCorner
+ kCorner
- 5);
298 grid
.SetSize(kSmallSize
);
300 // The scalable images around the sides and in the center should be hidden.
301 EXPECT_FALSE(grid
.top_layer()->visible());
302 EXPECT_FALSE(grid
.bottom_layer()->visible());
303 EXPECT_FALSE(grid
.left_layer()->visible());
304 EXPECT_FALSE(grid
.right_layer()->visible());
305 EXPECT_FALSE(grid
.center_layer()->visible());
307 // The corner images' clip rects should sum to the expected size.
308 EXPECT_EQ(kSmallSize
.width(),
309 test_api
.top_left_clip_rect().width() +
310 test_api
.top_right_clip_rect().width());
311 EXPECT_EQ(kSmallSize
.width(),
312 test_api
.bottom_left_clip_rect().width() +
313 test_api
.bottom_right_clip_rect().width());
314 EXPECT_EQ(kSmallSize
.height(),
315 test_api
.top_left_clip_rect().height() +
316 test_api
.bottom_left_clip_rect().height());
317 EXPECT_EQ(kSmallSize
.height(),
318 test_api
.top_right_clip_rect().height() +
319 test_api
.bottom_right_clip_rect().height());
321 // Resize the grid to be large enough to show all images.
322 const gfx::Size
kLargeSize(kCorner
+ kCorner
+ kCenter
,
323 kCorner
+ kCorner
+ kCenter
);
324 grid
.SetSize(kLargeSize
);
326 // The scalable images should be visible now.
327 EXPECT_TRUE(grid
.top_layer()->visible());
328 EXPECT_TRUE(grid
.bottom_layer()->visible());
329 EXPECT_TRUE(grid
.left_layer()->visible());
330 EXPECT_TRUE(grid
.right_layer()->visible());
331 EXPECT_TRUE(grid
.center_layer()->visible());
333 // We shouldn't be clipping the corner images anymore.
334 EXPECT_TRUE(test_api
.top_left_clip_rect().IsEmpty());
335 EXPECT_TRUE(test_api
.top_right_clip_rect().IsEmpty());
336 EXPECT_TRUE(test_api
.bottom_left_clip_rect().IsEmpty());
337 EXPECT_TRUE(test_api
.bottom_right_clip_rect().IsEmpty());