Author: fireball
Date: Sat Apr  4 22:52:14 2009
New Revision: 40363

URL: http://svn.reactos.org/svn/reactos?rev=40363&view=rev
Log:
Evgeniy Boltik <[email protected]>
- Enable and use mask support in UserDrawIconEx, fully compatible with Windows, 
based on tests in bug 4336.
- Remove IntSet[Text/Bk]Color hacks from UserDrawIconEx, no longer required due 
to fix in CreateCompatibleDC.
- Change a few comments in the code of UserDrawIconEx.
See issue #4336 for more details.

Modified:
    trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c?rev=40363&r1=40362&r2=40363&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] 
(original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Sat 
Apr  4 22:52:14 2009
@@ -1388,8 +1388,6 @@
    return FALSE;
 }
 
-
-/* FIXME: ReactOS specific hack */
 BOOL
 UserDrawIconEx(
    HDC hDc,
@@ -1405,7 +1403,6 @@
    BOOL Ret = FALSE;
    HBITMAP hbmMask, hbmColor;
    BITMAP bmpMask, bmpColor;
-   COLORREF oldFg, oldBg;
    BOOL DoFlickerFree;
    SIZE IconSize;
 
@@ -1413,8 +1410,10 @@
    HGDIOBJ hOldOffBrush = 0;
    HGDIOBJ hOldOffBmp = 0;
    HBITMAP hbmOff = 0;
-   HDC hdcMem = 0;
-   HGDIOBJ hOldMem;
+   HDC hdcMask = 0;
+   HGDIOBJ hOldMask = NULL;
+   HDC hdcImage = 0;
+   HGDIOBJ hOldImage = NULL;
    BOOL bAlpha = FALSE;
 
    hbmMask = pIcon->IconInfo.hbmMask;
@@ -1452,7 +1451,8 @@
       PFN_DIB_GetPixel fnSource_GetPixel = NULL;
       INT x, y;
 
-      //Find alpha into icon
+      /* In order to correctly display 32 bit icons Windows first scans the 
image,
+         because information about transparency is not stored in any image's 
headers */
       psurfOff = SURFACE_LockSurface(hbmColor ? hbmColor : hbmMask);
       if (psurfOff)
       {
@@ -1549,60 +1549,62 @@
    else
        hdcOff = hDc;
 
-   hdcMem = NtGdiCreateCompatibleDC(hDc);
-   if (!hdcMem)
-   {
-      DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
-      goto cleanup;
-   }
-
-   oldFg = IntGdiSetTextColor(hdcOff, RGB(0, 0, 0));
-   oldBg = IntGdiSetBkColor(hdcOff, RGB(255, 255, 255));
-
-   if (diFlags & DI_MASK)
-   {
-      hOldMem = NtGdiSelectBitmap(hdcMem, hbmMask);
-      if (!hOldMem)
+   if (diFlags & DI_IMAGE)
+   {
+      hdcImage = NtGdiCreateCompatibleDC(hDc);
+      if (!hdcImage)
+      {
+         DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
+         goto cleanup;
+      }
+      hOldImage = NtGdiSelectBitmap(hdcImage, (hbmColor ? hbmColor : hbmMask));
+      if (!hOldImage)
       {
          DPRINT("NtGdiSelectBitmap() failed!\n");
          goto cleanup;
       }
-
-      NtGdiStretchBlt(hdcOff,
-                   (DoFlickerFree || bAlpha ? 0 : xLeft),
-                   (DoFlickerFree || bAlpha ? 0 : yTop), 
-                   cxWidth,
-                   cyHeight,
-                   hdcMem,
-                   0,
-                   0,
-                   IconSize.cx,
-                   IconSize.cy,
-                   ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY),
-                   0);
-
-      NtGdiSelectBitmap(hdcMem, hOldMem);
-   }
-
-   if(diFlags & DI_IMAGE)
-   {
-      hOldMem = NtGdiSelectBitmap(hdcMem, (hbmColor ? hbmColor : hbmMask));
-
-      NtGdiStretchBlt(hdcOff, 
-                   (DoFlickerFree || bAlpha ? 0 : xLeft),
-                   (DoFlickerFree || bAlpha ? 0 : yTop),
-                   cxWidth,
-                   cyHeight,
-                   hdcMem,
-                   0,
-                   (hbmColor ? 0 : IconSize.cy),
-                   IconSize.cx,
-                   IconSize.cy,
-                   ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY),
-                   0);
-
-      NtGdiSelectBitmap(hdcMem, hOldMem);
-   }
+   }
+
+   /* If DI_IMAGE flag is specified and hbmMask exists, then always use mask 
for drawing */
+   if (diFlags & DI_MASK || (diFlags & DI_IMAGE && hbmMask))
+   {
+      hdcMask = NtGdiCreateCompatibleDC(hDc);
+      if (!hdcMask)
+      {
+         DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
+         goto cleanup;
+      }
+
+      hOldMask = NtGdiSelectBitmap(hdcMask, hbmMask);
+      if (!hOldMask)
+      {
+         DPRINT("NtGdiSelectBitmap() failed!\n");
+         goto cleanup;
+      }
+   }
+
+   if (hdcMask || hdcImage)
+   {
+      GreStretchBltMask(hdcOff,
+                        (DoFlickerFree || bAlpha) ? 0 : xLeft,
+                        (DoFlickerFree || bAlpha) ? 0 : yTop, 
+                        cxWidth,
+                        cyHeight,
+                        hdcImage ? hdcImage : hdcMask,
+                        0,
+                        ((diFlags & DI_MASK && !(diFlags & DI_IMAGE)) || 
+                         (diFlags & DI_IMAGE && hbmColor) ? 0 : IconSize.cy),
+                        IconSize.cx,
+                        IconSize.cy,
+                        SRCCOPY,
+                        0,
+                        hdcImage ? hdcMask : NULL);
+   }
+
+   if (hOldMask) NtGdiSelectBitmap(hdcMask, hOldMask);
+   if (hOldImage) NtGdiSelectBitmap(hdcImage, hOldImage);
+   if (hdcImage) NtGdiDeleteObjectApp(hdcImage);
+   if (hdcMask) NtGdiDeleteObjectApp(hdcMask);
 
     if (bAlpha)
     {
@@ -1673,9 +1675,6 @@
                     cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
     }
 
-   IntGdiSetTextColor(hdcOff, oldFg);
-   IntGdiSetBkColor(hdcOff, oldBg);
-
    Ret = TRUE;
 
 cleanup:
@@ -1687,7 +1686,6 @@
       if(hdcOff) NtGdiDeleteObjectApp(hdcOff);
    }
 
-   if(hdcMem) NtGdiDeleteObjectApp(hdcMem);
    return Ret;
 }
 

Reply via email to