This patch fixes applications that draws 32 bpp icons manually.
v3: create 8-bit intermediate mask from alpha instead of 32-bit.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/user32/cursoricon.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c index 0adb73bf56..5d63a42373 100644 --- a/dlls/user32/cursoricon.c +++ b/dlls/user32/cursoricon.c @@ -1296,6 +1296,41 @@ 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 )) + { + DWORD alpha_mask_bits_size = bmi_width * bmi_height; + unsigned char *alpha_mask_bits = HeapAlloc( GetProcessHeap(), 0, alpha_mask_bits_size ); + + if (alpha_mask_bits) + { + const unsigned char *src = color_bits; + unsigned char *dst = alpha_mask_bits; + + while (alpha_mask_bits_size--) + { + *dst++ = src[3] == 0xff ? 0 : 1; + src += 4; + } + + /* DIB palette and color count are already initialized correctly + * for the monochrome case, so just correct the bit depth. + */ + if (bmi_copy->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) + bmi_copy->bmiHeader.biBitCount = 8; + else + ((BITMAPCOREINFO *)bmi_copy)->bmciHeader.bcBitCount = 8; + + 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:
Dmitry Timoshkov dmitry@baikal.ru writes:
diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c index 0adb73bf56..5d63a42373 100644 --- a/dlls/user32/cursoricon.c +++ b/dlls/user32/cursoricon.c @@ -1296,6 +1296,41 @@ 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 ))
{
DWORD alpha_mask_bits_size = bmi_width * bmi_height;
unsigned char *alpha_mask_bits = HeapAlloc( GetProcessHeap(), 0, alpha_mask_bits_size );
Rows need to be 32-bit aligned. I expect it would also cause less code duplication to directly create a 1-bpp bitmap.
Alexandre Julliard julliard@winehq.org wrote:
- else
- {
if (bmi_has_alpha( bmi, color_bits ))
{
DWORD alpha_mask_bits_size = bmi_width * bmi_height;
unsigned char *alpha_mask_bits = HeapAlloc( GetProcessHeap(), 0, alpha_mask_bits_size );
Rows need to be 32-bit aligned.
Well spotted, thanks.
I expect it would also cause less code duplication to directly create a 1-bpp bitmap.
What kind of code duplication do you have in mind?
Dmitry Timoshkov dmitry@baikal.ru writes:
Alexandre Julliard julliard@winehq.org wrote:
- else
- {
if (bmi_has_alpha( bmi, color_bits ))
{
DWORD alpha_mask_bits_size = bmi_width * bmi_height;
unsigned char *alpha_mask_bits = HeapAlloc( GetProcessHeap(), 0, alpha_mask_bits_size );
Rows need to be 32-bit aligned.
Well spotted, thanks.
I expect it would also cause less code duplication to directly create a 1-bpp bitmap.
What kind of code duplication do you have in mind?
The duplicate setting of biBitCount and the StretchDIBits call. If you generate a 1-bpp mask you can get rid of all that and simply fall through to the normal code path.
Alexandre Julliard julliard@winehq.org wrote:
I expect it would also cause less code duplication to directly create a 1-bpp bitmap.
What kind of code duplication do you have in mind?
The duplicate setting of biBitCount and the StretchDIBits call. If you generate a 1-bpp mask you can get rid of all that and simply fall through to the normal code path.
With the setting of biBitCount and the StretchDIBits call it's still going to be considerably less code than the 1-bpp mask generarion from the 32-bpp RGBA bitmap.
Dmitry Timoshkov dmitry@baikal.ru writes:
Alexandre Julliard julliard@winehq.org wrote:
I expect it would also cause less code duplication to directly create a 1-bpp bitmap.
What kind of code duplication do you have in mind?
The duplicate setting of biBitCount and the StretchDIBits call. If you generate a 1-bpp mask you can get rid of all that and simply fall through to the normal code path.
With the setting of biBitCount and the StretchDIBits call it's still going to be considerably less code than the 1-bpp mask generarion from the 32-bpp RGBA bitmap.
I don't see why, it should be about the same amount of code as an 8-bpp mask, with just a couple of extra shifts and masks.