
f you've done any Windows graphics programming at all, you know about Pens and Brushes. Pens determine the characteristics of lines, such as color and thickness. Brushes determine the characteristics of filled areas, notably the fill color.
Many programmers use the Pens class to get stock, one-pixel wide pens of various colors as in the code
e.Graphics.DrawLine(Pens.Red, 10, 10, 100, 100).
They also use the Brushes class to get stock solid colored brushes as in:
e.Graphics.FillEllipse(Brushes.Beige, _
New Rectangle(10, 10, 50, 100))
But Pens and Brushes can do moremuch more.
Line Joins
When you use the
DrawLines or
DrawPolygon methods to draw a series of connected lines, you can choose to connect the lines in one of the four ways shown in
Figure 1. The thick orange lines show the join styles and thin black lines drawn on top show where the lines are actually drawn.
The
Bevel style cuts the corners off at each turn so the bevel touches a point where two lines meet. The bevel's angle is evenly spaced between the angles of the incoming and outgoing lines. If you think of the line as a laser beam, the bevel is like a mirror making it bounce from one line to the next.
 | |
Figure 1. Line Join Styles: Here's the output of the sample program "LineJoins," which demonstrates line join styles. |
The
Miter style extends the sides of the lines at a corner until they meet. For very sharp turns, that can make the corner stick pretty far out.
The
MiterClipped style is the same as Miter unless a corner sticks out too far in which case it switches to Bevel.
Finally the
Round style makes the corners rounded so the edge of the line is the same distance from the lines at all times.
To use a particular join style, you first create a Pen object and then set its
LineJoin property as shown in the following code:
' Use an orange Pen, 10 pixels wide.
Using the_pen As New Pen(Color.Orange, 10)
the_pen.LineJoin = LineJoin.Round
e.Graphics.DrawLines(the_pen, pts)
End Using
Author's Note: The new Using statement automatically calls a Pen's or Brush's Dispose method, so I often employ it to simplify the code when dealing with Pens and Brushes. |
Most of the Pen techniques described in this article follow a similar pattern: you create a Pen and then modify the Pen's properties.
Line Caps
A Pen's
StartCap and
EndCap properties determine what the ends of lines look like.
Figure 2 shows samples of the available styles.
 | |
Figure 2. StartCap and EndCap Properties: The sample program "PenCaps" shows various Pen StartCap and EndCap styles. |
The
Round cap styles go nicely with the
Round LineJoin style. The
Flat cap styles usually work well with the other
LineJoin styles.
For example, the following code draws a line with a round ball at the start and an arrowhead at the end:
Using the_pen As New Pen(Color.Blue, 10)
the_pen.StartCap = LineCap.RoundAnchor
the_pen.EndCap = LineCap.ArrowAnchor
e.Graphics.DrawLine(the_pen, 10, 10, 100, 100)
End Using
Dash Styles
The
DashStyle property determines whether a Pen draws lines that are solid, dashed, dotted, or in some other style.
Figure 3 shows samples of the five pre-defined dash styles plus one custom style at the bottom.
To use a standard dash style, simply set the Pen's
DashStyle property as in the following code.
 | |
Figure 3. Dash Styles: The sample program "DashStyles" shows standard dash styles and one custom style (at the bottom). |
Using the_pen As New Pen(Color.Red, 3)
the_pen.DashStyle = DashStyle.Dash
e.Graphics.DrawLine(the_pen, 10, 10, 100, 200)
End Using
To make a custom dash style, create an array of Singles that indicate the number of units that should be drawn and then skipped while drawing the line. The array can contain as many values as you like. For example, if the Singles array holds the values
5,
1,
5,
1,
1,
1, it means: draw
5 units, skip
1 unit, draw
5 more, skip
1, draw
1, and finally, skip
1 unit. The Pen repeats these values as needed to draw longer lines.
The units in this array are Pen widths; so if the Pen you're using is
5 pixels wide then a
1 in the array means skip
5 pixels.
After you create the array, set the Pen's
DashStyle property to
Custom and set its
DashPattern property to the array. The following code draws a line with the pattern shown at the bottom of
Figure 3:
Using the_pen As New Pen(Color.Red, 3)
Dim dash_pattern() As Single = {5, 1, 5, 1, 1, 1}
the_pen.DashStyle = DashStyle.Custom
the_pen.DashPattern = dash_pattern
e.Graphics.DrawLine(the_pen, 10, 10, 100, 200)
End Using
Dash Caps
 | |
Figure 4. Dash Caps: The output of the sample program "DashCaps" illustrates how you can control the ends of dashed lines. |
Just as you can specify how the Pen should draw its end points, you can similarly specify how it should draw the ends of dashes. Set the Pen's
DashStyle property to something other than Solid and then set its
DashCap property to one of the three values shown in
Figure 4.
For example, the following code draws a thick green line with the
Triangle dash cap:
Using the_pen As New Pen(Color.Green, 11)
the_pen.DashStyle = DashStyle.Dash
the_pen.DashCap = DashCap.Triangle
e.Graphics.DrawLine(the_pen, 10, 10, 100, 100)
End Using