1 11 package org.eclipse.swt.widgets; 12 13 14 import org.eclipse.swt.internal.win32.*; 15 import org.eclipse.swt.*; 16 import org.eclipse.swt.graphics.*; 17 18 class ImageList { 19 int handle, style, refCount; 20 Image [] images; 21 22 public ImageList (int style) { 23 this.style = style; 24 int flags = OS.ILC_MASK; 25 if (OS.IsWinCE) { 26 flags |= OS.ILC_COLOR; 27 } else { 28 if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { 29 flags |= OS.ILC_COLOR32; 30 } else { 31 int hDC = OS.GetDC (0); 32 int bits = OS.GetDeviceCaps (hDC, OS.BITSPIXEL); 33 int planes = OS.GetDeviceCaps (hDC, OS.PLANES); 34 OS.ReleaseDC (0, hDC); 35 int depth = bits * planes; 36 switch (depth) { 37 case 4: flags |= OS.ILC_COLOR4; break; 38 case 8: flags |= OS.ILC_COLOR8; break; 39 case 16: flags |= OS.ILC_COLOR16; break; 40 case 24: flags |= OS.ILC_COLOR24; break; 41 case 32: flags |= OS.ILC_COLOR32; break; 42 default: flags |= OS.ILC_COLOR; break; 43 } 44 } 45 } 46 if ((style & SWT.RIGHT_TO_LEFT) != 0) flags |= OS.ILC_MIRROR; 47 handle = OS.ImageList_Create (32, 32, flags, 16, 16); 48 images = new Image [4]; 49 } 50 51 public int add (Image image) { 52 int count = OS.ImageList_GetImageCount (handle); 53 int index = 0; 54 while (index < count) { 55 if (images [index] != null) { 56 if (images [index].isDisposed ()) images [index] = null; 57 } 58 if (images [index] == null) break; 59 index++; 60 } 61 if (count == 0) { 62 Rectangle rect = image.getBounds (); 63 OS.ImageList_SetIconSize (handle, rect.width, rect.height); 64 } 65 set (index, image, count); 66 if (index == images.length) { 67 Image [] newImages = new Image [images.length + 4]; 68 System.arraycopy (images, 0, newImages, 0, images.length); 69 images = newImages; 70 } 71 images [index] = image; 72 return index; 73 } 74 75 int addRef() { 76 return ++refCount; 77 } 78 79 int copyBitmap (int hImage, int width, int height) { 80 BITMAP bm = new BITMAP (); 81 OS.GetObject (hImage, BITMAP.sizeof, bm); 82 int hDC = OS.GetDC (0); 83 int hdc1 = OS.CreateCompatibleDC (hDC); 84 OS.SelectObject (hdc1, hImage); 85 int hdc2 = OS.CreateCompatibleDC (hDC); 86 96 int hBitmap; 97 if (bm.bmBitsPixel == 32 && OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { 98 BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); 99 bmiHeader.biSize = BITMAPINFOHEADER.sizeof; 100 bmiHeader.biWidth = width; 101 bmiHeader.biHeight = -height; 102 bmiHeader.biPlanes = 1; 103 bmiHeader.biBitCount = (short)24; 104 if (OS.IsWinCE) bmiHeader.biCompression = OS.BI_BITFIELDS; 105 else bmiHeader.biCompression = OS.BI_RGB; 106 byte[] bmi = new byte[BITMAPINFOHEADER.sizeof + (OS.IsWinCE ? 12 : 0)]; 107 OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof); 108 109 if (OS.IsWinCE) { 110 int redMask = 0xFF00; 111 int greenMask = 0xFF0000; 112 int blueMask = 0xFF000000; 113 114 int offset = BITMAPINFOHEADER.sizeof; 115 bmi[offset] = (byte)((redMask & 0xFF000000) >> 24); 116 bmi[offset + 1] = (byte)((redMask & 0xFF0000) >> 16); 117 bmi[offset + 2] = (byte)((redMask & 0xFF00) >> 8); 118 bmi[offset + 3] = (byte)((redMask & 0xFF) >> 0); 119 bmi[offset + 4] = (byte)((greenMask & 0xFF000000) >> 24); 120 bmi[offset + 5] = (byte)((greenMask & 0xFF0000) >> 16); 121 bmi[offset + 6] = (byte)((greenMask & 0xFF00) >> 8); 122 bmi[offset + 7] = (byte)((greenMask & 0xFF) >> 0); 123 bmi[offset + 8] = (byte)((blueMask & 0xFF000000) >> 24); 124 bmi[offset + 9] = (byte)((blueMask & 0xFF0000) >> 16); 125 bmi[offset + 10] = (byte)((blueMask & 0xFF00) >> 8); 126 bmi[offset + 11] = (byte)((blueMask & 0xFF) >> 0); 127 } 128 int[] pBits = new int[1]; 129 hBitmap = OS.CreateDIBSection(0, bmi, OS.DIB_RGB_COLORS, pBits, 0, 0); 130 } else { 131 hBitmap = OS.CreateCompatibleBitmap (hDC, width, height); 132 } 133 OS.SelectObject (hdc2, hBitmap); 134 if (width != bm.bmWidth || height != bm.bmHeight) { 135 if (!OS.IsWinCE) OS.SetStretchBltMode(hdc2, OS.COLORONCOLOR); 136 OS.StretchBlt (hdc2, 0, 0, width, height, hdc1, 0, 0, bm.bmWidth, bm.bmHeight, OS.SRCCOPY); 137 } else { 138 OS.BitBlt (hdc2, 0, 0, width, height, hdc1, 0, 0, OS.SRCCOPY); 139 } 140 OS.DeleteDC (hdc1); 141 OS.DeleteDC (hdc2); 142 OS.ReleaseDC (0, hDC); 143 return hBitmap; 144 } 145 146 int copyIcon (int hImage, int width, int height) { 147 if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); 148 int hIcon = OS.CopyImage (hImage, OS.IMAGE_ICON, width, height, 0); 149 return hIcon != 0 ? hIcon : hImage; 150 } 151 152 int copyWithAlpha (int hBitmap, int background, byte[] alphaData, int destWidth, int destHeight) { 153 BITMAP bm = new BITMAP (); 154 OS.GetObject (hBitmap, BITMAP.sizeof, bm); 155 int srcWidth = bm.bmWidth; 156 int srcHeight = bm.bmHeight; 157 158 159 int hdc = OS.GetDC (0); 160 int srcHdc = OS.CreateCompatibleDC (hdc); 161 int oldSrcBitmap = OS.SelectObject (srcHdc, hBitmap); 162 int memHdc = OS.CreateCompatibleDC (hdc); 163 BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER (); 164 bmiHeader.biSize = BITMAPINFOHEADER.sizeof; 165 bmiHeader.biWidth = srcWidth; 166 bmiHeader.biHeight = -srcHeight; 167 bmiHeader.biPlanes = 1; 168 bmiHeader.biBitCount = 32; 169 bmiHeader.biCompression = OS.BI_RGB; 170 byte [] bmi = new byte[BITMAPINFOHEADER.sizeof]; 171 OS.MoveMemory (bmi, bmiHeader, BITMAPINFOHEADER.sizeof); 172 int [] pBits = new int [1]; 173 int memDib = OS.CreateDIBSection (0, bmi, OS.DIB_RGB_COLORS, pBits, 0, 0); 174 if (memDib == 0) SWT.error (SWT.ERROR_NO_HANDLES); 175 int oldMemBitmap = OS.SelectObject (memHdc, memDib); 176 177 BITMAP dibBM = new BITMAP (); 178 OS.GetObject (memDib, BITMAP.sizeof, dibBM); 179 int sizeInBytes = dibBM.bmWidthBytes * dibBM.bmHeight; 180 181 182 OS.BitBlt (memHdc, 0, 0, srcWidth, srcHeight, srcHdc, 0, 0, OS.SRCCOPY); 183 byte[] srcData = new byte [sizeInBytes]; 184 OS.MoveMemory (srcData, dibBM.bmBits, sizeInBytes); 185 186 187 if (alphaData != null) { 188 int spinc = dibBM.bmWidthBytes - srcWidth * 4; 189 int ap = 0, sp = 3; 190 for (int y = 0; y < srcHeight; ++y) { 191 for (int x = 0; x < srcWidth; ++x) { 192 srcData [sp] = alphaData [ap++]; 193 sp += 4; 194 } 195 sp += spinc; 196 } 197 } else { 198 byte transRed = (byte)(background & 0xFF); 199 byte transGreen = (byte)((background >> 8) & 0xFF); 200 byte transBlue = (byte)((background >> 16) & 0xFF); 201 final int spinc = dibBM.bmWidthBytes - srcWidth * 4; 202 int sp = 3; 203 for (int y = 0; y < srcHeight; ++y) { 204 for (int x = 0; x < srcWidth; ++x) { 205 srcData [sp] = (srcData[sp-1] == transRed && srcData[sp-2] == transGreen && srcData[sp-3] == transBlue) ? 0 : (byte)255; 206 sp += 4; 207 } 208 sp += spinc; 209 } 210 } 211 OS.MoveMemory (dibBM.bmBits, srcData, sizeInBytes); 212 213 214 if (srcWidth != destWidth || srcHeight != destHeight) { 215 BITMAPINFOHEADER bmiHeader2 = new BITMAPINFOHEADER (); 216 bmiHeader2.biSize = BITMAPINFOHEADER.sizeof; 217 bmiHeader2.biWidth = destWidth; 218 bmiHeader2.biHeight = -destHeight; 219 bmiHeader2.biPlanes = 1; 220 bmiHeader2.biBitCount = 32; 221 bmiHeader2.biCompression = OS.BI_RGB; 222 byte [] bmi2 = new byte[BITMAPINFOHEADER.sizeof]; 223 OS.MoveMemory (bmi2, bmiHeader2, BITMAPINFOHEADER.sizeof); 224 int [] pBits2 = new int [1]; 225 int memDib2 = OS.CreateDIBSection (0, bmi2, OS.DIB_RGB_COLORS, pBits2, 0, 0); 226 int memHdc2 = OS.CreateCompatibleDC (hdc); 227 int oldMemBitmap2 = OS.SelectObject (memHdc2, memDib2); 228 if (!OS.IsWinCE) OS.SetStretchBltMode(memHdc2, OS.COLORONCOLOR); 229 OS.StretchBlt (memHdc2, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY); 230 OS.SelectObject (memHdc2, oldMemBitmap2); 231 OS.DeleteDC (memHdc2); 232 OS.SelectObject (memHdc, oldMemBitmap); 233 OS.DeleteDC (memHdc); 234 OS.DeleteObject (memDib); 235 memDib = memDib2; 236 } else { 237 OS.SelectObject (memHdc, oldMemBitmap); 238 OS.DeleteDC (memHdc); 239 } 240 OS.SelectObject (srcHdc, oldSrcBitmap); 241 OS.DeleteDC (srcHdc); 242 OS.ReleaseDC (0, hdc); 243 return memDib; 244 } 245 246 int createMask (int hBitmap, int destWidth, int destHeight, int background, int transparentPixel) { 247 BITMAP bm = new BITMAP (); 248 OS.GetObject (hBitmap, BITMAP.sizeof, bm); 249 int srcWidth = bm.bmWidth; 250 int srcHeight = bm.bmHeight; 251 int hMask = OS.CreateBitmap (destWidth, destHeight, 1, 1, null); 252 int hDC = OS.GetDC (0); 253 int hdc1 = OS.CreateCompatibleDC (hDC); 254 if (background != -1) { 255 OS.SelectObject (hdc1, hBitmap); 256 257 265 boolean isDib = bm.bmBits != 0; 266 byte[] originalColors = null; 267 if (!OS.IsWinCE && transparentPixel != -1 && isDib && bm.bmBitsPixel <= 8) { 268 int maxColors = 1 << bm.bmBitsPixel; 269 byte[] oldColors = new byte[maxColors * 4]; 270 OS.GetDIBColorTable(hdc1, 0, maxColors, oldColors); 271 int offset = transparentPixel * 4; 272 byte[] newColors = new byte[oldColors.length]; 273 newColors[offset] = (byte)0xFF; 274 newColors[offset+1] = (byte)0xFF; 275 newColors[offset+2] = (byte)0xFF; 276 OS.SetDIBColorTable(hdc1, 0, maxColors, newColors); 277 originalColors = oldColors; 278 OS.SetBkColor (hdc1, 0xFFFFFF); 279 } else { 280 OS.SetBkColor (hdc1, background); 281 } 282 283 int hdc2 = OS.CreateCompatibleDC (hDC); 284 OS.SelectObject (hdc2, hMask); 285 if (destWidth != srcWidth || destHeight != srcHeight) { 286 if (!OS.IsWinCE) OS.SetStretchBltMode (hdc2, OS.COLORONCOLOR); 287 OS.StretchBlt (hdc2, 0, 0, destWidth, destHeight, hdc1, 0, 0, srcWidth, srcHeight, OS.SRCCOPY); 288 } else { 289 OS.BitBlt (hdc2, 0, 0, destWidth, destHeight, hdc1, 0, 0, OS.SRCCOPY); 290 } 291 OS.DeleteDC (hdc2); 292 293 294 if (originalColors != null) OS.SetDIBColorTable(hdc1, 0, 1 << bm.bmBitsPixel, originalColors); 295 } else { 296 int hOldBitmap = OS.SelectObject (hdc1, hMask); 297 OS.PatBlt (hdc1, 0, 0, destWidth, destHeight, OS.BLACKNESS); 298 OS.SelectObject (hdc1, hOldBitmap); 299 } 300 OS.ReleaseDC (0, hDC); 301 OS.DeleteDC (hdc1); 302 return hMask; 303 } 304 305 public void dispose () { 306 if (handle != 0) OS.ImageList_Destroy (handle); 307 handle = 0; 308 images = null; 309 } 310 311 public Image get (int index) { 312 return images [index]; 313 } 314 315 public int getStyle () { 316 return style; 317 } 318 319 public int getHandle () { 320 return handle; 321 } 322 323 public Point getImageSize() { 324 int [] cx = new int [1], cy = new int [1]; 325 OS.ImageList_GetIconSize (handle, cx, cy); 326 return new Point (cx [0], cy [0]); 327 } 328 329 public int indexOf (Image image) { 330 int count = OS.ImageList_GetImageCount (handle); 331 for (int i=0; i<count; i++) { 332 if (images [i] != null) { 333 if (images [i].isDisposed ()) images [i] = null; 334 if (images [i] != null && images [i].equals (image)) return i; 335 } 336 } 337 return -1; 338 } 339 340 public void put (int index, Image image) { 341 int count = OS.ImageList_GetImageCount (handle); 342 if (!(0 <= index && index < count)) return; 343 if (image != null) set(index, image, count); 344 images [index] = image; 345 } 346 347 public void remove (int index) { 348 int count = OS.ImageList_GetImageCount (handle); 349 if (!(0 <= index && index < count)) return; 350 OS.ImageList_Remove (handle, index); 351 System.arraycopy (images, index + 1, images, index, --count - index); 352 images [index] = null; 353 } 354 355 int removeRef() { 356 return --refCount; 357 } 358 359 void set (int index, Image image, int count) { 360 int hImage = image.handle; 361 int [] cx = new int [1], cy = new int [1]; 362 OS.ImageList_GetIconSize (handle, cx, cy); 363 switch (image.type) { 364 case SWT.BITMAP: { 365 368 int hBitmap = 0, hMask = 0; 369 ImageData data = image.getImageData (); 370 switch (data.getTransparencyType ()) { 371 case SWT.TRANSPARENCY_ALPHA: 372 if (OS.COMCTL32_MAJOR >= 6) { 373 hBitmap = copyWithAlpha (hImage, -1, data.alphaData, cx [0], cy [0]); 374 } else { 375 hBitmap = copyBitmap (hImage, cx [0], cy [0]); 376 hMask = Display.createMaskFromAlpha (data, cx [0], cy [0]); 377 } 378 break; 379 case SWT.TRANSPARENCY_PIXEL: 380 int background = -1; 381 Color color = image.getBackground (); 382 if (color != null) background = color.handle; 383 hBitmap = copyBitmap (hImage, cx [0], cy [0]); 384 hMask = createMask (hImage, cx [0], cy [0], background, data.transparentPixel); 385 break; 386 case SWT.TRANSPARENCY_NONE: 387 default: 388 hBitmap = copyBitmap (hImage, cx [0], cy [0]); 389 if (index != count) hMask = createMask (hImage, cx [0], cy [0], -1, -1); 390 break; 391 } 392 if (index == count) { 393 OS.ImageList_Add (handle, hBitmap, hMask); 394 } else { 395 396 OS.ImageList_Replace (handle, index, hBitmap, hMask); 397 } 398 if (hMask != 0) OS.DeleteObject (hMask); 399 if (hBitmap != hImage) OS.DeleteObject (hBitmap); 400 break; 401 } 402 case SWT.ICON: { 403 if (OS.IsWinCE) { 404 OS.ImageList_ReplaceIcon (handle, index == count ? -1 : index, hImage); 405 } else { 406 int hIcon = copyIcon (hImage, cx [0], cy [0]); 407 OS.ImageList_ReplaceIcon (handle, index == count ? -1 : index, hIcon); 408 OS.DestroyIcon (hIcon); 409 } 410 break; 411 } 412 } 413 } 414 415 public int size () { 416 int result = 0; 417 int count = OS.ImageList_GetImageCount (handle); 418 for (int i=0; i<count; i++) { 419 if (images [i] != null) { 420 if (images [i].isDisposed ()) images [i] = null; 421 if (images [i] != null) result++; 422 } 423 } 424 return result; 425 } 426 427 } 428 | Popular Tags |