天天看點

Direct2D教程II——繪制基本圖形和線型(StrokeStyle)的設定詳解

繪制基本圖形:直線、矩形、圓角矩形、橢圓

和GDI+類似,在RenderTarget對象下有各個繪圖指令(GDI+是在Graphics對象下有各個繪圖指令),下面是各個基本圖形的繪圖指令的函數原型

直線: 

Public Sub DrawLine(firstPoint As Direct2D1.Point2F, secondPoint As Direct2D1.Point2F, brush As Direct2D1.Brush, skrokeWidth As Single, strokeStyle As Direct2D1.StrokeStyle)

矩形: 

Public Sub DrawRectangle(rect As Direct2D1.RectF, brush As Direct2D1.Brush, strokeWidth As Single)  

Public Sub DrawRectangle(rect As Direct2D1.RectF, brush As Direct2D1.Brush, strokeWidth As Single, strokeStyle As Direct2D1.StrokeStyle)  

Public Sub FillRectangle(rect As Direct2D1.RectF, brush As Direct2D1.Brush)

圓角矩形: 

Public Sub DrawRoundedRectangle(roundedRect As Direct2D1.RoundedRect, brush As Direct2D1.Brush, strokeWidth As Single) 

Public Sub DrawRoundedRectangle(roundedRect As Direct2D1.RoundedRect, brush As Direct2D1.Brush, strokeWidth As Single, strokeStyle As Direct2D1.StrokeStyle)  

Public Sub FillRoundedRectangle(roundedRect As Direct2D1.RoundedRect, brush As Direct2D1.Brush)

橢圓: 

Public Sub DrawEllipse(ellipse As Direct2D1.Ellipse, brush As Direct2D1.Brush, strokeWidth As Single) 

Public Sub DrawEllipse(ellipse As Direct2D1.Ellipse, brush As Direct2D1.Brush, strokeWidth As Single, strokeStyle As Direct2D1.StrokeStyle)  

Public Sub FillEllipse(ellipse As Direct2D1.Ellipse, brush As Direct2D1.Brush)

從上面的函數原型可以看出,以Draw開頭的函數都是繪制函數。以Fill開頭的函數都是填充函數。繪制函數的線寬由strokeWidth參數指定,繪制函數的線型由strokeStyle參數指定(預設是實線)。和GDI+不同的是,在Direct2D中,不再區分Brush(畫刷)和Pen(畫筆)對象,而統一用Brush(畫刷)對象,在用Brush(畫刷)繪制線的時候再指定線寬和線型參數。

從參數strokeWidth和參數strokeStyle來看,都帶有單詞stroke。熟悉PS的都知道,stroke指的是描邊,在PS中描邊的位置分為“外部”、“内部”、“居中”。那麼在Direct2D中,這裡的描邊的位置在哪兒呢?我們用代碼實驗一下。

說明:為了代碼的複用,我們把前文中的_d2DFactory和_renderTarget修飾限定詞從Private改為Protected。這樣在後面的例子中直接繼承前文的類,也可以直接用_d2DFactory和_renderTarget這兩個對象。

先給出Point2F、RectF、RoundedRect、Ellipse這四個類的原型定義,參數都簡介明了,不再詳述

Direct2D1.Point2F(x As Single, y As Single) 

Direct2D1.RectF(left As Single, top As Single, right As Single, buttom As Single) 

Direct2D1.RoundedRect(rect As Direct2D1.RectF, radiusX As Single, radiusY As Single) 

Direct2D1.Ellipse(point As Direct2D1.Point2F, radiusX As Single, radiusY As Single)

下面是實驗示例代碼

Public Class clsDirect2DSample2 

    Inherits clsDirect2DSample 

    Public Shadows Sub Render() 

        If Not _renderTarget Is Nothing Then 

            With _renderTarget 

                .BeginDraw() 

                Dim F1 As New Direct2D1.RectF(0, 0, 100, 50) 

                Dim F2 As New Direct2D1.RectF(200, 200, 300, 250) 

                Dim B As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(New Direct2D1.ColorF(1, 0, 0)) 

                _renderTarget.DrawRectangle(F1, B, 10) 

                _renderTarget.DrawRectangle(F2, B, 10) 

                .EndDraw() 

            End With 

        End If 

    End Sub 

End Class

從上圖的代碼來看,在(0,0)位置上畫了一個100*50的矩形,描邊寬度10px。在(200,200)位置上畫了一個矩形,描邊寬度10px,如下圖所示

Direct2D教程II——繪制基本圖形和線型(StrokeStyle)的設定詳解

從上面的效果可以看出兩點:

一是左上角的矩形說明,Direct2D中的描邊類型應該是“居中”;

二是右邊的矩形說明Direct2D中的RectF定義和原本GDI+中的RectangleF定義不同,Direct2D中的RectF中後兩個參數是右下角的坐标,而GDI+中的RectangleF中的後兩個參數指的是矩形的寬和高。

線型(StrokeStyle)的設定

