rop.cpp

来自「Windows 图形编程 书籍」· C++ 代码 · 共 835 行 · 第 1/2 页

CPP
835
字号
		// D^(P&(S^D)), if P then S else D
		StretchDIBits(hDC, x, y, w, h, 0, 0, w, h, pBits, pBMI, DIB_RGB_COLORS, 0xCA07A9);
				
		SelectObject(hDC, hOld);
		DeleteObject(hBrush);
	}
}

// dx, dy, dw, dh defines a destination rectangle
// sw, sh is the dimension of source rectangle
// sx, sy is the starting point winthin the source bitmap, which will be tiled to sw x sh in size
BOOL StretchTile(HDC      hDC, int dx, int dy, int dw, int dh, 
				 HBITMAP hSrc, int sx, int sy, int sw, int sh, 
				 DWORD rop)
{
	BITMAP bmp;

	if ( ! GetObject(hSrc, sizeof(BITMAP), & bmp) )
		return FALSE;
	
	HDC   hMemDC = CreateCompatibleDC(NULL);
	HGDIOBJ hOld = SelectObject(hMemDC, hSrc);
	
	int sy0 = sy % bmp.bmHeight;						// current tile y origin
	
	for (int y=0; y<sh; y+=(bmp.bmHeight - sy0))
	{
		int height = min(bmp.bmHeight - sy0, sh - y);	// current tile height
		int sx0    = sx % bmp.bmWidth;					// current tile x origin
		
		for (int x=0; x<sw; x+=(bmp.bmWidth  - sx0))
		{
			int width = min(bmp.bmWidth - sx0, sw - x); // current tile width
		
			StretchBlt(hDC,    dx+x*dw/sw, dy+y*dh/sh, dw*width/sw, dh*height/sh, 
					   hMemDC, sx0,        sy0,        width,       height, 
					   rop);
			sx0 = 0;	// after the first tile in a row, change to full tile width
		}
		sy0 = 0; // after the the first row, change to full tile height
	}

	SelectObject(hMemDC, hOld);
	DeleteObject(hMemDC);
		
	return TRUE;
}


BOOL G_PlgBlt(HDC hdcDest, const POINT * pPoint, 
			HDC hdcSrc, int nXSrc, int nYSrc, int nWidth, int nHeight, 
			HBITMAP hbmMask, int xMask, int yMask)
{
	KReverseAffine map(pPoint);

	if ( map.Simple() ) // no shear and rotation
	{
		int x = pPoint[0].x;
		int y = pPoint[0].y;
		int w = pPoint[1].x-pPoint[0].x;
		int h = pPoint[2].y-pPoint[0].y;

		if ( hbmMask ) // has a mask bitmap, if (M) the S else D, S ^ (~M & (S^D))
		{
		 	StretchBlt(hdcDest, x, y, w, h, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, SRCINVERT);
		  StretchTile(hdcDest, x, y, w, h,  hbmMask, xMask, yMask, nWidth, nHeight, 0x220326);
			return StretchBlt(hdcDest, x, y, w, h, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, SRCINVERT);
		}
		else
			return StretchBlt(hdcDest, x, y, w, h, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, SRCCOPY);
	}

	map.Setup(nXSrc, nYSrc, nWidth, nHeight);

	HDC hdcMask   = NULL;
	int maskwidth = 0;
	int maskheight= 0;

	if ( hbmMask )
	{
		BITMAP bmp;
		GetObject(hbmMask, sizeof(bmp), & bmp);
	
		maskwidth  = bmp.bmWidth;
		maskheight = bmp.bmHeight;

		hdcMask = CreateCompatibleDC(NULL);
		SelectObject(hdcMask, hbmMask);
	}

	for (int dy=map.miny; dy<=map.maxy; dy++)
	for (int dx=map.minx; dx<=map.maxx; dx++)
	{
		float sx, sy;
		map.Map(dx, dy, sx, sy);

		if ( (sx>=nXSrc) && (sx<=(nXSrc+nWidth))  )
		if ( (sy>=nYSrc) && (sy<=(nYSrc+nHeight)) )
			if ( hbmMask )
			{
				if ( GetPixel(hdcMask, ((int)sx+xMask) % maskwidth, ((int)sy+yMask) % maskheight) )
					SetPixel(hdcDest, dx, dy, GetPixel(hdcSrc, (int)sx, (int)sy));
			}
			else
				SetPixel(hdcDest, dx, dy, GetPixel(hdcSrc, (int)sx, (int)sy));
	}

	if ( hdcMask )
		DeleteObject(hdcMask);

	return TRUE;
}


