This article has been 
excerpted from book "Graphics Programming with GDI+".
We briefly discussed how to create a graphics path, and graphics items to path, 
and draw and fill graphics paths using FillPath and DrawPath in earlier 
articles.
A graphics path is a set of connected lines, curves, and other simple graphics 
objects, including rectangles, ellipses, and text. A path works as a single 
graphics object, so an effect applied to the graphics path will be applied to 
all the components of the path. For example, if a graphics path contains a line, 
a rectangle, and an ellipse and we draw the path using a red pen, all three 
components (line, rectangle, and ellipse) of the graphics path will be drawn 
with the red pen.
To create and use a graphics path, we create a GraphicsPath object and add its 
components by using add methods. For example, you can use the AddLine, 
AddRectangle, and AddEllipse methods to add a line, a rectangle, and an ellipse, 
respectively, to the graphics path. After adding components to a path, you can 
use DrawPath or FillPath to draw and fill it.
By default, all graphics shapes of a path are connected to one another and 
treated as a single entity with a collection of points and point types. But by 
using StartFigure and CloseFigure, an application can draw more than one image.
Creating a GraphicsPath object
The GraphicsPath class represents a graphics path in the .NET Framework library. 
It provides six overloaded constructors, which take as arguments a fill mode, 
array of points, and array of bytes (an array of PathPointTypes enumerations 
that defines the type of each corresponding point in the point array) to 
construct a GraphicsPath object. The following snippet uses different overloaded 
constructors to create GraphicsPath objects.
            GraphicsPath 
path1 = new GraphicsPath();
            GraphicsPath 
path2 = new GraphicsPath(FillMode.Winding);
            GraphicsPath 
path3 = new GraphicsPath
            pts, 
PathPointTypes, FillMode.Alternate);
In this function, pts represents an array of Point structures, and types 
represent an array of bytes, which take the PathPointType enumeration types, 
defined as follows:
            byte[] types = 
            {
             (byte) 
PathPointType.Start,
             (byte) 
PathPointType.Line,
             (byte) 
PathPointType.DashMode
            };
The GraphicsPath object includes an array of points and an array of types. Point 
types that make up shapes include starting points, ending points, and Bezier 
curve points. The PathPointType enumeration defines the type of a point in a 
graphics path. The members of the PathPointType enumeration are described in the 
Table 9.6.
Using GraphicsPath's Add Methods
You can create a GraphicsPath object from an array of points with PathPointType 
values, but I recommend that you use the methods of GraphicsPath to add various 
objects, instead of using PathPointType.
Now let's create a simple graphics path. Listing 9.9 gives the code for a simple 
graphics path with a line, a rectangle, and an ellipse. To test this code, 
create a Windows application, add a reference to the Sytem.Drawing.Advnaced2D 
namespace, and add the code on the form's load, or a button, or a menu item 
click event handler. The code creates a graphics path using GraphicsPath; adds 
two lines, a rectangle, and an ellipse using AddLine, AddRectangle, and 
AddEllipse, respectively; and draws the path using a red pen.
TABLE 9.6 PathPointType members
		| 
		Member | 
		Description | 
	
		| 
		Bezier | 
		Default Bezier 
		curve. | 
	
		| 
		Bezier3 | 
		Cubic Bezier 
		curve. There is no practical difference between Bezier and Bezier3. | 
	
		| 
		CloseSubpath | 
		Ending point of a 
		subpath. | 
	
		| 
		DashMode | 
		Dashed segment. | 
	
		| 
		Line  | 
		Line segment. | 
	
		| 
		PathMarker | 
		Path marker, which 
		allows easy traversal of a path by marking the points. | 
	
		| 
		PathTypeMarker
		 | 
		Mask point, which 
		allows us to show or hide points. | 
	
		| 
		Start | 
		Starting point of 
		a graphics path. | 
LISTING 9.9: Creating a simple graphics path
        private void 
Sample_Click(object sender, System.EventArgs 
e)
        {
            Graphics g = this.CreateGraphics();
            g.Clear(this.BackColor);
            // 
Create a graphics path
            GraphicsPath 
path = new GraphicsPath();
            // Add two lines, a rectangle and an ellipse
             path.AddLine(20, 20, 200, 20);
             path.AddLine(20, 20, 20, 200);
             path.AddRectangle(new
Rectangle(30, 30, 100, 100));
             path.AddEllipse(new 
Rectangle(50, 50, 60, 60));
            // Draw path
            Pen redPen = new
Pen(Color.Red, 
2);
             g.DrawPath(redPen, path);
            // Dispose of objects
            redPen.Dispose();
            g.Dispose();
        }
