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

📄 bitmaps.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (0 == Width || 0 == Height)
	{
		Bmp = NtGdiCreateBitmap (1, 1, 1, 1, NULL);
	}
	else
	{
		Bmp = NtGdiCreateBitmap(Width, Height, 1, Dc->w.bitsPerPixel, NULL);
	}

	return Bmp;
}

HBITMAP STDCALL
NtGdiCreateCompatibleBitmap(
	HDC hDC,
	INT Width,
	INT Height)
{
	HBITMAP Bmp;
	PDC Dc;

	Dc = DC_LockDc(hDC);

	DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, Dc->w.bitsPerPixel);

	if (NULL == Dc)
	{
		SetLastWin32Error(ERROR_INVALID_HANDLE);
		return NULL;
	}

	Bmp = IntCreateCompatibleBitmap(Dc, Width, Height);

	DPRINT ("\t\t%04x\n", Bmp);
	DC_UnlockDc(Dc);
	return Bmp;
}

HBITMAP STDCALL
NtGdiCreateBitmapIndirect(CONST BITMAP *UnsafeBM)
{
  BITMAP BM;
  NTSTATUS Status = STATUS_SUCCESS;

  _SEH_TRY
  {
    ProbeForRead(UnsafeBM, sizeof(BITMAP), 1);
    BM = *UnsafeBM;
    if (NULL != BM.bmBits)
      {
      ProbeForRead(BM.bmBits, BM.bmWidthBytes * abs(BM.bmHeight), 2);
      }
  }
  _SEH_HANDLE
  {
    Status = _SEH_GetExceptionCode();
  }
  _SEH_END;
  if(!NT_SUCCESS(Status))
  {
    SetLastNtError(Status);
    return NULL;
  }

  return IntCreateBitmapIndirect(&BM);
}

HBITMAP STDCALL
NtGdiCreateDiscardableBitmap(
	HDC  hDC,
	INT  Width,
	INT  Height)
{
	/* FIXME: this probably should do something else */
	return  NtGdiCreateCompatibleBitmap(hDC, Width, Height);
}

BOOL STDCALL
NtGdiExtFloodFill(
	HDC  hDC,
	INT  XStart,
	INT  YStart,
	COLORREF  Color,
	UINT  FillType)
{
   DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");

   /* lie and say we succeded */
	return TRUE;
}

BOOL STDCALL
NtGdiFloodFill(
	HDC  hDC,
	INT  XStart,
	INT  YStart,
	COLORREF  Fill)
{
	return NtGdiExtFloodFill(hDC, XStart, YStart, Fill, FLOODFILLBORDER );
}

BOOL STDCALL
NtGdiGetBitmapDimensionEx(
	HBITMAP  hBitmap,
	LPSIZE  Dimension)
{
	PBITMAPOBJ  bmp;

	bmp = BITMAPOBJ_LockBitmap(hBitmap);
	if (bmp == NULL)
	{
		return FALSE;
	}

	*Dimension = bmp->dimension;

	BITMAPOBJ_UnlockBitmap(bmp);

	return  TRUE;
}

