关于裁剪
应用程序以各种方法来使用剪切。WORD程序和电子表格程序裁剪键盘输入来避免其出现在页或表格的边界;CAD和绘画程序裁剪图形输出是为了避免在图画的边界被覆盖。
一个裁剪区域是一个直线或曲线边的区域;一个裁剪路径是边可以为直线、曲线或他们的组合的区域。更多的信息参见区域和路径。
区域
区域可以是一个矩形、多边形、椭圆形(或他们两个或三个的组合的图形),他们能够被填充、着色、被转向、也可以加边框并且被用来执行点击测试(为光标位置测试)。
关于区域
下面的三种已经被填充和加边框了。
路径
路径是一到多个图像(图形),他们可以被填充,有轮廓,或者两者都有。路径用在绘画和着色的应用程序中。CAD应用程序使用路径来创建独特的裁减区域,画出不规则的图形外观,然后填充这些不规则的图形内部。一个不规则的图形是由Bzier曲线和直线组成的图形。(规则的图形包括椭圆、圆、矩形、多边形)
关于路径
路径是与DC相关联的对象之一;然而不像默认对象(笔、刷子、字体)是任何新的DC的一部分,没有默认的路径对象。
裁减区域
裁减区域是应用程序可以选进DC的图形对象之一。通常是一个矩形。如果没有提供裁减区域的话,有些DC提供一个预定义的或默认的裁减区域。例如,如果你从BeginPaint函数获得了一个DC的HANDLE,DC包含一个相对应于需要被重绘的无效矩形的预定义矩形的裁减区域。然而,当你通过GetDC而提供NULL作为hWnd参数时获得的设备HANDLE,或者通过CreateDC函数创建的,DC并不包含默认的裁减区域。更多的关于BeginPaint返回的DC的内容参见Painting and Drawing;而CreateDC和GetDC返回的DC信息参见Device Contexts.
应用程序可以在裁减区域上执行各种操作。许多操作需要一个标示区域的HANDLE,而有些不需要。例如,应用程序可以直接在一个DC的裁减区域上执行下面操作:
ü 通过传递相应的线、弧、位图、文本或填充图形给PtVisible函数来判断图形输出是否在区域的边界。
ü 通过调用RectVisible函数来判断区域和客户区的部分存在交集。
ü 通过传递给OffsetClipRgn函数一个指定的偏移来移动一个存在的区域
ü 通过调用ExcludeClipRect函数来从当前裁减区中去除客户区的某矩形部分。
ü 调用IntersectClipRect函数来合并当前裁减区域和客户区的矩形区域
在获得一个裁减区域的HANDLE之后,应用程序能执行通常区域进行的任何操作,如下:
ü 通过调用CombineRgn来合并当前的裁减区域和第二个区域
ü 调用EqualRgn来比较当前裁减区域和第二个区域
ü 通过调用PtInRegion来判断一个点是否在当前裁减区域的副本内部
裁减路径
和裁减区域一样,裁减路径是另一个可被应用程序选进DC中的图形对象。和裁减区域不同的是,裁减路径一直由应用成天许来创建,通常用来裁减一到多个不规则图形。例如,一个应用程序使用线和曲线得到一个字符串文本中字符路径。
为了创建裁减路径,首先创建一个路径来描述不规则图形是必要的。路径通过在BeginPath和EndPath之间调用适当的GDI函数来创建,这个函数集合被叫做路径支架。更多的关于路径和路径支架的信息参见Paths.
在路径被创建之后,能通过SelectClipPath函数来将其转换为裁减路径,标示一个DC并指定使用模式。使用模式决定了系统怎么样合并原来的裁减区域和新的裁减路径。下面是使用模式的介绍:
模式 |
描述 |
RGN_AND |
裁减路径包含当前路径和设备参见区域的交集(重叠部分) |
RGN_COPY |
裁减路径是当前路径 |
RGN_DIFF |
裁减路径是设备内容裁减区域减去当前路径与其的交集 |
RGN_OR |
包含两者,是并集 |
RGN_XOR |
两者的并去掉交集 |
使用裁减
本节包含一个例子介绍怎么样生成一个由字符串组成的裁减路径。例子创建一个逻辑字体并使用它在一个裁减路径中画一个字符串,然后用水平和垂直线来填充路径。
// DoClipPat - Draws a clip path using the specified string
// Return value - TRUE if successful; FALSE otherwise
// lplf - address of a LOGFONT structure that defines the font to
// use to draw the clip path
// lpsz - address of a string to use for the clip path
BOOL DoClipPath(LPLOGFONT lplf, LPSTR lpsz)
{
LOGFONT lf; // logical font structure
HFONT hfont; // new logical font handle
HFONT hfontOld; // original logical font handle
HDC hdc; // display DC handle
int nXStart, nYStart; // drawing coordinates
RECT rc; // rectangle structure for painting window
SIZE sz; // size structure that receives text extents
int nStrLen; // length of the string
int i; // loop counter
HRESULT hr;
size_t * pcch;
// Retrieve a cached DC for the window.
hdc = GetDC(hwnd);
// Erase the current window contents.
GetClientRect(hwnd, &rc);
FillRect(hdc, &rc, GetStockObject(WHITE_BRUSH));
// Use the specified font to create a logical font and select it
// into the DC.
hfont = CreateFontIndirect(lplf);
if (hfont == NULL)
return FALSE;
hfontOld = SelectObject(hdc, hfont);
// Create a clip path.
hr = StringCchLength(lpsz, STRSAFE_MAX_CCH, pcch);
if (FAILED(hr))
{
// TODO: write error handler
}
nStrLen = *pcch
BeginPath(hdc);
TextOut(hdc, nXStart, nYStart, lpsz, nStrLen);
EndPath(hdc);
SelectClipPath(hdc, RGN_DIFF);
// Retrieve the dimensions of the rectangle surrounding
// the text.
GetTextExtentPoint32(hdc, lpsz, nStrLen, &sz);
// Draw horizontal lines through the clip path.
for (i = nYStart + 1; i < (nYStart + sz.cy); i += 3)
{
MoveToEx(hdc, nXStart, i, (LPPOINT) NULL);
LineTo(hdc, (nXStart + sz.cx), i);
}
// Draw vertical lines through the clip path.
for (i = nXStart + 1; i < (nXStart + sz.cx); i += 3)
{
MoveToEx(hdc, i, nYStart, (LPPOINT) NULL);
LineTo(hdc, i, (nYStart + sz.cy));
}
// Select the original font into the DC and release the DC.
SelectObject(hdc, hfontOld);
DeleteObject(hfont);
ReleaseDC(hwnd, hdc);
return TRUE;
}