From 8086b49ef7860fa1f1017b198042ede1edffa04c Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Wed, 24 Jan 2024 09:21:12 +0100 Subject: [PATCH] [Win32] Extract alpha values from icons if available #715 Under certain conditions, program icons loaded on Windows via GDI+ have empty mask data, even though the original icon has proper mask data. As a result, these icons are printed with a black instead of a transparent background. Still these icons can contain valid alpha data in their usual 32-bit data. With this change, alpha data is extracted for icons which are loaded without proper mask data to ensure that they have proper transparency information. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/715 --- .../win32/org/eclipse/swt/graphics/Image.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) 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 29573d09907..70193f01461 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 @@ -1430,6 +1430,7 @@ public ImageData getImageDataAtCurrentZoom() { /* Do the mask */ byte [] maskData = null; + byte [] alphaData = null; if (info.hbmColor == 0) { /* Do the bottom half of the mask */ maskData = new byte[imageSize]; @@ -1459,7 +1460,9 @@ public ImageData getImageDataAtCurrentZoom() { maskData = new byte[imageSize]; OS.GetDIBits(hBitmapDC, info.hbmMask, 0, height, maskData, bmi, OS.DIB_RGB_COLORS); /* Loop to invert the mask */ + boolean hasMaskData = false; for (int i = 0; i < maskData.length; i++) { + hasMaskData |= maskData[i] != 0; maskData[i] ^= -1; } /* Make sure mask scanlinePad is 2 */ @@ -1470,6 +1473,21 @@ public ImageData getImageDataAtCurrentZoom() { if (calcBpl == bpl) break; } maskData = ImageData.convertPad(maskData, width, height, 1, maskPad, 2); + // For missing mask data, see https://github.com/eclipse-platform/eclipse.platform.swt/issues/715 + if (!hasMaskData && depth == 32) { + alphaData = new byte[width * height]; + boolean hasAlphaData = false; + for (int pixelIndex = 0; pixelIndex < alphaData.length; pixelIndex++) { + alphaData[pixelIndex] = data[pixelIndex * 4 + 3]; + hasAlphaData |= alphaData[pixelIndex] != -1; + } + // In case there is alpha data, replace the empty mask data with proper alpha data + if (hasAlphaData) { + maskData = null; + } else { + alphaData = null; + } + } } /* Clean up */ OS.SelectObject(hBitmapDC, hOldBitmap); @@ -1482,6 +1500,7 @@ public ImageData getImageDataAtCurrentZoom() { if (info.hbmMask != 0) OS.DeleteObject(info.hbmMask); /* Construct and return the ImageData */ ImageData imageData = new ImageData(width, height, depth, palette, 4, data); + imageData.alphaData = alphaData; imageData.maskData = maskData; imageData.maskPad = 2; return imageData;