From cc33d0bac169df686de086346f42d676530a85de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Mon, 24 Oct 2005 21:57:32 +0000 Subject: [PATCH] Workaround for icon stretching. Makes icons in title bar and taskbar display properly. svn path=/trunk/; revision=18763 --- reactos/subsys/win32k/ntuser/cursoricon.c | 139 +++++++++++++++------- 1 file changed, 96 insertions(+), 43 deletions(-) diff --git a/reactos/subsys/win32k/ntuser/cursoricon.c b/reactos/subsys/win32k/ntuser/cursoricon.c index ea26e0085d9..82fd424c3ba 100644 --- a/reactos/subsys/win32k/ntuser/cursoricon.c +++ b/reactos/subsys/win32k/ntuser/cursoricon.c @@ -1269,7 +1269,82 @@ NtUserSetSystemCursor( } -#define CANSTRETCHBLT 0 +#define STRETCH_CAN_SRCCOPY_ONLY + +#ifdef STRETCH_CAN_SRCCOPY_ONLY +void +FASTCALL +DoStretchBlt(HDC DcDest, int XDest, int YDest, int WidthDest, int HeightDest, + HDC DcSrc, int XSrc, int YSrc, int WidthSrc, int HeightSrc, + DWORD Rop3, BOOL Color) +{ + HDC DcStretched; + HBITMAP BitmapStretched; + HBITMAP OldBitmap; + + if (WidthDest == WidthSrc && HeightDest == HeightSrc) + { + NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest, + DcSrc, XSrc, YSrc, Rop3); + } + else if (SRCCOPY == Rop3) + { + NtGdiStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest, + DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, + Rop3); + } + else + { + DcStretched = NtGdiCreateCompatibleDC(DcSrc); + if (NULL == DcStretched) + { + DPRINT1("Failed to create compatible DC\n"); + return; + } + if (Color) + { + BitmapStretched = NtGdiCreateCompatibleBitmap(DcDest, WidthDest, + HeightDest); + } + else + { + BitmapStretched = NtGdiCreateBitmap(WidthDest, HeightDest, 1, 1, NULL); + } + if (NULL == BitmapStretched) + { + NtGdiDeleteDC(DcStretched); + DPRINT1("Failed to create temporary bitmap\n"); + return; + } + OldBitmap = NtGdiSelectObject(DcStretched, BitmapStretched); + if (NULL == OldBitmap) + { + NtGdiDeleteObject(BitmapStretched); + NtGdiDeleteDC(DcStretched); + DPRINT1("Failed to create temporary bitmap\n"); + return; + } + if (! NtGdiStretchBlt(DcStretched, 0, 0, WidthDest, HeightDest, + DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, + SRCCOPY) || + ! NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest, + DcStretched, 0, 0, Rop3)) + { + DPRINT1("Failed to blt\n"); + } + NtGdiSelectObject(DcStretched, OldBitmap); + NtGdiDeleteObject(BitmapStretched); + NtGdiDeleteDC(DcStretched); + } +} +#else +#define DoStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest, \ + DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, Rop3, Color) \ + NtGdiStretchBlt((DcDest), (XDest), (YDest), (WidthDest), (HeightDest), \ + (DcSrc), (XSrc), (YSrc), (WidthSrc), (HeightSrc), \ + (Rop3)) +#endif /* STRETCH_CAN_SRCCOPY_ONLY */ + /* * @implemented */ @@ -1281,7 +1356,7 @@ NtUserDrawIconEx( int yTop, HICON hIcon, int cxWidth, - int cyWidth, + int cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags, @@ -1299,10 +1374,7 @@ NtUserDrawIconEx( HBITMAP hbmOff = (HBITMAP)0; HGDIOBJ hOldOffBrush = 0, hOldOffBmp = 0, hOldMem; BOOL Ret = FALSE; -#if CANSTRETCHBLT - INT nStretchMode; -#endif DECLARE_RETURN(BOOL); @@ -1349,8 +1421,8 @@ NtUserDrawIconEx( if(!cxWidth) cxWidth = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CXICON) : IconSize.cx); - if(!cyWidth) - cyWidth = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CYICON) : IconSize.cy); + if(!cyHeight) + cyHeight = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CYICON) : IconSize.cy); DoFlickerFree = (hbrFlickerFreeDraw && (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_BRUSH)); @@ -1358,13 +1430,13 @@ NtUserDrawIconEx( { RECT r; r.right = cxWidth; - r.bottom = cyWidth; + r.bottom = cyHeight; hdcOff = NtGdiCreateCompatibleDC(hdc); if(!hdcOff) goto done; - hbmOff = NtGdiCreateCompatibleBitmap(hdc, cxWidth, cyWidth); + hbmOff = NtGdiCreateCompatibleBitmap(hdc, cxWidth, cyHeight); if(!hbmOff) { NtGdiDeleteDC(hdcOff); @@ -1383,10 +1455,7 @@ NtUserDrawIconEx( if(!DoFlickerFree) hdcOff = hdc; -#if CANSTRETCHBLT - nStretchMode = NtGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS); -#endif oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0)); oldBg = NtGdiSetBkColor(hdcOff, RGB(255, 255, 255)); @@ -1394,27 +1463,18 @@ NtUserDrawIconEx( if(diFlags & DI_MASK) { hOldMem = NtGdiSelectObject(hdcMem, hbmMask); -#if CANSTRETCHBLT - NtGdiStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop), - cxWidth, cyWidth, hdcMem, 0, 0, IconSize.cx, IconSize.cy, - ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY)); -#else - - NtGdiBitBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop), - cxWidth, cyWidth, hdcMem, 0, 0, ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY)); -#endif + DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), + (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem, + 0, 0, IconSize.cx, IconSize.cy, + ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), FALSE); if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth) && (diFlags & DI_IMAGE)) { -#if CANSTRETCHBLT - NtGdiStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop), - cxWidth, cyWidth, hdcMem, 0, IconSize.cy, IconSize.cx, IconSize.cy, SRCINVERT); -#else - - NtGdiBitBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop), - cxWidth, cyWidth, hdcMem, 0, IconSize.cy, SRCINVERT); -#endif + DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), + (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem, + 0, IconSize.cy, IconSize.cx, IconSize.cy, SRCINVERT, + FALSE); diFlags &= ~DI_IMAGE; } @@ -1424,30 +1484,23 @@ NtUserDrawIconEx( if(diFlags & DI_IMAGE) { hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask)); -#if CANSTRETCHBLT - NtGdiStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop), - cxWidth, cyWidth, hdcMem, 0, (hbmColor ? 0 : IconSize.cy), - IconSize.cx, IconSize.cy, ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY)); -#else - - NtGdiBitBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop), - cxWidth, cyWidth, hdcMem, 0, (hbmColor ? 0 : IconSize.cy), - ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY)); -#endif + DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), + (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem, + 0, (hbmColor ? 0 : IconSize.cy), IconSize.cx, IconSize.cy, + ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY), + NULL != hbmColor); NtGdiSelectObject(hdcMem, hOldMem); } if(DoFlickerFree) - NtGdiBitBlt(hdc, xLeft, yTop, cxWidth, cyWidth, hdcOff, 0, 0, SRCCOPY); + NtGdiBitBlt(hdc, xLeft, yTop, cxWidth, cyHeight, hdcOff, 0, 0, SRCCOPY); NtGdiSetTextColor(hdcOff, oldFg); NtGdiSetBkColor(hdcOff, oldBg); -#if CANSTRETCHBLT - SetStretchBltMode(hdcOff, nStretchMode); -#endif + NtGdiSetStretchBltMode(hdcOff, nStretchMode); Ret = TRUE;