裁剪(Clipping)-Window GDI
http://blog.csdn.net/windcsn/article/details/492105
裁剪是在一個應(yīng)用程序的窗口中限制輸出區(qū)域或路徑的過程,下面討論裁剪.
關(guān)于裁剪
應(yīng)用程序以各種方法來使用剪切。WORD程序和電子表格程序裁剪鍵盤輸入來避免其出現(xiàn)在頁或表格的邊界;CAD和繪畫程序裁剪圖形輸出是為了避免在圖畫的邊界被覆蓋。
一個裁剪區(qū)域是一個直線或曲線邊的區(qū)域;一個裁剪路徑是邊可以為直線、曲線或他們的組合的區(qū)域。更多的信息參見區(qū)域和路徑。
?
區(qū)域
區(qū)域可以是一個矩形、多邊形、橢圓形(或他們兩個或三個的組合的圖形),他們能夠被填充、著色、被轉(zhuǎn)向、也可以加邊框并且被用來執(zhí)行點擊測試(為光標位置測試)。
關(guān)于區(qū)域
下面的三種已經(jīng)被填充和加邊框了。
?
路徑
路徑是一到多個圖像(圖形),他們可以被填充,有輪廓,或者兩者都有。路徑用在繪畫和著色的應(yīng)用程序中。CAD應(yīng)用程序使用路徑來創(chuàng)建獨特的裁減區(qū)域,畫出不規(guī)則的圖形外觀,然后填充這些不規(guī)則的圖形內(nèi)部。一個不規(guī)則的圖形是由Bzier曲線和直線組成的圖形。(規(guī)則的圖形包括橢圓、圓、矩形、多邊形)
關(guān)于路徑
路徑是與DC相關(guān)聯(lián)的對象之一;然而不像默認對象(筆、刷子、字體)是任何新的DC的一部分,沒有默認的路徑對象。
?
裁減區(qū)域
裁減區(qū)域是應(yīng)用程序可以選進DC的圖形對象之一。通常是一個矩形。如果沒有提供裁減區(qū)域的話,有些DC提供一個預(yù)定義的或默認的裁減區(qū)域。例如,如果你從BeginPaint函數(shù)獲得了一個DC的HANDLE,DC包含一個相對應(yīng)于需要被重繪的無效矩形的預(yù)定義矩形的裁減區(qū)域。然而,當你通過GetDC而提供NULL作為hWnd參數(shù)時獲得的設(shè)備HANDLE,或者通過CreateDC函數(shù)創(chuàng)建的,DC并不包含默認的裁減區(qū)域。更多的關(guān)于BeginPaint返回的DC的內(nèi)容參見Painting and Drawing;而CreateDC和GetDC返回的DC信息參見Device Contexts.
應(yīng)用程序可以在裁減區(qū)域上執(zhí)行各種操作。許多操作需要一個標示區(qū)域的HANDLE,而有些不需要。例如,應(yīng)用程序可以直接在一個DC的裁減區(qū)域上執(zhí)行下面操作:
ü?????????通過傳遞相應(yīng)的線、弧、位圖、文本或填充圖形給PtVisible函數(shù)來判斷圖形輸出是否在區(qū)域的邊界。
ü?????????通過調(diào)用RectVisible函數(shù)來判斷區(qū)域和客戶區(qū)的部分存在交集。
ü?????????通過傳遞給OffsetClipRgn函數(shù)一個指定的偏移來移動一個存在的區(qū)域
ü?????????通過調(diào)用ExcludeClipRect函數(shù)來從當前裁減區(qū)中去除客戶區(qū)的某矩形部分。
ü?????????調(diào)用IntersectClipRect函數(shù)來合并當前裁減區(qū)域和客戶區(qū)的矩形區(qū)域
在獲得一個裁減區(qū)域的HANDLE之后,應(yīng)用程序能執(zhí)行通常區(qū)域進行的任何操作,如下:
ü?????????通過調(diào)用CombineRgn來合并當前的裁減區(qū)域和第二個區(qū)域
ü?????????調(diào)用EqualRgn來比較當前裁減區(qū)域和第二個區(qū)域
ü?????????通過調(diào)用PtInRegion來判斷一個點是否在當前裁減區(qū)域的副本內(nèi)部
?
裁減路徑
和裁減區(qū)域一樣,裁減路徑是另一個可被應(yīng)用程序選進DC中的圖形對象。和裁減區(qū)域不同的是,裁減路徑一直由應(yīng)用成天許來創(chuàng)建,通常用來裁減一到多個不規(guī)則圖形。例如,一個應(yīng)用程序使用線和曲線得到一個字符串文本中字符路徑。
為了創(chuàng)建裁減路徑,首先創(chuàng)建一個路徑來描述不規(guī)則圖形是必要的。路徑通過在BeginPath和EndPath之間調(diào)用適當?shù)腉DI函數(shù)來創(chuàng)建,這個函數(shù)集合被叫做路徑支架。更多的關(guān)于路徑和路徑支架的信息參見Paths.
在路徑被創(chuàng)建之后,能通過SelectClipPath函數(shù)來將其轉(zhuǎn)換為裁減路徑,標示一個DC并指定使用模式。使用模式?jīng)Q定了系統(tǒng)怎么樣合并原來的裁減區(qū)域和新的裁減路徑。下面是使用模式的介紹:
| 模式 | 描述 |
| RGN_AND | 裁減路徑包含當前路徑和設(shè)備參見區(qū)域的交集(重疊部分) |
| RGN_COPY | 裁減路徑是當前路徑 |
| RGN_DIFF | 裁減路徑是設(shè)備內(nèi)容裁減區(qū)域減去當前路徑與其的交集 |
| RGN_OR | 包含兩者,是并集 |
| RGN_XOR | 兩者的并去掉交集 |
?
使用裁減
本節(jié)包含一個例子介紹怎么樣生成一個由字符串組成的裁減路徑。例子創(chuàng)建一個邏輯字體并使用它在一個裁減路徑中畫一個字符串,然后用水平和垂直線來填充路徑。
// 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; }總結(jié)
以上是生活随笔為你收集整理的裁剪(Clipping)-Window GDI的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows Mobile的高效贴图
- 下一篇: 区域和裁减区域-Window GDI