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