Figure 9.16 shows the output from Listing 9.9: two lines a rectangle, and an 
ellipse.
You can also fill a path with FillPath. If you replace the DrawPath line in 
Listing 9.9 with
            g.FillPath(new
SolidBrush(Color.Black), 
path);
the code will generate a new figure that looks like Figure 9.17.
FIGURE 9.16: A simple graphics path
FIGURE 9.17: A filled graphics path
Note: In a graphics path, all lines and curves are connected, even though 
you don't connect them explicitly. Objects like rectangle and circles may not be 
connected (unless you connect them explicitly) but they are still part of the 
path.
Shaped Forms and Graphics Paths
Graphics paths are very useful when you need to create shaped (non-rectangular) 
forms and controls. Using a graphics path, you can also write a form with a 
text-based shape. For example you can write a form application that looks like 
Figure 9.18, which includes a text string, two ellipses, and two rectangles.
Writing applications with shaped forms is easy if we use graphics paths. First 
we create a GraphicsPath object and add components (such as rectangles, ellipse, 
or text) to the path. Then we create a Region object from the graphics path and 
set it as the form's Region property. For example, Listing 9.10 adds text, two 
rectangles, and two ellipses to a graphics path, creates a Region object from 
this graphics path, and sets it as the Region property of the form. The output 
of this code will generate a form that looks like Figure 9.18.
LISTING 9.10: Using graphics paths to create shaped forms
            GraphicsPath 
path = new GraphicsPath(FillMode.Alternate);
             path.AddString("Close? Right Click!",
            new FontFamily("Verdana"),
            (int)FontStyle.Bold, 
50, new Point(0, 
0),
            StringFormat.GenericDefault);
             path.AddRectangle(new
Rectangle(20, 70, 100, 100));
             path.AddEllipse(new 
Rectangle(140, 70, 100, 100));
             path.AddEllipse(new 
Rectangle(260, 70, 100, 100));
             path.AddRectangle(new
Rectangle(380, 70, 100, 100));
            Region rgn = new
Region(path);
            this.Region = rgn;
To test this code, create a Windows application and add this code to the form's 
load event handler.
![Figure 9.18.jpg]()
FIGURE 9.18: A shaped form
GraphicsPath Properties and Methods
Let's examine the properties and methods of the GraphicsPath class before we 
start using them. Table 9.7 describes the properties.
The following code snippet read some of the GraphicsPath properties
            // Getting GraphicsPath properties
            FillMode fMode 
= path.FillMode;
            PathData data 
= path.PathData;
            PointF[] pts = path.PathPoints;
            byte[] ptsTypes = path.PathTypes;
            int count = path.PointCount;
TABLE 9.7: GraphicsPath properties
			| 
			
			Property | 
			Description | 
	
	
		| 
		FillMode | 
		Represents the 
		fill mode of a graphics path, which determines how the interior of a 
		graphics path is filled. This property is a FillMode enumeration type 
		and has two values: Alternate and Winding. | 
	
		| 
		PathData | 
		Returns a PathData 
		object containing path data for a graphics path. The path data of a 
		graphics path is composed of arrays of points and types. The Points 
		property of PathData returns an array of points, and the Types property 
		returns an array of types of points. | 
	
		| 
		PathPoint | 
		Represents all 
		points in a path. | 
	
		| 
		PathTypes | 
		Represents types 
		of the corresponding points in the PathPoints array.  | 
	
		| 
		PointCount | 
		Represents the 
		total number of items in PathPoints | 
