|
|
Definition at line 1047 of file cursoricon.c.
Referenced by NtUserDrawIconEx(), and UserDrawCaption().
{
BOOL Ret = FALSE;
HBITMAP hbmMask, hbmColor;
BITMAP bmpColor, bm;
BOOL DoFlickerFree;
INT iOldBkColor = 0, iOldTxtColor = 0;
HDC hMemDC, hDestDC = hDc;
HGDIOBJ hOldOffBrush = 0;
HGDIOBJ hOldOffBmp = 0;
HBITMAP hTmpBmp = 0, hOffBmp = 0;
BOOL bAlpha = FALSE;
INT x=xLeft, y=yTop;
hbmMask = pIcon->IconInfo.hbmMask;
hbmColor = pIcon->IconInfo.hbmColor;
if (istepIfAniCur)
ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
if (!hbmMask || !GreGetObject(hbmMask, sizeof(BITMAP), (PVOID)&bm))
{
return FALSE;
}
if (hbmColor && !GreGetObject(hbmColor, sizeof(BITMAP), (PVOID)&bmpColor))
{
return FALSE;
}
if(!(hMemDC = NtGdiCreateCompatibleDC(hDc)))
{
ERR("NtGdiCreateCompatibleDC failed!\n");
return FALSE;
}
if (hbmColor
&& (bmpColor.bmBitsPixel == 32)
&& (diFlags & DI_IMAGE))
{
SURFACE *psurfOff = NULL;
PFN_DIB_GetPixel fnSource_GetPixel = NULL;
INT i, j;
psurfOff = SURFACE_ShareLockSurface(hbmColor);
if (psurfOff)
{
fnSource_GetPixel = DibFunctionsForBitmapFormat[psurfOff->SurfObj.iBitmapFormat].DIB_GetPixel;
if (fnSource_GetPixel)
{
for (i = 0; i < psurfOff->SurfObj.sizlBitmap.cx; i++)
{
for (j = 0; j < psurfOff->SurfObj.sizlBitmap.cy; j++)
{
bAlpha = ((BYTE)(fnSource_GetPixel(&psurfOff->SurfObj, i, j) >> 24) & 0xff);
if (bAlpha)
break;
}
if (bAlpha)
break;
}
}
SURFACE_ShareUnlockSurface(psurfOff);
}
}
if (!cxWidth)
cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
UserGetSystemMetrics(SM_CXICON) : pIcon->Size.cx);
if (!cyHeight)
cyHeight = ((diFlags & DI_DEFAULTSIZE) ?
UserGetSystemMetrics(SM_CYICON) : pIcon->Size.cy);
DoFlickerFree = (hbrFlickerFreeDraw &&
(GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH));
if (DoFlickerFree)
{
hDestDC = NtGdiCreateCompatibleDC(hDc);
if(!hDestDC)
{
ERR("NtGdiCreateCompatibleDC failed!\n");
Ret = FALSE;
goto Cleanup ;
}
hOffBmp = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
if(!hOffBmp)
{
ERR("NtGdiCreateCompatibleBitmap failed!\n");
goto Cleanup ;
}
hOldOffBmp = NtGdiSelectBitmap(hDestDC, hOffBmp);
hOldOffBrush = NtGdiSelectBrush(hDestDC, hbrFlickerFreeDraw);
NtGdiPatBlt(hDestDC, 0, 0, cxWidth, cyHeight, PATCOPY);
NtGdiSelectBrush(hDestDC, hOldOffBrush);
x=y=0;
}
iOldTxtColor = IntGdiSetTextColor(hDc, 0);
iOldBkColor = IntGdiSetBkColor(hDc, 0x00FFFFFF);
if(bAlpha && (diFlags & DI_IMAGE))
{
BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
BYTE Alpha;
INT i, j;
PSURFACE psurf;
PBYTE ptr ;
HBITMAP hMemBmp = NULL;
hMemBmp = BITMAP_CopyBitmap(hbmColor);
if(!hMemBmp)
{
ERR("BITMAP_CopyBitmap failed!");
goto CleanupAlpha;
}
psurf = SURFACE_ShareLockSurface(hMemBmp);
if(!psurf)
{
ERR("SURFACE_LockSurface failed!\n");
goto CleanupAlpha;
}
for (i = 0; i < psurf->SurfObj.sizlBitmap.cy; i++)
{
ptr = (PBYTE)psurf->SurfObj.pvScan0 + i*psurf->SurfObj.lDelta;
for (j = 0; j < psurf->SurfObj.sizlBitmap.cx; j++)
{
Alpha = ptr[3];
ptr[0] = (ptr[0] * Alpha) / 0xff;
ptr[1] = (ptr[1] * Alpha) / 0xff;
ptr[2] = (ptr[2] * Alpha) / 0xff;
ptr += 4;
}
}
SURFACE_ShareUnlockSurface(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(hMemBmp) NtGdiDeleteObjectApp(hMemBmp);
if(Ret) goto done;
}
if (diFlags & DI_MASK)
{
DWORD rop = (diFlags & DI_IMAGE) ? SRCAND : SRCCOPY;
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
NtGdiStretchBlt(hDestDC,
x,
y,
cxWidth,
cyHeight,
hMemDC,
0,
0,
pIcon->Size.cx,
pIcon->Size.cy,
rop,
0);
NtGdiSelectBitmap(hMemDC, hTmpBmp);
}
if(diFlags & DI_IMAGE)
{
if (hbmColor)
{
DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ;
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmColor);
NtGdiStretchBlt(hDestDC,
x,
y,
cxWidth,
cyHeight,
hMemDC,
0,
0,
pIcon->Size.cx,
pIcon->Size.cy,
rop,
0);
NtGdiSelectBitmap(hMemDC, hTmpBmp);
}
else
{
DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ;
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
NtGdiStretchBlt(hDestDC,
x,
y,
cxWidth,
cyHeight,
hMemDC,
0,
pIcon->Size.cy,
pIcon->Size.cx,
pIcon->Size.cy,
rop,
0);
NtGdiSelectBitmap(hMemDC, hTmpBmp);
}
}
done:
if(hDestDC != hDc)
{
NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, cyHeight, hDestDC, 0, 0, SRCCOPY, 0, 0);
}
IntGdiSetBkColor(hDc, iOldBkColor);
IntGdiSetTextColor(hDc, iOldTxtColor);
Ret = TRUE ;
Cleanup:
NtGdiDeleteObjectApp(hMemDC);
if(hDestDC != hDc)
{
if(hOldOffBmp) NtGdiSelectBitmap(hDestDC, hOldOffBmp);
NtGdiDeleteObjectApp(hDestDC);
if(hOffBmp) NtGdiDeleteObjectApp(hOffBmp);
}
return Ret;
}
|