BOOL AffineBlt(HDC hdcDest, const POINT * pPoint, 
			   HDC hdcSrc, int nXSrc, int nYSrc, int nWidth, int nHeight, DWORD rop)
{
	KReverseAffine map(pPoint);

	if ( map.Simple() ) // no shear and rotation
		return StretchBlt(hdcDest, pPoint[0].x, pPoint[0].y, 
				   pPoint[1].x-pPoint[0].x, pPoint[2].y-pPoint[0].y, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, rop);
	else
	{
		map.Setup(nXSrc, nYSrc, nWidth, nHeight);

		for (int dy=map.miny; dy<=map.maxy; dy++)
		for (int dx=map.minx; dx<=map.maxx; dx++)
		{
			float sx, sy;
			map.Map(dx, dy, sx, sy);

			if ( (sx>=nXSrc) && (sx<=(nXSrc+nWidth))  )
			if ( (sy>=nYSrc) && (sy<=(nYSrc+nHeight)) )
			{
				COLORREF s = GetPixel(hdcSrc, (int)sx, (int)sy);

				switch ( rop )
				{
					case SRCCOPY: 
						SetPixel(hdcDest, dx, dy, s); break;

					case SRCAND:
						SetPixel(hdcDest, dx, dy, s & GetPixel(hdcDest, dx, dy) ); break;

					case SRCINVERT:
						SetPixel(hdcDest, dx, dy, s ^ GetPixel(hdcDest, dx, dy) ); break;
					
					default:
						return FALSE;
				}
			}
		}

		return TRUE;
	}
}


BOOL AffineTile(HDC hdcDest, const POINT * pPoint, 
			    HBITMAP hSrc, int xMask, int yMask, int nWidth, int nHeight, DWORD rop)
{
	KReverseAffine map(pPoint);

	if ( map.Simple() ) // no shear and rotation
		return StretchTile(hdcDest, pPoint[0].x, pPoint[0].y, 
				   pPoint[1].x-pPoint[0].x, pPoint[2].y-pPoint[0].y, hSrc, xMask, yMask, nWidth, nHeight, rop);
	else
	{
		map.Setup(0, 0, nWidth, nHeight);

		BITMAP bmp;
		GetObject(hSrc, sizeof(bmp), & bmp);
		
		HDC hdcSrc = CreateCompatibleDC(NULL);
		SelectObject(hdcSrc, hSrc);

		for (int dy=map.miny; dy<=map.maxy; dy++)
		for (int dx=map.minx; dx<=map.maxx; dx++)
		{
			float sx, sy;
			map.Map(dx, dy, sx, sy);

			if ( (sx>=0) && (sx<=nWidth)  )
			if ( (sy>=0) && (sy<=nHeight) )
			{
				COLORREF s = GetPixel(hdcSrc, ((int)sx+xMask) % bmp.bmWidth, 
											  ((int)sy+yMask) % bmp.bmHeight);

				switch ( rop )
				{
					case SRCAND:
						SetPixel(hdcDest, dx, dy, s & GetPixel(hdcDest, dx, dy) ); break;

					case 0x220326: // ~S & D
						if ( s==RGB(0xFF, 0xFF, 0xFF) )
							SetPixel(hdcDest, dx, dy, RGB(0, 0, 0));
						else if ( s!=0 )
							SetPixel(hdcDest, dx, dy, (~s & GetPixel(hdcDest, dx, dy)) & 0xFFFFFF ); 
						break;

					default:
						DeleteObject(hdcSrc);
						return FALSE;
				}
			}
		}
		
		DeleteObject(hdcSrc);
		return TRUE;
	}
}

