Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / ui / gfx / icon_util_unittest.cc
blobe462c2d7de28aca2a9107965cefc1b23ac9636db
1 // Copyright (c) 2011 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 "base/file_util.h"
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/path_service.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/skia/include/core/SkBitmap.h"
11 #include "ui/gfx/gfx_paths.h"
12 #include "ui/gfx/icon_util.h"
13 #include "ui/gfx/image/image.h"
14 #include "ui/gfx/size.h"
15 #include "ui/test/ui_unittests_resource.h"
17 namespace {
19 static const char kSmallIconName[] = "icon_util/16_X_16_icon.ico";
20 static const char kLargeIconName[] = "icon_util/128_X_128_icon.ico";
21 static const char kTempIconFilename[] = "temp_test_icon.ico";
23 class IconUtilTest : public testing::Test {
24 public:
25 IconUtilTest() {
26 PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_);
28 ~IconUtilTest() {}
30 static const int kSmallIconWidth = 16;
31 static const int kSmallIconHeight = 16;
32 static const int kLargeIconWidth = 128;
33 static const int kLargeIconHeight = 128;
35 // Given a file name for an .ico file and an image dimentions, this
36 // function loads the icon and returns an HICON handle.
37 HICON LoadIconFromFile(const base::FilePath& filename,
38 int width, int height) {
39 HICON icon = static_cast<HICON>(LoadImage(NULL,
40 filename.value().c_str(),
41 IMAGE_ICON,
42 width,
43 height,
44 LR_LOADTRANSPARENT | LR_LOADFROMFILE));
45 return icon;
48 SkBitmap CreateBlackSkBitmap(int width, int height) {
49 SkBitmap bitmap;
50 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
51 bitmap.allocPixels();
52 // Setting the pixels to black.
53 memset(bitmap.getPixels(), 0, width * height * 4);
54 return bitmap;
57 protected:
58 // The root directory for test files.
59 base::FilePath test_data_directory_;
61 // Directory for creating files by this test.
62 base::ScopedTempDir temp_directory_;
64 private:
65 DISALLOW_COPY_AND_ASSIGN(IconUtilTest);
68 } // namespace
70 // The following test case makes sure IconUtil::SkBitmapFromHICON fails
71 // gracefully when called with invalid input parameters.
72 TEST_F(IconUtilTest, TestIconToBitmapInvalidParameters) {
73 base::FilePath icon_filename =
74 test_data_directory_.AppendASCII(kSmallIconName);
75 gfx::Size icon_size(kSmallIconWidth, kSmallIconHeight);
76 HICON icon = LoadIconFromFile(icon_filename,
77 icon_size.width(),
78 icon_size.height());
79 ASSERT_TRUE(icon != NULL);
81 // Invalid size parameter.
82 gfx::Size invalid_icon_size(kSmallIconHeight, 0);
83 EXPECT_EQ(IconUtil::CreateSkBitmapFromHICON(icon, invalid_icon_size),
84 static_cast<SkBitmap*>(NULL));
86 // Invalid icon.
87 EXPECT_EQ(IconUtil::CreateSkBitmapFromHICON(NULL, icon_size),
88 static_cast<SkBitmap*>(NULL));
90 // The following code should succeed.
91 scoped_ptr<SkBitmap> bitmap;
92 bitmap.reset(IconUtil::CreateSkBitmapFromHICON(icon, icon_size));
93 EXPECT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
94 ::DestroyIcon(icon);
97 // The following test case makes sure IconUtil::CreateHICONFromSkBitmap fails
98 // gracefully when called with invalid input parameters.
99 TEST_F(IconUtilTest, TestBitmapToIconInvalidParameters) {
100 HICON icon = NULL;
101 scoped_ptr<SkBitmap> bitmap;
103 // Wrong bitmap format.
104 bitmap.reset(new SkBitmap);
105 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
106 bitmap->setConfig(SkBitmap::kA8_Config, kSmallIconWidth, kSmallIconHeight);
107 icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
108 EXPECT_EQ(icon, static_cast<HICON>(NULL));
110 // Invalid bitmap size.
111 bitmap.reset(new SkBitmap);
112 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
113 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 0, 0);
114 icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
115 EXPECT_EQ(icon, static_cast<HICON>(NULL));
117 // Valid bitmap configuration but no pixels allocated.
118 bitmap.reset(new SkBitmap);
119 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
120 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
121 kSmallIconWidth,
122 kSmallIconHeight);
123 icon = IconUtil::CreateHICONFromSkBitmap(*bitmap);
124 EXPECT_TRUE(icon == NULL);
127 // The following test case makes sure IconUtil::CreateIconFileFromSkBitmap
128 // fails gracefully when called with invalid input parameters.
129 TEST_F(IconUtilTest, TestCreateIconFileInvalidParameters) {
130 scoped_ptr<SkBitmap> bitmap;
131 base::FilePath valid_icon_filename = test_data_directory_.AppendASCII(
132 kSmallIconName);
133 base::FilePath invalid_icon_filename(FILE_PATH_LITERAL("C:\\<>?.ico"));
135 // Wrong bitmap format.
136 bitmap.reset(new SkBitmap);
137 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
138 bitmap->setConfig(SkBitmap::kA8_Config, kSmallIconWidth, kSmallIconHeight);
139 EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap, SkBitmap(),
140 valid_icon_filename));
142 // Invalid bitmap size.
143 bitmap.reset(new SkBitmap);
144 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
145 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 0, 0);
146 EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap, SkBitmap(),
147 valid_icon_filename));
149 // Bitmap with no allocated pixels.
150 bitmap.reset(new SkBitmap);
151 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
152 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
153 kSmallIconWidth,
154 kSmallIconHeight);
155 EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap, SkBitmap(),
156 valid_icon_filename));
158 // Invalid file name.
159 bitmap->allocPixels();
160 // Setting the pixels to black.
161 memset(bitmap->getPixels(), 0, bitmap->width() * bitmap->height() * 4);
162 EXPECT_FALSE(IconUtil::CreateIconFileFromSkBitmap(*bitmap, SkBitmap(),
163 invalid_icon_filename));
166 // This test case makes sure that when we load an icon from disk and convert
167 // the HICON into a bitmap, the bitmap has the expected format and dimentions.
168 TEST_F(IconUtilTest, TestCreateSkBitmapFromHICON) {
169 scoped_ptr<SkBitmap> bitmap;
170 base::FilePath small_icon_filename = test_data_directory_.AppendASCII(
171 kSmallIconName);
172 gfx::Size small_icon_size(kSmallIconWidth, kSmallIconHeight);
173 HICON small_icon = LoadIconFromFile(small_icon_filename,
174 small_icon_size.width(),
175 small_icon_size.height());
176 ASSERT_NE(small_icon, static_cast<HICON>(NULL));
177 bitmap.reset(IconUtil::CreateSkBitmapFromHICON(small_icon, small_icon_size));
178 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
179 EXPECT_EQ(bitmap->width(), small_icon_size.width());
180 EXPECT_EQ(bitmap->height(), small_icon_size.height());
181 EXPECT_EQ(bitmap->config(), SkBitmap::kARGB_8888_Config);
182 ::DestroyIcon(small_icon);
184 base::FilePath large_icon_filename = test_data_directory_.AppendASCII(
185 kLargeIconName);
186 gfx::Size large_icon_size(kLargeIconWidth, kLargeIconHeight);
187 HICON large_icon = LoadIconFromFile(large_icon_filename,
188 large_icon_size.width(),
189 large_icon_size.height());
190 ASSERT_NE(large_icon, static_cast<HICON>(NULL));
191 bitmap.reset(IconUtil::CreateSkBitmapFromHICON(large_icon, large_icon_size));
192 ASSERT_NE(bitmap.get(), static_cast<SkBitmap*>(NULL));
193 EXPECT_EQ(bitmap->width(), large_icon_size.width());
194 EXPECT_EQ(bitmap->height(), large_icon_size.height());
195 EXPECT_EQ(bitmap->config(), SkBitmap::kARGB_8888_Config);
196 ::DestroyIcon(large_icon);
199 // This test case makes sure that when an HICON is created from an SkBitmap,
200 // the returned handle is valid and refers to an icon with the expected
201 // dimentions color depth etc.
202 TEST_F(IconUtilTest, TestBasicCreateHICONFromSkBitmap) {
203 SkBitmap bitmap = CreateBlackSkBitmap(kSmallIconWidth, kSmallIconHeight);
204 HICON icon = IconUtil::CreateHICONFromSkBitmap(bitmap);
205 EXPECT_NE(icon, static_cast<HICON>(NULL));
206 ICONINFO icon_info;
207 ASSERT_TRUE(::GetIconInfo(icon, &icon_info));
208 EXPECT_TRUE(icon_info.fIcon);
210 // Now that have the icon information, we should obtain the specification of
211 // the icon's bitmap and make sure it matches the specification of the
212 // SkBitmap we started with.
214 // The bitmap handle contained in the icon information is a handle to a
215 // compatible bitmap so we need to call ::GetDIBits() in order to retrieve
216 // the bitmap's header information.
217 BITMAPINFO bitmap_info;
218 ::ZeroMemory(&bitmap_info, sizeof(BITMAPINFO));
219 bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFO);
220 HDC hdc = ::GetDC(NULL);
221 int result = ::GetDIBits(hdc,
222 icon_info.hbmColor,
224 kSmallIconWidth,
225 NULL,
226 &bitmap_info,
227 DIB_RGB_COLORS);
228 ASSERT_GT(result, 0);
229 EXPECT_EQ(bitmap_info.bmiHeader.biWidth, kSmallIconWidth);
230 EXPECT_EQ(bitmap_info.bmiHeader.biHeight, kSmallIconHeight);
231 EXPECT_EQ(bitmap_info.bmiHeader.biPlanes, 1);
232 EXPECT_EQ(bitmap_info.bmiHeader.biBitCount, 32);
233 ::ReleaseDC(NULL, hdc);
234 ::DestroyIcon(icon);
237 // The following test case makes sure IconUtil::CreateIconFileFromSkBitmap
238 // creates a valid .ico file given an SkBitmap.
239 TEST_F(IconUtilTest, TestCreateIconFile) {
240 base::FilePath icon_filename =
241 test_data_directory_.AppendASCII(kTempIconFilename);
243 SkBitmap bitmap = CreateBlackSkBitmap(kSmallIconWidth, kSmallIconHeight);
244 EXPECT_TRUE(IconUtil::CreateIconFileFromSkBitmap(bitmap, SkBitmap(),
245 icon_filename));
247 // We are currently only testing that it is possible to load an icon from
248 // the .ico file we just created. We don't really check the additional icon
249 // images created by IconUtil::CreateIconFileFromSkBitmap.
250 HICON icon = LoadIconFromFile(icon_filename,
251 kSmallIconWidth,
252 kSmallIconHeight);
253 EXPECT_NE(icon, static_cast<HICON>(NULL));
254 if (icon != NULL) {
255 ::DestroyIcon(icon);
259 TEST_F(IconUtilTest, TestCreateIconFileWithLargeBitmap) {
260 const base::FilePath icon_path(
261 temp_directory_.path().AppendASCII("test.ico"));
262 const SkBitmap bitmap_48 = CreateBlackSkBitmap(48, 48);
263 const SkBitmap bitmap_256 = CreateBlackSkBitmap(256, 256);
265 // First, create the icon file.
266 ASSERT_TRUE(IconUtil::CreateIconFileFromSkBitmap(bitmap_48, bitmap_256,
267 icon_path));
268 ASSERT_TRUE(file_util::PathExists(icon_path));
270 // Then, read the file and ensure it has a valid 256x256 PNG icon entry.
271 std::string icon_data;
272 ASSERT_TRUE(file_util::ReadFileToString(icon_path, &icon_data));
273 ASSERT_GE(icon_data.length(), sizeof(IconUtil::ICONDIR));
275 const IconUtil::ICONDIR* icon_dir =
276 reinterpret_cast<const IconUtil::ICONDIR*>(icon_data.data());
277 ASSERT_GE(icon_data.length(),
278 sizeof(IconUtil::ICONDIR) +
279 icon_dir->idCount * sizeof(IconUtil::ICONDIRENTRY));
280 const IconUtil::ICONDIRENTRY* png_entry = NULL;
281 for (size_t i = 0; i < icon_dir->idCount; ++i) {
282 const IconUtil::ICONDIRENTRY* entry = &icon_dir->idEntries[i];
283 if (entry->bWidth == 0 && entry->bHeight == 0) {
284 EXPECT_EQ(NULL, png_entry);
285 png_entry = entry;
288 ASSERT_TRUE(png_entry);
290 // Convert the PNG entry data back to a SkBitmap to ensure it's valid.
291 ASSERT_GE(icon_data.length(),
292 png_entry->dwImageOffset + png_entry->dwBytesInRes);
293 const unsigned char* png_bytes = reinterpret_cast<const unsigned char*>(
294 icon_data.data() + png_entry->dwImageOffset);
295 gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(png_bytes,
296 png_entry->dwBytesInRes);
297 SkBitmap bitmap = image.AsBitmap();
298 EXPECT_EQ(256, bitmap.width());
299 EXPECT_EQ(256, bitmap.height());
302 TEST_F(IconUtilTest, TestCreateSkBitmapFromIconResource48x48) {
303 HMODULE module = GetModuleHandle(NULL);
304 scoped_ptr<SkBitmap> bitmap(
305 IconUtil::CreateSkBitmapFromIconResource(module, IDR_MAINFRAME, 48));
306 ASSERT_TRUE(bitmap.get());
307 EXPECT_EQ(48, bitmap->width());
308 EXPECT_EQ(48, bitmap->height());
311 TEST_F(IconUtilTest, TestCreateSkBitmapFromIconResource256x256) {
312 HMODULE module = GetModuleHandle(NULL);
313 scoped_ptr<SkBitmap> bitmap(
314 IconUtil::CreateSkBitmapFromIconResource(module, IDR_MAINFRAME, 256));
315 ASSERT_TRUE(bitmap.get());
316 EXPECT_EQ(256, bitmap->width());
317 EXPECT_EQ(256, bitmap->height());