| 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 <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/files/important_file_writer.h" | 10 #include "base/files/important_file_writer.h" |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 // All images should have one of the kIconDimensions sizes. | 112 // All images should have one of the kIconDimensions sizes. |
| 113 DCHECK_GT(image.Width(), 0); | 113 DCHECK_GT(image.Width(), 0); |
| 114 DCHECK_LE(image.Width(), IconUtil::kLargeIconSize); | 114 DCHECK_LE(image.Width(), IconUtil::kLargeIconSize); |
| 115 DCHECK_GT(image.Height(), 0); | 115 DCHECK_GT(image.Height(), 0); |
| 116 DCHECK_LE(image.Height(), IconUtil::kLargeIconSize); | 116 DCHECK_LE(image.Height(), IconUtil::kLargeIconSize); |
| 117 | 117 |
| 118 SkBitmap bitmap = image.AsBitmap(); | 118 SkBitmap bitmap = image.AsBitmap(); |
| 119 | 119 |
| 120 // Only 32 bit ARGB bitmaps are supported. We also make sure the bitmap has | 120 // Only 32 bit ARGB bitmaps are supported. We also make sure the bitmap has |
| 121 // been properly initialized. | 121 // been properly initialized. |
| 122 SkAutoLockPixels bitmap_lock(bitmap); | |
| 123 if ((bitmap.colorType() != kN32_SkColorType) || | 122 if ((bitmap.colorType() != kN32_SkColorType) || |
| 124 (bitmap.getPixels() == NULL)) { | 123 (bitmap.getPixels() == NULL)) { |
| 125 return false; | 124 return false; |
| 126 } | 125 } |
| 127 | 126 |
| 128 // Special case: Icons exactly 256x256 are stored in PNG format. | 127 // Special case: Icons exactly 256x256 are stored in PNG format. |
| 129 if (image.Width() == IconUtil::kLargeIconSize && | 128 if (image.Width() == IconUtil::kLargeIconSize && |
| 130 image.Height() == IconUtil::kLargeIconSize) { | 129 image.Height() == IconUtil::kLargeIconSize) { |
| 131 *png_bytes = image.As1xPNGBytes(); | 130 *png_bytes = image.As1xPNGBytes(); |
| 132 } else { | 131 } else { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 160 256 // Used by Vista onwards for large icons. | 159 256 // Used by Vista onwards for large icons. |
| 161 }; | 160 }; |
| 162 | 161 |
| 163 const size_t IconUtil::kNumIconDimensions = arraysize(kIconDimensions); | 162 const size_t IconUtil::kNumIconDimensions = arraysize(kIconDimensions); |
| 164 const size_t IconUtil::kNumIconDimensionsUpToMediumSize = 9; | 163 const size_t IconUtil::kNumIconDimensionsUpToMediumSize = 9; |
| 165 | 164 |
| 166 base::win::ScopedHICON IconUtil::CreateHICONFromSkBitmap( | 165 base::win::ScopedHICON IconUtil::CreateHICONFromSkBitmap( |
| 167 const SkBitmap& bitmap) { | 166 const SkBitmap& bitmap) { |
| 168 // Only 32 bit ARGB bitmaps are supported. We also try to perform as many | 167 // Only 32 bit ARGB bitmaps are supported. We also try to perform as many |
| 169 // validations as we can on the bitmap. | 168 // validations as we can on the bitmap. |
| 170 SkAutoLockPixels bitmap_lock(bitmap); | |
| 171 if ((bitmap.colorType() != kN32_SkColorType) || | 169 if ((bitmap.colorType() != kN32_SkColorType) || |
| 172 (bitmap.width() <= 0) || (bitmap.height() <= 0) || | 170 (bitmap.width() <= 0) || (bitmap.height() <= 0) || |
| 173 (bitmap.getPixels() == NULL)) | 171 (bitmap.getPixels() == NULL)) |
| 174 return base::win::ScopedHICON(); | 172 return base::win::ScopedHICON(); |
| 175 | 173 |
| 176 // We start by creating a DIB which we'll use later on in order to create | 174 // We start by creating a DIB which we'll use later on in order to create |
| 177 // the HICON. We use BITMAPV5HEADER since the bitmap we are about to convert | 175 // the HICON. We use BITMAPV5HEADER since the bitmap we are about to convert |
| 178 // may contain an alpha channel and the V5 header allows us to specify the | 176 // may contain an alpha channel and the V5 header allows us to specify the |
| 179 // alpha mask for the DIB. | 177 // alpha mask for the DIB. |
| 180 BITMAPV5HEADER bitmap_header; | 178 BITMAPV5HEADER bitmap_header; |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 SkBitmap IconUtil::CreateSkBitmapFromHICONHelper(HICON icon, | 378 SkBitmap IconUtil::CreateSkBitmapFromHICONHelper(HICON icon, |
| 381 const gfx::Size& s) { | 379 const gfx::Size& s) { |
| 382 DCHECK(icon); | 380 DCHECK(icon); |
| 383 DCHECK(!s.IsEmpty()); | 381 DCHECK(!s.IsEmpty()); |
| 384 | 382 |
| 385 // Allocating memory for the SkBitmap object. We are going to create an ARGB | 383 // Allocating memory for the SkBitmap object. We are going to create an ARGB |
| 386 // bitmap so we should set the configuration appropriately. | 384 // bitmap so we should set the configuration appropriately. |
| 387 SkBitmap bitmap; | 385 SkBitmap bitmap; |
| 388 bitmap.allocN32Pixels(s.width(), s.height()); | 386 bitmap.allocN32Pixels(s.width(), s.height()); |
| 389 bitmap.eraseARGB(0, 0, 0, 0); | 387 bitmap.eraseARGB(0, 0, 0, 0); |
| 390 SkAutoLockPixels bitmap_lock(bitmap); | |
| 391 | 388 |
| 392 // Now we should create a DIB so that we can use ::DrawIconEx in order to | 389 // Now we should create a DIB so that we can use ::DrawIconEx in order to |
| 393 // obtain the icon's image. | 390 // obtain the icon's image. |
| 394 BITMAPV5HEADER h; | 391 BITMAPV5HEADER h; |
| 395 InitializeBitmapHeader(&h, s.width(), s.height()); | 392 InitializeBitmapHeader(&h, s.width(), s.height()); |
| 396 HDC hdc = ::GetDC(NULL); | 393 HDC hdc = ::GetDC(NULL); |
| 397 uint32_t* bits; | 394 uint32_t* bits; |
| 398 HBITMAP dib = ::CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO*>(&h), | 395 HBITMAP dib = ::CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO*>(&h), |
| 399 DIB_RGB_COLORS, reinterpret_cast<void**>(&bits), NULL, 0); | 396 DIB_RGB_COLORS, reinterpret_cast<void**>(&bits), NULL, 0); |
| 400 DCHECK(dib); | 397 DCHECK(dib); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 // opaque. | 630 // opaque. |
| 634 unsigned char* image_addr = reinterpret_cast<unsigned char*>(icon_image); | 631 unsigned char* image_addr = reinterpret_cast<unsigned char*>(icon_image); |
| 635 unsigned char* xor_mask_addr = image_addr + sizeof(BITMAPINFOHEADER); | 632 unsigned char* xor_mask_addr = image_addr + sizeof(BITMAPINFOHEADER); |
| 636 CopySkBitmapBitsIntoIconBuffer(bitmap, xor_mask_addr, xor_mask_size); | 633 CopySkBitmapBitsIntoIconBuffer(bitmap, xor_mask_addr, xor_mask_size); |
| 637 *image_byte_count = bytes_in_resource; | 634 *image_byte_count = bytes_in_resource; |
| 638 } | 635 } |
| 639 | 636 |
| 640 void IconUtil::CopySkBitmapBitsIntoIconBuffer(const SkBitmap& bitmap, | 637 void IconUtil::CopySkBitmapBitsIntoIconBuffer(const SkBitmap& bitmap, |
| 641 unsigned char* buffer, | 638 unsigned char* buffer, |
| 642 size_t buffer_size) { | 639 size_t buffer_size) { |
| 643 SkAutoLockPixels bitmap_lock(bitmap); | |
| 644 unsigned char* bitmap_ptr = static_cast<unsigned char*>(bitmap.getPixels()); | 640 unsigned char* bitmap_ptr = static_cast<unsigned char*>(bitmap.getPixels()); |
| 645 size_t bitmap_size = bitmap.height() * bitmap.width() * 4; | 641 size_t bitmap_size = bitmap.height() * bitmap.width() * 4; |
| 646 DCHECK_EQ(buffer_size, bitmap_size); | 642 DCHECK_EQ(buffer_size, bitmap_size); |
| 647 for (size_t i = 0; i < bitmap_size; i += bitmap.width() * 4) { | 643 for (size_t i = 0; i < bitmap_size; i += bitmap.width() * 4) { |
| 648 memcpy(buffer + bitmap_size - bitmap.width() * 4 - i, | 644 memcpy(buffer + bitmap_size - bitmap.width() * 4 - i, |
| 649 bitmap_ptr + i, | 645 bitmap_ptr + i, |
| 650 bitmap.width() * 4); | 646 bitmap.width() * 4); |
| 651 } | 647 } |
| 652 } | 648 } |
| 653 | 649 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 // Once we compute the size for a singe AND mask scan line, we multiply that | 698 // Once we compute the size for a singe AND mask scan line, we multiply that |
| 703 // number by the image height in order to get the total number of bytes for | 699 // number by the image height in order to get the total number of bytes for |
| 704 // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes | 700 // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes |
| 705 // for the monochrome bitmap representing the AND mask. | 701 // for the monochrome bitmap representing the AND mask. |
| 706 size_t and_line_length = (bitmap.width() + 7) >> 3; | 702 size_t and_line_length = (bitmap.width() + 7) >> 3; |
| 707 and_line_length = (and_line_length + 3) & ~3; | 703 and_line_length = (and_line_length + 3) & ~3; |
| 708 size_t and_mask_size = and_line_length * bitmap.height(); | 704 size_t and_mask_size = and_line_length * bitmap.height(); |
| 709 size_t masks_size = *xor_mask_size + and_mask_size; | 705 size_t masks_size = *xor_mask_size + and_mask_size; |
| 710 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); | 706 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); |
| 711 } | 707 } |
| OLD | NEW |