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