1 11 package org.eclipse.swt.internal; 12 13 14 import org.eclipse.swt.internal.win32.*; 15 import org.eclipse.swt.*; 16 import org.eclipse.swt.graphics.*; 17 18 public 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) { 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 public 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 createMaskFromAlpha (ImageData data, int destWidth, int destHeight) { 247 int srcWidth = data.width; 248 int srcHeight = data.height; 249 ImageData mask = ImageData.internal_new (srcWidth, srcHeight, 1, 250 new PaletteData(new RGB [] {new RGB (0, 0, 0), new RGB (0xff, 0xff, 0xff)}), 251 2, null, 1, null, null, -1, -1, -1, 0, 0, 0, 0); 252 int ap = 0; 253 for (int y = 0; y < mask.height; y++) { 254 for (int x = 0; x < mask.width; x++) { 255 mask.setPixel (x, y, (data.alphaData [ap++] & 0xff) <= 127 ? 1 : 0); 256 } 257 } 258 int hMask = OS.CreateBitmap (srcWidth, srcHeight, 1, 1, mask.data); 259 if (srcWidth != destWidth || srcHeight != destHeight) { 260 int hdc = OS.GetDC (0); 261 int hdc1 = OS.CreateCompatibleDC (hdc); 262 OS.SelectObject (hdc1, hMask); 263 int hdc2 = OS.CreateCompatibleDC (hdc); 264 int hMask2 = OS.CreateBitmap (destWidth, destHeight, 1, 1, null); 265 OS.SelectObject (hdc2, hMask2); 266 if (!OS.IsWinCE) OS.SetStretchBltMode(hdc2, OS.COLORONCOLOR); 267 OS.StretchBlt (hdc2, 0, 0, destWidth, destHeight, hdc1, 0, 0, srcWidth, srcHeight, OS.SRCCOPY); 268 OS.DeleteDC (hdc1); 269 OS.DeleteDC (hdc2); 270 OS.ReleaseDC (0, hdc); 271 OS.DeleteObject(hMask); 272 hMask = hMask2; 273 } 274 return hMask; 275 } 276 277 int createMask (int hBitmap, int destWidth, int destHeight, int background, int transparentPixel) { 278 BITMAP bm = new BITMAP (); 279 OS.GetObject (hBitmap, BITMAP.sizeof, bm); 280 int srcWidth = bm.bmWidth; 281 int srcHeight = bm.bmHeight; 282 int hMask = OS.CreateBitmap (destWidth, destHeight, 1, 1, null); 283 int hDC = OS.GetDC (0); 284 int hdc1 = OS.CreateCompatibleDC (hDC); 285 if (background != -1) { 286 OS.SelectObject (hdc1, hBitmap); 287 288 296 boolean isDib = bm.bmBits != 0; 297 byte[] originalColors = null; 298 if (!OS.IsWinCE && transparentPixel != -1 && isDib && bm.bmBitsPixel <= 8) { 299 int maxColors = 1 << bm.bmBitsPixel; 300 byte[] oldColors = new byte[maxColors * 4]; 301 OS.GetDIBColorTable(hdc1, 0, maxColors, oldColors); 302 int offset = transparentPixel * 4; 303 byte[] newColors = new byte[oldColors.length]; 304 newColors[offset] = (byte)0xFF; 305 newColors[offset+1] = (byte)0xFF; 306 newColors[offset+2] = (byte)0xFF; 307 OS.SetDIBColorTable(hdc1, 0, maxColors, newColors); 308 originalColors = oldColors; 309 OS.SetBkColor (hdc1, 0xFFFFFF); 310 } else { 311 OS.SetBkColor (hdc1, background); 312 } 313 314 int hdc2 = OS.CreateCompatibleDC (hDC); 315 OS.SelectObject (hdc2, hMask); 316 if (destWidth != srcWidth || destHeight != srcHeight) { 317 if (!OS.IsWinCE) OS.SetStretchBltMode (hdc2, OS.COLORONCOLOR); 318 OS.StretchBlt (hdc2, 0, 0, destWidth, destHeight, hdc1, 0, 0, srcWidth, srcHeight, OS.SRCCOPY); 319 } else { 320 OS.BitBlt (hdc2, 0, 0, destWidth, destHeight, hdc1, 0, 0, OS.SRCCOPY); 321 } 322 OS.DeleteDC (hdc2); 323 324 325 if (originalColors != null) OS.SetDIBColorTable(hdc1, 0, 1 << bm.bmBitsPixel, originalColors); 326 } else { 327 int hOldBitmap = OS.SelectObject (hdc1, hMask); 328 OS.PatBlt (hdc1, 0, 0, destWidth, destHeight, OS.BLACKNESS); 329 OS.SelectObject (hdc1, hOldBitmap); 330 } 331 OS.ReleaseDC (0, hDC); 332 OS.DeleteDC (hdc1); 333 return hMask; 334 } 335 336 public void dispose () { 337 if (handle != 0) OS.ImageList_Destroy (handle); 338 handle = 0; 339 images = null; 340 } 341 342 public Image get (int index) { 343 return images [index]; 344 } 345 346 public int getStyle () { 347 return style; 348 } 349 350 public int getHandle () { 351 return handle; 352 } 353 354 public Point getImageSize() { 355 int [] cx = new int [1], cy = new int [1]; 356 OS.ImageList_GetIconSize (handle, cx, cy); 357 return new Point (cx [0], cy [0]); 358 } 359 360 public int indexOf (Image image) { 361 int count = OS.ImageList_GetImageCount (handle); 362 for (int i=0; i<count; i++) { 363 if (images [i] != null) { 364 if (images [i].isDisposed ()) images [i] = null; 365 if (images [i] != null && images [i].equals (image)) return i; 366 } 367 } 368 return -1; 369 } 370 371 public void put (int index, Image image) { 372 int count = OS.ImageList_GetImageCount (handle); 373 if (!(0 <= index && index < count)) return; 374 if (image != null) set(index, image, count); 375 images [index] = image; 376 } 377 378 public void remove (int index) { 379 int count = OS.ImageList_GetImageCount (handle); 380 if (!(0 <= index && index < count)) return; 381 OS.ImageList_Remove (handle, index); 382 System.arraycopy (images, index + 1, images, index, --count - index); 383 images [index] = null; 384 } 385 386 public int removeRef() { 387 return --refCount; 388 } 389 390 void set (int index, Image image, int count) { 391 int hImage = image.handle; 392 int [] cx = new int [1], cy = new int [1]; 393 OS.ImageList_GetIconSize (handle, cx, cy); 394 switch (image.type) { 395 case SWT.BITMAP: { 396 399 int hBitmap = 0, hMask = 0; 400 ImageData data = image.getImageData (); 401 switch (data.getTransparencyType ()) { 402 case SWT.TRANSPARENCY_ALPHA: 403 if (OS.COMCTL32_MAJOR >= 6) { 404 hBitmap = copyWithAlpha (hImage, -1, data.alphaData, cx [0], cy [0]); 405 } else { 406 hBitmap = copyBitmap (hImage, cx [0], cy [0]); 407 hMask = createMaskFromAlpha (data, cx [0], cy [0]); 408 } 409 break; 410 case SWT.TRANSPARENCY_PIXEL: 411 int background = -1; 412 Color color = image.getBackground (); 413 if (color != null) background = color.handle; 414 hBitmap = copyBitmap (hImage, cx [0], cy [0]); 415 hMask = createMask (hImage, cx [0], cy [0], background, data.transparentPixel); 416 break; 417 case SWT.TRANSPARENCY_NONE: 418 default: 419 hBitmap = copyBitmap (hImage, cx [0], cy [0]); 420 if (index != count) hMask = createMask (hImage, cx [0], cy [0], -1, -1); 421 break; 422 } 423 if (index == count) { 424 OS.ImageList_Add (handle, hBitmap, hMask); 425 } else { 426 427 OS.ImageList_Replace (handle, index, hBitmap, hMask); 428 } 429 if (hMask != 0) OS.DeleteObject (hMask); 430 if (hBitmap != hImage) OS.DeleteObject (hBitmap); 431 break; 432 } 433 case SWT.ICON: { 434 if (OS.IsWinCE) { 435 OS.ImageList_ReplaceIcon (handle, index == count ? -1 : index, hImage); 436 } else { 437 int hIcon = copyIcon (hImage, cx [0], cy [0]); 438 OS.ImageList_ReplaceIcon (handle, index == count ? -1 : index, hIcon); 439 OS.DestroyIcon (hIcon); 440 } 441 break; 442 } 443 } 444 } 445 446 public int size () { 447 int result = 0; 448 int count = OS.ImageList_GetImageCount (handle); 449 for (int i=0; i<count; i++) { 450 if (images [i] != null) { 451 if (images [i].isDisposed ()) images [i] = null; 452 if (images [i] != null) result++; 453 } 454 } 455 return result; 456 } 457 458 } 459 | Popular Tags |