Customizing Line Caps and Line joins in GDI+


This article has been excerpted from book "Graphics Programming with GDI+".

Customizing Line Caps

Sometimes we need to use custom caps. Figure 9.8 shows a line with customized caps of different sizes.

The CustomLineCap and AdjustableArrowCap classes provide functionality to draw custom line caps. CustomLineCap allows us to define custom caps, which can be attached to a pen- then an application can use the pen to draw graphics objects.

The CustomLineCap class constructor takes two parameters of type GraphicsPath. The first parameter defines the fill path, which identifies the fill for the custom cap. The second parameter defines the stroke path, which defines the outline of the custom cap. The fill path and stroke path parameters cannot be used at the same time.

Figure-9.8.gif

FIGURE 9.8: A line with customs caps

To create a CustomLineCap object, first we create a GraphicsPath object and add items to the path such as a line, ellipse, or rectangle using any of the add methods. Then we pass the GraphicsPath object as an argument to CustomLineCap. The following code snippet shows how to create a CustomLineCap object:

        GraphicsPath path1 = new GraphicsPath()
        // Add items to GraphicsPath
        CutomLineCap cap1 = new CustomLineCap (null, path1);

Once we have a CustomLineCap object, we can set the CustomStartCap and CutomEndCap properties of the pen to apply custom line caps. We will see a full working example of custom line caps in a moment.

Table 9.4 describes the properties of the CustomLineCap class.

Line joins

A line join defines how lines and curves are joined in a graphics path. The LineJoin enumeration represents a line join. Its members are described in Table 9.5.

We can set the line join of a pen using its LineJoin property. To see the line joins, we create a Windows application and add a group box, four radio buttons, and a button to the form. The final form looks like Figure 9.9.

TABLE 9.4: CustomLineCap properties

Property

Description

BaseCap

The base line cap. LineCap enumeration type.

BaseInset

The distance between the cap and the line.

StrokeJoin

How lines and curves in the path that will be stroked are joined. LineJoin enumeration type.

WidthScale

Width scale of custom line cap. A WidthScale value of 2 methods that the cap will be double the pen size that is drawing the line cap.

TABLE 9.5: LineJoin members

Member

Description

Bevel

Beveled join with a diagonal corner.

Miter

Mitered join with a sharp corner or a clipped corner.

MiterClipped

Mitered join with a sharp corner or a beveled corner.

Round

Circular join with a smooth, circular arc between the lines.

Figure 9.9.jpg

FIGURE 9.9: The line join test application

When we select different line join types and hit the Apply LineJoin button, the application draws lines with different joins.

The code for the Apply LineJoin button click event handler and DrawJoinedLines method is given in Listing 9.6. As the listing shows, the Apply LineJoin button click event handler calls the DrawJoinedLines method with a LineJoin value determined by the current selection.

LISTING 9.6: The Apply LineJoin button click event handler

        private void ApplyLineJoin_Click(object sender, System.EventArgs e)
        {
            // Create a Graphics object
            Graphics g = this.CreateGraphics();
            g.Clear(this.BackColor);

            // Line join type
            if (BevelRadBtn.Checked)
            {
                 DrawJoinedLines(g, LineJoin.Bevel);
            }

            if (MiterRadBtn.Checked)
            {
                 DrawJoinedLines(g, LineJoin.Miter);
            }

            if (MiterClippedRadBtn.Checked)
            {
                 DrawJoinedLines(g, LineJoin.MiterClipped);
            }

            if (RoundRadBtn.Checked)
            {
                 DrawJoinedLines(g, LineJoin.Round);
            }

            // Dispose of object
            g.Dispose();
        }

        private void DrawJoinedLines(Graphics g, LineJoin JoinType)
        {
            // Set smoothing mode
             g.SmoothingMode = SmoothingMode.AntiAlias;

            // Create a pen with width 20
            Pen redPen = new Pen(Color.Red, 20);

            // Set line join
             redPen.LineJoin = JoinType;

            // Create an array of points
            Point[] pts =
            {
                        new Point (150, 20),
                        new Point (50, 20),
                        new Point (80, 60),
                        new Point (50, 150),
                        new Point (150, 150)
            };

            // Create a rectangle using lines
            Point[] pts1 =
            {
                        new Point (200, 20),
                        new Point (300, 20),
                        new Point (300, 120),
                        new Point (200, 120),
            new Point (200, 20)
            };

            // Draw lines
            g.DrawLines(redPen, pts);
             g.DrawLines(redPen, pts1);

            // Dispose of object
            redPen.Dispose();
        }

Now if we run the code, the Bevel linejoin output looks like Figure 9.10.

The Miter line join output looks like Figure 9.11.

The Round line join output looks like Figure 9.12.

Figure 9.10.jpg

FIGURE 9.10: The Bevel line join effect

Figure 9.11.jpg

FIGURE 9.11: The Miter line join effect

Conclusion

Hope the article would have helped you in understanding Customizing Line Caps and Line joins in GDI+. Read other articles on GDI+ on the website.

bookGDI.jpg
This book teaches .NET developers how to work with GDI+ as they develop applications that include graphics, or that interact with monitors or printers. It begins by explaining the difference between GDI and GDI+, and covering the basic concepts of graphics programming in Windows.

erver'>

Mindcracker
Founded in 2003, Mindcracker is the authority in custom software development and innovation. We put best practices into action. We deliver solutions based on consumer and industry analysis.