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 <bstsoft(a)narod.ru>
- 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/nt…
==============================================================================
--- 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;
}