diff options
author | Jonathan Meier | 2022-02-14 04:33:57 +0000 |
---|---|---|
committer | Niraj Modi | 2022-03-21 14:37:52 +0000 |
commit | 125a29b517d51f71c9c54c9b98a06903bc0fbe8c (patch) | |
tree | 6c7b2e060aeac8bac5e1da4743d92b295033595f | |
parent | def5c63081058881bcce98004349276f577bd32f (diff) | |
download | eclipse.platform.swt-125a29b517d51f71c9c54c9b98a06903bc0fbe8c.tar.gz eclipse.platform.swt-125a29b517d51f71c9c54c9b98a06903bc0fbe8c.tar.xz eclipse.platform.swt-125a29b517d51f71c9c54c9b98a06903bc0fbe8c.zip |
Bug 493455 - [win32] wrong transparency for some icons and images
Almost all win32 APIs working with transparent bitmaps expect them to
be in premultiplied alpha format. Notable exceptions are bitmaps used
to create icons and the ImageList API. Therefore, transparent images
switched from being stored in straight alpha format to premultiplied
alpha format in commit 8d21781c6b65b49d2f30db28ada54be673b5925c.
This was not properly reflected in Display.create32BitDIB(Image image)
that now wrongly applied the alpha multiplication again to already pre-
multiplied RGB values. Moreover, both Display.create32BitDIB taking a
native bitmap and converting it to a 32-bit bitmap that is then used to
create an icon as well as ImageList.set are expected to produce bitmaps
in straight alpha format. However, they now failed to properly convert
back from premultiplied alpha format.
Change-Id: I0cfa74161227bfd9204b531e9c7d028c1a5bcc82
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/190757
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/internal/ImageList.java | 10 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java | 48 |
2 files changed, 21 insertions, 37 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java index ff2a39ff6c..34ccb923d2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java @@ -151,10 +151,16 @@ long copyWithAlpha (long hBitmap, int background, byte[] alphaData, int destWidt /* Merge the alpha channel in place */ if (alphaData != null) { int spinc = dibBM.bmWidthBytes - srcWidth * 4; - int ap = 0, sp = 3; + int ap = 0, sp = 0; for (int y = 0; y < srcHeight; ++y) { for (int x = 0; x < srcWidth; ++x) { - srcData [sp] = alphaData [ap++]; + int a = alphaData [ap++] & 0xFF; + if (a != 0) { + srcData [sp ] = (byte)((((srcData [sp ] & 0xFF) * 0xFF) + a / 2) / a); + srcData [sp + 1] = (byte)((((srcData [sp + 1] & 0xFF) * 0xFF) + a / 2) / a); + srcData [sp + 2] = (byte)((((srcData [sp + 2] & 0xFF) * 0xFF) + a / 2) / a); + } + srcData [sp + 3] = (byte)a; sp += 4; } sp += spinc; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java index 151be728f1..2e71ec17df 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java @@ -991,39 +991,6 @@ static long create32bitDIB (Image image) { dp += 4; } } - } else if (alpha != -1) { - for (int y = 0, dp = 0; y < imgHeight; ++y) { - for (int x = 0; x < imgWidth; ++x) { - int r = ((srcData[dp + 0] & 0xFF) * alpha) + 128; - r = (r + (r >> 8)) >> 8; - int g = ((srcData[dp + 1] & 0xFF) * alpha) + 128; - g = (g + (g >> 8)) >> 8; - int b = ((srcData[dp + 2] & 0xFF) * alpha) + 128; - b = (b + (b >> 8)) >> 8; - srcData[dp+0] = (byte)r; - srcData[dp+1] = (byte)g; - srcData[dp+2] = (byte)b; - 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) { - int a = alphaData[ap++] & 0xFF; - int r = ((srcData[dp + 0] & 0xFF) * a) + 128; - r = (r + (r >> 8)) >> 8; - int g = ((srcData[dp + 1] & 0xFF) * a) + 128; - g = (g + (g >> 8)) >> 8; - int b = ((srcData[dp + 2] & 0xFF) * a) + 128; - b = (b + (b >> 8)) >> 8; - srcData[dp+0] = (byte)r; - srcData[dp+1] = (byte)g; - srcData[dp+2] = (byte)b; - srcData[dp+3] = (byte)a; - dp += 4; - } - } } else if (transparentPixel != -1) { for (int y = 0, dp = 0; y < imgHeight; ++y) { for (int x = 0; x < imgWidth; ++x) { @@ -1035,7 +1002,7 @@ static long create32bitDIB (Image image) { dp += 4; } } - } else { + } else if (alpha == -1 && alphaData == null) { for (int y = 0, dp = 0; y < imgHeight; ++y) { for (int x = 0; x < imgWidth; ++x) { srcData [dp + 3] = (byte)0xFF; @@ -1117,6 +1084,11 @@ static long create32bitDIB (long hBitmap, int alpha, byte [] alphaData, int tran if (alpha != -1) { for (int y = 0, dp = 0; y < imgHeight; ++y) { for (int x = 0; x < imgWidth; ++x) { + if (alpha != 0) { + srcData [dp ] = (byte)((((srcData[dp ] & 0xFF) * 0xFF) + alpha / 2) / alpha); + srcData [dp + 1] = (byte)((((srcData[dp + 1] & 0xFF) * 0xFF) + alpha / 2) / alpha); + srcData [dp + 2] = (byte)((((srcData[dp + 2] & 0xFF) * 0xFF) + alpha / 2) / alpha); + } srcData [dp + 3] = (byte)alpha; dp += 4; } @@ -1124,7 +1096,13 @@ static long create32bitDIB (long hBitmap, int alpha, byte [] alphaData, int tran } 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++]; + int a = alphaData [ap++] & 0xFF; + if (a != 0) { + srcData [dp ] = (byte)((((srcData[dp ] & 0xFF) * 0xFF) + a / 2) / a); + srcData [dp + 1] = (byte)((((srcData[dp + 1] & 0xFF) * 0xFF) + a / 2) / a); + srcData [dp + 2] = (byte)((((srcData[dp + 2] & 0xFF) * 0xFF) + a / 2) / a); + } + srcData [dp + 3] = (byte)a; dp += 4; } } |