Author: gedmurphy
Date: Sat Oct 6 21:59:21 2007
New Revision: 29419
URL:
http://svn.reactos.org/svn/reactos?rev=29419&view=rev
Log:
fix painting of alpha channels in 32bpp icons onto windows/dialogs
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 (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c Sat Oct 6 21:59:21 2007
@@ -1376,20 +1376,20 @@
hbmMask = pIcon->IconInfo.hbmMask;
hbmColor = pIcon->IconInfo.hbmColor;
- if(istepIfAniCur)
+ if (istepIfAniCur)
DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
- if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
+ if (!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
{
return FALSE;
}
- if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
+ if (hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
{
return FALSE;
}
- if(hbmColor)
+ if (hbmColor)
{
IconSize.cx = bmpColor.bmWidth;
IconSize.cy = bmpColor.bmHeight;
@@ -1405,60 +1405,64 @@
bAlpha = TRUE;
}
- if(!diFlags)
+ if (!diFlags)
diFlags = DI_NORMAL;
- if(!cxWidth)
+ if (!cxWidth)
cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
UserGetSystemMetrics(SM_CXICON) : IconSize.cx);
-
- if(!cyHeight)
+
+ if (!cyHeight)
cyHeight = ((diFlags & DI_DEFAULTSIZE) ?
UserGetSystemMetrics(SM_CYICON) : IconSize.cy);
DoFlickerFree = (hbrFlickerFreeDraw &&
(GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH));
- if(DoFlickerFree)
+ if (DoFlickerFree || bAlpha)
{
RECT r;
r.right = cxWidth;
r.bottom = cyHeight;
hdcOff = NtGdiCreateCompatibleDC(hDc);
- if(!hdcOff)
+ if (!hdcOff)
{
DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
return FALSE;
}
hbmOff = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
- if(!hbmOff)
+ if (!hbmOff)
{
DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n");
goto cleanup;
}
-
- hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw);
- if(!hOldOffBrush)
+
+ hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff);
+ if (!hOldOffBmp)
{
DPRINT1("NtGdiSelectObject() failed!\n");
goto cleanup;
}
-
- hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff);
- if(!hOldOffBmp)
- {
- DPRINT1("NtGdiSelectObject() failed!\n");
- goto cleanup;
- }
-
- NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
- }
- else hdcOff = hDc;
-
+
+ if (DoFlickerFree)
+ {
+ hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw);
+ if (!hOldOffBrush)
+ {
+ DPRINT1("NtGdiSelectObject() failed!\n");
+ goto cleanup;
+ }
+
+ NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
+ }
+ }
+ else
+ hdcOff = hDc;
+
hdcMem = NtGdiCreateCompatibleDC(hDc);
- if(!hdcMem)
+ if (!hdcMem)
{
DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
goto cleanup;
@@ -1469,10 +1473,10 @@
oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0));
oldBg = NtGdiSetBkColor(hdcOff, RGB(255, 255, 255));
- if(diFlags & DI_MASK)
+ if (diFlags & DI_MASK)
{
hOldMem = NtGdiSelectObject(hdcMem, hbmMask);
- if(!hOldMem)
+ if (!hOldMem)
{
DPRINT("NtGdiSelectObject() failed!\n");
goto cleanup;
@@ -1483,7 +1487,7 @@
0, 0, IconSize.cx, IconSize.cy,
((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), FALSE);
- if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth)
+ if (!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth)
&& (diFlags & DI_IMAGE))
{
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
@@ -1496,7 +1500,7 @@
NtGdiSelectObject(hdcMem, hOldMem);
}
-
+
if(diFlags & DI_IMAGE)
{
hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask));
@@ -1510,103 +1514,87 @@
NtGdiSelectObject(hdcMem, hOldMem);
}
- if(DoFlickerFree)
- {
- if (bAlpha)
+ if (bAlpha)
+ {
+ BITMAP bm;
+ BITMAPOBJ *BitmapObj = NULL;
+ PBYTE pBits = NULL;
+ BLENDFUNCTION BlendFunc;
+ BYTE Red, Green, Blue, Alpha;
+ DWORD Count = 0;
+ INT i, j;
+
+ BitmapObj = BITMAPOBJ_LockBitmap(hbmOff);
+ if (BitmapObj == NULL)
{
- BITMAPINFO bi;
- BITMAP bm;
- BITMAPOBJ *Bitmap = NULL;
- PBYTE pBits = NULL;
- BLENDFUNCTION BlendFunc;
- BYTE Red, Green, Blue, Alpha;
- DWORD Count = 0;
- INT i, j;
-
- /* Bitmap header */
- bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
- bi.bmiHeader.biWidth = cxWidth;
- bi.bmiHeader.biHeight = cyHeight;
- bi.bmiHeader.biPlanes = 1;
- bi.bmiHeader.biBitCount = 32;
- bi.bmiHeader.biCompression = BI_RGB;
- bi.bmiHeader.biSizeImage = cxWidth * cyHeight * 4;
- bi.bmiHeader.biClrUsed = 0;
- bi.bmiHeader.biClrImportant = 0;
-
- Bitmap = GDIOBJ_LockObj(GdiHandleTable, hbmOff, GDI_OBJECT_TYPE_BITMAP);
- if (Bitmap == NULL)
+ DPRINT1("GDIOBJ_LockObj() failed!\n");
+ goto cleanup;
+ }
+ BITMAP_GetObject(BitmapObj, sizeof(BITMAP), &bm);
+
+ pBits = ExAllocatePoolWithTag(PagedPool, bm.bmWidthBytes * abs(bm.bmHeight),
TAG_BITMAP);
+ if (pBits == NULL)
+ {
+ DPRINT1("ExAllocatePoolWithTag() failed!\n");
+ BITMAPOBJ_UnlockBitmap(BitmapObj);
+ goto cleanup;
+ }
+
+ /* get icon bits */
+ IntGetBitmapBits(BitmapObj, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
+
+ /* premultiply with the alpha channel value */
+ for (i = 0; i < cyHeight; i++)
+ {
+ for (j = 0; j < cxWidth; j++)
{
- DPRINT1("GDIOBJ_LockObj() failed!\n");
- goto cleanup;
+ DWORD OrigPixel = 0;
+ DWORD AlphaPixel = 0;
+
+ OrigPixel = *(DWORD *)(pBits + Count);
+
+ Red = (BYTE)((OrigPixel >> 0) & 0xff);
+ Green = (BYTE)((OrigPixel >> 8) & 0xff);
+ Blue = (BYTE)((OrigPixel >> 16) & 0xff);
+ Alpha = (BYTE)((OrigPixel >> 24) & 0xff);
+
+ Red = (Red * Alpha) / 0xff;
+ Green = (Green * Alpha) / 0xff;
+ Blue = (Blue * Alpha) / 0xff;
+
+ AlphaPixel = (DWORD)(Red | (Green << 8) | (Blue << 16) |
(Alpha << 24));
+
+ *(DWORD *)(pBits + Count) = AlphaPixel;
+ Count += sizeof (DWORD);
}
- BITMAP_GetObject(Bitmap, sizeof(BITMAP), &bm);
-
- /* Buffer */
- pBits = ExAllocatePoolWithTag(PagedPool, bm.bmWidthBytes * abs(bm.bmHeight),
TAG_BITMAP);
- if (pBits == NULL)
- {
- DPRINT1("ExAllocatePoolWithTag() failed!\n");
- GDIOBJ_UnlockObjByPtr(GdiHandleTable, Bitmap);
- goto cleanup;
- }
-
- /* get icon bits */
- IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
-
- /* premultiply with the alpha channel value */
- for (i = 0; i < cyHeight; i++)
- {
- for (j = 0; j < cxWidth; j++)
- {
- DWORD OrigPixel = 0;
- DWORD AlphaPixel = 0;
-
- OrigPixel = *(DWORD *)(pBits + Count);
-
- Red = (BYTE)((OrigPixel >> 0) & 0xff);
- Green = (BYTE)((OrigPixel >> 8) & 0xff);
- Blue = (BYTE)((OrigPixel >> 16) & 0xff);
- Alpha = (BYTE)((OrigPixel >> 24) & 0xff);
-
- Red = (Red * Alpha) / 0xff;
- Green = (Green * Alpha) / 0xff;
- Blue = (Blue * Alpha) / 0xff;
-
- AlphaPixel = (DWORD)(Red | (Green << 8) | (Blue << 16) |
(Alpha << 24));
-
- *(DWORD *)(pBits + Count) = AlphaPixel;
- Count += sizeof (DWORD);
- }
- }
-
- /* set icon bits */
- IntSetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
- ExFreePool(pBits);
-
- GDIOBJ_UnlockObjByPtr(GdiHandleTable, Bitmap);
-
- BlendFunc.BlendOp = AC_SRC_OVER;
- BlendFunc.BlendFlags = 0;
- BlendFunc.SourceConstantAlpha = 255;
- BlendFunc.AlphaFormat = AC_SRC_ALPHA;
-
- NtGdiAlphaBlend(hDc, xLeft, yTop, cxWidth, cyHeight,
- hdcOff, 0, 0, cxWidth, cyHeight, BlendFunc, 0);
}
- else
- {
- NtGdiBitBlt(hDc, xLeft, yTop, cxWidth,
- cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
- }
- }
-
+
+ /* set icon bits */
+ IntSetBitmapBits(BitmapObj, bm.bmWidthBytes * abs(bm.bmHeight), pBits);
+ ExFreePool(pBits);
+
+ BITMAPOBJ_UnlockBitmap(BitmapObj);
+
+ BlendFunc.BlendOp = AC_SRC_OVER;
+ BlendFunc.BlendFlags = 0;
+ BlendFunc.SourceConstantAlpha = 255;
+ BlendFunc.AlphaFormat = AC_SRC_ALPHA;
+
+ NtGdiAlphaBlend(hDc, xLeft, yTop, cxWidth, cyHeight,
+ hdcOff, 0, 0, cxWidth, cyHeight, BlendFunc, 0);
+ }
+ else if (DoFlickerFree)
+ {
+ NtGdiBitBlt(hDc, xLeft, yTop, cxWidth,
+ cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
+ }
+
NtGdiSetTextColor(hdcOff, oldFg);
NtGdiSetBkColor(hdcOff, oldBg);
NtGdiSetStretchBltMode(hdcOff, nStretchMode);
-
+
Ret = TRUE;
-
+
cleanup:
if(DoFlickerFree)
{