| 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/file_util.h" |    7 #include "base/file_util.h" | 
|    8 #include "base/logging.h" |    8 #include "base/logging.h" | 
|    9 #include "base/memory/scoped_ptr.h" |    9 #include "base/memory/scoped_ptr.h" | 
 |   10 #include "base/win/resource_util.h" | 
|   10 #include "base/win/scoped_gdi_object.h" |   11 #include "base/win/scoped_gdi_object.h" | 
|   11 #include "base/win/scoped_handle.h" |   12 #include "base/win/scoped_handle.h" | 
|   12 #include "base/win/scoped_hdc.h" |   13 #include "base/win/scoped_hdc.h" | 
|   13 #include "skia/ext/image_operations.h" |   14 #include "skia/ext/image_operations.h" | 
|   14 #include "third_party/skia/include/core/SkBitmap.h" |   15 #include "third_party/skia/include/core/SkBitmap.h" | 
|   15 #include "ui/gfx/gdi_util.h" |   16 #include "ui/gfx/gdi_util.h" | 
|   16 #include "ui/gfx/image/image.h" |   17 #include "ui/gfx/image/image.h" | 
|   17 #include "ui/gfx/size.h" |   18 #include "ui/gfx/size.h" | 
|   18  |   19  | 
|   19 namespace { |   20 namespace { | 
 |   21  | 
|   20 struct ScopedICONINFO : ICONINFO { |   22 struct ScopedICONINFO : ICONINFO { | 
|   21   ScopedICONINFO() { |   23   ScopedICONINFO() { | 
|   22     hbmColor = NULL; |   24     hbmColor = NULL; | 
|   23     hbmMask = NULL; |   25     hbmMask = NULL; | 
|   24   } |   26   } | 
|   25  |   27  | 
|   26   ~ScopedICONINFO() { |   28   ~ScopedICONINFO() { | 
|   27     if (hbmColor) |   29     if (hbmColor) | 
|   28       ::DeleteObject(hbmColor); |   30       ::DeleteObject(hbmColor); | 
|   29     if (hbmMask) |   31     if (hbmMask) | 
|   30       ::DeleteObject(hbmMask); |   32       ::DeleteObject(hbmMask); | 
|   31   } |   33   } | 
|   32 }; |   34 }; | 
|   33 } |   35  | 
 |   36 }  // namespace | 