在上面的函數原型中,線型是由參數strokeStyle決定的,它是StrokeStyle類。這個類不能直接初始化,必須由D2DFactory對象的CreateStrokeStyle函數建立(Direct2D中有不少的類不能直接初始化,必須由D2DFactory或RenderTarget對象的相應的函數建立,如上面的SolidColorBrush對象就必須由RenderTarget對象的CreateSolidColorBrush函數建立)。

先看看CreateStrokeStyle函數的原型定義: 

Public Function CreateStrokeStyle(strokeStyleProperties As Direct2D1.StrokeStyleProperties) As Direct2D1.StrokeStyle 

Public Function CreateStrokeStyle(strokeStyleProperties As Direct2D1.StrokeStyleProperties, dashes() As Single) As Direct2D1.StrokeStyle

主要是通過strokeStyleProperties參數來設定線型,來看看StrokeStyleProperties結構及其參數對象的原型定義。

Direct2D1.StrokeStyleProperties(startCap As Direct2D1.CapStyle, endCap As Direct2D1.CapStyle, dashCap As Direct2D1.CapStyle, _ 

                                            lineJoin As Direct2D1.LineJoin, miterLimit As Single, _ 

                                            dashStyle As Direct2D1.DashStyle, dashOffset As Single) 

Public Enum CapStyle 

    Flat = 0 

    Square = 1 

    Round = 2 

    Triangle = 3 

End Enum 

Public Enum LineJoin 

    Miter = 0 

    Bevel = 1 

    MiterOrBevel = 3 

Public Enum DashStyle 

    Solid = 0 

    Dash = 1 

    Dot = 2 

    DashDot = 3 

    DashDotDot = 4 

    Custom = 5 

其中CapStyle枚舉指的是線端的線頭類型,分别是Flat(平整,即無)、Square(方塊)、Round(圓)、Triangle(三角)。和GDI+中的DashCap枚舉類似,多了一個Square(方塊),而在下面的例子中會說明Flat和Square的差別。參數startCap決定線起點的線頭類型、endCap決定線終點的線頭類型、dashCap決定中間劃線端的線頭類型。

而DashStyle枚舉指的是線型,分别是Solid(實線)、Dash(劃線)、Dot(點線)、DashDot(點劃線)、DashDotDot(點點劃線)、Custom(自定義)。和GDI+中的DashStyle一樣。

參數dashOffset指的是點劃線的偏移量

下面的代碼是對上面的兩個枚舉的示範,請注意枚舉CapStyle中的Flat和Square的差別。

Public Class clsDirect2DSample3 

                Dim SP As New Direct2D1.StrokeStyleProperties() 

                Dim S As Direct2D1.StrokeStyle 

                SP.StartCap = Direct2D1.CapStyle.Flat 

                SP.EndCap = Direct2D1.CapStyle.Flat 

                S = _d2DFactory.CreateStrokeStyle(SP) 

                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 20), New Direct2D1.Point2F(200, 20), B, 8, S) 

                SP.StartCap = Direct2D1.CapStyle.Square 

                SP.EndCap = Direct2D1.CapStyle.Square 

                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 40), New Direct2D1.Point2F(200, 40), B, 8, S) 

                SP.StartCap = Direct2D1.CapStyle.Round 

                SP.EndCap = Direct2D1.CapStyle.Round 

                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 60), New Direct2D1.Point2F(200, 60), B, 8, S) 

                SP.StartCap = Direct2D1.CapStyle.Triangle 

                SP.EndCap = Direct2D1.CapStyle.Triangle 

                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 80), New Direct2D1.Point2F(200, 80), B, 8, S) 

                SP.DashCap = Direct2D1.CapStyle.Round 

                SP.DashStyle = Direct2D1.DashStyle.Solid 

                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 120), New Direct2D1.Point2F(200, 120), B, 6, S) 

                SP.DashStyle = Direct2D1.DashStyle.Dash 

                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 140), New Direct2D1.Point2F(200, 140), B, 6, S) 

                SP.DashStyle = Direct2D1.DashStyle.Dot 

                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 160), New Direct2D1.Point2F(200, 160), B, 6, S) 

                SP.DashStyle = Direct2D1.DashStyle.DashDot 

                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 180), New Direct2D1.Point2F(200, 180), B, 6, S) 

                SP.DashStyle = Direct2D1.DashStyle.DashDotDot 

                _renderTarget.DrawLine(New Direct2D1.Point2F(10, 200), New Direct2D1.Point2F(200, 200), B, 6, S) 

Direct2D教程II——繪制基本圖形和線型(StrokeStyle)的設定詳解

上面四條線是示範枚舉CapStyle的四種類型,注意第一條線是Flat,第二條線是Square。雖然都是方形,但是很明顯第二條線比第一條線兩邊還多出一點(方形線帽)

下面五條線是示範枚舉DashStyle表示的五個線型。注意:上面代碼中紅色的部分,DashCap不能設定為Direct2D1.CapStyle.Flat,如果設定為Flat,則所有的點都不見了;設定其他三種類型分别代表不同的點(方形點、圓點、菱形點)。

