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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 48, // Alt+Tab icon size. | 156 48, // Alt+Tab icon size. |
157 64, // Recommended by the MSDN as a nice to have icon size. | 157 64, // Recommended by the MSDN as a nice to have icon size. |
158 96, // Recommended by the MSDN as a nice to have icon size. | 158 96, // Recommended by the MSDN as a nice to have icon size. |
159 128, // Used by the Shell (e.g. for shortcuts). | 159 128, // Used by the Shell (e.g. for shortcuts). |
160 256 // Used by Vista onwards for large icons. | 160 256 // Used by Vista onwards for large icons. |
161 }; | 161 }; |
162 | 162 |
163 const size_t IconUtil::kNumIconDimensions = arraysize(kIconDimensions); | 163 const size_t IconUtil::kNumIconDimensions = arraysize(kIconDimensions); |
164 const size_t IconUtil::kNumIconDimensionsUpToMediumSize = 9; | 164 const size_t IconUtil::kNumIconDimensionsUpToMediumSize = 9; |
165 | 165 |
166 HICON IconUtil::CreateHICONFromSkBitmap(const SkBitmap& bitmap) { | 166 base::win::ScopedHICON IconUtil::CreateHICONFromSkBitmap( |
167 const SkBitmap& bitmap) { | |
167 // Only 32 bit ARGB bitmaps are supported. We also try to perform as many | 168 // Only 32 bit ARGB bitmaps are supported. We also try to perform as many |
168 // validations as we can on the bitmap. | 169 // validations as we can on the bitmap. |
169 SkAutoLockPixels bitmap_lock(bitmap); | 170 SkAutoLockPixels bitmap_lock(bitmap); |
170 if ((bitmap.colorType() != kN32_SkColorType) || | 171 if ((bitmap.colorType() != kN32_SkColorType) || |
171 (bitmap.width() <= 0) || (bitmap.height() <= 0) || | 172 (bitmap.width() <= 0) || (bitmap.height() <= 0) || |
172 (bitmap.getPixels() == NULL)) | 173 (bitmap.getPixels() == NULL)) |
173 return NULL; | 174 return base::win::ScopedHICON(); |
174 | 175 |
175 // We start by creating a DIB which we'll use later on in order to create | 176 // We start by creating a DIB which we'll use later on in order to create |
176 // the HICON. We use BITMAPV5HEADER since the bitmap we are about to convert | 177 // the HICON. We use BITMAPV5HEADER since the bitmap we are about to convert |
177 // may contain an alpha channel and the V5 header allows us to specify the | 178 // may contain an alpha channel and the V5 header allows us to specify the |
178 // alpha mask for the DIB. | 179 // alpha mask for the DIB. |
179 BITMAPV5HEADER bitmap_header; | 180 BITMAPV5HEADER bitmap_header; |
180 InitializeBitmapHeader(&bitmap_header, bitmap.width(), bitmap.height()); | 181 InitializeBitmapHeader(&bitmap_header, bitmap.width(), bitmap.height()); |
181 | 182 |
182 void* bits = NULL; | 183 void* bits = NULL; |
183 HBITMAP dib; | 184 HBITMAP dib; |
184 | 185 |
185 { | 186 { |
186 base::win::ScopedGetDC hdc(NULL); | 187 base::win::ScopedGetDC hdc(NULL); |
187 dib = ::CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO*>(&bitmap_header), | 188 dib = ::CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO*>(&bitmap_header), |
188 DIB_RGB_COLORS, &bits, NULL, 0); | 189 DIB_RGB_COLORS, &bits, NULL, 0); |
189 } | 190 } |
190 if (!dib || !bits) | 191 if (!dib || !bits) |
191 return NULL; | 192 return base::win::ScopedHICON(); |
192 | 193 |
193 memcpy(bits, bitmap.getPixels(), bitmap.width() * bitmap.height() * 4); | 194 memcpy(bits, bitmap.getPixels(), bitmap.width() * bitmap.height() * 4); |
194 | 195 |
195 // Icons are generally created using an AND and XOR masks where the AND | 196 // Icons are generally created using an AND and XOR masks where the AND |
196 // specifies boolean transparency (the pixel is either opaque or | 197 // specifies boolean transparency (the pixel is either opaque or |
197 // transparent) and the XOR mask contains the actual image pixels. If the XOR | 198 // transparent) and the XOR mask contains the actual image pixels. If the XOR |
198 // mask bitmap has an alpha channel, the AND monochrome bitmap won't | 199 // mask bitmap has an alpha channel, the AND monochrome bitmap won't |
199 // actually be used for computing the pixel transparency. Even though all our | 200 // actually be used for computing the pixel transparency. Even though all our |
200 // bitmap has an alpha channel, Windows might not agree when all alpha values | 201 // bitmap has an alpha channel, Windows might not agree when all alpha values |
201 // are zero. So the monochrome bitmap is created with all pixels transparent | 202 // are zero. So the monochrome bitmap is created with all pixels transparent |
(...skipping 18 matching lines...) Expand all Loading... | |
220 HBITMAP mono_bitmap = ::CreateBitmap(bitmap.width(), bitmap.height(), 1, 1, | 221 HBITMAP mono_bitmap = ::CreateBitmap(bitmap.width(), bitmap.height(), 1, 1, |
221 reinterpret_cast<LPVOID>(mask_bits.get())); | 222 reinterpret_cast<LPVOID>(mask_bits.get())); |
222 DCHECK(mono_bitmap); | 223 DCHECK(mono_bitmap); |
223 | 224 |
224 ICONINFO icon_info; | 225 ICONINFO icon_info; |
225 icon_info.fIcon = TRUE; | 226 icon_info.fIcon = TRUE; |
226 icon_info.xHotspot = 0; | 227 icon_info.xHotspot = 0; |
227 icon_info.yHotspot = 0; | 228 icon_info.yHotspot = 0; |
228 icon_info.hbmMask = mono_bitmap; | 229 icon_info.hbmMask = mono_bitmap; |
229 icon_info.hbmColor = dib; | 230 icon_info.hbmColor = dib; |
230 HICON icon = ::CreateIconIndirect(&icon_info); | 231 base::win::ScopedHICON icon(CreateIconIndirect(&icon_info)); |
231 ::DeleteObject(dib); | 232 ::DeleteObject(dib); |
232 ::DeleteObject(mono_bitmap); | 233 ::DeleteObject(mono_bitmap); |
233 return icon; | 234 return icon.Pass(); |
234 } | 235 } |
235 | 236 |
236 SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon, const gfx::Size& s) { | 237 SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon, const gfx::Size& s) { |
237 // We start with validating parameters. | 238 // We start with validating parameters. |
238 if (!icon || s.IsEmpty()) | 239 if (!icon || s.IsEmpty()) |
239 return NULL; | 240 return NULL; |
240 ScopedICONINFO icon_info; | 241 ScopedICONINFO icon_info; |
241 if (!::GetIconInfo(icon, &icon_info)) | 242 if (!::GetIconInfo(icon, &icon_info)) |
242 return NULL; | 243 return NULL; |
243 if (!icon_info.fIcon) | 244 if (!icon_info.fIcon) |
244 return NULL; | 245 return NULL; |
245 return new SkBitmap(CreateSkBitmapFromHICONHelper(icon, s)); | 246 return new SkBitmap(CreateSkBitmapFromHICONHelper(icon, s)); |
246 } | 247 } |
247 | 248 |
248 scoped_ptr<SkBitmap> IconUtil::CreateSkBitmapFromIconResource(HMODULE module, | 249 scoped_ptr<SkBitmap> IconUtil::CreateSkBitmapFromIconResource(HMODULE module, |
249 int resource_id, | 250 int resource_id, |
250 int size) { | 251 int size) { |
251 DCHECK_LE(size, kLargeIconSize); | 252 DCHECK_LE(size, kLargeIconSize); |
252 | 253 |
253 // For everything except the Vista+ 256x256 icons, use |LoadImage()|. | 254 // For everything except the Vista+ 256x256 icons, use |LoadImage()|. |
254 if (size != kLargeIconSize) { | 255 if (size != kLargeIconSize) { |
255 HICON icon_handle = | 256 base::win::ScopedHICON icon( |
256 static_cast<HICON>(LoadImage(module, MAKEINTRESOURCE(resource_id), | 257 static_cast<HICON>(LoadImage(module, MAKEINTRESOURCE(resource_id), |
257 IMAGE_ICON, size, size, | 258 IMAGE_ICON, size, size, |
258 LR_DEFAULTCOLOR | LR_DEFAULTSIZE)); | 259 LR_DEFAULTCOLOR | LR_DEFAULTSIZE))); |
259 scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON(icon_handle)); | 260 scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON(icon.get())); |
grt (UTC plus 2)
2015/11/10 16:44:43
return make_scoped_ptr(CreateSkBitmapFromHICON(ico
| |
260 DestroyIcon(icon_handle); | |
261 return bitmap.Pass(); | 261 return bitmap.Pass(); |
262 } | 262 } |
263 | 263 |
264 // For Vista+ 256x256 PNG icons, read the resource directly and find | 264 // For Vista+ 256x256 PNG icons, read the resource directly and find |
265 // the corresponding icon entry to get its PNG bytes. | 265 // the corresponding icon entry to get its PNG bytes. |
266 void* icon_dir_data = NULL; | 266 void* icon_dir_data = NULL; |
267 size_t icon_dir_size = 0; | 267 size_t icon_dir_size = 0; |
268 if (!base::win::GetResourceFromModule(module, resource_id, RT_GROUP_ICON, | 268 if (!base::win::GetResourceFromModule(module, resource_id, RT_GROUP_ICON, |
269 &icon_dir_data, &icon_dir_size)) { | 269 &icon_dir_data, &icon_dir_size)) { |
270 return nullptr; | 270 return nullptr; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 if (!::GetIconInfo(icon, &icon_info)) | 312 if (!::GetIconInfo(icon, &icon_info)) |
313 return NULL; | 313 return NULL; |
314 | 314 |
315 if (!::GetObject(icon_info.hbmMask, sizeof(bitmap_info), &bitmap_info)) | 315 if (!::GetObject(icon_info.hbmMask, sizeof(bitmap_info), &bitmap_info)) |
316 return NULL; | 316 return NULL; |
317 | 317 |
318 gfx::Size icon_size(bitmap_info.bmWidth, bitmap_info.bmHeight); | 318 gfx::Size icon_size(bitmap_info.bmWidth, bitmap_info.bmHeight); |
319 return new SkBitmap(CreateSkBitmapFromHICONHelper(icon, icon_size)); | 319 return new SkBitmap(CreateSkBitmapFromHICONHelper(icon, icon_size)); |
320 } | 320 } |
321 | 321 |
322 HICON IconUtil::CreateCursorFromDIB(const gfx::Size& icon_size, | 322 base::win::ScopedHICON IconUtil::CreateCursorFromDIB(const gfx::Size& icon_size, |
323 const gfx::Point& hotspot, | 323 const gfx::Point& hotspot, |
324 const void* dib_bits, | 324 const void* dib_bits, |
325 size_t dib_size) { | 325 size_t dib_size) { |
326 BITMAPINFO icon_bitmap_info = {}; | 326 BITMAPINFO icon_bitmap_info = {}; |
327 gfx::CreateBitmapHeader( | 327 gfx::CreateBitmapHeader( |
328 icon_size.width(), | 328 icon_size.width(), |
329 icon_size.height(), | 329 icon_size.height(), |
330 reinterpret_cast<BITMAPINFOHEADER*>(&icon_bitmap_info)); | 330 reinterpret_cast<BITMAPINFOHEADER*>(&icon_bitmap_info)); |
331 | 331 |
332 base::win::ScopedGetDC dc(NULL); | 332 base::win::ScopedGetDC dc(NULL); |
333 base::win::ScopedCreateDC working_dc(CreateCompatibleDC(dc)); | 333 base::win::ScopedCreateDC working_dc(CreateCompatibleDC(dc)); |
334 base::win::ScopedGDIObject<HBITMAP> bitmap_handle( | 334 base::win::ScopedGDIObject<HBITMAP> bitmap_handle( |
335 CreateDIBSection(dc, | 335 CreateDIBSection(dc, |
336 &icon_bitmap_info, | 336 &icon_bitmap_info, |
337 DIB_RGB_COLORS, | 337 DIB_RGB_COLORS, |
338 0, | 338 0, |
339 0, | 339 0, |
340 0)); | 340 0)); |
341 if (dib_size > 0) { | 341 if (dib_size > 0) { |
342 SetDIBits(0, | 342 SetDIBits(0, |
343 bitmap_handle, | 343 bitmap_handle.get(), |
344 0, | 344 0, |
345 icon_size.height(), | 345 icon_size.height(), |
346 dib_bits, | 346 dib_bits, |
347 &icon_bitmap_info, | 347 &icon_bitmap_info, |
348 DIB_RGB_COLORS); | 348 DIB_RGB_COLORS); |
349 } | 349 } |
350 | 350 |
351 HBITMAP old_bitmap = reinterpret_cast<HBITMAP>( | 351 HBITMAP old_bitmap = reinterpret_cast<HBITMAP>( |
352 SelectObject(working_dc.Get(), bitmap_handle)); | 352 SelectObject(working_dc.Get(), bitmap_handle.get())); |
353 SetBkMode(working_dc.Get(), TRANSPARENT); | 353 SetBkMode(working_dc.Get(), TRANSPARENT); |
354 SelectObject(working_dc.Get(), old_bitmap); | 354 SelectObject(working_dc.Get(), old_bitmap); |
355 | 355 |
356 base::win::ScopedGDIObject<HBITMAP> mask( | 356 base::win::ScopedGDIObject<HBITMAP> mask( |
357 CreateBitmap(icon_size.width(), | 357 CreateBitmap(icon_size.width(), |
358 icon_size.height(), | 358 icon_size.height(), |
359 1, | 359 1, |
360 1, | 360 1, |
361 NULL)); | 361 NULL)); |
362 ICONINFO ii = {0}; | 362 ICONINFO ii = {0}; |
363 ii.fIcon = FALSE; | 363 ii.fIcon = FALSE; |
364 ii.xHotspot = hotspot.x(); | 364 ii.xHotspot = hotspot.x(); |
365 ii.yHotspot = hotspot.y(); | 365 ii.yHotspot = hotspot.y(); |
366 ii.hbmMask = mask; | 366 ii.hbmMask = mask.get(); |
367 ii.hbmColor = bitmap_handle; | 367 ii.hbmColor = bitmap_handle.get(); |
368 | 368 |
369 return CreateIconIndirect(&ii); | 369 return base::win::ScopedHICON(CreateIconIndirect(&ii)).Pass(); |
grt (UTC plus 2)
2015/11/10 16:44:43
can you remove .Pass() here?
| |
370 } | 370 } |
371 | 371 |
372 SkBitmap IconUtil::CreateSkBitmapFromHICONHelper(HICON icon, | 372 SkBitmap IconUtil::CreateSkBitmapFromHICONHelper(HICON icon, |
373 const gfx::Size& s) { | 373 const gfx::Size& s) { |
374 DCHECK(icon); | 374 DCHECK(icon); |
375 DCHECK(!s.IsEmpty()); | 375 DCHECK(!s.IsEmpty()); |
376 | 376 |
377 // Allocating memory for the SkBitmap object. We are going to create an ARGB | 377 // Allocating memory for the SkBitmap object. We are going to create an ARGB |
378 // bitmap so we should set the configuration appropriately. | 378 // bitmap so we should set the configuration appropriately. |
379 SkBitmap bitmap; | 379 SkBitmap bitmap; |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
694 // Once we compute the size for a singe AND mask scan line, we multiply that | 694 // Once we compute the size for a singe AND mask scan line, we multiply that |
695 // number by the image height in order to get the total number of bytes for | 695 // number by the image height in order to get the total number of bytes for |
696 // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes | 696 // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes |
697 // for the monochrome bitmap representing the AND mask. | 697 // for the monochrome bitmap representing the AND mask. |
698 size_t and_line_length = (bitmap.width() + 7) >> 3; | 698 size_t and_line_length = (bitmap.width() + 7) >> 3; |
699 and_line_length = (and_line_length + 3) & ~3; | 699 and_line_length = (and_line_length + 3) & ~3; |
700 size_t and_mask_size = and_line_length * bitmap.height(); | 700 size_t and_mask_size = and_line_length * bitmap.height(); |
701 size_t masks_size = *xor_mask_size + and_mask_size; | 701 size_t masks_size = *xor_mask_size + and_mask_size; |
702 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); | 702 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); |
703 } | 703 } |
OLD | NEW |