Alternate and Winding Modes
As defined in the MSDN documentation, the alternate mode specifies that areas 
are filled according to the even-odd parity rule. According to this rule, you 
can determine whether a test point is inside or outside a closed curve as 
follows: Draw a line from the test point to a point that is distant from the 
curve. If that line crosses the curve an odd number of times, the test point is 
inside the curve; otherwise the test point is outside the curve.
The Winding mode specifies that areas are filled according to the nonzero 
winding rule, which says that you can determine whether a test point is inside 
or outside a closed curve as follows: Draw a line from test point to a point 
that is distant from the curve. Count the number of times the curve crosses the 
test line from left to right, and the number of times the curve crosses the test 
line from right to left. If those two numbers are the same, the test point is 
outside the curve; otherwise the test point is inside the curve.
The GraphicsPath class provides more than a dozen add methods to add graphics 
objects to a path. Among these methods are AddArc, AddBezier, AddBeziers, 
AddCloseCurve, AddCurve, AddEllipse, AddLine, AddLines, AddPath, AddPie, 
AddPolygon, AddRectangle, AddRectangles, and AddString. These methods are used 
to add an arc, a Bezier, a set of Beziers, a close curve, a curve, an ellipse, a 
line, a set of lines, a path, a pie, a polygon, a rectangle, as set of 
rectangles, and a string respectively. Other methods, which don't belong to the 
add category, are described in Table 9.8.
Subpaths
A graphics path can contain many subpaths. Having subpaths provides better 
control over individual paths. An application can break a graphics path into 
subpaths by using the StartFigure method. It can close open subpaths by using 
the CloseFigure or CloseAllFigures methods. StartFigure starts a new subpath of 
a path, and CloseFigure closes the opened subpath. CloseAllFigures closes all 
subpaths of graphics paths.
Listing 9.11 uses the StartFigure method to create three subpaths, and the 
CloseFigure and CloseAllFigures methods to close open figures. The first path 
contains an arc and a line, the second path contains two lines and a curve and 
the third path contains two lines.
TABLE 9.8: Some GraphicsPath methods
			| 
			
			Method | 
			Description | 
	
	
		| 
		ClearMarkers | 
		Clears all markers 
		from a path if any were set with PathPointType.PathMarker. | 
	
		| 
		CloseAllFigures | 
		Closes all open 
		figures in a path. | 
	
		| 
		CloseFigure | 
		Closes the current 
		figure. | 
	
		| 
		Flatten | 
		Approximates each 
		curve in a path with a sequence of connected line segment. | 
	
		| 
		GetLastPoint | 
		Returns the last 
		point in the PathPoints array. | 
	
		| 
		Reset | 
		Removes all points 
		and types from a path and sets the fill mode to Alternative. | 
	
		| 
		Reverse | 
		Reverse the order 
		of points in the PathPoints array of a path. | 
	
		| 
		SetMarkers | 
		Sets a marker on a 
		path. | 
	
		| 
		StartFigure | 
		Starts a new 
		figure. | 
	
		| 
		Transform | 
		Transforms a path 
		by applying a matrix on the path. | 
	
		| 
		Warp | 
		Applies a warp 
		transformation. | 
	
		| 
		Widen | 
		Replace a path 
		with curves that enclose the area that is filled when the path  is drawn 
		by the specified pen. | 
LISTING 9.11: Create Graphics subpaths
        private void 
SubPathMenu_Click(object sender, System.EventArgs 
e)
        {
            // Create a Graphics object
            Graphics g = this.CreateGraphics();
            g.Clear(this.BackColor);
            // Create a GrphicsPath object
            GraphicsPath 
path = new GraphicsPath();
            // Create an array of points
            Point[] pts =
            {
                        
new
Point (40, 80),
                        
new
Point (50, 70),
                        
new
Point (70, 90),
                        
new
Point (100, 120),
                        
new
Point (80, 120)
            };
            // Start first figure and add an arc and a line
             path.StartFigure();
             path.AddArc(250, 80, 100, 50, 30, -180);
             path.AddLine(180, 220, 320, 80);
            // Close first figure
             path.CloseFigure();
            // Start second figure and two lines and 
            // a curve and close all figures
             path.StartFigure();
             path.AddLine(50, 20, 5, 90);
             path.AddLine(50, 150, 150, 180);
             path.AddCurve(pts, 5);
             path.CloseAllFigures();
            // Create third figure and don't close it
             path.StartFigure();
             path.AddLine(200, 230, 250, 200);
             path.AddLine(200, 230, 250, 270);
            // Draw path
            g.DrawPath(new
Pen(Color.FromArgb(255, 255, 0, 0), 2), 
path);
            // path.Reverse();
            //path.Reset();
            // Dispose of object
            g.Dispose();
        }
Figure 9.19 shows the output from Listing 9.11. There are three unconnected 
subpaths.
The Reverse method can be used to reveres the order of points in a path, and the 
Reset method to remove (empty) all points from a path. The following code 
snipped shows how to use these two methods.
            path.Reverse();
            path.Reset();
