<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 5.3 設備上下文中的繪畫函數 在這一小節里,我們來近距離的了解一下怎樣在設備上下文中繪畫。下表列出了設備上下文類主要的成員函數,在接下來的小節里,我們會舉例介紹其中的大部分函數,你也可以從wxWidgets的手冊中獲取它們的詳細信息。 | Blit | 把某個設備上下文的一部分拷貝到另外一個設備上下文上. 你可以指定的參數包括拷貝多大,拷貝到什么位置,拷貝的邏輯函數以及如果源設備上下文是內存設備上下文的時候,是不是使用透明遮罩等。 | |:--- |:--- | | Clear | 使用當前的背景刷刷新背景. | | SetClippingRegion DestroyClippingRegion GetClippingBox | 用來設置和釋放設備上下文使用的區域。區域是用來將設備上下文中所有的繪畫操作限制在某個范圍內的,它可以是一個矩形,也可以是由wxRegion指定的復雜區域,使用GetClippingBox函數來取得包含當前區域的一個矩形范圍。 | | DrawArc DrawEllipticArc | 使用當前的畫筆和畫刷畫一段圓弧或者橢圓弧線. | | DrawBitmap DrawIcon | 在指定位置畫一副圖片或者是一個圖標.如果是圖片可以指定一個透明遮罩. | | DrawCircle | 使用當前的畫筆和畫刷畫一個圓形. | | DrawEllipse | 使用當前的畫筆和畫刷畫一個橢圓形. | | DrawLine DrawLines | 使用當前的畫筆畫一條線或者多條線。最后的那個點是不被顯示的。 | | DrawPoint | 使用當前設置的畫筆畫一個點. | | DrawPolygon DrawPolyPolygon | DrawPolygon函數通過指定一個點的數組或者指向點結構的指針的列表來繪制一個封閉的多邊形,還可以指定一個可選的座標平移。wxWidgets 會自動封閉第一個點和最后一個點,所以你不必在最開始和最末端指定同一個點。 DrawPolyPolygon函數則同時繪制多個多邊形,在某些平臺上這比多次調用DrawPolygon函數更有效率。 | | DrawRectangle DrawRoundedRectangle | 使用當前的畫筆和畫刷繪制一個矩形或者圓角矩形 | | DrawText DrawRotatedText | 使用當前字體,文本前景色和文本背景色在指定的位置繪制一段文本或者一段旋轉的文本。 | | DrawSpline | 使用當前的畫筆在指定的控制點下使用云行規畫一條平滑曲線. | | FloodFill | 以Flood填充的方式使用當前的畫刷對指定起始點的范圍進行填充(比如:封閉相鄰同顏色區域中的顏色將被替換). | | Ok | 如果設備已經準備好可以開始繪畫則返回true. | | SetBackground GetBackground | 用來設置或者獲取背景畫刷設置。這些設置將在Clear函數或者其它一些設置了復雜的繪畫邏輯參數的函數中被使用。默認設置為wxtrANSPARENT_BRUSH。 | | SetBackgroundMode GetBackgroundMode | 用來設置繪制文本時候的背景類型,取值為wxSOLID或者wxTRANSPARENT。通常你希望設置為后者,以便保留繪制文本區域已經存在的背景。 | | SetBrush GetBrush | 用來設置當前畫刷,默認值未定義。 | | SetPen GetPen | 用來設置當前畫筆,默認值未定義。 | | SetFont GetFont | 用來設置當前字體,默認值未定義。 | | SetPalette GetPalette | 用來設置當前調色板。 | | SetTextForeground GetTextForeground SetTextBackground GetTextBackground | 用來設置文本的前景顏色和背景顏色,默認值前景為黑色背景為白色。 | | SetLogicalFunction GetLogicalFunction | 邏輯函數用來設置畫筆或者畫刷或者(在Blit函數中)設備上下文自己的象素的顯示和傳輸方式。默認值wxCOPY表示直接顯示或者拷貝當前顏色。 | | GetPixel | 返回某個點的顏色.在wxPostScriptDC和wxMetafileDC中還沒有實現這個功能. | | GetTextExtent GetPartialTextExtents | 返回給定文本的大小。 | | GetSize GetSizeMM | 返回以設備單位或者毫米指定的長寬。 | | StartDoc EndDoc | 這兩個函數只在打印設備上下文中使用,前者顯示一條消息表明正在打印,后者則隱藏這個消息。 | | StartPage EndPage | 在打印設備上下文中開始和結束一頁。 | | DeviceToLogicalX DeviceToLogicalXRel DeviceToLogicalY DeviceToLogicalYRel | 將設備座標轉換成邏輯座標,可以是絕對值也可以是相對值。 | | LogicalToDeviceX LogicalToDeviceXRel LogicalToDeviceY LogicalToDeviceYRel | 將邏輯座標轉換成設備座標。 | | SetMapMode GetMapMode | 象前面描述過的那樣,MapMode用來(和SetUserScale一起)指定邏輯單位到設備單位的映射。 | | SetAxisOrientation | 用來指定X軸和Y軸的方向。默認X軸為從左到右(True),Y軸為從上到下(False)。 | | SetDeviceOrigin GetDeviceOrigin | 設置座標原點,可以用來實現平移。 | | SetUserScale GetUserScale | 設置縮放值。該值用于邏輯單位到設備單位的轉換。 | 繪制文本 設備上下文繪制文本的方式取決于以下幾個參數:當前字體,字體背景模式,文本背景色和文本前景色。如果背景模式是wxSOLID,文本背后的部分將會以當前的文本背景色擦除,如果是wxTRANSPARENT,則文本的背景將保留原先的背景。 傳遞給DrawText的參數是一個字符串和一個點(或者兩個整數)。其中點(或者兩個整數)指定的位置將會是文本最左上角的位置。下面是一個例子: ``` void DrawTextString(wxDC& dc, const wxString& text, const wxPoint& pt) { wxFont font(12, wxFONTFAMILY_SWISS, wxNORMAL, wxBOLD); dc.SetFont(font); dc.SetBackgroundMode(wxTRANSPARENT); dc.SetTextForeground(*wxBLACK); dc.SetTextBackground(*wxWHITE); dc.DrawText(text, pt); } ``` 你也可以使用DrawRotatedText函數來繪制一段旋轉的文本,其中角度的值由函數的最后一個參數指定,下面的代碼演示了一段以45度角增加的文本: ``` wxFont font(20, wxFONTFAMILY_SWISS, wxNORMAL, wxNORMAL); dc.SetFont(font); dc.SetTextForeground(wxBLACK); dc.SetBackgroundMode(wxTRANSPARENT); for (int angle = 0; angle &lt; 360; angle += 45) dc.DrawRotatedText(wxT("Rotated text..."), 300, 300, angle); ``` 運行結果如下圖所示: ![](img/mht30B0%281%29.tmp) 在Windows平臺上,只有TrueType類型的字體才可以實現旋轉輸出,要注意wxNORMAL_FONT指定的字體并不是TrueType字體。 通常情況下,你需要知道當前正要繪制的文本將占用設備上下文中多大的地方,你可以通過GetTextExtent函數來作到這一點,它的原型如下: ``` void GetTextExtent(const wxString& string, wxCoord* width, wxCoord* height, wxCoord* descent = NULL, wxCoord* externalLeading = NULL, wxFont* font = NULL); ``` 從這個函數的原型中可以看出,后面的三個參數是可選的,其中descent參數和externalLeading參數(譯者注:在漢字里面用處不大)的含義是:英文字符的基線通常不是字符的最底端,descent用來獲取某個字符的最底端到基線的距離,而externalLeading則用來獲取descent到下一行頂端的距離。最后一個參數font可以用來指定以這個字體為基準(而不是設備上下文自己的字體)來獲取測量值。 下面的代碼把一段文本在窗口的中間位置顯示: ``` void CenterText(const wxString& text, wxDC& dc, wxWindow* win) { dc.SetFont(*wxNORMAL_FONT); dc.SetBackgroundMode(wxTRANSPARENT); dc.SetTextForeground(*wxRED); // 獲取窗口大小和文本大小 wxSize sz = win->GetClientSize(); wxCoord w, h; dc.GetTextExtent(text, & w, & h); // 計算為了居中顯示需要的文本開始位置 // 并保證其不為負數. int x = wxMax(0, (sz.x - w)/2); int y = wxMax(0, (sz.y - h)/2); dc.DrawText(msg, x, y); } ``` 如果你需要知道每個字符的精確占用大小,你可以使用GetPartialTextExtents函數,它使用wxString和一個wxArrayInt的引用作為參數。這個函數的效率在某些平臺上優于對每個單個的字符使用GetTextExtent函數。 繪制線段和形狀 這里用到的函數原型包括那些用來畫點,畫線,矩形,圓形以及橢圓等的函數。它們都使用當前的畫筆設置和畫刷設置,畫筆用來決定輪廓線的顏色和模式,畫刷用來決定填充的顏色和方式: 下面演示了一段代碼和這段代碼產生的圖形: ``` void DrawSimpleShapes(wxDC& dc) { // 設置黑色的輪廓線,綠色的填充色 dc.SetPen(wxPen(*wxBLACK, 2, wxSOLID)); dc.SetBrush(wxBrush(*wxGREEN, wxSOLID)); // 畫點 dc.DrawPoint(5, 5); // 畫線 dc.DrawLine(10, 10, 100, 100); // 畫矩形 dc.SetBrush(wxBrush(*wxBLACK, wxCROSS_HATCH)); dc.DrawRectangle(50, 50, 150, 100); // 改成紅色畫刷 dc.SetBrush(*wxRED_BRUSH); // 畫圓角矩形 dc.DrawRoundedRectangle(150, 20, 100, 50, 10); // 沒有輪廓線的圓角矩形 dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(wxBrush(*wxBLUE)); dc.DrawRoundedRectangle(250, 80, 100, 50, 10); // 改變顏色 dc.SetPen(wxPen(*wxBLACK, 2, wxSOLID)); dc.SetBrush(*wxBLACK); // 畫圓 dc.DrawCircle(100, 150, 60); // 再次改變畫刷顏色 dc.SetBrush(*wxWHITE); // 畫一個橢圓 dc.DrawEllipse(wxRect(120, 120, 150, 50)); } ``` ![](img/mht30B3%281%29.tmp) 注意一個約定俗成的規矩,線上的最后一個點將不會繪制。 要繪制一段圓弧,需要使用DrawArc函數,提供一個起點,一個終點和一個圓心的位置。這段圓弧將以逆時針方向從起點畫至終點,舉例如下: ``` int x = 10, y = 200, radius = 20; dc.DrawArc(xradius, y, x + radius, y, x, y); ``` ![](img/mht30C6%281%29.tmp) 繪制橢圓弧的函數DrawEllipticArc采用一個容納這個橢圓的矩形的四個頂點,以及橢圓弧開始和結束的角度作為參數,如果開始和結束的角度相同,則將繪制一個完整的橢圓。 ``` // 繪制一個包含在頂點為(10, 100), // 大小為 200x40\. 圓弧角度從 270到420度的圓弧. dc.DrawEllipticArc(10, 100, 200, 40, 270, 420); ``` ![](img/mht30C9%281%29.tmp) 如果你需要快速繪制很多條線段,那么DrawLines將會比多次調用DrawLine擁有更高的效率,下面的例子演示了快速繪制10個點之間的線段,并且指定了一個(100,100)的偏移量: ``` wxPoint points[10]; for (size_t i = 0; i &lt; 10; i++) { pt.x = i*10; pt.y = i*20; } int offsetX = 100; int offsetY = 100; dc.DrawLines(10, points, offsetX, offsetY); ``` DrawLines不會填充線段環繞的區域。如果你想在畫線的同時填充其環繞區域,你需要使用DrawPolygon函數,它的參數包括點的個數,點的列表,可選的平移參數以及填充類型。填充類型默認為wxODDEVEN_RULE,也可以使用wxWINDING_RULE。而 DrawPolygonPolygon用來同時繪制多個Polygon,它的額外的一個參數是另外一個整數的數組,用來指定在前面的點的數組中每個 Polygon中點的個數。 下面代碼演示了怎樣使用這兩個函數繪制polygons: ``` void DrawPolygons(wxDC& dc) { wxBrush brushHatch(*wxRED, wxFDIAGONAL_HATCH); dc.SetBrush(brushHatch); wxPoint star[5]; star[0] = wxPoint(100, 60); star[1] = wxPoint(60, 150); star[2] = wxPoint(160, 100); star[3] = wxPoint(40, 100); star[4] = wxPoint(140, 150); dc.DrawPolygon(WXSIZEOF(star), star, 0, 30); dc.DrawPolygon(WXSIZEOF(star), star, 160, 30, wxWINDING_RULE); wxPoint star2[10]; star2[0] = wxPoint(0, 100); star2[1] = wxPoint(-59, -81); star2[2] = wxPoint(95, 31); star2[3] = wxPoint(-95, 31); star2[4] = wxPoint(59, -81); star2[5] = wxPoint(0, 80); star2[6] = wxPoint(-47, -64); star2[7] = wxPoint(76, 24); star2[8] = wxPoint(-76, 24); star2[9] = wxPoint(47, -64); int count[2] = {5, 5}; dc.DrawPolyPolygon(WXSIZEOF(count), count, star2, 450, 150); } ``` 結果如下圖所示: ![](img/mht30CC%281%29.tmp) 使用云行規畫平滑曲線 DrawSpline函數讓你可以繪制一個稱為?云行規?的平滑曲線.這個函數有三個點和多個點兩個形式,下面的代碼對兩者都進行了演示: ``` // 三點云行規曲線 dc.DrawSpline(10, 100, 200, 200, 50, 230); // 五點云行規曲線 wxPoint star[5]; star[0] = wxPoint(100, 60); star[1] = wxPoint(60, 150); star[2] = wxPoint(160, 100); star[3] = wxPoint(40, 100); star[4] = wxPoint(140, 150); dc.DrawSpline(WXSIZEOF(star), star); ``` 結果如下圖所示: ![](img/mht30DE%281%29.tmp) 繪制位圖 在設備上下文上繪制位圖有兩種主要的方法:DrawBitmap和Blit。DrawBitmap其實是Blit的一種簡寫形式,它使用一個位圖,一個位置和一個bool類型的透明標志參數。根據圖像的制作和讀取過程的不同,位圖的透明繪制可以通過指定一個透明遮罩或者一個Alpha通道(通常用來實現半透明)來實現,下面的代碼演示了在一段文本上顯示的半透明的圖片: ``` wxString msg = wxT("Some text will appear mixed in the image's shadow..."); int y = 75; for (size_t i = 0; i &lt; 10; i++) { y += dc.GetCharHeight() + 5; dc.DrawText(msg, 200, y); } wxBitmap bmp(wxT("toucan.png"), wxBITMAP_TYPE_PNG); dc.DrawBitmap(bmp, 250, 100, true); ``` 運行結果如下圖所示:文本在圖片下面以半透明的方式隱隱浮現。 ![](img/mht30E1%281%29.tmp) Blit函數就略微顯的復雜些,它允許你拷貝一個設備上下文的一部分到另外一個設備上下文,下面是這個函數的原型: ``` bool Blit(wxCoord destX, wxCoord destY, wxCoord width, wxCoord height, wxDC* dcSource, wxCoord srcX, wxCoord srcY, int logicalFunc = wxCOPY, bool useMask = false, wxCoord srcMaskX = -1, wxCoord srcMaskY = -1); ``` 這個函數將dcSource參數指定的設備上下文中開始于srcX,srcY的位置,大小為width,height的區域拷貝到目標設備上下文(函數調用者自己)的destX,destY的位置,并且使用指定的邏輯函數進行拷貝。默認的邏輯函數是wxCOPY,意味著直接把源中的象素原封不動的傳輸到目標去。其它的邏輯函數依照平臺的不同有所不同,不是所有的邏輯函數都支持所有的平臺。我們將在本節稍后對邏輯函數進行專門介紹。 最后三個參數僅在園設備上下文為透明位圖的時候才有效。useMask參數指定是否使用透明遮罩,而srcMaskX和srcMaskY則可以通過其設置不采用和主位圖一致的遮罩位置。 下面的代碼演示了怎樣讀取一個位圖并將其平鋪在另外一個更大的設備上下文上,并且保留圖片本身的透明屬性: ``` wxMemoryDC dcDest; wxMemoryDC dcSource; int destWidth = 200, destHeight = 200; // 創建目標位圖 wxBitmap bitmapDest(destWidth, destHeight); // 加載調色板位圖 wxBitmap bitmapSource(wxT("pattern.png"), wxBITMAP_TYPE_PNG); int sourceWidth = bitmapSource.GetWidth(); int sourceHeight = bitmapSource.GetHeight(); // 用白色清除目標背景 dcDest.SelectObject(bitmapDest); dcDest.SetBackground(*wxWHITE_BRUSH); dcDest.Clear(); dcSource.SelectObject(bitmapSource); // 將小的位圖平鋪到大的位圖 for (int i = 0; i &lt; destWidth; i += sourceWidth) for (int j = 0; j &lt; destHeight; j += sourceHeight) { dcDest.Blit(i, j, sourceWidth, sourceHeight, & dcSource, 0, 0, wxCOPY, true); } //釋放內存設備上下文的位圖部分 dcDest.SelectBitmap(wxNullBitmap); dcSource.SelectBitmap(wxNullBitmap); ``` 你可以使用DrawIcon函數直接在設備上下文的某個位置顯示圖標,圖標將總以透明方式顯示: ``` #include "file.xpm" wxIcon icon(file_xpm); dc.DrawIcon(icon, 20, 30); ``` 填充特定區域 FloodFill函數采用三個參數來填充某個特定的區域。一個起始點參數,一個顏色參數用來確定填充的邊界和一個填充類型參數,設備上下文將使用當前的畫刷定義進行填充。 下面的例子演示了繪制一個綠色矩形區域,它的輪廓線是紅色,先進行黑色填充,進行藍色填充: ``` // 畫一個紅邊綠色的矩形 dc.SetPen(*wxRED_PEN); dc.SetBrush(*wxGREEN_BRUSH); dc.DrawRectangle(10, 10, 100, 100); dc.SetBrush(*wxBLACK_BRUSH); // 將綠色區域變成黑色 dc.FloodFill(50, 50, *wxGREEN, wxFLOOD_SURFACE); dc.SetBrush(*wxBLUE_BRUSH); // 開始填充藍色(直到遇到紅色) dc.FloodFill(50, 50, *wxRED, wxFLOOD_BORDER); ``` 如果找不到指定的顏色,這個函數可能返回失敗,如果指定的點在當前區域以外,這個函數也將返回失敗。這個函數不支持打印設備上下文以及wxMetafileDC。 邏輯函數 邏輯函數指定在繪畫時,源象素怎樣和目標象素進行合并操作,默認的wxCOPY只是使用源象素取代目標象素。其它的值則指定了一種邏輯操作。比如wxINVERT指定將目標象素的值取反作為新的值,這通常被用來繪制臨時邊框,因為使用這種方法進行繪圖在第二次以同樣的方法繪圖的時候將會恢復原樣。 下面的例子演示了怎樣繪制一條點線段,然后再將相關區域恢復原來的樣子。 ``` wxPen pen(*wxBLACK, 1, wxDOT); dc.SetPen(pen); // 以取反邏輯函數繪制 dc.SetLogicalFunction(wxINVERT); dc.DrawLine(10, 10, 100, 100); // 再次繪制 dc.DrawLine(10, 10, 100, 100); // 恢復正常繪制方法 dc.SetLogicalFunction(wxCOPY); ``` 邏輯函數的另外一個用法是通過組合的方式創建新的圖形。例如,我們可以用下面的方法來通過一個圖片創建一組對應的拼圖游戲需要的方塊。首先在一幅白色背景的圖片上使用固定但是隨機的大小創建一個黑色輪廓線的網格作為拼圖板的邊界,然后對于每一個網格小塊,使用flood-fill的方法將其填充成黑色以便創建一個白色背景上的黑色小方塊,然后使用wxAND_REVERSE邏輯函數將原圖Blit到這個模板,這樣作的結果是使得方塊內的部分變成原圖,而白色的背景則變成黑色的背景,然后我們再指定黑色為透明色創建一個wxImage,然后將其轉換成透明的wxBitmap對象,就可以直接在拼圖游戲中使用了。(注意這樣的作法需要原圖中沒有黑色,否則在拼圖小方塊中就會出現沒有顏色的窟窿了)。 下表列出了所有的邏輯函數以及它們的含義: | 邏輯函數 | 含義 (src = 源, dst = 目的) | |:--- |:--- | | wxAND | src AND dst | | wxAND_INVERT | (NOT src) AND dst | | wxAND_REVERSE | src AND (NOT dst) | | wxCLEAR | 0 | | wxCOPY | src | | wxEQUIV | (NOT src) XOR dst | | wxINVERT | NOT dst | | wxNAND | (NOT src) OR (NOT dst) | | wxNOR | (NOT src) AND (NOT dst) | | wxNO_OP | dst | | wxOR | src OR dst | | wxOR_INVERT | (NOT src) OR dst | | wxOR_REVERSE | src OR (NOT dst) | | wxSET | 1 | | wxSRC_INVERT | NOT src | | wxXOR | src XOR dst |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看