Alexandre Julliard julliard@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?