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 |