Workaround for icon stretching. Makes icons in title bar and taskbar display

properly.

svn path=/trunk/; revision=18763
This commit is contained in:
Gé van Geldorp 2005-10-24 21:57:32 +00:00
parent 4b3bf39cbc
commit cc33d0bac1

View file

@ -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;