📄 bitmaps.c
字号:
}
COLORREF STDCALL
NtGdiSetPixel(
HDC hDC,
INT X,
INT Y,
COLORREF Color)
{
DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color);
DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color);
if (NtGdiSetPixelV(hDC,X,Y,Color))
{
Color = NtGdiGetPixel(hDC,X,Y);
DPRINT("1 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color);
return Color;
}
Color = ((COLORREF) -1);
DPRINT("2 NtGdiSetPixel X %ld Y %ld C %ld\n",X,Y,Color);
return Color;
}
BOOL STDCALL
NtGdiSetPixelV(
HDC hDC,
INT X,
INT Y,
COLORREF Color)
{
HBRUSH NewBrush = NtGdiCreateSolidBrush(Color, NULL);
HGDIOBJ OldBrush;
if (NewBrush == NULL)
return(FALSE);
OldBrush = NtGdiSelectObject(hDC, NewBrush);
if (OldBrush == NULL)
{
NtGdiDeleteObject(NewBrush);
return(FALSE);
}
NtGdiPatBlt(hDC, X, Y, 1, 1, PATCOPY);
NtGdiSelectObject(hDC, OldBrush);
NtGdiDeleteObject(NewBrush);
return TRUE;
}
BOOL STDCALL
NtGdiStretchBlt(
HDC hDCDest,
INT XOriginDest,
INT YOriginDest,
INT WidthDest,
INT HeightDest,
HDC hDCSrc,
INT XOriginSrc,
INT YOriginSrc,
INT WidthSrc,
INT HeightSrc,
DWORD ROP,
IN DWORD dwBackColor)
{
PDC DCDest = NULL;
PDC DCSrc = NULL;
BITMAPOBJ *BitmapDest, *BitmapSrc;
RECTL DestRect;
RECTL SourceRect;
BOOL Status;
XLATEOBJ *XlateObj = NULL;
HPALETTE SourcePalette = 0, DestPalette = 0;
PGDIBRUSHOBJ BrushObj;
BOOL UsesSource = ((ROP & 0xCC0000) >> 2) != (ROP & 0x330000);
BOOL UsesPattern = ((ROP & 0xF00000) >> 4) != (ROP & 0x0F0000);
if (0 == WidthDest || 0 == HeightDest || 0 == WidthSrc || 0 == HeightSrc)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
DCDest = DC_LockDc(hDCDest);
if (NULL == DCDest)
{
DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCDest);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (DCDest->IsIC)
{
DC_UnlockDc(DCDest);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if (UsesSource)
{
if (hDCSrc != hDCDest)
{
DCSrc = DC_LockDc(hDCSrc);
if (NULL == DCSrc)
{
DC_UnlockDc(DCDest);
DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (DCSrc->IsIC)
{
DC_UnlockDc(DCSrc);
DC_UnlockDc(DCDest);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
}
else
{
DCSrc = DCDest;
}
}
else
{
DCSrc = NULL;
}
/* Offset the destination and source by the origin of their DCs. */
XOriginDest += DCDest->w.DCOrgX;
YOriginDest += DCDest->w.DCOrgY;
if (UsesSource)
{
XOriginSrc += DCSrc->w.DCOrgX;
YOriginSrc += DCSrc->w.DCOrgY;
}
DestRect.left = XOriginDest;
DestRect.top = YOriginDest;
DestRect.right = XOriginDest+WidthDest;
DestRect.bottom = YOriginDest+HeightDest;
SourceRect.left = XOriginSrc;
SourceRect.top = YOriginSrc;
SourceRect.right = XOriginSrc+WidthSrc;
SourceRect.bottom = YOriginSrc+HeightSrc;
/* Determine surfaces to be used in the bitblt */
BitmapDest = BITMAPOBJ_LockBitmap(DCDest->w.hBitmap);
if (UsesSource)
{
if (DCSrc->w.hBitmap == DCDest->w.hBitmap)
BitmapSrc = BitmapDest;
else
BitmapSrc = BITMAPOBJ_LockBitmap(DCSrc->w.hBitmap);
}
else
{
BitmapSrc = NULL;
}
if ( UsesSource )
{
int sw = BitmapSrc->SurfObj.sizlBitmap.cx;
int sh = BitmapSrc->SurfObj.sizlBitmap.cy;
if ( SourceRect.left < 0 )
{
DestRect.left = DestRect.right - (DestRect.right-DestRect.left) * (SourceRect.right)/abs(SourceRect.right-SourceRect.left);
SourceRect.left = 0;
}
if ( SourceRect.top < 0 )
{
DestRect.top = DestRect.bottom - (DestRect.bottom-DestRect.top) * (SourceRect.bottom)/abs(SourceRect.bottom-SourceRect.top);
SourceRect.top = 0;
}
if ( SourceRect.right < -1 )
{
DestRect.right = DestRect.left + (DestRect.right-DestRect.left) * (-1-SourceRect.left)/abs(SourceRect.right-SourceRect.left);
SourceRect.right = -1;
}
if ( SourceRect.bottom < -1 )
{
DestRect.bottom = DestRect.top + (DestRect.bottom-DestRect.top) * (-1-SourceRect.top)/abs(SourceRect.bottom-SourceRect.top);
SourceRect.bottom = -1;
}
if ( SourceRect.right > sw )
{
DestRect.right = DestRect.left + (DestRect.right-DestRect.left) * abs(sw-SourceRect.left) / abs(SourceRect.right-SourceRect.left);
SourceRect.right = sw;
}
if ( SourceRect.bottom > sh )
{
DestRect.bottom = DestRect.top + (DestRect.bottom-DestRect.top) * abs(sh-SourceRect.top) / abs(SourceRect.bottom-SourceRect.top);
SourceRect.bottom = sh;
}
sw--;
sh--;
if ( SourceRect.left > sw )
{
DestRect.left = DestRect.right - (DestRect.right-DestRect.left) * (SourceRect.right-sw) / abs(SourceRect.right-SourceRect.left);
SourceRect.left = 0;
}
if ( SourceRect.top > sh )
{
DestRect.top = DestRect.bottom - (DestRect.bottom-DestRect.top) * (SourceRect.bottom-sh) / abs(SourceRect.bottom-SourceRect.top);
SourceRect.top = 0;
}
if (0 == (DestRect.right-DestRect.left) || 0 == (DestRect.bottom-DestRect.top) || 0 == (SourceRect.right-SourceRect.left) || 0 == (SourceRect.bottom-SourceRect.top))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Status = FALSE;
goto failed;
}
}
if (UsesPattern)
{
BrushObj = BRUSHOBJ_LockBrush(DCDest->w.hBrush);
if (NULL == BrushObj)
{
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(DCSrc);
}
DC_UnlockDc(DCDest);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
}
else
{
BrushObj = NULL;
}
/* Create the XLATEOBJ. */
if (UsesSource)
{
if (DCDest->w.hPalette != 0)
DestPalette = DCDest->w.hPalette;
if (DCSrc->w.hPalette != 0)
SourcePalette = DCSrc->w.hPalette;
/* FIXME: Use the same logic for create XLATEOBJ as in NtGdiBitBlt. */
XlateObj = (XLATEOBJ*)IntEngCreateXlate(0, 0, DestPalette, SourcePalette);
if (NULL == XlateObj)
{
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(DCSrc);
}
DC_UnlockDc(DCDest);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return FALSE;
}
}
/* Perform the bitblt operation */
Status = IntEngStretchBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
NULL, DCDest->CombinedClip, XlateObj,
&DestRect, &SourceRect, NULL, NULL, NULL,
COLORONCOLOR);
if (UsesSource)
EngDeleteXlate(XlateObj);
if (UsesPattern)
{
BRUSHOBJ_UnlockBrush(BrushObj);
}
failed:
if (UsesSource && DCSrc->w.hBitmap != DCDest->w.hBitmap)
{
BITMAPOBJ_UnlockBitmap(BitmapSrc);
}
BITMAPOBJ_UnlockBitmap(BitmapDest);
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(DCSrc);
}
DC_UnlockDc(DCDest);
return Status;
}
BOOL STDCALL
NtGdiAlphaBlend(
HDC hDCDest,
LONG XOriginDest,
LONG YOriginDest,
LONG WidthDest,
LONG HeightDest,
HDC hDCSrc,
LONG XOriginSrc,
LONG YOriginSrc,
LONG WidthSrc,
LONG HeightSrc,
BLENDFUNCTION BlendFunc)
{
PDC DCDest = NULL;
PDC DCSrc = NULL;
BITMAPOBJ *BitmapDest, *BitmapSrc;
RECTL DestRect, SourceRect;
BOOL Status;
XLATEOBJ *XlateObj;
BLENDOBJ BlendObj;
HPALETTE SourcePalette = 0, DestPalette = 0;
BlendObj.BlendFunction = BlendFunc;
DCDest = DC_LockDc(hDCDest);
if (NULL == DCDest)
{
DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCDest);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (DCDest->IsIC)
{
DC_UnlockDc(DCDest);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if (hDCSrc != hDCDest)
{
DCSrc = DC_LockDc(hDCSrc);
if (NULL == DCSrc)
{
DC_UnlockDc(DCDest);
DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (DCSrc->IsIC)
{
DC_UnlockDc(DCSrc);
DC_UnlockDc(DCDest);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
}
else
{
DCSrc = DCDest;
}
/* Offset the destination and source by the origin of their DCs. */
XOriginDest += DCDest->w.DCOrgX;
YOriginDest += DCDest->w.DCOrgY;
XOriginSrc += DCSrc->w.DCOrgX;
YOriginSrc += DCSrc->w.DCOrgY;
DestRect.left = XOriginDest;
DestRect.top = YOriginDest;
DestRect.right = XOriginDest + WidthDest;
DestRect.bottom = YOriginDest + HeightDest;
SourceRect.left = XOriginSrc;
SourceRect.top = YOriginSrc;
SourceRect.right = XOriginSrc + WidthSrc;
SourceRect.bottom = YOriginSrc + HeightSrc;
/* Determine surfaces to be used in the bitblt */
BitmapDest = BITMAPOBJ_LockBitmap(DCDest->w.hBitmap);
if (DCSrc->w.hBitmap == DCDest->w.hBitmap)
BitmapSrc = BitmapDest;
else
BitmapSrc = BITMAPOBJ_LockBitmap(DCSrc->w.hBitmap);
/* Create the XLATEOBJ. */
if (DCDest->w.hPalette != 0)
DestPalette = DCDest->w.hPalette;
if (DCSrc->w.hPalette != 0)
SourcePalette = DCSrc->w.hPalette;
/* KB41464 details how to convert between mono and color */
if (DCDest->w.bitsPerPixel == 1 && DCSrc->w.bitsPerPixel == 1)
{
XlateObj = NULL;
}
else
{
if (DCDest->w.bitsPerPixel == 1)
{
XlateObj = IntEngCreateMonoXlate(0, DestPalette, SourcePalette, DCSrc->w.backgroundColor);
}
else if (DCSrc->w.bitsPerPixel == 1)
{
XlateObj = IntEngCreateSrcMonoXlate(DestPalette, DCSrc->w.backgroundColor, DCSrc->w.textColor);
}
else
{
XlateObj = IntEngCreateXlate(0, 0, DestPalette, SourcePalette);
}
if (NULL == XlateObj)
{
BITMAPOBJ_UnlockBitmap(BitmapDest);
if (BitmapSrc != BitmapDest)
BITMAPOBJ_UnlockBitmap(BitmapSrc);
DC_UnlockDc(DCDest);
if (hDCSrc != hDCDest)
DC_UnlockDc(DCSrc);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return FALSE;
}
}
/* Perform the alpha blend operation */
Status = IntEngAlphaBlend(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
DCDest->CombinedClip, XlateObj,
&DestRect, &SourceRect, &BlendObj);
if (XlateObj != NULL)
EngDeleteXlate(XlateObj);
BITMAPOBJ_UnlockBitmap(BitmapDest);
if (BitmapSrc != BitmapDest)
BITMAPOBJ_UnlockBitmap(BitmapSrc);
DC_UnlockDc(DCDest);
if (hDCSrc != hDCDest)
DC_UnlockDc(DCSrc);
return Status;
}
/* Internal Functions */
INT FASTCALL
BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
{
#if 0
switch(bpp)
{
case 1:
return 2 * ((bmWidth+15) >> 4);
case 24:
bmWidth *= 3; /* fall through */
case 8:
return bmWidth + (bmWidth & 1);
case 32:
return bmWidth * 4;
case 16:
case 15:
return bmWidth * 2;
case 4:
return 2 * ((bmWidth+3) >> 2);
default:
DPRINT ("stub");
}
return -1;
#endif
return ((bmWidth * bpp + 15) & ~15) >> 3;
}
HBITMAP FASTCALL
BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)
{
HBITMAP res;
BITMAP bm;
BITMAPOBJ *Bitmap;
if (hBitmap == NULL)
return 0;
Bitmap = GDIOBJ_LockObj(GdiHandleTable, hBitmap, GDI_OBJECT_TYPE_BITMAP);
if (Bitmap == NULL)
return 0;
BITMAP_GetObject(Bitmap, sizeof(BITMAP), &bm);
bm.bmBits = NULL;
if (Bitmap->SurfObj.lDelta >= 0)
bm.bmHeight = -bm.bmHeight;
res = IntCreateBitmapIndirect(&bm);
if(res)
{
PBYTE buf;
buf = ExAllocatePoolWithTag (PagedPool, bm.bmWidthBytes * abs(bm.bmHeight), TAG_BITMAP);
NtGdiGetBitmapBits (hBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
NtGdiSetBitmapBits (res, bm.bmWidthBytes * abs(bm.bmHeight), buf);
ExFreePool (buf);
}
GDIOBJ_UnlockObjByPtr(GdiHandleTable, Bitmap);
return res;
}
INT STDCALL
BITMAP_GetObject(BITMAPOBJ * bmp, INT Count, LPVOID buffer)
{
if( buffer == NULL ) return sizeof(BITMAP);
if (Count < sizeof(BITMAP)) return 0;
if(bmp->dib)
{
if(Count < (INT) sizeof(DIBSECTION))
{
if (Count > (INT) sizeof(BITMAP)) Count = sizeof(BITMAP);
}
else
{
if (Count > (INT) sizeof(DIBSECTION)) Count = sizeof(DIBSECTION);
}
memcpy(buffer, bmp->dib, Count);
return Count;
}
else
{
BITMAP Bitmap;
if (Count > (INT) sizeof(BITMAP)) Count = sizeof(BITMAP);
Bitmap.bmType = 0;
Bitmap.bmWidth = bmp->SurfObj.sizlBitmap.cx;
Bitmap.bmHeight = bmp->SurfObj.sizlBitmap.cy;
Bitmap.bmWidthBytes = abs(bmp->SurfObj.lDelta);
Bitmap.bmPlanes = 1;
Bitmap.bmBitsPixel = BitsPerFormat(bmp->SurfObj.iBitmapFormat);
//Bitmap.bmBits = bmp->SurfObj.pvBits;
Bitmap.bmBits = NULL; /* not set accoring wine test confirm in win2k */
memcpy(buffer, &Bitmap, Count);
return Count;
}
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -