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 + -
显示快捷键?