license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 1 | // Copyright (c) 2006-2008 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. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
[email protected] | 1125d80 | 2010-03-13 08:26:32 | [diff] [blame] | 5 | #ifndef GFX_ICON_UTIL_H_ |
| 6 | #define GFX_ICON_UTIL_H_ |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 7 | |
| 8 | #include <windows.h> |
| 9 | #include <string> |
| 10 | #include <vector> |
| 11 | #include "base/basictypes.h" |
| 12 | |
| 13 | namespace gfx { |
| 14 | class Size; |
| 15 | } |
| 16 | class SkBitmap; |
| 17 | |
| 18 | /////////////////////////////////////////////////////////////////////////////// |
| 19 | // |
| 20 | // The IconUtil class contains helper functions for manipulating Windows icons. |
| 21 | // The class interface contains methods for converting an HICON handle into an |
| 22 | // SkBitmap object and vice versa. The class can also create a .ico file given |
| 23 | // a PNG image contained in an SkBitmap object. The following code snippet |
| 24 | // shows an example usage of IconUtil::CreateHICONFromSkBitmap(): |
| 25 | // |
| 26 | // SkBitmap bitmap; |
| 27 | // |
| 28 | // // Fill |bitmap| with valid data |
| 29 | // bitmap.setConfig(...); |
| 30 | // bitmap.allocPixels(); |
| 31 | // |
| 32 | // ... |
| 33 | // |
| 34 | // // Convert the bitmap into a Windows HICON |
| 35 | // HICON icon = IconUtil::CreateHICONFromSkBitmap(bitmap); |
| 36 | // if (icon == NULL) { |
| 37 | // // Handle error |
| 38 | // ... |
| 39 | // } |
| 40 | // |
| 41 | // // Use the icon with a WM_SETICON message |
| 42 | // ::SendMessage(hwnd, WM_SETICON, static_cast<WPARAM>(ICON_BIG), |
| 43 | // reinterpret_cast<LPARAM>(icon)); |
| 44 | // |
| 45 | // // Destroy the icon when we are done |
| 46 | // ::DestroyIcon(icon); |
| 47 | // |
| 48 | /////////////////////////////////////////////////////////////////////////////// |
| 49 | class IconUtil { |
| 50 | public: |
| 51 | // Given an SkBitmap object, the function converts the bitmap to a Windows |
| 52 | // icon and returns the corresponding HICON handle. If the function can not |
| 53 | // convert the bitmap, NULL is returned. |
| 54 | // |
| 55 | // The client is responsible for destroying the icon when it is no longer |
| 56 | // needed by calling ::DestroyIcon(). |
| 57 | static HICON CreateHICONFromSkBitmap(const SkBitmap& bitmap); |
| 58 | |
| 59 | // Given a valid HICON handle representing an icon, this function converts |
| 60 | // the icon into an SkBitmap object containing an ARGB bitmap using the |
| 61 | // dimensions specified in |s|. |s| must specify valid dimensions (both |
| 62 | // width() an height() must be greater than zero). If the function can |
| 63 | // convert the icon to a bitmap (most probably due to an invalid parameter), |
| 64 | // the return value is NULL. |
| 65 | // |
| 66 | // The client owns the returned bitmap object and is responsible for deleting |
| 67 | // it when it is no longer needed. |
| 68 | static SkBitmap* CreateSkBitmapFromHICON(HICON icon, const gfx::Size& s); |
| 69 | |
| 70 | // Given an initialized SkBitmap object and a file name, this function |
| 71 | // creates a .ico file with the given name using the provided bitmap. The |
| 72 | // icon file is created with multiple icon images of varying predefined |
| 73 | // dimensions because Windows uses different image sizes when loading icons, |
| 74 | // depending on where the icon is drawn (ALT+TAB window, desktop shortcut, |
| 75 | // Quick Launch, etc.). |icon_file_name| needs to specify the full path for |
| 76 | // the desired .ico file. |
| 77 | // |
| 78 | // The function returns true on success and false otherwise. |
| 79 | static bool CreateIconFileFromSkBitmap(const SkBitmap& bitmap, |
| 80 | const std::wstring& icon_file_name); |
| 81 | |
| 82 | private: |
| 83 | // The icon format is published in the MSDN but there is no definition of |
| 84 | // the icon file structures in any of the Windows header files so we need to |
| 85 | // define these structure within the class. We must make sure we use 2 byte |
| 86 | // packing so that the structures are layed out properly within the file. |
| 87 | #pragma pack(push) |
| 88 | #pragma pack(2) |
| 89 | |
| 90 | // ICONDIRENTRY contains meta data for an individual icon image within a |
| 91 | // .ico file. |
| 92 | struct ICONDIRENTRY { |
| 93 | BYTE bWidth; |
| 94 | BYTE bHeight; |
| 95 | BYTE bColorCount; |
| 96 | BYTE bReserved; |
| 97 | WORD wPlanes; |
| 98 | WORD wBitCount; |
| 99 | DWORD dwBytesInRes; |
| 100 | DWORD dwImageOffset; |
| 101 | }; |
| 102 | |
| 103 | // ICONDIR Contains information about all the icon images contained within a |
| 104 | // single .ico file. |
| 105 | struct ICONDIR { |
| 106 | WORD idReserved; |
| 107 | WORD idType; |
| 108 | WORD idCount; |
| 109 | ICONDIRENTRY idEntries[1]; |
| 110 | }; |
| 111 | |
| 112 | // Contains the actual icon image. |
| 113 | struct ICONIMAGE { |
| 114 | BITMAPINFOHEADER icHeader; |
| 115 | RGBQUAD icColors[1]; |
| 116 | BYTE icXOR[1]; |
| 117 | BYTE icAND[1]; |
| 118 | }; |
| 119 | #pragma pack(pop) |
| 120 | |
| 121 | // Used for indicating that the .ico contains an icon (rather than a cursor) |
| 122 | // image. This value is set in the |idType| field of the ICONDIR structure. |
| 123 | static const int kResourceTypeIcon = 1; |
| 124 | |
| 125 | // The dimensions of the icon images we insert into the .ico file. |
| 126 | static const int icon_dimensions_[]; |
| 127 | |
| 128 | // Returns how many icon dimensions are defined. |
| 129 | static int GetIconDimensionCount(); |
| 130 | |
[email protected] | 1e625a4 | 2009-11-25 23:04:16 | [diff] [blame] | 131 | // Returns true if any pixel in the given pixels buffer has an non-zero alpha. |
| 132 | static bool PixelsHaveAlpha(const uint32* pixels, size_t num_pixels); |
| 133 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 134 | // A helper function that initializes a BITMAPV5HEADER structure with a set |
| 135 | // of values. |
| 136 | static void InitializeBitmapHeader(BITMAPV5HEADER* header, int width, |
| 137 | int height); |
| 138 | |
| 139 | // Given a single SkBitmap object and pointers to the corresponding icon |
| 140 | // structures within the icon data buffer, this function sets the image |
| 141 | // information (dimensions, color depth, etc.) in the icon structures and |
| 142 | // also copies the underlying icon image into the appropriate location. |
| 143 | // |
| 144 | // The function will set the data pointed to by |image_byte_count| with the |
| 145 | // number of image bytes written to the buffer. Note that the number of bytes |
| 146 | // includes only the image data written into the memory pointed to by |
| 147 | // |icon_image|. |
| 148 | static void SetSingleIconImageInformation(const SkBitmap& bitmap, |
| 149 | int index, |
| 150 | ICONDIR* icon_dir, |
| 151 | ICONIMAGE* icon_image, |
| 152 | int image_offset, |
| 153 | int* image_byte_count); |
| 154 | |
| 155 | // Copies the bits of an SkBitmap object into a buffer holding the bits of |
| 156 | // the corresponding image for an icon within the .ico file. |
| 157 | static void CopySkBitmapBitsIntoIconBuffer(const SkBitmap& bitmap, |
| 158 | unsigned char* buffer, |
| 159 | int buffer_size); |
| 160 | |
| 161 | // Given a single bitmap, this function creates a set of bitmaps with |
| 162 | // specific dimensions by resizing the given bitmap to the appropriate sizes. |
| 163 | static void CreateResizedBitmapSet(const SkBitmap& bitmap_to_resize, |
| 164 | std::vector<SkBitmap>* bitmaps); |
| 165 | |
| 166 | // Given a set of bitmaps with varying dimensions, this function computes |
| 167 | // the amount of memory needed in order to store the bitmaps as image icons |
| 168 | // in a .ico file. |
| 169 | static int ComputeIconFileBufferSize(const std::vector<SkBitmap>& set); |
| 170 | |
| 171 | // A helper function for computing various size components of a given bitmap. |
| 172 | // The different sizes can be used within the various .ico file structures. |
| 173 | // |
| 174 | // |xor_mask_size| - the size, in bytes, of the XOR mask in the ICONIMAGE |
| 175 | // structure. |
| 176 | // |and_mask_size| - the size, in bytes, of the AND mask in the ICONIMAGE |
| 177 | // structure. |
| 178 | // |bytes_in_resource| - the total number of bytes set in the ICONIMAGE |
| 179 | // structure. This value is equal to the sum of the |
| 180 | // bytes in the AND mask and the XOR mask plus the size |
| 181 | // of the BITMAPINFOHEADER structure. Note that since |
| 182 | // only 32bpp are handled by the IconUtil class, the |
| 183 | // icColors field in the ICONIMAGE structure is ignored |
| 184 | // and is not accounted for when computing the |
| 185 | // different size components. |
| 186 | static void ComputeBitmapSizeComponents(const SkBitmap& bitmap, |
| 187 | int* xor_mask_size, |
| 188 | int* and_mask_size, |
| 189 | int* bytes_in_resource); |
| 190 | |
| 191 | // Prevent clients from instantiating objects of that class by declaring the |
| 192 | // ctor/dtor as private. |
| 193 | DISALLOW_IMPLICIT_CONSTRUCTORS(IconUtil); |
| 194 | }; |
| 195 | |
[email protected] | 1125d80 | 2010-03-13 08:26:32 | [diff] [blame] | 196 | #endif // GFX_ICON_UTIL_H_ |