Author: jgardou
Date: Fri Oct 24 17:31:50 2014
New Revision: 64967
URL:
http://svn.reactos.org/svn/reactos?rev=64967&view=rev
Log:
[USER32]
- Use CreateDIBitmap with the CDM_CREATEDIB undocumented flag to create alpha bitmaps.
This permits to create display compatible yet 32bpp DDBs.
CORE-8695 #comment PLease retest, should be OK now.
Modified:
trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c
Modified: trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/window…
==============================================================================
--- trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c [iso-8859-1] Fri Oct 24
17:31:50 2014
@@ -241,56 +241,41 @@
*
* Create the alpha bitmap for a 32-bpp icon that has an alpha channel.
*/
-static HBITMAP create_alpha_bitmap(
- _In_ HBITMAP color,
- _In_opt_ const BITMAPINFO *src_info,
- _In_opt_ const void *color_bits )
+static
+HBITMAP
+create_alpha_bitmap(
+ _In_opt_ HBITMAP color,
+ _In_opt_ BITMAPINFO *src_info,
+ _In_opt_ const void *color_bits,
+ _In_ LONG width,
+ _In_ LONG height)
{
HBITMAP alpha = NULL, hbmpOld;
- BITMAPINFO *info = NULL;
HDC hdc = NULL, hdcScreen;
+ unsigned char *ptr;
void *bits = NULL;
- unsigned char *ptr;
int i;
- LONG width, height;
- BITMAP bm;
-
- if (!GetObjectW( color, sizeof(bm), &bm ))
+
+ hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
+ if (!hdcScreen)
return NULL;
- if (bm.bmBitsPixel != 32)
+ hdc = CreateCompatibleDC(hdcScreen);
+ if (!hdc)
+ {
+ DeleteDC(hdcScreen);
return NULL;
-
- hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
- if(!hdcScreen)
- return NULL;
- if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
- goto done;
- hdc = CreateCompatibleDC(hdcScreen);
- if(!hdc)
- goto done;
-
- if(src_info)
- {
- WORD bpp;
- DWORD compr;
- int size;
-
- if(!bmi_has_alpha(src_info, color_bits))
+ }
+
+ if (color)
+ {
+ BITMAP bm;
+ BITMAPINFO *info = NULL;
+
+ if (!GetObjectW( color, sizeof(bm), &bm ))
goto done;
-
- if(!DIB_GetBitmapInfo(&src_info->bmiHeader, &width, &height,
&bpp, &compr))
+ if (bm.bmBitsPixel != 32)
goto done;
- if(bpp != 32)
- goto done;
-
- size = get_dib_image_size(width, height, bpp);
- bits = HeapAlloc(GetProcessHeap(), 0, size);
- if(!bits)
- goto done;
- CopyMemory(bits, color_bits, size);
- }
- else
- {
+
info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
if(!info)
goto done;
@@ -308,46 +293,116 @@
bits = HeapAlloc(GetProcessHeap(), 0, info->bmiHeader.biSizeImage);
if(!bits)
+ {
+ HeapFree(GetProcessHeap(), 0, info);
goto done;
+ }
if(!GetDIBits( hdc, color, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
+ {
+ HeapFree(GetProcessHeap(), 0, info);
goto done;
+ }
if (!bmi_has_alpha( info, bits ))
+ {
+ HeapFree(GetProcessHeap(), 0, info);
goto done;
- width = bm.bmWidth;
- height = bm.bmHeight;
- }
-
- /* pre-multiply by alpha */
- for (i = 0, ptr = bits; i < width * height; i++, ptr += 4)
- {
- unsigned int alpha = ptr[3];
- ptr[0] = ptr[0] * alpha / 255;
- ptr[1] = ptr[1] * alpha / 255;
- ptr[2] = ptr[2] * alpha / 255;
- }
-
- /* Create the bitmap */
- alpha = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
- if(!alpha)
- goto done;
- hbmpOld = SelectObject(hdc, alpha);
- if(!hbmpOld)
- goto done;
- if(!StretchDIBits( hdc, 0, 0, bm.bmWidth, bm.bmHeight,
- 0, 0, width, height,
- bits, src_info ? src_info : info, DIB_RGB_COLORS, SRCCOPY ))
- {
- SelectObject(hdc, hbmpOld);
- hbmpOld = NULL;
- DeleteObject(alpha);
- alpha = NULL;
- }
- SelectObject(hdc, hbmpOld);
+ }
+
+ /* pre-multiply by alpha */
+ for (i = 0, ptr = bits; i < width * height; i++, ptr += 4)
+ {
+ unsigned int alpha = ptr[3];
+ ptr[0] = (ptr[0] * alpha) / 255;
+ ptr[1] = (ptr[1] * alpha) / 255;
+ ptr[2] = (ptr[2] * alpha) / 255;
+ }
+
+ /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag).
*/
+ alpha = CreateDIBitmap(hdc, NULL, CBM_INIT | 2, bits, info, DIB_RGB_COLORS);
+
+ HeapFree(GetProcessHeap(), 0, info);
+ HeapFree(GetProcessHeap(), 0, bits);
+ }
+ else
+ {
+ WORD bpp;
+ DWORD compr;
+ int size;
+ LONG orig_width, orig_height;
+
+ if(!bmi_has_alpha(src_info, color_bits))
+ goto done;
+
+ if(!DIB_GetBitmapInfo(&src_info->bmiHeader, &orig_width,
&orig_height, &bpp, &compr))
+ goto done;
+ if(bpp != 32)
+ goto done;
+
+ size = get_dib_image_size(orig_width, orig_height, bpp);
+ bits = HeapAlloc(GetProcessHeap(), 0, size);
+ if(!bits)
+ goto done;
+ CopyMemory(bits, color_bits, size);
+ /* pre-multiply by alpha */
+ for (i = 0, ptr = bits; i < width * height; i++, ptr += 4)
+ {
+ unsigned int alpha = ptr[3];
+ ptr[0] = (ptr[0] * alpha) / 255;
+ ptr[1] = (ptr[1] * alpha) / 255;
+ ptr[2] = (ptr[2] * alpha) / 255;
+ }
+
+ /* Create the bitmap. Set the bitmap info to have the right width and height */
+ if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = width;
+ ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = height;
+ }
+ else
+ {
+ src_info->bmiHeader.biWidth = width;
+ src_info->bmiHeader.biHeight = height;
+ }
+ /* Directly create a 32-bits DDB (thanks to undocumented CreateDIBitmap flag).
*/
+ alpha = CreateDIBitmap(hdcScreen, NULL, 2, NULL, src_info, DIB_RGB_COLORS);
+ /* Restore values */
+ if(src_info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcWidth = orig_width;
+ ((BITMAPCOREHEADER*)&src_info->bmiHeader)->bcHeight = orig_height;
+ }
+ else
+ {
+ src_info->bmiHeader.biWidth = orig_width;
+ src_info->bmiHeader.biHeight = orig_height;
+ }
+ if(!alpha)
+ goto done;
+ hbmpOld = SelectObject(hdc, alpha);
+ if(!hbmpOld)
+ {
+ DeleteObject(alpha);
+ alpha = NULL;
+ goto done;
+ }
+ if(!StretchDIBits( hdc, 0, 0, width, height,
+ 0, 0, orig_width, orig_height,
+ bits, src_info, DIB_RGB_COLORS, SRCCOPY ))
+ {
+ SelectObject(hdc, hbmpOld);
+ hbmpOld = NULL;
+ DeleteObject(alpha);
+ alpha = NULL;
+ }
+ else
+ {
+ SelectObject(hdc, hbmpOld);
+ }
+ }
done:
DeleteDC(hdcScreen);
- if(hdc) DeleteDC( hdc );
- if(info) HeapFree( GetProcessHeap(), 0, info );
+ DeleteDC( hdc );
if(bits) HeapFree(GetProcessHeap(), 0, bits);
TRACE("Returning 0x%08x.\n", alpha);
@@ -571,8 +626,7 @@
pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
goto done;
pdata->bpp = GetDeviceCaps(hdcScreen, BITSPIXEL);
- if(pdata->bpp == 32)
- pdata->hbmAlpha = create_alpha_bitmap(pdata->hbmColor, pbmiCopy,
pvColor);
+ pdata->hbmAlpha = create_alpha_bitmap(NULL, pbmiCopy, pvColor, pdata->cx,
pdata->cy);
/* Now convert the info to monochrome for the mask bits */
if (pbmiCopy->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
@@ -673,7 +727,7 @@
pCursorData->cx = bm.bmWidth;
pCursorData->cy = bm.bmHeight;
if(pCursorData->bpp == 32)
- pCursorData->hbmAlpha = create_alpha_bitmap(pCursorData->hbmColor,
NULL, NULL);
+ pCursorData->hbmAlpha = create_alpha_bitmap(pCursorData->hbmColor,
NULL, NULL, 0, 0);
}
else
{