[USER32]
authorJérôme Gardou <jerome.gardou@reactos.org>
Tue, 13 Jul 2010 18:32:33 +0000 (18:32 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Tue, 13 Jul 2010 18:32:33 +0000 (18:32 +0000)
  - exchange mask and color bitmaps if needed in CreateIconIndirect
[WIN32K]
  - Simplify a bit UserDrawIconEx

svn path=/branches/reactos-yarotows/; revision=48026

dll/win32/user32/windows/cursoricon.c
subsystems/win32/win32k/ntuser/cursoricon.c

index 3729adb..5e01fe9 100644 (file)
@@ -1393,6 +1393,7 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
 {
     BITMAP ColorBitmap;
        BITMAP MaskBitmap;
+       ICONINFO safeIconInfo;
 
        if(!iconinfo)
        {
@@ -1400,13 +1401,15 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
                return (HICON)0;
        }
 
-       if(!GetObjectW(iconinfo->hbmMask, sizeof(BITMAP), &MaskBitmap))
+       safeIconInfo = *iconinfo;
+
+       if(!GetObjectW(safeIconInfo.hbmMask, sizeof(BITMAP), &MaskBitmap))
        {
                return (HICON)0;
        }
 
        /* Try to get color bitmap */
-       if (GetObjectW(iconinfo->hbmColor, sizeof(BITMAP), &ColorBitmap))
+       if (GetObjectW(safeIconInfo.hbmColor, sizeof(BITMAP), &ColorBitmap))
        {
                /* Compare size of color and mask bitmap*/
                if (ColorBitmap.bmWidth != MaskBitmap.bmWidth ||
@@ -1416,8 +1419,22 @@ HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
                        SetLastError(ERROR_INVALID_PARAMETER);
                        return (HICON)0;
                }
+               /* Test if they are inverted */
+               if(ColorBitmap.bmBitsPixel == 1)
+               {
+                       if(MaskBitmap.bmBitsPixel != 1)
+                       {
+                               safeIconInfo.hbmMask = iconinfo->hbmColor;
+                               safeIconInfo.hbmColor = iconinfo->hbmMask;
+                       }
+                       else
+                       {
+                               /* Wine tests say so */
+                               safeIconInfo.hbmColor = NULL;
+                       }
+               }
        }
-       return (HICON)NtUserCreateCursorIconHandle(iconinfo, TRUE);
+       return (HICON)NtUserCreateCursorIconHandle(&safeIconInfo, TRUE);
 }
 
 /******************************************************************************
index ee068d4..2ff72d9 100644 (file)
@@ -528,8 +528,8 @@ NtUserCreateCursorIconHandle(PICONINFO IconInfo OPTIONAL, BOOL Indirect)
                 GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
                 if(CurIcon->IconInfo.hbmColor)
                 {
-                    CurIcon->IconInfo.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
-                    GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
+                                       CurIcon->IconInfo.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
+                                       GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
                 }
             }
             if (CurIcon->IconInfo.hbmColor &&
@@ -1376,7 +1376,7 @@ UserDrawIconEx(
         hDestDC = NtGdiCreateCompatibleDC(hDc);
         if(!hDestDC)
         {
-            DPRINT1("NtGdiCreateCompatibleBitmap failed!\n");
+            DPRINT1("NtGdiCreateCompatibleDC failed!\n");
             Ret = FALSE;
             goto Cleanup ;
         }
@@ -1397,7 +1397,92 @@ UserDrawIconEx(
     iOldTxtColor = IntGdiSetTextColor(hDc, 0); //black
     iOldBkColor = IntGdiSetBkColor(hDc, 0x00FFFFFF); //white
 
-    if ((diFlags & DI_MASK) && (!bAlpha || !(diFlags & DI_IMAGE)))
+       if(bAlpha && (diFlags & DI_IMAGE))
+       {
+               BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
+        DWORD Pixel;
+        BYTE Red, Green, Blue, Alpha;
+        DWORD Count = 0;
+        INT i, j;
+        PSURFACE psurf;
+        PBYTE pBits ;
+        HBITMAP hMemBmp = NULL;
+
+        pBits = ExAllocatePoolWithTag(PagedPool,
+                                      bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
+                                      TAG_BITMAP);
+        if (pBits == NULL)
+        {
+            Ret = FALSE;
+            goto CleanupAlpha;
+        }
+
+        hMemBmp = BITMAP_CopyBitmap(hbmColor);
+        if(!hMemBmp)
+        {
+            DPRINT1("BITMAP_CopyBitmap failed!");
+            goto CleanupAlpha;
+        }
+
+        psurf = SURFACE_LockSurface(hMemBmp);
+        if(!psurf)
+        {
+            DPRINT1("SURFACE_LockSurface failed!\n");
+            goto CleanupAlpha;
+        }
+        /* get color bits */
+        IntGetBitmapBits(psurf,
+                         bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
+                         pBits);
+
+        /* premultiply with the alpha channel value */
+        for (i = 0; i < cyHeight; i++)
+        {
+            for (j = 0; j < cxWidth; j++)
+            {
+                Pixel = *(DWORD *)(pBits + Count);
+
+                Alpha = ((BYTE)(Pixel >> 24) & 0xff);
+
+                Red   = (((BYTE)(Pixel >>  0)) * Alpha) / 0xff;
+                Green = (((BYTE)(Pixel >>  8)) * Alpha) / 0xff;
+                Blue  = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff;
+
+                *(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24));
+
+                Count += sizeof(DWORD);
+            }
+        }
+
+        /* set mem bits */
+        IntSetBitmapBits(psurf,
+                         bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
+                         pBits);
+        SURFACE_UnlockSurface(psurf);
+
+        hTmpBmp = NtGdiSelectBitmap(hMemDC, hMemBmp);
+
+        Ret = NtGdiAlphaBlend(hDestDC,
+                                                 x,
+                                                     y,
+                              cxWidth,
+                              cyHeight,
+                              hMemDC,
+                              0,
+                              0,
+                              pIcon->Size.cx,
+                              pIcon->Size.cy,
+                              pixelblend,
+                              NULL);
+        NtGdiSelectBitmap(hMemDC, hTmpBmp);
+    CleanupAlpha:
+        if(pBits) ExFreePoolWithTag(pBits, TAG_BITMAP);
+        if(hMemBmp) NtGdiDeleteObjectApp(hMemBmp);
+               if(Ret) goto done;
+    }
+
+
+    if (diFlags & DI_MASK)
     {
         hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
         NtGdiStretchBlt(hDestDC,
@@ -1417,89 +1502,7 @@ UserDrawIconEx(
 
     if(diFlags & DI_IMAGE)
     {
-        if (bAlpha)
-        {
-            BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
-            DWORD Pixel;
-            BYTE Red, Green, Blue, Alpha;
-            DWORD Count = 0;
-            INT i, j;
-            PSURFACE psurf;
-            PBYTE pBits ;
-            HBITMAP hMemBmp = NULL;
-
-            pBits = ExAllocatePoolWithTag(PagedPool,
-                                          bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
-                                          TAG_BITMAP);
-            if (pBits == NULL)
-            {
-                Ret = FALSE;
-                goto CleanupAlpha;
-            }
-
-            hMemBmp = BITMAP_CopyBitmap(hbmColor);
-            if(!hMemBmp)
-            {
-                DPRINT1("BITMAP_CopyBitmap failed!");
-                goto CleanupAlpha;
-            }
-
-            psurf = SURFACE_LockSurface(hMemBmp);
-            if(!psurf)
-            {
-                DPRINT1("SURFACE_LockSurface failed!\n");
-                goto CleanupAlpha;
-            }
-            /* get color bits */
-            IntGetBitmapBits(psurf,
-                             bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
-                             pBits);
-
-            /* premultiply with the alpha channel value */
-            for (i = 0; i < cyHeight; i++)
-            {
-                for (j = 0; j < cxWidth; j++)
-                {
-                    Pixel = *(DWORD *)(pBits + Count);
-
-                    Alpha = ((BYTE)(Pixel >> 24) & 0xff);
-
-                    Red   = (((BYTE)(Pixel >>  0)) * Alpha) / 0xff;
-                    Green = (((BYTE)(Pixel >>  8)) * Alpha) / 0xff;
-                    Blue  = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff;
-
-                    *(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24));
-
-                    Count += sizeof(DWORD);
-                }
-            }
-
-            /* set mem bits */
-            IntSetBitmapBits(psurf,
-                             bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
-                             pBits);
-            SURFACE_UnlockSurface(psurf);
-
-            hTmpBmp = NtGdiSelectBitmap(hMemDC, hMemBmp);
-
-            NtGdiAlphaBlend(hDestDC,
-                            x,
-                            y,
-                            cxWidth,
-                            cyHeight,
-                            hMemDC,
-                            0,
-                            0,
-                            pIcon->Size.cx,
-                            pIcon->Size.cy,
-                            pixelblend,
-                            NULL);
-            NtGdiSelectBitmap(hMemDC, hTmpBmp);
-        CleanupAlpha:
-            if(pBits) ExFreePoolWithTag(pBits, TAG_BITMAP);
-            if(hMemBmp) NtGdiDeleteObjectApp(hMemBmp);
-        }
-        else if (hbmColor)
+               if (hbmColor)
         {
             DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ;
             hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmColor);
@@ -1538,6 +1541,7 @@ UserDrawIconEx(
         }
     }
 
+done:
     if(hDestDC != hDc)
     {
         NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, cyHeight, hDestDC, 0, 0, SRCCOPY, 0, 0);