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

Dmitry Timoshkov dmitry at baikal.ru
Fri May 31 04:22:58 CDT 2019


Alexandre Julliard <julliard at winehq.org> wrote:

> >> > +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.
> >
> > I've heard that before but didn't see the reasoning, in which cases it's
> > supposed to fail? Are you probably suggesting to use GdiAlphaBlend() or
> > something else?
> 
> GetDIBits() is a better choice. Though in general you'd have a DIB
> section already, in which case you don't need to copy the bits at all.

In this particular case there is no a DIB section, so I'd need to copy.
I still fail to see why BitBlt() won't work in general when copying a
bitmap with an alpah channel, and my experiance clearly shows that it
does both under Windows and Wine.

> It's not clear that an alpha channel is even meaningful with a DDB, did
> you test that case?

I'm testing with DIB sections, why would I need to test with a DDB?

-- 
Dmitry.



More information about the wine-devel mailing list