|   34  |   37  | 
|   35 // Defining the dimensions for the icon images. We store only one value because |   38 // Defining the dimensions for the icon images. We store only one value because | 
|   36 // we always resize to a square image; that is, the value 48 means that we are |   39 // we always resize to a square image; that is, the value 48 means that we are | 
|   37 // going to resize the given bitmap to a 48 by 48 pixels bitmap. |   40 // going to resize the given bitmap to a 48 by 48 pixels bitmap. | 
|   38 // |   41 // | 
|   39 // The icon images appear in the icon file in same order in which their |   42 // The icon images appear in the icon file in same order in which their | 
|   40 // corresponding dimensions appear in the |icon_dimensions_| array, so it is |   43 // corresponding dimensions appear in the |icon_dimensions_| array, so it is | 
|   41 // important to keep this array sorted. Also note that the maximum icon image |   44 // important to keep this array sorted. Also note that the maximum icon image | 
|   42 // size we can handle is 255 by 255. |   45 // size we can handle is 255 by 255. | 
|   43 const int IconUtil::icon_dimensions_[] = { |   46 const int IconUtil::icon_dimensions_[] = { | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  125   if (!icon || s.IsEmpty()) |  128   if (!icon || s.IsEmpty()) | 
|  126     return NULL; |  129     return NULL; | 
|  127   ScopedICONINFO icon_info; |  130   ScopedICONINFO icon_info; | 
|  128   if (!::GetIconInfo(icon, &icon_info)) |  131   if (!::GetIconInfo(icon, &icon_info)) | 
|  129     return NULL; |  132     return NULL; | 
|  130   if (!icon_info.fIcon) |  133   if (!icon_info.fIcon) | 
|  131     return NULL; |  134     return NULL; | 
|  132   return new SkBitmap(CreateSkBitmapFromHICONHelper(icon, s)); |  135   return new SkBitmap(CreateSkBitmapFromHICONHelper(icon, s)); | 
|  133 } |  136 } | 
|  134  |  137  | 
 |  138 scoped_ptr<SkBitmap> IconUtil::CreateSkBitmapFromIconResource(HMODULE module, | 
 |  139                                                               int resource_id, | 
 |  140                                                               int size) { | 
 |  141   DCHECK_LE(size, 256); | 
 |  142  | 
 |  143   // For everything except the Vista+ 256x256 icons, use |LoadImage()|. | 
 |  144   if (size != 256) { | 
 |  145     HICON icon_handle = | 
 |  146         static_cast<HICON>(LoadImage(module, MAKEINTRESOURCE(resource_id), | 
 |  147                                      IMAGE_ICON, size, size, | 
 |  148                                      LR_DEFAULTCOLOR | LR_DEFAULTSIZE)); | 
 |  149     scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON(icon_handle)); | 
 |  150     DestroyIcon(icon_handle); | 
 |  151     return bitmap.Pass(); | 
 |  152   } | 
 |  153  | 
 |  154   // For Vista+ 256x256 PNG icons, read the resource directly and find | 
 |  155   // the corresponding icon entry to get its PNG bytes. | 
 |  156   void* icon_dir_data = NULL; | 
 |  157   size_t icon_dir_size = 0; | 
 |  158   if (!base::win::GetResourceFromModule(module, resource_id, RT_GROUP_ICON, | 
 |  159                                         &icon_dir_data, &icon_dir_size)) { | 
 |  160     return scoped_ptr<SkBitmap>(); | 
 |  161   } | 
 |  162   DCHECK(icon_dir_data); | 
 |  163   DCHECK_GE(icon_dir_size, sizeof(GRPICONDIR)); | 
 |  164  | 
 |  165   const GRPICONDIR* icon_dir = | 
 |  166       reinterpret_cast<const GRPICONDIR*>(icon_dir_data); | 
 |  167   const GRPICONDIRENTRY* large_icon_entry = NULL; | 
 |  168   for (size_t i = 0; i < icon_dir->idCount; ++i) { | 
 |  169     const GRPICONDIRENTRY* entry = &icon_dir->idEntries[i]; | 
 |  170     // 256x256 icons are stored with width and height set to 0. | 
 |  171     // See: http://en.wikipedia.org/wiki/ICO_(file_format) | 
 |  172     if (entry->bWidth == 0 && entry->bHeight == 0) { | 
 |  173       large_icon_entry = entry; | 
 |  174       break; | 
 |  175     } | 
 |  176   } | 
 |  177   if (!large_icon_entry) | 
 |  178     return scoped_ptr<SkBitmap>(); | 
 |  179  | 
 |  180   void* png_data = NULL; | 
 |  181   size_t png_size = 0; | 
 |  182   if (!base::win::GetResourceFromModule(module, large_icon_entry->nID, RT_ICON, | 
 |  183                                         &png_data, &png_size)) { | 
 |  184     return scoped_ptr<SkBitmap>(); | 
 |  185   } | 
 |  186   DCHECK(png_data); | 
 |  187   DCHECK_EQ(png_size, large_icon_entry->dwBytesInRes); | 
 |  188  | 
 |  189   const unsigned char* png_bytes = | 
 |  190       reinterpret_cast<const unsigned char*>(png_data); | 
 |  191   gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(png_bytes, png_size); | 
 |  192   return scoped_ptr<SkBitmap>(new SkBitmap(image.AsBitmap())); | 
 |  193 } | 
 |  194  | 
|  135 SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon) { |  195 SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon) { | 
|  136   // We start with validating parameters. |  196   // We start with validating parameters. | 
|  137   if (!icon) |  197   if (!icon) | 
|  138     return NULL; |  198     return NULL; | 
|  139  |  199  | 
|  140   ScopedICONINFO icon_info; |  200   ScopedICONINFO icon_info; | 
|  141   BITMAP bitmap_info = { 0 }; |  201   BITMAP bitmap_info = { 0 }; | 
|  142  |  202  | 
|  143   if (!::GetIconInfo(icon, &icon_info)) |  203   if (!::GetIconInfo(icon, &icon_info)) | 
|  144     return NULL; |  204     return NULL; | 
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  577   // Once we compute the size for a singe AND mask scan line, we multiply that |  637   // Once we compute the size for a singe AND mask scan line, we multiply that | 
|  578   // number by the image height in order to get the total number of bytes for |  638   // number by the image height in order to get the total number of bytes for | 
|  579   // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes |  639   // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes | 
|  580   // for the monochrome bitmap representing the AND mask. |  640   // for the monochrome bitmap representing the AND mask. | 
|  581   size_t and_line_length = (bitmap.width() + 7) >> 3; |  641   size_t and_line_length = (bitmap.width() + 7) >> 3; | 
|  582   and_line_length = (and_line_length + 3) & ~3; |  642   and_line_length = (and_line_length + 3) & ~3; | 
|  583   size_t and_mask_size = and_line_length * bitmap.height(); |  643   size_t and_mask_size = and_line_length * bitmap.height(); | 
|  584   size_t masks_size = *xor_mask_size + and_mask_size; |  644   size_t masks_size = *xor_mask_size + and_mask_size; | 
|  585   *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); |  645   *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); | 
|  586 } |  646 } | 
| OLD | NEW |