15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/icon_util.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gfx_paths.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/icon_util_unittests_resource.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/image/image_family.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kSmallIconName[] = "icon_util/16_X_16_icon.ico";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kLargeIconName[] = "icon_util/128_X_128_icon.ico";
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kTempIconFilename[] = "temp_test_icon.ico";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IconUtilTest : public testing::Test {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    gfx::RegisterPathProvider();
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ASSERT_TRUE(PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_));
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    temp_directory_.CreateUniqueTempDir();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kSmallIconWidth = 16;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kSmallIconHeight = 16;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kLargeIconWidth = 128;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kLargeIconHeight = 128;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Given a file name for an .ico file and an image dimensions, this
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // function loads the icon and returns an HICON handle.
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HICON LoadIconFromFile(const base::FilePath& filename,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         int width, int height) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HICON icon = static_cast<HICON>(LoadImage(NULL,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    filename.value().c_str(),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    IMAGE_ICON,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    width,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    height,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    LR_LOADTRANSPARENT | LR_LOADFROMFILE));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return icon;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkBitmap CreateBlackSkBitmap(int width, int height) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkBitmap bitmap;
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bitmap.allocN32Pixels(width, height);
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Setting the pixels to transparent-black.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memset(bitmap.getPixels(), 0, width * height * 4);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return bitmap;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Loads an .ico file from |icon_filename| and asserts that it contains all of
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the expected icon sizes up to and including |max_icon_size|, and no other
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // icons. If |max_icon_size| >= 256, this tests for a 256x256 PNG icon entry.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CheckAllIconSizes(const base::FilePath& icon_filename,
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         int max_icon_size);
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The root directory for test files. This should be treated as read-only.
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath test_data_directory_;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Directory for creating files by this test.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_directory_;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IconUtilTest::CheckAllIconSizes(const base::FilePath& icon_filename,
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     int max_icon_size) {
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::PathExists(icon_filename));
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Determine how many icons to expect, based on |max_icon_size|.
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int expected_num_icons = 0;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < IconUtil::kNumIconDimensions; ++i) {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (IconUtil::kIconDimensions[i] > max_icon_size)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++expected_num_icons;
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // First, use the Windows API to load the icon, a basic validity test.
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HICON icon = LoadIconFromFile(icon_filename, kSmallIconWidth,
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                kSmallIconHeight);
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_NE(static_cast<HICON>(NULL), icon);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (icon != NULL)
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ::DestroyIcon(icon);
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Read the file completely into memory.
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string icon_data;
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(base::ReadFileToString(icon_filename, &icon_data));
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_GE(icon_data.length(), sizeof(IconUtil::ICONDIR));
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Ensure that it has exactly the expected number and sizes of icons, in the
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // expected order. This matches each entry of the loaded file's icon directory
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with the corresponding element of kIconDimensions.
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Also extracts the 256x256 entry as png_entry.
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const IconUtil::ICONDIR* icon_dir =
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      reinterpret_cast<const IconUtil::ICONDIR*>(icon_data.data());
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(expected_num_icons, icon_dir->idCount);
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_GE(IconUtil::kNumIconDimensions, icon_dir->idCount);
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_GE(icon_data.length(),
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            sizeof(IconUtil::ICONDIR) +
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                icon_dir->idCount * sizeof(IconUtil::ICONDIRENTRY));
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const IconUtil::ICONDIRENTRY* png_entry = NULL;
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < icon_dir->idCount; ++i) {
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const IconUtil::ICONDIRENTRY* entry = &icon_dir->idEntries[i];
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Mod 256 because as a special case in ICONDIRENTRY, the value 0 represents
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // a width or height of 256.
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int expected_size = IconUtil::kIconDimensions[i] % 256;
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(expected_size, static_cast<int>(entry->bWidth));
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(expected_size, static_cast<int>(entry->bHeight));
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (entry->bWidth == 0 && entry->bHeight == 0) {
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_EQ(NULL, png_entry);
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      png_entry = entry;
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (max_icon_size >= 256) {
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(png_entry);
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Convert the PNG entry data back to a SkBitmap to ensure it's valid.
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_GE(icon_data.length(),
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              png_entry->dwImageOffset + png_entry->dwBytesInRes);
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const unsigned char* png_bytes = reinterpret_cast<const unsigned char*>(
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        icon_data.data() + png_entry->dwImageOffset);
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        png_bytes, png_entry->dwBytesInRes);
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SkBitmap bitmap = image.AsBitmap();
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(256, bitmap.width());
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(256, bitmap.height());
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following test case makes sure IconUtil::SkBitmapFromHICON fails
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gracefully when called with invalid input parameters.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IconUtilTest, TestIconToBitmapInvalidParameters) {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath icon_filename =
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_data_directory_.AppendASCII(kSmallIconName);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size icon_size(kSmallIconWidth, kSmallIconHeight);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HICON icon = LoadIconFromFile(icon_filename,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                icon_size.width(),
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                icon_size.height());
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(icon != NULL);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid size parameter.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size invalid_icon_size(kSmallIconHeight, 0);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(IconUtil::CreateSkBitmapFromHICON(icon, invalid_icon_size),
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<SkBitmap*>(NULL));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid icon.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(IconUtil::CreateSkBitmapFromHICON(NULL, icon_size),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<SkBitmap*>(NULL));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following code should succeed.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> bitmap;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.reset(IconUtil::CreateSkBitmapFromHICON(icon, icon_size));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::DestroyIcon(icon);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following test case makes sure IconUtil::CreateHICONFromSkBitmap fails
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gracefully when called with invalid input parameters.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IconUtilTest, TestBitmapToIconInvalidParameters) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HICON icon = NULL;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> bitmap;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrong bitmap format.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.reset(new SkBitmap);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bitmap->setInfo(SkImageInfo::MakeA8(kSmallIconWidth, kSmallIconHeight));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon, static_cast<HICON>(NULL));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid bitmap size.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.reset(new SkBitmap);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bitmap->setInfo(SkImageInfo::MakeN32Premul(0, 0));
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(icon, static_cast<HICON>(NULL));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid bitmap configuration but no pixels allocated.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.reset(new SkBitmap);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bitmap->setInfo(SkImageInfo::MakeN32Premul(kSmallIconWidth,
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             kSmallIconHeight));
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(icon == NULL);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The following test case makes sure IconUtil::CreateIconFileFromImageFamily
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fails gracefully when called with invalid input parameters.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IconUtilTest, TestCreateIconFileInvalidParameters) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> bitmap;
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::ImageFamily image_family;
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath valid_icon_filename = temp_directory_.path().AppendASCII(
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kTempIconFilename);
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath invalid_icon_filename = temp_directory_.path().AppendASCII(
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "<>?.ico");
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrong bitmap format.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.reset(new SkBitmap);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Must allocate pixels or else ImageSkia will ignore the bitmap and just
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // return an empty image.
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bitmap->allocPixels(SkImageInfo::MakeA8(kSmallIconWidth, kSmallIconHeight));
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  memset(bitmap->getPixels(), 0, bitmap->width() * bitmap->height());
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(*bitmap));
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(IconUtil::CreateIconFileFromImageFamily(image_family,
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       valid_icon_filename));
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(valid_icon_filename));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid bitmap size.
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.clear();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.reset(new SkBitmap);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bitmap->allocPixels(SkImageInfo::MakeN32Premul(0, 0));
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(*bitmap));
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(IconUtil::CreateIconFileFromImageFamily(image_family,
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       valid_icon_filename));
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(valid_icon_filename));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bitmap with no allocated pixels.
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.clear();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.reset(new SkBitmap);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bitmap->setInfo(SkImageInfo::MakeN32Premul(kSmallIconWidth,
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                             kSmallIconHeight));
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(*bitmap));
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(IconUtil::CreateIconFileFromImageFamily(image_family,
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       valid_icon_filename));
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(valid_icon_filename));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid file name.
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.clear();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap->allocPixels();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setting the pixels to black.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(bitmap->getPixels(), 0, bitmap->width() * bitmap->height() * 4);
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(*bitmap));
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(IconUtil::CreateIconFileFromImageFamily(image_family,
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       invalid_icon_filename));
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(invalid_icon_filename));
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This test case makes sure IconUtil::CreateIconFileFromImageFamily fails if
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the image family is empty or invalid.
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(IconUtilTest, TestCreateIconFileEmptyImageFamily) {
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath icon_filename = temp_directory_.path().AppendASCII(
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kTempIconFilename);
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Empty image family.
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(IconUtil::CreateIconFileFromImageFamily(gfx::ImageFamily(),
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       icon_filename));
2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(icon_filename));
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Image family with only an empty image.
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::ImageFamily image_family;
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image());
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(IconUtil::CreateIconFileFromImageFamily(image_family,
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       icon_filename));
2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(icon_filename));
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test case makes sure that when we load an icon from disk and convert
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the HICON into a bitmap, the bitmap has the expected format and dimensions.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IconUtilTest, TestCreateSkBitmapFromHICON) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> bitmap;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath small_icon_filename = test_data_directory_.AppendASCII(
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kSmallIconName);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size small_icon_size(kSmallIconWidth, kSmallIconHeight);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HICON small_icon = LoadIconFromFile(small_icon_filename,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      small_icon_size.width(),
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      small_icon_size.height());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(small_icon, static_cast<HICON>(NULL));
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.reset(IconUtil::CreateSkBitmapFromHICON(small_icon, small_icon_size));
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bitmap->width(), small_icon_size.width());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bitmap->height(), small_icon_size.height());
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(bitmap->colorType(), kN32_SkColorType);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::DestroyIcon(small_icon);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath large_icon_filename = test_data_directory_.AppendASCII(
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kLargeIconName);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size large_icon_size(kLargeIconWidth, kLargeIconHeight);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HICON large_icon = LoadIconFromFile(large_icon_filename,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      large_icon_size.width(),
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      large_icon_size.height());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(large_icon, static_cast<HICON>(NULL));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.reset(IconUtil::CreateSkBitmapFromHICON(large_icon, large_icon_size));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bitmap->width(), large_icon_size.width());
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bitmap->height(), large_icon_size.height());
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(bitmap->colorType(), kN32_SkColorType);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::DestroyIcon(large_icon);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test case makes sure that when an HICON is created from an SkBitmap,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the returned handle is valid and refers to an icon with the expected
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// dimensions color depth etc.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IconUtilTest, TestBasicCreateHICONFromSkBitmap) {
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkBitmap bitmap = CreateBlackSkBitmap(kSmallIconWidth, kSmallIconHeight);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HICON icon = IconUtil::CreateHICONFromSkBitmap(bitmap);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(icon, static_cast<HICON>(NULL));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ICONINFO icon_info;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(::GetIconInfo(icon, &icon_info));
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(icon_info.fIcon);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now that have the icon information, we should obtain the specification of
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the icon's bitmap and make sure it matches the specification of the
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SkBitmap we started with.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The bitmap handle contained in the icon information is a handle to a
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // compatible bitmap so we need to call ::GetDIBits() in order to retrieve
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the bitmap's header information.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BITMAPINFO bitmap_info;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::ZeroMemory(&bitmap_info, sizeof(BITMAPINFO));
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFO);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HDC hdc = ::GetDC(NULL);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = ::GetDIBits(hdc,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           icon_info.hbmColor,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           0,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           kSmallIconWidth,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           NULL,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           &bitmap_info,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           DIB_RGB_COLORS);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_GT(result, 0);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bitmap_info.bmiHeader.biWidth, kSmallIconWidth);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bitmap_info.bmiHeader.biHeight, kSmallIconHeight);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bitmap_info.bmiHeader.biPlanes, 1);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bitmap_info.bmiHeader.biBitCount, 32);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::ReleaseDC(NULL, hdc);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::DestroyIcon(icon);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This test case makes sure that CreateIconFileFromImageFamily creates a
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// valid .ico file given an ImageFamily, and appropriately creates all icon
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// sizes from the given input.
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(IconUtilTest, TestCreateIconFileFromImageFamily) {
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::ImageFamily image_family;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath icon_filename =
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      temp_directory_.path().AppendASCII(kTempIconFilename);
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test with only a 16x16 icon. Should only scale up to 48x48.
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateBlackSkBitmap(kSmallIconWidth, kSmallIconHeight)));
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(IconUtil::CreateIconFileFromImageFamily(image_family,
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                      icon_filename));
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckAllIconSizes(icon_filename, 48);
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test with a 48x48 icon. Should only scale down.
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(CreateBlackSkBitmap(48, 48)));
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(IconUtil::CreateIconFileFromImageFamily(image_family,
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                      icon_filename));
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckAllIconSizes(icon_filename, 48);
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test with a 64x64 icon. Should scale up to 256x256.
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(CreateBlackSkBitmap(64, 64)));
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(IconUtil::CreateIconFileFromImageFamily(image_family,
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                      icon_filename));
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckAllIconSizes(icon_filename, 256);
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test with a 256x256 icon. Should include the 256x256 in the output.
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CreateBlackSkBitmap(256, 256)));
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(IconUtil::CreateIconFileFromImageFamily(image_family,
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                      icon_filename));
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckAllIconSizes(icon_filename, 256);
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test with a 49x49 icon. Should scale up to 256x256, but exclude the
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // original 49x49 representation from the output.
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.clear();
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(CreateBlackSkBitmap(49, 49)));
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(IconUtil::CreateIconFileFromImageFamily(image_family,
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                      icon_filename));
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckAllIconSizes(icon_filename, 256);
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test with a non-square 16x32 icon. Should scale up to 48, but exclude the
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // original 16x32 representation from the output.
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.clear();
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(CreateBlackSkBitmap(16, 32)));
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(IconUtil::CreateIconFileFromImageFamily(image_family,
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                      icon_filename));
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckAllIconSizes(icon_filename, 48);
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test with a non-square 32x49 icon. Should scale up to 256, but exclude the
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // original 32x49 representation from the output.
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(CreateBlackSkBitmap(32, 49)));
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(IconUtil::CreateIconFileFromImageFamily(image_family,
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                      icon_filename));
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckAllIconSizes(icon_filename, 256);
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test with an empty and non-empty image.
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The empty image should be ignored.
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.clear();
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image());
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  image_family.Add(gfx::Image::CreateFrom1xBitmap(CreateBlackSkBitmap(16, 16)));
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(IconUtil::CreateIconFileFromImageFamily(image_family,
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       icon_filename));
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckAllIconSizes(icon_filename, 48);
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(IconUtilTest, TestCreateSkBitmapFromIconResource48x48) {
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HMODULE module = GetModuleHandle(NULL);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SkBitmap> bitmap(
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IconUtil::CreateSkBitmapFromIconResource(module, IDR_MAINFRAME, 48));
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(bitmap.get());
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(48, bitmap->width());
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(48, bitmap->height());
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(IconUtilTest, TestCreateSkBitmapFromIconResource256x256) {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HMODULE module = GetModuleHandle(NULL);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SkBitmap> bitmap(
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IconUtil::CreateSkBitmapFromIconResource(module, IDR_MAINFRAME, 256));
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(bitmap.get());
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(256, bitmap->width());
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(256, bitmap->height());
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This tests that kNumIconDimensionsUpToMediumSize has the correct value.
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(IconUtilTest, TestNumIconDimensionsUpToMediumSize) {
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_LE(IconUtil::kNumIconDimensionsUpToMediumSize,
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            IconUtil::kNumIconDimensions);
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(IconUtil::kMediumIconSize,
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            IconUtil::kIconDimensions[
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                IconUtil::kNumIconDimensionsUpToMediumSize - 1]);
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
433