| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/icon_util.h" | 5 #include "ui/gfx/icon_util.h" |
| 6 | 6 |
| 7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
| 8 #include "base/files/important_file_writer.h" | 8 #include "base/files/important_file_writer.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 if (!icon || s.IsEmpty()) | 232 if (!icon || s.IsEmpty()) |
| 233 return NULL; | 233 return NULL; |
| 234 ScopedICONINFO icon_info; | 234 ScopedICONINFO icon_info; |
| 235 if (!::GetIconInfo(icon, &icon_info)) | 235 if (!::GetIconInfo(icon, &icon_info)) |
| 236 return NULL; | 236 return NULL; |
| 237 if (!icon_info.fIcon) | 237 if (!icon_info.fIcon) |
| 238 return NULL; | 238 return NULL; |
| 239 return new SkBitmap(CreateSkBitmapFromHICONHelper(icon, s)); | 239 return new SkBitmap(CreateSkBitmapFromHICONHelper(icon, s)); |
| 240 } | 240 } |
| 241 | 241 |
| 242 scoped_ptr<SkBitmap> IconUtil::CreateSkBitmapFromIconResource(HMODULE module, | 242 // static |
| 243 int resource_id, | 243 scoped_ptr<gfx::ImageFamily> IconUtil::CreateImageFamilyFromIconResource( |
| 244 int size) { | 244 HMODULE module, |
| 245 DCHECK_LE(size, kLargeIconSize); | 245 int resource_id) { |
| 246 | 246 // Read the resource directly so we can get the icon image sizes. This data |
| 247 // For everything except the Vista+ 256x256 icons, use |LoadImage()|. | 247 // will also be used to directly get the PNG bytes for large images. |
| 248 if (size != kLargeIconSize) { | |
| 249 HICON icon_handle = | |
| 250 static_cast<HICON>(LoadImage(module, MAKEINTRESOURCE(resource_id), | |
| 251 IMAGE_ICON, size, size, | |
| 252 LR_DEFAULTCOLOR | LR_DEFAULTSIZE)); | |
| 253 scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON(icon_handle)); | |
| 254 DestroyIcon(icon_handle); | |
| 255 return bitmap.Pass(); | |
| 256 } | |
| 257 | |
| 258 // For Vista+ 256x256 PNG icons, read the resource directly and find | |
| 259 // the corresponding icon entry to get its PNG bytes. | |
| 260 void* icon_dir_data = NULL; | 248 void* icon_dir_data = NULL; |
| 261 size_t icon_dir_size = 0; | 249 size_t icon_dir_size = 0; |
| 262 if (!base::win::GetResourceFromModule(module, resource_id, RT_GROUP_ICON, | 250 if (!base::win::GetResourceFromModule(module, resource_id, RT_GROUP_ICON, |
| 263 &icon_dir_data, &icon_dir_size)) { | 251 &icon_dir_data, &icon_dir_size)) { |
| 264 return nullptr; | 252 return nullptr; |
| 265 } | 253 } |
| 266 DCHECK(icon_dir_data); | 254 DCHECK(icon_dir_data); |
| 267 DCHECK_GE(icon_dir_size, sizeof(GRPICONDIR)); | 255 DCHECK_GE(icon_dir_size, sizeof(GRPICONDIR)); |
| 268 | 256 |
| 269 const GRPICONDIR* icon_dir = | 257 const GRPICONDIR* icon_dir = |
| 270 reinterpret_cast<const GRPICONDIR*>(icon_dir_data); | 258 reinterpret_cast<const GRPICONDIR*>(icon_dir_data); |
| 271 const GRPICONDIRENTRY* large_icon_entry = NULL; | 259 scoped_ptr<gfx::ImageFamily> result(new gfx::ImageFamily); |
| 272 for (size_t i = 0; i < icon_dir->idCount; ++i) { | 260 for (size_t i = 0; i < icon_dir->idCount; ++i) { |
| 273 const GRPICONDIRENTRY* entry = &icon_dir->idEntries[i]; | 261 const GRPICONDIRENTRY* entry = &icon_dir->idEntries[i]; |
| 274 // 256x256 icons are stored with width and height set to 0. | 262 if (entry->bWidth != 0 || entry->bHeight != 0) { |
| 275 // See: http://en.wikipedia.org/wiki/ICO_(file_format) | 263 // Ignore the low-bit-depth versions of the icon. |
| 276 if (entry->bWidth == 0 && entry->bHeight == 0) { | 264 if (entry->wBitCount != 32) |
| 277 large_icon_entry = entry; | 265 continue; |
| 278 break; | 266 |
| 267 // For everything except the Vista+ 256x256 icons, use |LoadImage()|. |
| 268 HICON icon_handle = static_cast<HICON>(LoadImage( |
| 269 module, MAKEINTRESOURCE(resource_id), IMAGE_ICON, entry->bWidth, |
| 270 entry->bHeight, LR_DEFAULTCOLOR | LR_DEFAULTSIZE)); |
| 271 scoped_ptr<SkBitmap> bitmap( |
| 272 IconUtil::CreateSkBitmapFromHICON(icon_handle)); |
| 273 DestroyIcon(icon_handle); |
| 274 result->Add(gfx::Image::CreateFrom1xBitmap(*bitmap)); |
| 275 } else { |
| 276 // 256x256 icons are stored with width and height set to 0. |
| 277 // See: http://en.wikipedia.org/wiki/ICO_(file_format) |
| 278 void* png_data = NULL; |
| 279 size_t png_size = 0; |
| 280 if (!base::win::GetResourceFromModule(module, entry->nID, RT_ICON, |
| 281 &png_data, &png_size)) { |
| 282 return nullptr; |
| 283 } |
| 284 DCHECK(png_data); |
| 285 DCHECK_EQ(png_size, entry->dwBytesInRes); |
| 286 |
| 287 result->Add(gfx::Image::CreateFrom1xPNGBytes( |
| 288 new base::RefCountedStaticMemory(png_data, png_size))); |
| 279 } | 289 } |
| 280 } | 290 } |
| 281 if (!large_icon_entry) | 291 return result; |
| 282 return nullptr; | |
| 283 | |
| 284 void* png_data = NULL; | |
| 285 size_t png_size = 0; | |
| 286 if (!base::win::GetResourceFromModule(module, large_icon_entry->nID, RT_ICON, | |
| 287 &png_data, &png_size)) { | |
| 288 return nullptr; | |
| 289 } | |
| 290 DCHECK(png_data); | |
| 291 DCHECK_EQ(png_size, large_icon_entry->dwBytesInRes); | |
| 292 | |
| 293 gfx::Image image = gfx::Image::CreateFrom1xPNGBytes( | |
| 294 new base::RefCountedStaticMemory(png_data, png_size)); | |
| 295 return make_scoped_ptr(new SkBitmap(image.AsBitmap())); | |
| 296 } | 292 } |
| 297 | 293 |
| 298 SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon) { | 294 SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon) { |
| 299 // We start with validating parameters. | 295 // We start with validating parameters. |
| 300 if (!icon) | 296 if (!icon) |
| 301 return NULL; | 297 return NULL; |
| 302 | 298 |
| 303 ScopedICONINFO icon_info; | 299 ScopedICONINFO icon_info; |
| 304 BITMAP bitmap_info = { 0 }; | 300 BITMAP bitmap_info = { 0 }; |
| 305 | 301 |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 // Once we compute the size for a singe AND mask scan line, we multiply that | 684 // Once we compute the size for a singe AND mask scan line, we multiply that |
| 689 // number by the image height in order to get the total number of bytes for | 685 // number by the image height in order to get the total number of bytes for |
| 690 // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes | 686 // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes |
| 691 // for the monochrome bitmap representing the AND mask. | 687 // for the monochrome bitmap representing the AND mask. |
| 692 size_t and_line_length = (bitmap.width() + 7) >> 3; | 688 size_t and_line_length = (bitmap.width() + 7) >> 3; |
| 693 and_line_length = (and_line_length + 3) & ~3; | 689 and_line_length = (and_line_length + 3) & ~3; |
| 694 size_t and_mask_size = and_line_length * bitmap.height(); | 690 size_t and_mask_size = and_line_length * bitmap.height(); |
| 695 size_t masks_size = *xor_mask_size + and_mask_size; | 691 size_t masks_size = *xor_mask_size + and_mask_size; |
| 696 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); | 692 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); |
| 697 } | 693 } |
| OLD | NEW |