⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmaps.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
}

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 + -