[PATCH 2/2] comctl32: Paint 32-bpp bitmaps with an alpha channel using GdiAlphaBlend.

Alexandre Julliard julliard at winehq.org
Fri May 31 03:49:05 CDT 2019


Dmitry Timoshkov <dmitry at baikal.ru> writes:

> +static HBITMAP create_alpha_bitmap( HBITMAP hbitmap )
> +{
> +    HBITMAP alpha = 0;
> +    BITMAPINFO *info = NULL;
> +    BITMAP bm;
> +    HDC src, dst;
> +    void *bits;
> +    DWORD i;
> +    const unsigned char *ptr;
> +    BOOL has_alpha = FALSE;
> +
> +    if (!GetObjectW( hbitmap, sizeof(bm), &bm )) return 0;
> +    if (bm.bmBitsPixel != 32) return 0;
> +
> +    if (!(src = CreateCompatibleDC( 0 ))) return 0;
> +    if (!(dst = CreateCompatibleDC( src ))) goto done;
> +    if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) goto done;
> +    info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
> +    info->bmiHeader.biWidth = bm.bmWidth;
> +    info->bmiHeader.biHeight = -bm.bmHeight;
> +    info->bmiHeader.biPlanes = 1;
> +    info->bmiHeader.biBitCount = 32;
> +    info->bmiHeader.biCompression = BI_RGB;
> +    info->bmiHeader.biSizeImage = bm.bmWidth * bm.bmHeight * 4;
> +    info->bmiHeader.biXPelsPerMeter = 0;
> +    info->bmiHeader.biYPelsPerMeter = 0;
> +    info->bmiHeader.biClrUsed = 0;
> +    info->bmiHeader.biClrImportant = 0;
> +    if (!(alpha = CreateDIBSection( dst, info, DIB_RGB_COLORS, &bits, NULL, 0 ))) goto done;
> +
> +    SelectObject( src, hbitmap );
> +    SelectObject( dst, alpha );
> +    BitBlt(dst, 0, 0, bm.bmWidth, bm.bmHeight, src, 0, 0, SRCCOPY);

BitBlt() is not guaranteed to preserve alpha, it's not the right
function to use here.

> @@ -184,7 +235,15 @@ static HBITMAP STATIC_SetBitmap( HWND hwnd, HBITMAP hBitmap, DWORD style )
>      if (!extra) return 0;
>  
>      hOldBitmap = extra->image.hbitmap;
> -    extra->image.hbitmap = hBitmap;
> +    alpha = create_alpha_bitmap( hBitmap );
> +    if (alpha)
> +    {
> +        extra->image.hbitmap = alpha;
> +        extra->image_has_alpha = TRUE;
> +    }
> +    else
> +        extra->image.hbitmap = hBitmap;

You'd need to free the old bitmap and reset the flag, though I'm not
sure it makes sense to store the flag in the first place, you could
handle this at paint time. You probably also need to return the original
bitmap, this would need tests.

-- 
Alexandre Julliard
julliard at winehq.org



More information about the wine-devel mailing list