diff options
author | Niraj Modi | 2022-03-21 12:57:32 +0000 |
---|---|---|
committer | Niraj Modi | 2022-03-21 14:34:39 +0000 |
commit | 22797d3f9f09ca67bfd29c864f2aaf8eb452c75c (patch) | |
tree | c3d981556166a5e20c5e215abc45121cc8af41cc | |
parent | 1bb1a46ea5f4e6b22fece451ca6247f8999d3a10 (diff) | |
download | eclipse.platform.swt-22797d3f9f09ca67bfd29c864f2aaf8eb452c75c.tar.gz eclipse.platform.swt-22797d3f9f09ca67bfd29c864f2aaf8eb452c75c.tar.xz eclipse.platform.swt-22797d3f9f09ca67bfd29c864f2aaf8eb452c75c.zip |
Revert "Revert "Bug 493455 - [win32] remove alpha and alphaData from Image""
This reverts commit 7c722277240e346e521b5c97e802e261efcc8883.
Reason for revert: Considering for 4.24 M1
Change-Id: I1a6fc26f96a0ccd82c7aa5994fa134f798e40ef4
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/191861
Tested-by: Niraj Modi <niraj.modi@in.ibm.com>
Reviewed-by: Niraj Modi <niraj.modi@in.ibm.com>
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java | 111 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java | 266 |
2 files changed, 203 insertions, 174 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java index 6311b10dd8..ac2dfafd25 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java @@ -1220,8 +1220,8 @@ void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, data.hNullBitmap = 0; } } - if (srcImage.alpha != -1 || srcImage.alphaData != null) { - drawBitmapAlpha(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, imgWidth, imgHeight); + if (bm.bmPlanes * bm.bmBitsPixel == 32) { + drawBitmapAlpha(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple); } else if (srcImage.transparentPixel != -1) { drawBitmapTransparent(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, bm, imgWidth, imgHeight); } else { @@ -1233,35 +1233,15 @@ void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, } } -void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, int imgWidth, int imgHeight) { - /* Simple cases */ - if (srcImage.alpha == 0) return; - if (srcImage.alpha == 255) { - drawBitmapColor(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple); - return; - } - +void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) { boolean alphaBlendSupport = true; boolean isPrinter = OS.GetDeviceCaps(handle, OS.TECHNOLOGY) == OS.DT_RASPRINTER; + int sourceAlpha = -1; if (isPrinter) { int caps = OS.GetDeviceCaps(handle, OS.SHADEBLENDCAPS); if (caps != 0) { - if (srcImage.alpha != -1) { - alphaBlendSupport = (caps & OS.SB_CONST_ALPHA) != 0; - } else { - alphaBlendSupport = (caps & OS.SB_PIXEL_ALPHA) != 0; - } - } - } - if (alphaBlendSupport) { - BLENDFUNCTION blend = new BLENDFUNCTION(); - blend.BlendOp = OS.AC_SRC_OVER; - long srcHdc = OS.CreateCompatibleDC(handle); - long oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle); - if (srcImage.alpha != -1) { - blend.SourceConstantAlpha = (byte)srcImage.alpha; - OS.AlphaBlend(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, blend); - } else { + long srcHdc = OS.CreateCompatibleDC(handle); + long oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle); long memDib = Image.createDIB(srcWidth, srcHeight, 32); if (memDib == 0) SWT.error(SWT.ERROR_NO_HANDLES); long memHdc = OS.CreateCompatibleDC(handle); @@ -1271,34 +1251,41 @@ void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe OS.BitBlt(memHdc, 0, 0, srcWidth, srcHeight, srcHdc, srcX, srcY, OS.SRCCOPY); byte[] srcData = new byte[dibBM.bmWidthBytes * dibBM.bmHeight]; OS.MoveMemory(srcData, dibBM.bmBits, srcData.length); - final int apinc = imgWidth - srcWidth; - int ap = srcY * imgWidth + srcX, sp = 0; - byte[] alphaData = srcImage.alphaData; - for (int y = 0; y < srcHeight; ++y) { - for (int x = 0; x < srcWidth; ++x) { - int alpha = alphaData[ap++] & 0xff; - int r = ((srcData[sp + 0] & 0xFF) * alpha) + 128; - r = (r + (r >> 8)) >> 8; - int g = ((srcData[sp + 1] & 0xFF) * alpha) + 128; - g = (g + (g >> 8)) >> 8; - int b = ((srcData[sp + 2] & 0xFF) * alpha) + 128; - b = (b + (b >> 8)) >> 8; - srcData[sp+0] = (byte)r; - srcData[sp+1] = (byte)g; - srcData[sp+2] = (byte)b; - srcData[sp+3] = (byte)alpha; - sp += 4; + int size = srcData.length; + sourceAlpha = srcData[3] & 0xFF; + for (int sp = 7; sp < size; sp += 4) { + int currentAlpha = srcData[sp] & 0xFF; + if (sourceAlpha != currentAlpha) { + sourceAlpha = -1; + break; } - ap += apinc; } - OS.MoveMemory(dibBM.bmBits, srcData, srcData.length); - blend.SourceConstantAlpha = (byte)0xff; - blend.AlphaFormat = OS.AC_SRC_ALPHA; - OS.AlphaBlend(handle, destX, destY, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, blend); OS.SelectObject(memHdc, oldMemBitmap); OS.DeleteDC(memHdc); OS.DeleteObject(memDib); + OS.SelectObject(srcHdc, oldSrcBitmap); + OS.DeleteDC(srcHdc); + if (sourceAlpha != -1) { + if (sourceAlpha == 0) return; + if (sourceAlpha == 255) { + drawBitmapColor(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple); + return; + } + alphaBlendSupport = (caps & OS.SB_CONST_ALPHA) != 0; + } + else { + alphaBlendSupport = (caps & OS.SB_PIXEL_ALPHA) != 0; + } } + } + if (alphaBlendSupport) { + BLENDFUNCTION blend = new BLENDFUNCTION(); + blend.BlendOp = OS.AC_SRC_OVER; + long srcHdc = OS.CreateCompatibleDC(handle); + long oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle); + blend.SourceConstantAlpha = (byte)sourceAlpha; + blend.AlphaFormat = OS.AC_SRC_ALPHA; + OS.AlphaBlend(handle, destX, destY, destWidth, destHeight, srcHdc, 0, 0, srcWidth, srcHeight, blend); OS.SelectObject(srcHdc, oldSrcBitmap); OS.DeleteDC(srcHdc); return; @@ -1348,26 +1335,6 @@ void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe byte[] srcData = new byte[sizeInBytes]; OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes); - /* Merge the alpha channel in place */ - int alpha = srcImage.alpha; - final boolean hasAlphaChannel = (srcImage.alpha == -1); - if (hasAlphaChannel) { - final int apinc = imgWidth - srcWidth; - final int spinc = dibBM.bmWidthBytes - srcWidth * 4; - int ap = srcY * imgWidth + srcX, sp = 3; - byte[] alphaData = srcImage.alphaData; - for (int y = 0; y < srcHeight; ++y) { - for (int x = 0; x < srcWidth; ++x) { - srcData[sp] = alphaData[ap++]; - sp += 4; - } - ap += apinc; - sp += spinc; - } - } - - /* Scale the foreground pixels with alpha */ - OS.MoveMemory(dibBM.bmBits, srcData, sizeInBytes); /* * When drawing to a printer, StretchBlt does not correctly stretch if * the source and destination HDCs are the same. The workaround is to @@ -1403,10 +1370,10 @@ void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe int dp = 0; for (int y = 0; y < destHeight; ++y) { for (int x = 0; x < destWidth; ++x) { - if (hasAlphaChannel) alpha = srcData[dp + 3] & 0xff; - destData[dp] += ((srcData[dp] & 0xff) - (destData[dp] & 0xff)) * alpha / 255; - destData[dp + 1] += ((srcData[dp + 1] & 0xff) - (destData[dp + 1] & 0xff)) * alpha / 255; - destData[dp + 2] += ((srcData[dp + 2] & 0xff) - (destData[dp + 2] & 0xff)) * alpha / 255; + int alpha = srcData[dp + 3] & 0xFF; + destData[dp ] += (srcData[dp ] & 0xFF) - (destData[dp ] & 0xFF) * alpha / 255; + destData[dp + 1] += (srcData[dp + 1] & 0xFF) - (destData[dp + 1] & 0xFF) * alpha / 255; + destData[dp + 2] += (srcData[dp + 2] & 0xFF) - (destData[dp + 2] & 0xFF) * alpha / 255; dp += 4; } dp += dpinc; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index c0766ccab7..17cc99356a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -112,16 +112,6 @@ public final class Image extends Resource implements Drawable { GC memGC; /** - * the alpha data for the image - */ - byte[] alphaData; - - /** - * the global alpha value to be used for every pixel - */ - int alpha = -1; - - /** * ImageFileNameProvider to provide file names at various Zoom levels */ private ImageFileNameProvider imageFileNameProvider; @@ -283,11 +273,6 @@ public Image(Device device, Image srcImage, int flag) { device.internal_dispose_GC(hDC, null); transparentPixel = srcImage.transparentPixel; - alpha = srcImage.alpha; - if (srcImage.alphaData != null) { - alphaData = new byte[srcImage.alphaData.length]; - System.arraycopy(srcImage.alphaData, 0, alphaData, 0, alphaData.length); - } break; case SWT.ICON: handle = OS.CopyImage(srcImage.handle, OS.IMAGE_ICON, rect.width, rect.height, 0); @@ -977,9 +962,10 @@ void initNative(String filename) { long [] createGdipImage() { switch (type) { case SWT.BITMAP: { - if (alpha != -1 || alphaData != null || transparentPixel != -1) { - BITMAP bm = new BITMAP(); - OS.GetObject(handle, BITMAP.sizeof, bm); + BITMAP bm = new BITMAP(); + OS.GetObject(handle, BITMAP.sizeof, bm); + int depth = bm.bmPlanes * bm.bmBitsPixel; + if (depth == 32 || transparentPixel != -1) { int imgWidth = bm.bmWidth; int imgHeight = bm.bmHeight; long hDC = device.internal_new_GC(null); @@ -993,8 +979,14 @@ long [] createGdipImage() { OS.GetObject(memDib, BITMAP.sizeof, dibBM); int sizeInBytes = dibBM.bmWidthBytes * dibBM.bmHeight; OS.BitBlt(memHdc, 0, 0, imgWidth, imgHeight, srcHdc, 0, 0, OS.SRCCOPY); + long hHeap = OS.GetProcessHeap(); + long pixels = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, sizeInBytes); + if (pixels == 0) SWT.error(SWT.ERROR_NO_HANDLES); byte red = 0, green = 0, blue = 0; - if (transparentPixel != -1) { + if (depth == 32) { + OS.MoveMemory(pixels, bm.bmBits, sizeInBytes); + } + else { if (bm.bmBitsPixel <= 8) { byte[] color = new byte[4]; OS.GetDIBColorTable(srcHdc, transparentPixel, 1, color); @@ -1029,30 +1021,8 @@ long [] createGdipImage() { break; } } - } - OS.SelectObject(srcHdc, oldSrcBitmap); - OS.SelectObject(memHdc, oldMemBitmap); - OS.DeleteObject(srcHdc); - OS.DeleteObject(memHdc); - byte[] srcData = new byte[sizeInBytes]; - OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes); - OS.DeleteObject(memDib); - device.internal_dispose_GC(hDC, null); - if (alpha != -1) { - for (int y = 0, dp = 0; y < imgHeight; ++y) { - for (int x = 0; x < imgWidth; ++x) { - srcData[dp + 3] = (byte)alpha; - dp += 4; - } - } - } else if (alphaData != null) { - for (int y = 0, dp = 0, ap = 0; y < imgHeight; ++y) { - for (int x = 0; x < imgWidth; ++x) { - srcData[dp + 3] = alphaData[ap++]; - dp += 4; - } - } - } else if (transparentPixel != -1) { + byte[] srcData = new byte[sizeInBytes]; + OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes); for (int y = 0, dp = 0; y < imgHeight; ++y) { for (int x = 0; x < imgWidth; ++x) { if (srcData[dp] == blue && srcData[dp + 1] == green && srcData[dp + 2] == red) { @@ -1063,12 +1033,15 @@ long [] createGdipImage() { dp += 4; } } + OS.MoveMemory(pixels, srcData, sizeInBytes); } - long hHeap = OS.GetProcessHeap(); - long pixels = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, srcData.length); - if (pixels == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.MoveMemory(pixels, srcData, sizeInBytes); - return new long []{Gdip.Bitmap_new(imgWidth, imgHeight, dibBM.bmWidthBytes, Gdip.PixelFormat32bppARGB, pixels), pixels}; + OS.SelectObject(srcHdc, oldSrcBitmap); + OS.SelectObject(memHdc, oldMemBitmap); + OS.DeleteObject(srcHdc); + OS.DeleteObject(memHdc); + OS.DeleteObject(memDib); + int pixelFormat = depth == 32 ? Gdip.PixelFormat32bppPARGB : Gdip.PixelFormat32bppARGB; + return new long []{Gdip.Bitmap_new(imgWidth, imgHeight, dibBM.bmWidthBytes, pixelFormat, pixels), pixels}; } return new long []{Gdip.Bitmap_new(handle, 0), 0}; } @@ -1633,10 +1606,32 @@ public ImageData getImageDataAtCurrentZoom() { /* Construct and return the ImageData */ ImageData imageData = new ImageData(width, height, depth, palette, 4, data); imageData.transparentPixel = this.transparentPixel; - imageData.alpha = alpha; - if (alpha == -1 && alphaData != null) { - imageData.alphaData = new byte[alphaData.length]; - System.arraycopy(alphaData, 0, imageData.alphaData, 0, alphaData.length); + if (depth == 32) { + byte straightData[] = new byte[imageSize]; + byte alphaData[] = new byte[width * height]; + boolean validAlpha = true; + for (int ap = 0, dp = 0; validAlpha && ap < alphaData.length; ap++, dp += 4) { + int b = data[dp ] & 0xFF; + int g = data[dp + 1] & 0xFF; + int r = data[dp + 2] & 0xFF; + int a = data[dp + 3] & 0xFF; + alphaData[ap] = (byte) a; + validAlpha = validAlpha && b <= a && g <= a && r <= a; + if (a != 0) { + straightData[dp ] = (byte) (((b * 0xFF) + a / 2) / a); + straightData[dp + 1] = (byte) (((g * 0xFF) + a / 2) / a); + straightData[dp + 2] = (byte) (((r * 0xFF) + a / 2) / a); + } + } + if (validAlpha) { + imageData.data = straightData; + imageData.alphaData = alphaData; + } + else { + for (int dp = 3; dp < imageSize; dp += 4) { + data[dp] = (byte) 0xFF; + } + } } return imageData; } @@ -1729,6 +1724,9 @@ static long [] init(Device device, Image image, ImageData i) { img.alphaData = i.alphaData; i = img; } + + boolean hasAlpha = i.alpha != -1 || i.alphaData != null; + /* * Windows supports 16-bit mask of (0x7C00, 0x3E0, 0x1F), * 24-bit mask of (0xFF0000, 0xFF00, 0xFF) and 32-bit mask @@ -1745,51 +1743,56 @@ static long [] init(Device device, Image image, ImageData i) { int newOrder = ImageData.MSB_FIRST; PaletteData newPalette = null; - switch (i.depth) { - case 8: - /* - * Bug 566545. Usually each color mask selects a different part of the pixel - * value to encode the according color. In this common case it is rather trivial - * to convert an 8-bit direct color image to the Windows supported 16-bit image. - * However there is no enforcement for the color masks to be disjunct. For - * example an 8-bit image where all color masks select the same 8-bit of pixel - * value (mask = 0xFF and shift = 0 for all colors) results in a very efficient - * 8-bit gray-scale image without the need of defining a color table. - * - * That's why we need to calculate the actual required depth if all colors are - * stored non-overlapping which might require 24-bit instead of the usual - * expected 16-bit. - */ - int minDepth = ImageData.getChannelWidth(redMask, palette.redShift) - + ImageData.getChannelWidth(greenMask, palette.greenShift) - + ImageData.getChannelWidth(blueMask, palette.blueShift); - if (minDepth <= 16) { - newDepth = 16; + if (hasAlpha) { + newDepth = 32; + newPalette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); + } + else { + switch (i.depth) { + case 8: + /* + * Bug 566545. Usually each color mask selects a different part of the pixel + * value to encode the according color. In this common case it is rather trivial + * to convert an 8-bit direct color image to the Windows supported 16-bit image. + * However there is no enforcement for the color masks to be disjunct. For + * example an 8-bit image where all color masks select the same 8-bit of pixel + * value (mask = 0xFF and shift = 0 for all colors) results in a very efficient + * 8-bit gray-scale image without the need of defining a color table. + * + * That's why we need to calculate the actual required depth if all colors are + * stored non-overlapping which might require 24-bit instead of the usual + * expected 16-bit. + */ + int minDepth = ImageData.getChannelWidth(redMask, palette.redShift) + + ImageData.getChannelWidth(greenMask, palette.greenShift) + + ImageData.getChannelWidth(blueMask, palette.blueShift); + if (minDepth <= 16) { + newDepth = 16; + newOrder = ImageData.LSB_FIRST; + newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F); + } else { + newDepth = 24; + newPalette = new PaletteData(0xFF, 0xFF00, 0xFF0000); + } + break; + case 16: newOrder = ImageData.LSB_FIRST; - newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F); - } else { + if (!(redMask == 0x7C00 && greenMask == 0x3E0 && blueMask == 0x1F)) { + newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F); + } + break; + case 24: + if (!(redMask == 0xFF && greenMask == 0xFF00 && blueMask == 0xFF0000)) { + newPalette = new PaletteData(0xFF, 0xFF00, 0xFF0000); + } + break; + case 32: newDepth = 24; newPalette = new PaletteData(0xFF, 0xFF00, 0xFF0000); - } - break; - case 16: - newOrder = ImageData.LSB_FIRST; - if (!(redMask == 0x7C00 && greenMask == 0x3E0 && blueMask == 0x1F)) { - newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F); - } - break; - case 24: - if (!(redMask == 0xFF && greenMask == 0xFF00 && blueMask == 0xFF0000)) { - newPalette = new PaletteData(0xFF, 0xFF00, 0xFF0000); - } - break; - case 32: - if (!(redMask == 0xFF00 && greenMask == 0xFF0000 && blueMask == 0xFF000000)) { - newPalette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); - } - break; - default: - SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); + break; + default: + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); + } } if (newPalette != null) { ImageData img = new ImageData(i.width, i.height, newDepth, newPalette); @@ -1808,6 +1811,73 @@ static long [] init(Device device, Image image, ImageData i) { i = img; } } + else if (hasAlpha) { + int newDepth = 32; + PaletteData newPalette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); + int newOrder = ImageData.MSB_FIRST; + RGB[] rgbs = i.palette.getRGBs(); + int length = rgbs.length; + byte[] srcReds = new byte[length]; + byte[] srcGreens = new byte[length]; + byte[] srcBlues = new byte[length]; + for (int j = 0; j < rgbs.length; j++) { + RGB rgb = rgbs[j]; + if (rgb == null) continue; + srcReds[j] = (byte)rgb.red; + srcGreens[j] = (byte)rgb.green; + srcBlues[j] = (byte)rgb.blue; + } + ImageData img = new ImageData(i.width, i.height, newDepth, newPalette); + ImageData.blit(ImageData.BLIT_SRC, + i.data, i.depth, i.bytesPerLine, i.getByteOrder(), 0, 0, i.width, i.height, srcReds, srcGreens, srcBlues, + ImageData.ALPHA_OPAQUE, null, 0, 0, 0, + img.data, img.depth, img.bytesPerLine, newOrder, 0, 0, img.width, img.height, newPalette.redMask, newPalette.greenMask, newPalette.blueMask, + false, false); + + if (i.transparentPixel != -1) { + img.transparentPixel = newPalette.getPixel(i.palette.getRGB(i.transparentPixel)); + } + img.maskPad = i.maskPad; + img.maskData = i.maskData; + img.alpha = i.alpha; + img.alphaData = i.alphaData; + i = img; + } + if (i.alpha != -1) { + int alpha = i.alpha & 0xFF; + byte[] data = i.data; + for (int dp = 0; dp < i.data.length; dp += 4) { + /* pre-multiplied alpha */ + int r = ((data[dp ] & 0xFF) * alpha) + 128; + r = (r + (r >> 8)) >> 8; + int g = ((data[dp + 1] & 0xFF) * alpha) + 128; + g = (g + (g >> 8)) >> 8; + int b = ((data[dp + 2] & 0xFF) * alpha) + 128; + b = (b + (b >> 8)) >> 8; + data[dp ] = (byte) b; + data[dp + 1] = (byte) g; + data[dp + 2] = (byte) r; + data[dp + 3] = (byte) alpha; + } + } + else if (i.alphaData != null) { + byte[] data = i.data; + for (int ap = 0, dp = 0; dp < i.data.length; ap++, dp += 4) { + /* pre-multiplied alpha */ + int a = i.alphaData[ap] & 0xFF; + int r = ((data[dp ] & 0xFF) * a) + 128; + r = (r + (r >> 8)) >> 8; + int g = ((data[dp + 1] & 0xFF) * a) + 128; + g = (g + (g >> 8)) >> 8; + int b = ((data[dp + 2] & 0xFF) * a) + 128; + b = (b + (b >> 8)) >> 8; + data[dp ] = (byte) r; + data[dp + 1] = (byte) g; + data[dp + 2] = (byte) b; + data[dp + 3] = (byte) a; + } + } + /* Construct bitmap info header by hand */ RGB[] rgbs = i.palette.getRGBs(); BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); @@ -1894,14 +1964,6 @@ static long [] init(Device device, Image image, ImageData i) { image.handle = hDib; image.type = SWT.BITMAP; image.transparentPixel = i.transparentPixel; - if (image.transparentPixel == -1) { - image.alpha = i.alpha; - if (i.alpha == -1 && i.alphaData != null) { - int length = i.alphaData.length; - image.alphaData = new byte[length]; - System.arraycopy(i.alphaData, 0, image.alphaData, 0, length); - } - } } } return result; |