COLORREF STDCALL
NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
{
	PDC dc = NULL;
	COLORREF Result = (COLORREF)CLR_INVALID; // default to failure
	BOOL bInRect = FALSE;
	BITMAPOBJ *BitmapObject;
	SURFOBJ *SurfaceObject;
	HPALETTE Pal = 0;
	XLATEOBJ *XlateObj;
    HBITMAP hBmpTmp;

	dc = DC_LockDc (hDC);

	if ( !dc )
	{
		SetLastWin32Error(ERROR_INVALID_HANDLE);
		return Result;
	}
	if (dc->IsIC)
	{
		DC_UnlockDc(dc);
		return Result;
	}
	XPos += dc->w.DCOrgX;
	YPos += dc->w.DCOrgY;
	if ( IN_RECT(dc->CombinedClip->rclBounds,XPos,YPos) )
	{
		bInRect = TRUE;
		BitmapObject = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
		SurfaceObject = &BitmapObject->SurfObj;
		if ( BitmapObject )
		{
			if ( dc->w.hPalette != 0 )
				Pal = dc->w.hPalette;
			/* FIXME: Verify if it shouldn't be PAL_BGR! */
			XlateObj = (XLATEOBJ*)IntEngCreateXlate ( PAL_RGB, 0, NULL, Pal );
			if ( XlateObj )
			{
				// check if this DC has a DIB behind it...
				if ( SurfaceObject->pvScan0 ) // STYPE_BITMAP == SurfaceObject->iType
				{
					ASSERT ( SurfaceObject->lDelta );
					Result = XLATEOBJ_iXlate(XlateObj,
						DibFunctionsForBitmapFormat[SurfaceObject->iBitmapFormat].DIB_GetPixel ( SurfaceObject, XPos, YPos ) );
				}
				EngDeleteXlate(XlateObj);
			}
			BITMAPOBJ_UnlockBitmap(BitmapObject);
		}
	}
	DC_UnlockDc(dc);

	// if Result is still CLR_INVALID, then the "quick" method above didn't work
	if ( bInRect && Result == CLR_INVALID )
	{
		// FIXME: create a 1x1 32BPP DIB, and blit to it
		HDC hDCTmp = NtGdiCreateCompatibleDC(hDC);
		if ( hDCTmp )
		{
			static const BITMAPINFOHEADER bih = { sizeof(BITMAPINFOHEADER), 1, 1, 1, 32, BI_RGB, 0, 0, 0, 0, 0 };
			BITMAPINFO bi;
			RtlMoveMemory ( &(bi.bmiHeader), &bih, sizeof(bih) );
			hBmpTmp = NtGdiCreateDIBitmap ( hDC, &bi.bmiHeader, 0, NULL, &bi, DIB_RGB_COLORS );
			//HBITMAP hBmpTmp = NtGdiCreateBitmap ( 1, 1, 1, 32, NULL);
			if ( hBmpTmp )
			{
				HBITMAP hBmpOld = (HBITMAP)NtGdiSelectObject ( hDCTmp, hBmpTmp );
				if ( hBmpOld )
				{
					PBITMAPOBJ bmpobj;

					NtGdiBitBlt ( hDCTmp, 0, 0, 1, 1, hDC, XPos, YPos, SRCCOPY, 0, 0 );
					NtGdiSelectObject ( hDCTmp, hBmpOld );

					// our bitmap is no longer selected, so we can access it's stuff...
					bmpobj = BITMAPOBJ_LockBitmap ( hBmpTmp );
					if ( bmpobj )
					{
						Result = *(COLORREF*)bmpobj->SurfObj.pvScan0;
						BITMAPOBJ_UnlockBitmap ( bmpobj );
					}
				}
				NtGdiDeleteObject ( hBmpTmp );
			}
			NtGdiDeleteObjectApp ( hDCTmp );
		}
	}

	return Result;
}

/***********************************************************************
 * MaskBlt
 * Ported from WINE by sedwards 11-4-03
 *
 * Someone thought it would be faster to do it here and then switch back
 * to GDI32. I dunno. Write a test and let me know.
 */

static __inline BYTE
SwapROP3_SrcDst(BYTE bRop3)
{
	return (bRop3 & 0x99) | ((bRop3 & 0x22) << 1) | ((bRop3 & 0x44) >> 1);
}

#define FRGND_ROP3(ROP4)	((ROP4) & 0x00FFFFFF)
#define BKGND_ROP3(ROP4)	(ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
#define DSTCOPY 		0x00AA0029
#define DSTERASE		0x00220326 /* dest = dest & (~src) : DSna */

