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