BOOL C_PlgBlt(HDC hdcDest, const POINT * pPoint, 
			HDC hdcSrc, int nXSrc, int nYSrc, int nWidth, int nHeight, 
			HBITMAP hbmMask, int xMask, int yMask)
{
	if ( hbmMask )	// has a mask bitmap, if (M) the S else D, S ^ (~M & (S^D))
	{
		        AffineBlt(hdcDest, pPoint, hdcSrc,  nXSrc, nYSrc, nWidth, nHeight, SRCINVERT);
		       AffineTile(hdcDest, pPoint, hbmMask, xMask, yMask, nWidth, nHeight, 0x220326);
		return  AffineBlt(hdcDest, pPoint, hdcSrc,  nXSrc, nYSrc, nWidth, nHeight, SRCINVERT);
	}
	else
		return AffineBlt(hdcDest, pPoint, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, SRCCOPY);
}


void DrawCube(HDC hDC, int x, int y, int dh, int dx, int dy, HDC hMemDC, int w, int h, HBITMAP hMask, bool bSimulate)
{
	SetStretchBltMode(hDC, HALFTONE);

	//         6
	//    0         4
	//         1
	//    2         5
	//         3 
	POINT P[3] = { { x - dx, y - dy }, { x, y }, { x - dx, y - dy + dh } }; // 012
	POINT Q[3] = { { x, y }, { x + dx, y - dy }, { x, y + dh } };			// 143
	POINT R[3] = { { x - dx, y - dy }, { x, y - dy - dy }, { x, y } };		// 061

	if ( bSimulate )
	{
		G_PlgBlt(hDC, P, hMemDC, 0, 0, w, h, hMask, 0, 0);
		G_PlgBlt(hDC, Q, hMemDC, 0, 0, w, h, hMask, 0, 0);
		G_PlgBlt(hDC, R, hMemDC, 0, 0, w, h, hMask, 0, 0);
	}
	else
	{
		PlgBlt(hDC, P, hMemDC, 0, 0, w, h, hMask, 0, 0);
		PlgBlt(hDC, Q, hMemDC, 0, 0, w, h, hMask, 0, 0);
		PlgBlt(hDC, R, hMemDC, 0, 0, w, h, hMask, 0, 0);
	}
}

void MaskCube(HDC hDC, int size, int x, int y, int w, int h, HBITMAP hBmp, HDC hMemDC, bool mask, bool bSimulate)
{
	HBITMAP hMask = NULL;
	
	if ( mask )
	{
		hMask = CreateBitmap(w, h, 1, 1, NULL);
		SelectObject(hMemDC, hMask);
		PatBlt(hMemDC, 0, 0, w, h, BLACKNESS);
		RoundRect(hMemDC, 0, 0, w, h, w/2, h/2); // white
	}

	int dx  = size * 94 / 100; // cos(20)
	int dy  = size * 34 / 100; // sin(20)
	SelectObject(hMemDC, hBmp);
	DrawCube(hDC, x+dx, y+size, size, dx, dy, hMemDC, w, h, hMask, bSimulate);
	
	if ( hMask )
		DeleteObject(hMask);
}


BOOL TriBitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, 
			   HDC hdcSrc, int nXSrc, int nYSrc,
			   HBITMAP hbmMask, int xMask, int yMask, 
			   DWORD rop1, DWORD rop2, DWORD rop3)
{
	HDC hMemDC = CreateCompatibleDC(hdcDest);
	SelectObject(hMemDC, hbmMask);

	if ( (rop1>>16)!=0xAA ) // not D
		BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, rop1);

	BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hMemDC, xMask, yMask, rop2);

	DeleteObject(hMemDC);

	if ( (rop3>>16)!=0xAA ) // not D
		return BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, rop3);
	else
		return TRUE;
}


