From f0644c6d071e3aa9601a50d38c42dde68d667030 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 19 Apr 2010 14:49:26 +0200 Subject: [PATCH] winex11: Generate an alpha channel from the bitmask for icons that don't have one. --- dlls/winex11.drv/window.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index f8e7fb23167..73c45ff74f2 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -820,8 +820,9 @@ static unsigned long *get_bitmap_argb( HDC hdc, HBITMAP color, HBITMAP mask, uns { BITMAP bm; BITMAPINFO *info; - unsigned int *bits = NULL; - int i; + unsigned int *ptr, *bits = NULL; + unsigned char *mask_bits = NULL; + int i, j, has_alpha = 0; if (!GetObjectW( color, sizeof(bm), &bm )) return NULL; if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) return NULL; @@ -843,6 +844,23 @@ static unsigned long *get_bitmap_argb( HDC hdc, HBITMAP color, HBITMAP mask, uns bits[0] = bm.bmWidth; bits[1] = bm.bmHeight; + for (i = 0; i < bm.bmWidth * bm.bmHeight; i++) + if ((has_alpha = (bits[i + 2] & 0xff000000) != 0)) break; + + if (!has_alpha) + { + unsigned int width_bytes = (bm.bmWidth + 31) / 32 * 4; + /* generate alpha channel from the mask */ + info->bmiHeader.biBitCount = 1; + info->bmiHeader.biSizeImage = width_bytes * bm.bmHeight; + if (!(mask_bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto failed; + if (!GetDIBits( hdc, mask, 0, bm.bmHeight, mask_bits, info, DIB_RGB_COLORS )) goto failed; + ptr = bits + 2; + for (i = 0; i < bm.bmHeight; i++) + for (j = 0; j < bm.bmWidth; j++, ptr++) + if ((mask_bits[i * width_bytes + j / 8] << (j % 8)) & 0x80) *ptr |= 0xff000000; + } + /* convert to array of longs */ if (bits && sizeof(long) > sizeof(int)) for (i = *size - 1; i >= 0; i--) ((unsigned long *)bits)[i] = bits[i]; @@ -852,6 +870,7 @@ static unsigned long *get_bitmap_argb( HDC hdc, HBITMAP color, HBITMAP mask, uns failed: HeapFree( GetProcessHeap(), 0, info ); HeapFree( GetProcessHeap(), 0, bits ); + HeapFree( GetProcessHeap(), 0, mask_bits ); return NULL; }