再說說枚舉DashStyle中的Custom線型。設定為Custom後,必須用一個數組來指定自定義劃線的線型。數組按照{實、空、實、空……}順序來指定各部分的長度,機關是線寬。

例如{2,2}表示2線寬長的實線和2線寬長的空白組成的劃線,也就是枚舉DashStyle中的Dash

{0,2}表示0線寬長的實線和2線寬長的空白組成的劃線,就是枚舉DashStyle中的Dot。這也解釋了DashCap設定為Direct2D1.CapStyle.Flat時,為何點不見了(設定為其他值時,點實際上是由線頭組成的,點本身的長度為0)。

以此類推,{2,2,0,2}表示DashStyle中的DashDot,{2,2,0,2,0,2}表示DashStyle中的DashDotDot

要注意的是,隻有枚舉DashStyle設定為Custom時,才能傳遞數組,否則會直接報錯的。

最後說說LineJoin枚舉,指的是連接配接兩條線的連接配接方式。分别是Miter(折角)、Bevel(倒角)、Round(圓角)、MiterOrBevel(折角或倒角)。和GDI+中的LineJoin枚舉類似,隻是MiterOrBevel好像對應GDI+中LineJoin枚舉中的MiterClipped。

說說MiterOrBevel,當折角的值沒有超過指定的值(系統指定)時,是Miter(折角),反之超過的話是Bevel(倒角)。

參數miterLimit是指折角的限制,低于限制時會自動添加倒角。參數miterLimit最小是1。注意的是miterLimit參數并不是配合LineJoin使用。當miterLimit設定為1的時候,下面的例子中,LineJoin枚舉設定成Miter、Bevel、MiterOrBevel效果是一樣的。當miterLimit設定為3的時候,LineJoin枚舉設定成Miter、Bevel、MiterOrBevel效果才是不一樣的

下面是LineJoin的示例,由于是示範兩條線的連接配接,故用了一些後面才會詳述的代碼。不過,不影響我們了解枚舉LineJoin的各個設定值的意義。

左上是Miter,右上是Bevel,左下是Round,右下是MiterOrBevel

Public Class clsDirect2DSample4 

                Dim PG As Direct2D1.PathGeometry 

                Dim sink As Direct2D1.GeometrySink 

                PG = _d2DFactory.CreatePathGeometry 

                sink = PG.Open 

                sink.BeginFigure(New Direct2D1.Point2F(17, 17), Direct2D1.FigureBegin.Hollow) 

                sink.AddLine(New Direct2D1.Point2F(45, 85)) 

                sink.AddLine(New Direct2D1.Point2F(85, 45)) 

                sink.AddLine(New Direct2D1.Point2F(85, 125)) 

                sink.AddLine(New Direct2D1.Point2F(165, 17)) 

                sink.EndFigure(Direct2D1.FigureEnd.Open) 

                sink.Close() 

                SP.LineJoin = Direct2D1.LineJoin.Miter 

                SP.MiterLimit = 3 

                .DrawGeometry(PG, B, 10, S) 

                sink.BeginFigure(New Direct2D1.Point2F(217, 17), Direct2D1.FigureBegin.Hollow) 

                sink.AddLine(New Direct2D1.Point2F(245, 85)) 

                sink.AddLine(New Direct2D1.Point2F(285, 45)) 

                sink.AddLine(New Direct2D1.Point2F(285, 125)) 

                sink.AddLine(New Direct2D1.Point2F(365, 17)) 

                SP.LineJoin = Direct2D1.LineJoin.Bevel 

                sink.BeginFigure(New Direct2D1.Point2F(17, 217), Direct2D1.FigureBegin.Hollow) 

                sink.AddLine(New Direct2D1.Point2F(45, 285)) 

                sink.AddLine(New Direct2D1.Point2F(85, 245)) 

                sink.AddLine(New Direct2D1.Point2F(85, 325)) 

                sink.AddLine(New Direct2D1.Point2F(165, 217)) 

                SP.LineJoin = Direct2D1.LineJoin.Round 

                sink.BeginFigure(New Direct2D1.Point2F(217, 217), Direct2D1.FigureBegin.Hollow) 

                sink.AddLine(New Direct2D1.Point2F(245, 285)) 

                sink.AddLine(New Direct2D1.Point2F(285, 245)) 

                sink.AddLine(New Direct2D1.Point2F(285, 325)) 

                sink.AddLine(New Direct2D1.Point2F(365, 217)) 

                SP.LineJoin = Direct2D1.LineJoin.MiterOrBevel 

下面是效果圖

Direct2D教程II——繪制基本圖形和線型(StrokeStyle)的設定詳解

從上圖能看出四種類型的不同。左上是Miter,右上是Bevel,左下是Round,右下是MiterOrBevel

    本文轉自萬倉一黍部落格園部落格,原文連結:http://www.cnblogs.com/grenet/p/3250828.html,如需轉載請自行聯系原作者

繼續閱讀