BOOL G_MaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
			 HDC hdcSrc,  int nXSrc,  int nYSrc, 
			 HBITMAP hbmMask, int xMask, int yMask,
			 DWORD dwRop
)
{
	DWORD back = (dwRop >> 24) & 0xFF;
	DWORD fore = (dwRop >> 16) & 0xFF;

	if ( back==fore ) // foreground=background, hbmMask not needed
		return BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop & 0xFFFFFF);

	// if (M) D=fore(P,S,D) else D=back(P,S,D)
	
	if ( D_independent(back) )	// back independent of D
		return TriBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hbmMask, xMask, yMask,
			fore^back << 16,	// ( fore^back, fore^back )
			SRCAND,				// ( fore^back, 0 )
			(back^0xAA) << 16); // { fore, back }

	if ( D_independent(fore) )  // fore independent of D
		return TriBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hbmMask, xMask, yMask,
			(fore^back) << 16,  // ( fore^back, fore^back )
			0x22 << 16,			// ( 0, fore^back )
			(fore^0xAA) << 16); // { fore, back }

	// both foreground and background depend on D
	if ( S_independent(back) && S_independent(fore) )
		return TriBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, NULL, 0, 0, hbmMask, xMask, yMask,
			0xAA << 16,			// ( D, D )
			( (fore & 0xCC) || (back & 0x33) ) << 16,
			0xAA << 16);
	
	// both foreground and background depend on D
	// either foregounr or background depends on S
	HBITMAP hTemp  = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
	HDC     hMemDC = CreateCompatibleDC(hdcDest);
	SelectObject(hMemDC, hTemp);
	BitBlt(hMemDC, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
	SelectObject(hMemDC, GetCurrentObject(hdcDest, OBJ_BRUSH));
	BitBlt(hMemDC, 0, 0, nWidth, nHeight, hdcSrc,  nXSrc, nYSrc, back << 16); // hMemDC contains final background image

	BitBlt(hdcDest, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, fore << 16);  // foreground image

	TriBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hMemDC, 0, 0, hbmMask, xMask, yMask,
			SRCINVERT,	// ( fore^back, fore^back )
			SRCAND,		// ( fore^back, 0 )
			SRCINVERT); // { fore, back }

	DeleteObject(hMemDC);
	DeleteObject(hTemp);
	
	return TRUE;
}

// Use TransparentBlt to draw Icon
/*
void TransparentBltDrawIcon(HDC hDC, int x, int y, HICON hIcon)
{
	ICONINFO iconinfo;
	GetIconInfo(hIcon, & iconinfo);

	BITMAP bmp;
	GetObject(iconinfo.hbmMask, sizeof(bmp), & bmp);

	HDC hMemDC = CreateCompatibleDC(NULL);
	HGDIOBJ hOld = SelectObject(hMemDC, iconinfo.hbmColor);

	COLORREF crTrans = GetPixel(hMemDC, 0, 0);

	TransparentBlt(hDC,    x, y, bmp.bmWidth, bmp.bmHeight, 
		           hMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight,
		           crTrans);

	SelectObject(hMemDC, hOld);
	DeleteObject(iconinfo.hbmMask);
	DeleteObject(iconinfo.hbmColor);
	DeleteObject(hMemDC);
}
*/

// big pattern brush
void MaskBitmapNT(HDC hDC, int x, int y, int width, int height, HBITMAP hMask, HDC hMemDC)
{
	HBRUSH hBrush = CreatePatternBrush(hMask);
	HGDIOBJ hOld  = SelectObject(hDC, hBrush);

	POINT org = { x, y };
	LPtoDP(hDC, &org, 1);
	SetBrushOrgEx(hDC, org.x, org.y, NULL);

	BitBlt(hDC, x, y, width, height, hMemDC, 0, 0, 0x6C01E8); // S^(P&D)

	SelectObject(hDC, hOld);
	DeleteObject(hBrush);
}

void MaskBltDrawIcon(HDC hDC, int x, int y, HICON hIcon)
{
	ICONINFO iconinfo;
	GetIconInfo(hIcon, & iconinfo);

	BITMAP bmp;
	GetObject(iconinfo.hbmMask, sizeof(bmp), & bmp);

	HDC hMemDC = CreateCompatibleDC(NULL);
	HGDIOBJ hOld = SelectObject(hMemDC, iconinfo.hbmColor);

	MaskBlt(hDC, x, y, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, 
		iconinfo.hbmMask, 0, 0, MAKEROP4(SRCINVERT, SRCCOPY));

	SelectObject(hMemDC, hOld);
	DeleteObject(iconinfo.hbmMask);
	DeleteObject(iconinfo.hbmColor);
	DeleteObject(hMemDC);
}

⌨️ 快捷键说明

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