Home | History | Annotate | Download | only in corewm
      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.
      4 
      5 #include "testing/gtest/include/gtest/gtest.h"
      6 #include "third_party/skia/include/core/SkBitmap.h"
      7 #include "ui/views/test/views_test_base.h"
      8 #include "ui/gfx/image/image.h"
      9 #include "ui/gfx/image/image_skia.h"
     10 #include "ui/views/corewm/image_grid.h"
     11 
     12 namespace views {
     13 namespace corewm {
     14 
     15 namespace {
     16 
     17 // Creates a gfx::Image with the requested dimensions.
     18 gfx::Image* CreateImage(const gfx::Size& size) {
     19   SkBitmap bitmap;
     20   bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
     21   return new gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(bitmap));
     22 }
     23 
     24 }  // namespace
     25 
     26 typedef ViewsTestBase ImageGridTest;
     27 
     28 // Test that an ImageGrid's layers are transformed correctly when SetSize() is
     29 // called.
     30 TEST_F(ImageGridTest, Basic) {
     31   // Size of the images around the grid's border.
     32   const int kBorder = 2;
     33 
     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)));
     38 
     39   ImageGrid grid;
     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());
     43 
     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);
     54 
     55   const gfx::Size size(20, 30);
     56   grid.SetSize(size);
     57 
     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());
     62 
     63   // The top layer should be flush with the top edge and stretched horizontally
     64   // between the two top corners.
     65   EXPECT_EQ(gfx::RectF(
     66                 kBorder, 0, size.width() - 2 * kBorder, kBorder).ToString(),
     67             test_api.GetTransformedLayerBounds(
     68                 *grid.top_layer()).ToString());
     69 
     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());
     74 
     75   // The left layer should be flush with the left edge and stretched vertically
     76   // between the two left corners.
     77   EXPECT_EQ(gfx::RectF(
     78                 0, kBorder, kBorder, size.height() - 2 * kBorder).ToString(),
     79             test_api.GetTransformedLayerBounds(
     80                 *grid.left_layer()).ToString());
     81 
     82   // The center layer should fill the space in the middle of the grid.
     83   EXPECT_EQ(gfx::RectF(
     84                 kBorder, kBorder, size.width() - 2 * kBorder,
     85                 size.height() - 2 * kBorder).ToString(),
     86             test_api.GetTransformedLayerBounds(
     87                 *grid.center_layer()).ToString());
     88 
     89   // The right layer should be flush with the right edge and stretched
     90   // vertically between the two right corners.
     91   EXPECT_EQ(gfx::RectF(
     92                 size.width() - kBorder, kBorder,
     93                 kBorder, size.height() - 2 * kBorder).ToString(),
     94             test_api.GetTransformedLayerBounds(
     95                 *grid.right_layer()).ToString());
     96 
     97   // The bottom-left layer should be flush with the bottom-left corner and
     98   // unscaled.
     99   EXPECT_EQ(gfx::RectF(0, size.height() - kBorder, kBorder, kBorder).ToString(),
    100             test_api.GetTransformedLayerBounds(
    101                 *grid.bottom_left_layer()).ToString());
    102 
    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());
    110 
    111   // The bottom-right layer should be flush with the bottom-right corner and
    112   // unscaled.
    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());
    118 }
    119 
    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;
    125 
    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)));
    130 
    131   ImageGrid grid;
    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());
    135 
    136   ImageGrid::TestAPI test_api(&grid);
    137 
    138   const gfx::Point origin(5, 10);
    139   const gfx::Size size(20, 30);
    140   grid.SetContentBounds(gfx::Rect(origin, size));
    141 
    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());
    149 }
    150 
    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)));
    155 
    156   ImageGrid grid;
    157   grid.SetImages(NULL, image.get(), NULL,
    158                  NULL, NULL, NULL,
    159                  NULL, NULL, NULL);
    160 
    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);
    171 
    172   const gfx::Size kSize(10, 10);
    173   grid.SetSize(kSize);
    174 
    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());
    180 }
    181 
    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)));
    187 
    188   ImageGrid grid;
    189   grid.SetImages(NULL, image.get(), NULL,
    190                  NULL, NULL, NULL,
    191                  NULL, NULL, NULL);
    192 
    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);
    204 
    205   grid.SetImages(NULL, NULL, NULL,
    206                  NULL, NULL, NULL,
    207                  NULL, image.get(), NULL);
    208 
    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);
    219 }
    220 
    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;
    226   const int kEdge = 1;
    227 
    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)));
    235 
    236   ImageGrid grid;
    237   grid.SetImages(top_left_image.get(), top_image.get(), top_right_image.get(),
    238                  left_image.get(), NULL, right_image.get(),
    239                  NULL, NULL, NULL);
    240   ImageGrid::TestAPI test_api(&grid);
    241 
    242   const gfx::Size kSize(20, 30);
    243   grid.SetSize(kSize);
    244 
    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());
    251 
    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());
    258 
    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());
    266 }
    267 
    268 // Test that we hide or clip layers as needed when the grid is assigned a small
    269 // size.
    270 TEST_F(ImageGridTest, TooSmall) {
    271   const int kCorner = 5;
    272   const int kCenter = 3;
    273   const int kEdge = 3;
    274 
    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)));
    288 
    289   ImageGrid grid;
    290   grid.SetImages(
    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);
    295 
    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);
    299 
    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());
    306 
    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());
    320 
    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);
    325 
    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());
    332 
    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());
    338 }
    339 
    340 }  // namespace corewm
    341 }  // namespace views
    342