BOOL STDCALL
NtGdiMaskBlt (
	HDC hdcDest, INT nXDest, INT nYDest,
	INT nWidth, INT nHeight, HDC hdcSrc,
	INT nXSrc, INT nYSrc, HBITMAP hbmMask,
	INT xMask, INT yMask, DWORD dwRop,
	IN DWORD crBackColor)
{
	HBITMAP hOldMaskBitmap, hBitmap2, hOldBitmap2, hBitmap3, hOldBitmap3;
	HDC hDCMask, hDC1, hDC2;
	static const DWORD ROP3Table[256] =
	{
		0x00000042, 0x00010289,
		0x00020C89, 0x000300AA,
		0x00040C88, 0x000500A9,
		0x00060865, 0x000702C5,
		0x00080F08, 0x00090245,
		0x000A0329, 0x000B0B2A,
		0x000C0324, 0x000D0B25,
		0x000E08A5, 0x000F0001,
		0x00100C85, 0x001100A6,
		0x00120868, 0x001302C8,
		0x00140869, 0x001502C9,
		0x00165CCA, 0x00171D54,
		0x00180D59, 0x00191CC8,
		0x001A06C5, 0x001B0768,
		0x001C06CA, 0x001D0766,
		0x001E01A5, 0x001F0385,
		0x00200F09, 0x00210248,
		0x00220326, 0x00230B24,
		0x00240D55, 0x00251CC5,
		0x002606C8, 0x00271868,
		0x00280369, 0x002916CA,
		0x002A0CC9, 0x002B1D58,
		0x002C0784, 0x002D060A,
		0x002E064A, 0x002F0E2A,
		0x0030032A, 0x00310B28,
		0x00320688, 0x00330008,
		0x003406C4, 0x00351864,
		0x003601A8, 0x00370388,
		0x0038078A, 0x00390604,
		0x003A0644, 0x003B0E24,
		0x003C004A, 0x003D18A4,
		0x003E1B24, 0x003F00EA,
		0x00400F0A, 0x00410249,
		0x00420D5D, 0x00431CC4,
		0x00440328, 0x00450B29,
		0x004606C6, 0x0047076A,
		0x00480368, 0x004916C5,
		0x004A0789, 0x004B0605,
		0x004C0CC8, 0x004D1954,
		0x004E0645, 0x004F0E25,
		0x00500325, 0x00510B26,
		0x005206C9, 0x00530764,
		0x005408A9, 0x00550009,
		0x005601A9, 0x00570389,
		0x00580785, 0x00590609,
		0x005A0049, 0x005B18A9,
		0x005C0649, 0x005D0E29,
		0x005E1B29, 0x005F00E9,
		0x00600365, 0x006116C6,
		0x00620786, 0x00630608,
		0x00640788, 0x00650606,
		0x00660046, 0x006718A8,
		0x006858A6, 0x00690145,
		0x006A01E9, 0x006B178A,
		0x006C01E8, 0x006D1785,
		0x006E1E28, 0x006F0C65,
		0x00700CC5, 0x00711D5C,
		0x00720648, 0x00730E28,
		0x00740646, 0x00750E26,
		0x00761B28, 0x007700E6,
		0x007801E5, 0x00791786,
		0x007A1E29, 0x007B0C68,
		0x007C1E24, 0x007D0C69,
		0x007E0955, 0x007F03C9,
		0x008003E9, 0x00810975,
		0x00820C49, 0x00831E04,
		0x00840C48, 0x00851E05,
		0x008617A6, 0x008701C5,
		0x008800C6, 0x00891B08,
		0x008A0E06, 0x008B0666,
		0x008C0E08, 0x008D0668,
		0x008E1D7C, 0x008F0CE5,
		0x00900C45, 0x00911E08,
		0x009217A9, 0x009301C4,
		0x009417AA, 0x009501C9,
		0x00960169, 0x0097588A,
		0x00981888, 0x00990066,
		0x009A0709, 0x009B07A8,
		0x009C0704, 0x009D07A6,
		0x009E16E6, 0x009F0345,
		0x00A000C9, 0x00A11B05,
		0x00A20E09, 0x00A30669,
		0x00A41885, 0x00A50065,
		0x00A60706, 0x00A707A5,
		0x00A803A9, 0x00A90189,
		0x00AA0029, 0x00AB0889,
		0x00AC0744, 0x00AD06E9,
		0x00AE0B06, 0x00AF0229,
		0x00B00E05, 0x00B10665,
		0x00B21974, 0x00B30CE8,
		0x00B4070A, 0x00B507A9,
		0x00B616E9, 0x00B70348,
		0x00B8074A, 0x00B906E6,
		0x00BA0B09, 0x00BB0226,
		0x00BC1CE4, 0x00BD0D7D,
		0x00BE0269, 0x00BF08C9,
		0x00C000CA, 0x00C11B04,
		0x00C21884, 0x00C3006A,
		0x00C40E04, 0x00C50664,
		0x00C60708, 0x00C707AA,
		0x00C803A8, 0x00C90184,
		0x00CA0749, 0x00CB06E4,
		0x00CC0020, 0x00CD0888,
		0x00CE0B08, 0x00CF0224,
		0x00D00E0A, 0x00D1066A,
		0x00D20705, 0x00D307A4,
		0x00D41D78, 0x00D50CE9,
		0x00D616EA, 0x00D70349,
		0x00D80745, 0x00D906E8,
		0x00DA1CE9, 0x00DB0D75,
		0x00DC0B04, 0x00DD0228,
		0x00DE0268, 0x00DF08C8,
		0x00E003A5, 0x00E10185,
		0x00E20746, 0x00E306EA,
		0x00E40748, 0x00E506E5,
		0x00E61CE8, 0x00E70D79,
		0x00E81D74, 0x00E95CE6,
		0x00EA02E9, 0x00EB0849,
		0x00EC02E8, 0x00ED0848,
		0x00EE0086, 0x00EF0A08,
		0x00F00021, 0x00F10885,
		0x00F20B05, 0x00F3022A,
		0x00F40B0A, 0x00F50225,
		0x00F60265, 0x00F708C5,
		0x00F802E5, 0x00F90845,
		0x00FA0089, 0x00FB0A09,
		0x00FC008A, 0x00FD0A0A,
		0x00FE02A9, 0x00FF0062,
	};

	if (!hbmMask)
		return NtGdiBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop), 0, 0);

	/* 1. make mask bitmap's dc */
	hDCMask = NtGdiCreateCompatibleDC(hdcDest);
	hOldMaskBitmap = (HBITMAP)NtGdiSelectObject(hDCMask, hbmMask);

	/* 2. make masked Background bitmap */

	/* 2.1 make bitmap */
	hDC1 = NtGdiCreateCompatibleDC(hdcDest);
	hBitmap2 = NtGdiCreateCompatibleBitmap(hdcDest, nWidth, nHeight);
	hOldBitmap2 = (HBITMAP)NtGdiSelectObject(hDC1, hBitmap2);

	/* 2.2 draw dest bitmap and mask */
	NtGdiBitBlt(hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY, 0, 0);
	NtGdiBitBlt(hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, BKGND_ROP3(dwRop), 0, 0);
	NtGdiBitBlt(hDC1, 0, 0, nWidth, nHeight, hDCMask, xMask, yMask, DSTERASE, 0, 0);

	/* 3. make masked Foreground bitmap */

	/* 3.1 make bitmap */
	hDC2 = NtGdiCreateCompatibleDC(hdcDest);
	hBitmap3 = NtGdiCreateCompatibleBitmap(hdcDest, nWidth, nHeight);
	hOldBitmap3 = (HBITMAP)NtGdiSelectObject(hDC2, hBitmap3);

	/* 3.2 draw src bitmap and mask */
	NtGdiBitBlt(hDC2, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY, 0, 0);
	NtGdiBitBlt(hDC2, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop), 0,0);
	NtGdiBitBlt(hDC2, 0, 0, nWidth, nHeight, hDCMask, xMask, yMask, SRCAND, 0, 0);

	/* 4. combine two bitmap and copy it to hdcDest */
	NtGdiBitBlt(hDC1, 0, 0, nWidth, nHeight, hDC2, 0, 0, SRCPAINT, 0, 0);
	NtGdiBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hDC1, 0, 0, SRCCOPY, 0, 0);

	/* 5. restore all object */
	NtGdiSelectObject(hDCMask, hOldMaskBitmap);
	NtGdiSelectObject(hDC1, hOldBitmap2);
	NtGdiSelectObject(hDC2, hOldBitmap3);

	/* 6. delete all temp object */
	NtGdiDeleteObject(hBitmap2);
	NtGdiDeleteObject(hBitmap3);

	NtGdiDeleteObjectApp(hDC1);
	NtGdiDeleteObjectApp(hDC2);
	NtGdiDeleteObjectApp(hDCMask);

	return TRUE;
}

