| 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 | 
|---|