This patch fixes applications that draw the 32 bpp icons manually.
v4: directly create 1-bit mask from alpha.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/user32/cursoricon.c | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c index 0adb73bf56..7c09f50a5f 100644 --- a/dlls/user32/cursoricon.c +++ b/dlls/user32/cursoricon.c @@ -1296,6 +1296,49 @@ static HICON create_icon_from_bmi( const BITMAPINFO *bmi, DWORD maxsize, HMODULE 0, 0, bmi_width, bmi_height, mask_bits, bmi_copy, DIB_RGB_COLORS, SRCCOPY ); } + else + { + if (bmi_has_alpha( bmi, color_bits )) + { + LONG x, y, dst_stride = ((bmi_width + 31) / 8) & ~3; + unsigned char *alpha_mask_bits; + + mask_size = bmi_height * dst_stride; + alpha_mask_bits = HeapAlloc( GetProcessHeap(), 0, mask_size ); + + if (alpha_mask_bits) + { + const unsigned char *src = color_bits; + unsigned char *dst = alpha_mask_bits; + + for (y = 0; y < bmi_height; y++, dst += dst_stride) + { + unsigned char *dst_byte = dst; + + for (x = 0; x < bmi_width; x += 8, dst_byte++) + { + unsigned char mask = 0x80; + LONG bit_off; + + *dst_byte = 0; + + for (bit_off = 0; bit_off < 8; bit_off++, mask >>= 1, src += 4) + { + if (src[3] != 0xff && x + bit_off < bmi_width) + *dst_byte |= mask; + } + } + } + + SelectObject( hdc, mask ); + StretchDIBits( hdc, 0, 0, width, height, + 0, 0, bmi_width, bmi_height, + alpha_mask_bits, bmi_copy, DIB_RGB_COLORS, SRCCOPY ); + + HeapFree( GetProcessHeap(), 0, alpha_mask_bits ); + } + } + } ret = TRUE;
done:
On Wed, Aug 22, 2018 at 12:00 AM Dmitry Timoshkov dmitry@baikal.ru wrote:
for (bit_off = 0; bit_off < 8; bit_off++, mask >>= 1, src += 4)
{
if (src[3] != 0xff && x + bit_off < bmi_width)
*dst_byte |= mask;
}
Does this mean that only fully transparent pixels are added to the mask? If so, why not include any pixel that is more than 50% transparent?
-Alex
Alex Henrie alexhenrie24@gmail.com wrote:
for (bit_off = 0; bit_off < 8; bit_off++, mask >>= 1, src += 4)
{
if (src[3] != 0xff && x + bit_off < bmi_width)
*dst_byte |= mask;
}
Does this mean that only fully transparent pixels are added to the mask?
Yes, that's correct.
If so, why not include any pixel that is more than 50% transparent?
I have a test program that confirms this behaviour.