正文

GUI+2006-07-13 21:22:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/iamben250/16585.html

分享到:

Pens. Part 1

Pens are used to stroke lines, polygons, curves and shapes such as rectangles and ellipses. They can be very simple to use or rather complex. In many of the examples you've seen in this series, simple pens have been used to illustrate stroking of shapes so let's take a closer look at the pen and it capabilities.

One might imagine that there wasn't much that was difficult about drawing a line on a graphics surface. Even curves and ellipses can be approximated using straight-line segments so really, all you need is a way of connecting two points with a line of pixels and away you go! Nothing could be further from the truth for GDI+ however. The "simple" process of drawing a line is in fact full of a wealth of possibilities by virtue of the sheer quantity of properties including the width of the pen, the style of the line, the type and shape of the line end-caps and the way the line is filled. In this first part of the Pen exposé you will see some of the simpler options.

Standard Pens.

The System.Drawing namespace provides a standard set of pens which are always available for use. These are to be found in the Pens array and there is one pen for each system colour available. These pens are all of unit width and have been used before in some of the examples seen in this series. Drawing a line with one of the stock pens is accomplished as follows:

graphics.DrawLine(Pens.Black,0,0,100,100)

Remember however that GDI+ is a resolution independent system so a unit width pen might be an inch, a millimeter, a point or a pixel wide depending on the settings of the Graphics.PageUnit property. For more details see this article. If you don't want a pen that is a unit wide you have to construct a new pen with the desired width.

Pen Width.

Pens can be made to draw a line in any width. This is done by constructing a pen with a colour or a brush and a floating point value that specifies the width. Remember that a unit width pen will be one inch wide if the Graphics.PageUnit property is set to inches so you may need a pen of, say 1/20th of an inch in width to create a reasonable line. This is why the pens Width property is a floating point value.

The Pen constructor takes a width setting as shown in the following listing. In this case the pen will be 5 units wide.

Dim p as New Pen(Color.Red, 5)

A Pen object can be forced to draw a one-pixel wide line regardless of the page-unit settings by using a pen-width of -1.

When is a line not a line?

The answer is of course; "When it's a line in GDI+". All lines are in fact complex shapes that are created and filled with a specific brush. Even when the line appears to be just one pixel wide the lines are drawn in a complex way. To illustrate this point the following image shows what originally seems to be a single pixel line at several magnifications.

Figure 1. Same pen, different magnifications.

You can clearly see that as the magnification increases from one to twenty times, the form of the line is seen to be a rectangle. So, a line is a rectangle? Well, no. not really. A line is a shaped object that might in some circumstances be rectangular but the shape of the line-ends depends on the type of end-caps used. End-caps enable you to tidy up the end of a line to make it neater or to make it join up with other lines nicely. Here is the same output but using rounded line caps.

Figure 2. Round line-caps.

Why should line-caps be important? Figure 3 shows several lines drawn end-to end with square line-caps.

Figure 3. Square line-caps.

While Figure 4 shows the same lines drawn with round line-caps. The advantages are clear.

Figure 4. Rounded line caps.

The important thing to note is that the line isn't simply a line of pixels and the pen does a lot more than string dots out in straight lines. Pens create complex areas that can be filled with any colour, a gradient that fades from one colour to another or a texture made from a bitmap image.

More Line-Caps.

In addition to the rounded line caps there are a selection of other shapes and the ability for you to create your own which you'll see in a later article. The standard line caps can be seen in figure 5.

Figure 5. Lines and end caps.

The code that produced this drawing is shown in the following listing. Note that two members of the LineCaps enumeration, Custom and AnchorMask have been left out of the illustration in figure 5 because they are not germane to this article.

  'This file Imports System.Drawing.Drawing2D

  Protected Overloads Overrides Sub OnPaint(ByVal e As PaintEventArgs)

    Dim p As Pen = New Pen(Color.Black, 20)

    Dim y As Integer = 20

    Dim s As String

    For Each s In System.Enum.GetNames(GetType(LineCap))

      Dim linecap As LineCap = CType(System.Enum.Parse(GetType(LineCap), s), LineCap)

      p.StartCap = linecap

      p.EndCap = linecap

      e.Graphics.DrawLine(p, 30, y, 230, y)

      e.Graphics.DrawString(s, Font, Brushes.Black, 260, y - 10, StringFormat.GenericTypographic)

      y += 40

    Next

    MyBase.OnPaint(e)

  End Sub

 

Dots and dashes.

In addition to line caps, pens can be styled along their length with dotted lines and intricate pen-nibs that produce fancy parallel lines. Figure 6 shows a selection of standard line styles as defined by the DashStyle enumeration. The Custom dash-style has been omitted because it will be dealt with in a later article.

Figure 6. Standard dash-styles.

The code that drew this image can be seen in the following listing.

  Protected Overloads Overrides Sub OnPaint(ByVal e As PaintEventArgs)

    Dim p As Pen = New Pen(Color.Black, 10)

    Dim y As Integer = 20

    Dim s As String

    For Each s In System.Enum.GetNames(GetType(System.Drawing.Drawing2D.DashStyle))

      p.DashStyle = CType(System.Enum.Parse(GetType(DashStyle), s), DashStyle)

      e.Graphics.DrawLine(p, 20, y, 420, y)

      e.Graphics.DrawString(s, Font, Brushes.Black, 440, y - 10, StringFormat.GenericTypographic)

      y += 40

    Next

  End Sub

Compound pens.

A compound pen enables you to draw fancy borders and lines easily. Imagine a pen with a wide nib that you can cut into slices and take some bits out. A pen such as that shown in Figure 7 would draw a fancy line wherever it went. The nib should be considered as being one unit wide, whatever that unit may be, and the parallel lines created by subdividing the nib in fractions as seen in the illustration.

Figure 7. A compound pen.

The definition of this custom pen-nib is provided by an array of float or Single values that describe the distances between the lines and the thickness of the lines. Once created the compound pen may be used to draw fancy frames such as that seen in Figure 8.

Figure 8. Compound pens in action.

The code that produced this effect can be seen in the following listing.

  Protected Overloads Overrides Sub OnPaint(ByVal e As PaintEventArgs)

    Dim p As Pen = New Pen(Color.Black, 20)

    p.CompoundArray = New Single() {0, 0.2, 0.3, 0.6, 0.7, 1}

    e.Graphics.DrawRectangle(p, 20, 20, 200, 150)

    e.Graphics.DrawEllipse(p, 20, 200, 200, 150)

    MyBase.OnPaint(e)

  End Sub

 

Summary.

So far you've seen how pens are more complex than simple lines, how they create shapes that can be filled rather than true strokes, how they can be capped with interesting shapes and how they can be made to draw complex parallel figures. This has just been the start of what pens can do. They will return in another article soon.

Return to the Beginners Guide to GDI+

阅读(1652) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册