OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef UI_GFX_ICON_UTIL_H_ | |
6 #define UI_GFX_ICON_UTIL_H_ | |
7 | |
8 #include <windows.h> | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/gtest_prod_util.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "ui/gfx/gfx_export.h" | |
16 #include "ui/gfx/point.h" | |
17 #include "ui/gfx/size.h" | |
18 | |
19 namespace base { | |
20 class FilePath; | |
21 } | |
22 | |
23 namespace gfx { | |
24 class ImageFamily; | |
25 class Size; | |
26 } | |
27 class SkBitmap; | |
28 | |
29 /////////////////////////////////////////////////////////////////////////////// | |
30 // | |
31 // The IconUtil class contains helper functions for manipulating Windows icons. | |
32 // The class interface contains methods for converting an HICON handle into an | |
33 // SkBitmap object and vice versa. The class can also create a .ico file given | |
34 // a PNG image contained in an SkBitmap object. The following code snippet | |
35 // shows an example usage of IconUtil::CreateHICONFromSkBitmap(): | |
36 // | |
37 // SkBitmap bitmap; | |
38 // | |
39 // // Fill |bitmap| with valid data | |
40 // bitmap.setConfig(...); | |
41 // bitmap.allocPixels(); | |
42 // | |
43 // ... | |
44 // | |
45 // // Convert the bitmap into a Windows HICON | |
46 // HICON icon = IconUtil::CreateHICONFromSkBitmap(bitmap); | |
47 // if (icon == NULL) { | |
48 // // Handle error | |
49 // ... | |
50 // } | |
51 // | |
52 // // Use the icon with a WM_SETICON message | |
53 // ::SendMessage(hwnd, WM_SETICON, static_cast<WPARAM>(ICON_BIG), | |
54 // reinterpret_cast<LPARAM>(icon)); | |
55 // | |
56 // // Destroy the icon when we are done | |
57 // ::DestroyIcon(icon); | |
58 // | |
59 /////////////////////////////////////////////////////////////////////////////// | |
60 class GFX_EXPORT IconUtil { | |
61 public: | |
62 // The size of the large icon entries in .ico files on Windows Vista+. | |
63 static const int kLargeIconSize = 256; | |
64 // The size of icons in the medium icons view on Windows Vista+. This is the | |
65 // maximum size Windows will display an icon that does not have a 256x256 | |
66 // image, even at the large or extra large icons views. | |
67 static const int kMediumIconSize = 48; | |
68 | |
69 // The dimensions for icon images in Windows icon files. All sizes are square; | |
70 // that is, the value 48 means a 48x48 pixel image. Sizes are listed in | |
71 // ascending order. | |
72 static const int kIconDimensions[]; | |
73 | |
74 // The number of elements in kIconDimensions. | |
75 static const size_t kNumIconDimensions; | |
76 // The number of elements in kIconDimensions <= kMediumIconSize. | |
77 static const size_t kNumIconDimensionsUpToMediumSize; | |
78 | |
79 // Given an SkBitmap object, the function converts the bitmap to a Windows | |
80 // icon and returns the corresponding HICON handle. If the function cannot | |
81 // convert the bitmap, NULL is returned. | |
82 // | |
83 // The client is responsible for destroying the icon when it is no longer | |
84 // needed by calling ::DestroyIcon(). | |
85 static HICON CreateHICONFromSkBitmap(const SkBitmap& bitmap); | |
86 | |
87 // Given a valid HICON handle representing an icon, this function converts | |
88 // the icon into an SkBitmap object containing an ARGB bitmap using the | |
89 // dimensions specified in |s|. |s| must specify valid dimensions (both | |
90 // width() an height() must be greater than zero). If the function cannot | |
91 // convert the icon to a bitmap (most probably due to an invalid parameter), | |
92 // the return value is NULL. | |
93 // | |
94 // The client owns the returned bitmap object and is responsible for deleting | |
95 // it when it is no longer needed. | |
96 static SkBitmap* CreateSkBitmapFromHICON(HICON icon, const gfx::Size& s); | |
97 | |
98 // Loads an icon resource as a SkBitmap for the specified |size| from a | |
99 // loaded .dll or .exe |module|. Supports loading smaller icon sizes as well | |
100 // as the Vista+ 256x256 PNG icon size. If the icon could not be loaded or | |
101 // found, returns a NULL scoped_ptr. | |
102 static scoped_ptr<SkBitmap> CreateSkBitmapFromIconResource(HMODULE module, | |
103 int resource_id, | |
104 int size); | |
105 | |
106 // Given a valid HICON handle representing an icon, this function converts | |
107 // the icon into an SkBitmap object containing an ARGB bitmap using the | |
108 // dimensions of HICON. If the function cannot convert the icon to a bitmap | |
109 // (most probably due to an invalid parameter), the return value is NULL. | |
110 // | |
111 // The client owns the returned bitmap object and is responsible for deleting | |
112 // it when it is no longer needed. | |
113 static SkBitmap* CreateSkBitmapFromHICON(HICON icon); | |
114 | |
115 // Creates Windows .ico file at |icon_path|. The icon file is created with | |
116 // multiple BMP representations at varying predefined dimensions (by resizing | |
117 // an appropriately sized image from |image_family|) because Windows uses | |
118 // different image sizes when loading icons, depending on where the icon is | |
119 // drawn (ALT+TAB window, desktop shortcut, Quick Launch, etc.). | |
120 // | |
121 // If |image_family| contains an image larger than 48x48, the resulting icon | |
122 // will contain all sizes up to 256x256. The 256x256 image will be stored in | |
123 // PNG format inside the .ico file. If not, the resulting icon will contain | |
124 // all sizes up to 48x48. | |
125 // | |
126 // The function returns true on success and false otherwise. Returns false if | |
127 // |image_family| is empty. | |
128 static bool CreateIconFileFromImageFamily( | |
129 const gfx::ImageFamily& image_family, | |
130 const base::FilePath& icon_path); | |
131 | |
132 // Creates a cursor of the specified size from the DIB passed in. | |
133 // Returns the cursor on success or NULL on failure. | |
134 static HICON CreateCursorFromDIB(const gfx::Size& icon_size, | |
135 const gfx::Point& hotspot, | |
136 const void* dib_bits, | |
137 size_t dib_size); | |
138 | |
139 private: | |
140 // The icon format is published in the MSDN but there is no definition of | |
141 // the icon file structures in any of the Windows header files so we need to | |
142 // define these structure within the class. We must make sure we use 2 byte | |
143 // packing so that the structures are layed out properly within the file. | |
144 // See: http://msdn.microsoft.com/en-us/library/ms997538.aspx | |
145 #pragma pack(push) | |
146 #pragma pack(2) | |
147 | |
148 // ICONDIRENTRY contains meta data for an individual icon image within a | |
149 // .ico file. | |
150 struct ICONDIRENTRY { | |
151 BYTE bWidth; | |
152 BYTE bHeight; | |
153 BYTE bColorCount; | |
154 BYTE bReserved; | |
155 WORD wPlanes; | |
156 WORD wBitCount; | |
157 DWORD dwBytesInRes; | |
158 DWORD dwImageOffset; | |
159 }; | |
160 | |
161 // ICONDIR Contains information about all the icon images contained within a | |
162 // single .ico file. | |
163 struct ICONDIR { | |
164 WORD idReserved; | |
165 WORD idType; | |
166 WORD idCount; | |
167 ICONDIRENTRY idEntries[1]; | |
168 }; | |
169 | |
170 // GRPICONDIRENTRY contains meta data for an individual icon image within a | |
171 // RT_GROUP_ICON resource in an .exe or .dll. | |
172 struct GRPICONDIRENTRY { | |
173 BYTE bWidth; | |
174 BYTE bHeight; | |
175 BYTE bColorCount; | |
176 BYTE bReserved; | |
177 WORD wPlanes; | |
178 WORD wBitCount; | |
179 DWORD dwBytesInRes; | |
180 WORD nID; | |
181 }; | |
182 | |
183 // GRPICONDIR Contains information about all the icon images contained within | |
184 // a RT_GROUP_ICON resource in an .exe or .dll. | |
185 struct GRPICONDIR { | |
186 WORD idReserved; | |
187 WORD idType; | |
188 WORD idCount; | |
189 GRPICONDIRENTRY idEntries[1]; | |
190 }; | |
191 | |
192 // Contains the actual icon image. | |
193 struct ICONIMAGE { | |
194 BITMAPINFOHEADER icHeader; | |
195 RGBQUAD icColors[1]; | |
196 BYTE icXOR[1]; | |
197 BYTE icAND[1]; | |
198 }; | |
199 #pragma pack(pop) | |
200 | |
201 friend class IconUtilTest; | |
202 | |
203 // Used for indicating that the .ico contains an icon (rather than a cursor) | |
204 // image. This value is set in the |idType| field of the ICONDIR structure. | |
205 static const int kResourceTypeIcon = 1; | |
206 | |
207 // Returns true if any pixel in the given pixels buffer has an non-zero alpha. | |
208 static bool PixelsHaveAlpha(const uint32* pixels, size_t num_pixels); | |
209 | |
210 // A helper function that initializes a BITMAPV5HEADER structure with a set | |
211 // of values. | |
212 static void InitializeBitmapHeader(BITMAPV5HEADER* header, int width, | |
213 int height); | |
214 | |
215 // Given a single SkBitmap object and pointers to the corresponding icon | |
216 // structures within the icon data buffer, this function sets the image | |
217 // information (dimensions, color depth, etc.) in the icon structures and | |
218 // also copies the underlying icon image into the appropriate location. | |
219 // The width and height of |bitmap| must be < 256. | |
220 // (Note that the 256x256 icon is treated specially, as a PNG, and should not | |
221 // use this method.) | |
222 // | |
223 // The function will set the data pointed to by |image_byte_count| with the | |
224 // number of image bytes written to the buffer. Note that the number of bytes | |
225 // includes only the image data written into the memory pointed to by | |
226 // |icon_image|. | |
227 static void SetSingleIconImageInformation(const SkBitmap& bitmap, | |
228 size_t index, | |
229 ICONDIR* icon_dir, | |
230 ICONIMAGE* icon_image, | |
231 size_t image_offset, | |
232 size_t* image_byte_count); | |
233 | |
234 // Copies the bits of an SkBitmap object into a buffer holding the bits of | |
235 // the corresponding image for an icon within the .ico file. | |
236 static void CopySkBitmapBitsIntoIconBuffer(const SkBitmap& bitmap, | |
237 unsigned char* buffer, | |
238 size_t buffer_size); | |
239 | |
240 // Given a set of bitmaps with varying dimensions, this function computes | |
241 // the amount of memory needed in order to store the bitmaps as image icons | |
242 // in a .ico file. | |
243 static size_t ComputeIconFileBufferSize(const std::vector<SkBitmap>& set); | |
244 | |
245 // A helper function for computing various size components of a given bitmap. | |
246 // The different sizes can be used within the various .ico file structures. | |
247 // | |
248 // |xor_mask_size| - the size, in bytes, of the XOR mask in the ICONIMAGE | |
249 // structure. | |
250 // |and_mask_size| - the size, in bytes, of the AND mask in the ICONIMAGE | |
251 // structure. | |
252 // |bytes_in_resource| - the total number of bytes set in the ICONIMAGE | |
253 // structure. This value is equal to the sum of the | |
254 // bytes in the AND mask and the XOR mask plus the size | |
255 // of the BITMAPINFOHEADER structure. Note that since | |
256 // only 32bpp are handled by the IconUtil class, the | |
257 // icColors field in the ICONIMAGE structure is ignored | |
258 // and is not accounted for when computing the | |
259 // different size components. | |
260 static void ComputeBitmapSizeComponents(const SkBitmap& bitmap, | |
261 size_t* xor_mask_size, | |
262 size_t* bytes_in_resource); | |
263 | |
264 // A helper function of CreateSkBitmapFromHICON. | |
265 static SkBitmap CreateSkBitmapFromHICONHelper(HICON icon, | |
266 const gfx::Size& s); | |
267 | |
268 // Prevent clients from instantiating objects of that class by declaring the | |
269 // ctor/dtor as private. | |
270 DISALLOW_IMPLICIT_CONSTRUCTORS(IconUtil); | |
271 }; | |
272 | |
273 #endif // UI_GFX_ICON_UTIL_H_ | |
OLD | NEW |