The Graphics Path Iterator
As mentioned earlier, a graphics path is a set of graphics subpaths. We can 
determine the number of subpaths and the related data of a subpath by using the 
GraphicsPathIterator class. This class allows us to iterate through all the 
subpaths of a graphics path.
FIGURE 9.19: Three subpaths
The Count and SubpathCount properties of GraphicsPathIterator return the total 
number of points and the number of subpaths in a graphics path, respectively. 
The CopyData method can be used to copy the points of a path and their types. It 
returns the number of points, which is also the number of types copied.
The HasCurves method returns true if a path has curves in it; otherwise it 
returns false. The NextMarker method moves the iterator to the next marker in 
the path. The NextPathType method returns the starting and ending indices of the 
next group of data points that all have the same type.
The NextSubpath method returns the starting index, ending index, and a Boolean 
value of true if the subpath is closed (false if the subpath is open), and moves 
to the next subpath. The Rewind method resets the iterator to the beginning of 
the path.
Listing 9.12 creates and draws a graphics path and uses GraphicsPathIterator to 
find and show the data for all subpaths.
Listing 9.12: Iterating through subpaths
        private void 
GraphicsPathIterator_Paint(object sender, 
System.Windows.Forms.PaintEventArgs e)
        {
            // 
Get the Graphics object
            Graphics g = e.Graphics;
            // Create a rectangle
            Rectangle rect = new
Rectangle(50, 50, 100, 50);
            // Create a graphics path
            GraphicsPath 
path = new GraphicsPath();
            PointF[] ptsArray =
            {
                      new PointF(20, 
20),
                      new PointF(60, 
12),
                      new PointF(100, 
20)
            };
            // Add a curve, a rectangle, an ellipse, and a line
             path.AddCurve(ptsArray);
             path.AddRectangle(rect);
            rect.Y += 60;
             path.AddEllipse(rect);
             path.AddLine(120, 50, 220, 100);// Draw path
            g.DrawPath(Pens.Blue, 
path);
            // Create a graphics path iterator
             GraphicsPathIterator pathIterator =
            new GraphicsPathIterator(path);
            // Display total points and subpaths
            string str = "Total 
point = " + pathIterator.SubpathCount.ToString();
            MessageBox.Show(str);
            //Rewind
             pathIterator.Rewind();
            // Read all subpaths and their properties
            for (int i = 0; 
i < pathIterator.SubpathCount; i++)
            {
                int strIdx, endIdx;
                bool bClosedCurve;
                 pathIterator.NextSubpath(out strIdx,
                    out endIdx, out 
bClosedCurve);
                str =
"Start Index = " + strIdx.ToString()
                            + " , End Index = " + endIdx.ToString()
                            + ", IsColose = " + bClosedCurve.ToString();
                MessageBox.Show(str);
            }
        }
Graphics Containers
Suppose that you have a surface with 100 different graphics objects (text, 
shapes, and images), and you want to anti-alias just one object, perhaps for 
performance reasons. Without graphics containers, you would have to create a 
Graphics object and set the SmoothingMode property to AntiAlias – which would 
set anti-aliasing for everything drawn on the object. How do you set the 
smoothing mode of only one particular object on a surface? That's where 
containers come in.
The Graphics class provides methods and properties to define the attributes of 
graphics objects. For example, you can set the rendering quality to text using 
the TextRenderingHint property. The smoothing mode represents the quality of the 
graphics objects, the compositing quality represents the quality of composite 
images, the compositing mode represents whether pixels from a source image 
overwrite or are combined with background pixels, and the interpolation mode 
represents how intermediate values between two endpoints are calculated. These 
attributes are set with the SmoothingMode, CompositingMode, CompositingQuality, 
and InterpolationMode properties – which are applicable for an entire Graphics 
object. For example, if you set the SmoothingMode property of a Graphics object 
to AntiAlias, all graphics objects attached to that Graphics object will be 
anti-aliased.
A graphics container is a temporary graphics object that acts as a canvas for 
graphics shapes, allowing an application to set a container property separately 
from the main Graphics object. An application can apply properties to a Graphics 
object within a container and these properties won't be available outside of 
that container. Thus we can selectively apply properties to Graphics objects.
In Figure 9.20, for example, a Graphics object includes three graphics 
container, each with different properties. These properties are not available 
outside of their containers. All graphics objects inside a container may be 
affected by the container property. It's also possible to have nested 
containers.
FIGURE 9.20: Nested containers
Graphics containers do not inherit their parent's settings. In Figure 9.20, for 
example, the Graphics object is a container whose compositing quality is set to 
high and whose smoothing mode is set to high-speed. The graphics containers 
won't have high-speed and high-quality rendering unless we set them within the 
container itself. The smoothing mode of graphics container A is set to 
anti-aliasing; that of graphics container B is set to high quality. Graphics 
container C is a nested container within graphics container A, with 
interpolation mode set to high.
Before we discuss graphics containers in more detail, let's take a look at 
graphics states.
Conclusion
Hope the article would have helped you in understanding and using Graphics Paths 
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. |