BOOL
APIENTRY
NtGdiPlgBlt(
    IN HDC hdcTrg,
    IN LPPOINT pptlTrg,
    IN HDC hdcSrc,
    IN INT xSrc,
    IN INT ySrc,
    IN INT cxSrc,
    IN INT cySrc,
    IN HBITMAP hbmMask,
    IN INT xMask,
    IN INT yMask,
    IN DWORD crBackColor)
{
	UNIMPLEMENTED;
	return FALSE;
}

LONG STDCALL
NtGdiSetBitmapBits(
	HBITMAP  hBitmap,
	DWORD  Bytes,
	IN PBYTE Bits)
{
	LONG height, ret;
	PBITMAPOBJ bmp;

	bmp = BITMAPOBJ_LockBitmap(hBitmap);
	if (bmp == NULL || Bits == NULL)
	{
		return 0;
	}

	if (Bytes < 0)
	{
		DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
		Bytes = -Bytes;
	}

	/* Only get entire lines */
	height = Bytes / abs(bmp->SurfObj.lDelta);
	if (height > bmp->SurfObj.sizlBitmap.cy)
	{
		height = bmp->SurfObj.sizlBitmap.cy;
	}
	Bytes = height * abs(bmp->SurfObj.lDelta);
	DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
		hBitmap,
		Bytes,
		Bits,
		bmp->SurfObj.sizlBitmap.cx,
		bmp->SurfObj.sizlBitmap.cy,
		1 << BitsPerFormat(bmp->SurfObj.iBitmapFormat),
		height);

#if 0
	/* FIXME: call DDI specific function here if available  */
	if(bmp->DDBitmap)
	{
		DPRINT ("Calling device specific BitmapBits\n");
		if (bmp->DDBitmap->funcs->pBitmapBits)
		{
			ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap, (void *) Bits, Bytes, DDB_SET);
		}
		else
		{
			DPRINT ("BitmapBits == NULL??\n");
			ret = 0;
		}
	}
	else
#endif
	{
		memcpy(bmp->SurfObj.pvBits, Bits, Bytes);
		ret = Bytes;
	}

	BITMAPOBJ_UnlockBitmap(bmp);

	return ret;
}

BOOL STDCALL
NtGdiSetBitmapDimensionEx(
	HBITMAP  hBitmap,
	INT  Width,
	INT  Height,
	LPSIZE  Size)
{
	PBITMAPOBJ  bmp;

	bmp = BITMAPOBJ_LockBitmap(hBitmap);
	if (bmp == NULL)
	{
		return FALSE;
	}

	if (Size)
	{
		*Size = bmp->dimension;
	}
	bmp->dimension.cx = Width;
	bmp->dimension.cy = Height;

	BITMAPOBJ_UnlockBitmap (bmp);

	return TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -