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/windows/cursoricon_new.c?rev=64967&r1=64966&r2=64967&view=diff
==============================================================================
--- 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
     {


Reply via email to