Author: jgardou Date: Tue Jul 13 18:32:33 2010 New Revision: 48026
URL: http://svn.reactos.org/svn/reactos?rev=48026&view=rev Log: [USER32] - exchange mask and color bitmaps if needed in CreateIconIndirect [WIN32K] - Simplify a bit UserDrawIconEx
Modified: branches/reactos-yarotows/dll/win32/user32/windows/cursoricon.c branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c
Modified: branches/reactos-yarotows/dll/win32/user32/windows/cursoricon.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/dll/win32/user3... ============================================================================== --- branches/reactos-yarotows/dll/win32/user32/windows/cursoricon.c [iso-8859-1] (original) +++ branches/reactos-yarotows/dll/win32/user32/windows/cursoricon.c [iso-8859-1] Tue Jul 13 18:32:33 2010 @@ -1393,6 +1393,7 @@ { BITMAP ColorBitmap; BITMAP MaskBitmap; + ICONINFO safeIconInfo;
if(!iconinfo) { @@ -1400,13 +1401,15 @@ 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 @@ 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); }
/******************************************************************************
Modified: branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Tue Jul 13 18:32:33 2010 @@ -528,8 +528,8 @@ 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 @@ hDestDC = NtGdiCreateCompatibleDC(hDc); if(!hDestDC) { - DPRINT1("NtGdiCreateCompatibleBitmap failed!\n"); + DPRINT1("NtGdiCreateCompatibleDC failed!\n"); Ret = FALSE; goto Cleanup ; } @@ -1397,7 +1397,92 @@ 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 @@
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 @@ } }
+done: if(hDestDC != hDc) { NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, cyHeight, hDestDC, 0, 0, SRCCOPY, 0, 0);