GraphicsPath.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / CommonUI / System / Drawing / Advanced / GraphicsPath.cs / 1 / GraphicsPath.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Drawing.Drawing2D { 
    using System.Runtime.InteropServices; 
    using System.Diagnostics;
    using System; 
    using Microsoft.Win32;
    using System.Drawing;
    using System.ComponentModel;
    using System.Drawing.Internal; 
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization; 
 
    /**
     * Represent a Path object 
     */
    /// 
    /// 
    ///    Represents a series of connected lines and 
    ///    curves.
    ///  
    [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
    public sealed class GraphicsPath : MarshalByRefObject, ICloneable, IDisposable {
 
        /*
         * handle to native path object
         */
        internal IntPtr nativePath; 

        /** 
         * Create a new path object with the default fill mode 
         */
        ///  
        /// 
        ///    
        ///       Initializes a new instance of the  class with a  of 
        ///       . 
        ///    
        ///  
        public GraphicsPath() : this(System.Drawing.Drawing2D.FillMode.Alternate) { } 

        /** 
         * Create a new path object with the specified fill mode
         */
        /// 
        ///  
        ///    Initializes a new instance of the  class with the specified .
        ///  
        public GraphicsPath(FillMode fillMode) { 
            IntPtr nativePath = IntPtr.Zero;
 
            int status = SafeNativeMethods.Gdip.GdipCreatePath((int)fillMode, out nativePath);

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 

            this.nativePath = nativePath; 
        } 

        // float version 
        /// 
        /// 
        ///    
        ///    Initializes a new instance of the 
        ///     array with the
        ///    specified  
        ///    and  arrays. 
        ///    
        ///  
        public GraphicsPath(PointF[] pts, byte[] types) :
          this(pts, types, System.Drawing.Drawing2D.FillMode.Alternate) {}

        ///  
        /// 
        ///     
        ///       Initializes a new instance of the  array with the 
        ///       specified  and  arrays and with the
        ///       specified . 
        ///    
        /// 
        public GraphicsPath(PointF[] pts, byte[] types, FillMode fillMode) {
            if (pts == null) 
                throw new ArgumentNullException("pts");
            IntPtr nativePath = IntPtr.Zero; 
 
            if (pts.Length != types.Length)
                throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.InvalidParameter); 

            int count = types.Length;
            IntPtr ptbuf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts);
            IntPtr typebuf = Marshal.AllocHGlobal(count); 
            try {
                Marshal.Copy(types, 0, typebuf, count); 
 
                int status = SafeNativeMethods.Gdip.GdipCreatePath2(new HandleRef(null, ptbuf), new HandleRef(null, typebuf), count,
                                                     (int)fillMode, out nativePath); 


                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(ptbuf); 
                Marshal.FreeHGlobal(typebuf); 
            }
 
            this.nativePath = nativePath;
        }

        // int version 
        /// 
        ///  
        ///     
        ///    Initializes a new instance of the
        ///     array with the 
        ///    specified 
        ///    and  arrays.
        ///    
        ///  
        public GraphicsPath(Point[] pts, byte[] types) :
          this(pts, types, System.Drawing.Drawing2D.FillMode.Alternate) {} 
 
        /// 
        ///  
        ///    
        ///       Initializes a new instance of the  array with the
        ///       specified  and  arrays and with the
        ///       specified . 
        ///    
        ///  
        public GraphicsPath(Point[] pts, byte[] types, FillMode fillMode) { 
            if (pts == null)
                throw new ArgumentNullException("pts"); 
            IntPtr nativePath = IntPtr.Zero;

            if (pts.Length != types.Length)
                throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.InvalidParameter); 

            int count = types.Length; 
            IntPtr ptbuf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts); 
            IntPtr typebuf = Marshal.AllocHGlobal(count);
            try { 
                Marshal.Copy(types, 0, typebuf, count);

                int status = SafeNativeMethods.Gdip.GdipCreatePath2I(new HandleRef(null, ptbuf), new HandleRef(null, typebuf), count,
                                                      (int)fillMode, out nativePath); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally { 
                Marshal.FreeHGlobal(ptbuf);
                Marshal.FreeHGlobal(typebuf); 
            }

            this.nativePath = nativePath;
        } 

        /** 
         * Make a copy of the current path object 
         */
        ///  
        /// 
        ///    Creates an exact copy of this .
        /// 
        public object Clone() { 
            IntPtr clonePath = IntPtr.Zero;
 
            int status = SafeNativeMethods.Gdip.GdipClonePath(new HandleRef(this, nativePath), out clonePath); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);

            return new GraphicsPath(clonePath, 0);
 
        }
 
        /** 
         * 'extra' parameter is necessary to avoid conflict with
         * other constructor GraphicsPath(int fillmode) 
         */

        private GraphicsPath(IntPtr nativePath, int extra) {
            if (nativePath == IntPtr.Zero) 
                throw new ArgumentNullException("nativePath");
 
            this.nativePath = nativePath; 
        }
 
        /**
         * Dispose of resources associated with the
         */
        ///  
        /// 
        ///    Eliminates resources for this . 
        ///  
        public void Dispose() {
            Dispose(true); 
            GC.SuppressFinalize(this);
        }
        void Dispose(bool disposing) {
            if (nativePath != IntPtr.Zero) { 
                 try{
#if DEBUG 
                    int status = 
#endif
                    SafeNativeMethods.Gdip.GdipDeletePath(new HandleRef(this, nativePath)); 
#if DEBUG
                    Debug.Assert(status == SafeNativeMethods.Gdip.Ok, "GDI+ returned an error status: " + status.ToString(CultureInfo.InvariantCulture));
#endif
                } 
                catch( Exception ex ){
                    if( ClientUtils.IsSecurityOrCriticalException( ex ) ) { 
                        throw; 
                    }
 
                    Debug.Fail( "Exception thrown during Dispose: " + ex.ToString() );
                }
                finally{
                     nativePath = IntPtr.Zero; 
                }
            } 
        } 

        ///  
        /// 
        ///    Eliminates resources for this .
        /// 
        ~GraphicsPath() { 
            Dispose(false);
        } 
 
        /**
         * Reset the path object to empty 
         */
        /// 
        /// 
        ///    Empties the  
        ///    and  arrays
        ///    and sets the  to 
        ///    . 
        /// 
        public void Reset() { 
            int status = SafeNativeMethods.Gdip.GdipResetPath(new HandleRef(this, nativePath));

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        /** 
         * Get path fill mode information
         */ 
        /// 
        /// 
        ///    Gets or sets a  that determines how the interiors of
        ///    shapes in this  are filled. 
        /// 
        public FillMode FillMode { 
            get { 
                int fillmode = 0;
 
                int status = SafeNativeMethods.Gdip.GdipGetPathFillMode(new HandleRef(this, nativePath), out fillmode);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return(FillMode) fillmode; 
            } 
            set {
                //validate the FillMode enum 
                //valid values are 0x0 to 0x1
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)FillMode.Alternate, (int)FillMode.Winding))
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(FillMode)); 
                }
 
                int status = SafeNativeMethods.Gdip.GdipSetPathFillMode(new HandleRef(this, nativePath), (int) value); 

                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            }
        }
 
        private PathData _GetPathData() {
 
            int ptSize = (int) Marshal.SizeOf(typeof(GPPOINTF)); 

            int numPts = PointCount; 

            PathData pathData = new PathData();
            pathData.Types = new byte[numPts];
 
            IntPtr memoryPathData = Marshal.AllocHGlobal(3*IntPtr.Size);
            IntPtr memoryPoints = Marshal.AllocHGlobal(ptSize*numPts); 
            try { 
                GCHandle typesHandle = GCHandle.Alloc(pathData.Types, GCHandleType.Pinned);
                try { 
                    IntPtr typesPtr = typesHandle.AddrOfPinnedObject();
                    //IntPtr typesPtr = Marshal.AddrOfArrayElement(pathData.Types, IntPtr.Zero);

                    Marshal.StructureToPtr(numPts, memoryPathData, false); 
                    Marshal.StructureToPtr(memoryPoints, (IntPtr)((long)memoryPathData+IntPtr.Size), false);
                    Marshal.StructureToPtr(typesPtr, (IntPtr)((long)memoryPathData+2*IntPtr.Size), false); 
 
                    int status = SafeNativeMethods.Gdip.GdipGetPathData(new HandleRef(this, nativePath), memoryPathData);
 
                    if (status != SafeNativeMethods.Gdip.Ok) {
                        throw SafeNativeMethods.Gdip.StatusException(status);
                    }
 
                    pathData.Points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(memoryPoints, numPts);
                } finally { 
                    typesHandle.Free(); 
                }
            } finally { 
                Marshal.FreeHGlobal(memoryPathData);
                Marshal.FreeHGlobal(memoryPoints);
            }
 
            return pathData;
        } 
 
        /// 
        ///  
        ///    Gets a  object that
        ///    encapsulates both the  and  arrays of this .
        /// 
        public PathData PathData { 
            get {
                return _GetPathData(); 
            } 
        }
 
        /// 
        /// 
        ///    
        ///       Starts a new figure without closing the 
        ///       current figure. All subsequent points added to the path are added to this new
        ///       figure. 
        ///     
        /// 
        public void StartFigure() { 
            int status = SafeNativeMethods.Gdip.GdipStartPathFigure(new HandleRef(this, nativePath));

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        ///  
        /// 
        ///    Closes the current figure and starts a new 
        ///    figure. If the current figure contains a sequence of connected lines and curves,
        ///    it closes the loop by connecting a line from the ending point to the starting
        ///    point.
        ///  
        public void CloseFigure() {
            int status = SafeNativeMethods.Gdip.GdipClosePathFigure(new HandleRef(this, nativePath)); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    Closes all open figures in a path and
        ///    starts a new figure. It closes each open figure by connecting a line from it's 
        ///    ending point to it's starting point. 
        /// 
        public void CloseAllFigures() { 
            int status = SafeNativeMethods.Gdip.GdipClosePathFigures(new HandleRef(this, nativePath));

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        ///  
        /// 
        ///     
        ///       Sets a marker on this  .
        ///    
        /// 
        public void SetMarkers() { 
            int status = SafeNativeMethods.Gdip.GdipSetPathMarker(new HandleRef(this, nativePath));
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 

        /// 
        /// 
        ///    Clears all markers from this . 
        /// 
        public void ClearMarkers() { 
            int status = SafeNativeMethods.Gdip.GdipClearPathMarkers(new HandleRef(this, nativePath)); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        }

        ///  
        /// 
        ///    Reverses the order of points in the  array of this . 
        ///  
        public void Reverse() {
            int status = SafeNativeMethods.Gdip.GdipReversePath(new HandleRef(this, nativePath)); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 

        ///  
        ///  
        ///    Gets the last point in the  array of this .
        ///  
        public PointF GetLastPoint() {
            GPPOINTF gppt = new GPPOINTF();

            int status = SafeNativeMethods.Gdip.GdipGetPathLastPoint(new HandleRef(this, nativePath), gppt); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 

            return gppt.ToPoint(); 
        }

        /*
         * Hit testing 
         */
 
        ///  
        /// 
        ///     
        ///       Indicates whether the specified point is contained
        ///       within this 
        ///       .
        ///     
        /// 
        public bool IsVisible(float x, float y) { 
            return IsVisible(new PointF(x,y), (Graphics)null); 
        }
 
        /// 
        /// 
        ///    
        ///       Indicates whether the specified point is contained 
        ///       within this .
        ///     
        ///  
        public bool IsVisible(PointF point) {
            return IsVisible(point, (Graphics)null); 
        }

        /// 
        ///  
        ///    
        ///       Indicates whether the specified point is contained within this  in the visible clip region of the 
        ///       specified . 
        ///    
        ///  
        public bool IsVisible(float x, float y, Graphics graphics) {
            return IsVisible(new PointF(x,y), graphics);
        }
 
        /// 
        ///  
        ///     
        ///       Indicates whether the specified point is contained within this .
        ///     
        /// 
        public bool IsVisible(PointF pt, Graphics graphics) {
            int isVisible;
 
            int status = SafeNativeMethods.Gdip.GdipIsVisiblePathPoint(new HandleRef(this, nativePath),
                                                        pt.X, 
                                                        pt.Y, 
                                                        new HandleRef(graphics, (graphics != null) ?
                                                            graphics.NativeGraphics : IntPtr.Zero), 
                                                        out isVisible);

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 

            return isVisible != 0; 
        } 

        ///  
        /// 
        ///    
        ///       Indicates whether the specified point is contained within this  .
        ///     
        /// 
        public bool IsVisible(int x, int y) { 
            return IsVisible(new Point(x,y), (Graphics)null); 
        }
 
        /// 
        /// 
        ///    
        ///       Indicates whether the specified point is contained within this . 
        ///    
        ///  
        public bool IsVisible(Point point) { 
            return IsVisible(point, (Graphics)null);
        } 

        /// 
        /// 
        ///     
        ///       Indicates whether the specified point is contained within this  in the visible clip region of the
        ///       specified . 
        ///     
        /// 
        public bool IsVisible(int x, int y, Graphics graphics) { 
            return IsVisible(new Point(x,y), graphics);
        }

        ///  
        /// 
        ///     
        ///       Indicates whether the specified point is contained within this . 
        ///    
        ///  
        public bool IsVisible(Point pt, Graphics graphics) {
            int isVisible;

            int status = SafeNativeMethods.Gdip.GdipIsVisiblePathPointI(new HandleRef(this, nativePath), 
                                                         pt.X,
                                                         pt.Y, 
                                                         new HandleRef(graphics, (graphics != null) ? 
                                                             graphics.NativeGraphics : IntPtr.Zero),
                                                         out isVisible); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return isVisible != 0;
        } 
 
        /// 
        ///  
        ///    Indicates whether an outline drawn by the
        ///    specified  at the specified location is contained
        ///    within this .
        ///  
        public bool IsOutlineVisible(float x, float y, Pen pen) {
            return IsOutlineVisible(new PointF(x,y), pen, (Graphics)null); 
        } 

        ///  
        /// 
        ///    
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this . 
        ///    
        ///  
        public bool IsOutlineVisible(PointF point, Pen pen) { 
            return IsOutlineVisible(point, pen, (Graphics)null);
        } 

        /// 
        /// 
        ///     
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this  and within the visible clip region of 
        ///       the specified . 
        ///    
        ///  
        public bool IsOutlineVisible(float x, float y, Pen pen, Graphics graphics) {
            return IsOutlineVisible(new PointF(x,y), pen, graphics);
        }
 
        /// 
        ///  
        ///     
        ///       Indicates whether an outline drawn by the specified
        ///     at the specified 
        ///       location is contained within this  and within the visible clip region of
        ///       the specified .
        ///    
        ///  
        public bool IsOutlineVisible(PointF pt, Pen pen, Graphics graphics) {
            int isVisible; 
 
            if (pen == null)
                throw new ArgumentNullException("pen"); 

            int status = SafeNativeMethods.Gdip.GdipIsOutlineVisiblePathPoint(new HandleRef(this, nativePath),
                                                               pt.X,
                                                               pt.Y, 
                                                               new HandleRef(pen, pen.NativePen),
                                                               new HandleRef(graphics, (graphics != null) ? 
                                                                   graphics.NativeGraphics : IntPtr.Zero), 
                                                               out isVisible);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            return isVisible != 0; 
        }
 
        ///  
        /// 
        ///     
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this .
        ///    
        ///  
        public bool IsOutlineVisible(int x, int y, Pen pen) {
            return IsOutlineVisible(new Point(x,y), pen, (Graphics)null); 
        } 

        ///  
        /// 
        ///    
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this . 
        ///    
        ///  
        public bool IsOutlineVisible(Point point, Pen pen) { 
            return IsOutlineVisible(point, pen, (Graphics)null);
        } 

        /// 
        /// 
        ///     
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this  and within the visible clip region of 
        ///       the specified . 
        ///    
        ///  
        public bool IsOutlineVisible(int x, int y, Pen pen, Graphics graphics) {
            return IsOutlineVisible(new Point(x,y), pen, graphics);
        }
 
        /// 
        ///  
        ///     
        ///       Indicates whether an outline drawn by the specified
        ///     at the specified 
        ///       location is contained within this  and within the visible clip region of
        ///       the specified .
        ///    
        ///  
        public bool IsOutlineVisible(Point pt, Pen pen, Graphics graphics) {
            int isVisible; 
 
            if (pen == null)
                throw new ArgumentNullException("pen"); 

            int status = SafeNativeMethods.Gdip.GdipIsOutlineVisiblePathPointI(new HandleRef(this, nativePath),
                                                                pt.X,
                                                                pt.Y, 
                                                                new HandleRef(pen, pen.NativePen),
                                                                new HandleRef(graphics, (graphics != null) ? 
                                                                    graphics.NativeGraphics : IntPtr.Zero), 
                                                                out isVisible);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            return isVisible != 0; 
        }
 
        /* 
         * Add lines to the path object
         */ 
        // float version
        /// 
        /// 
        ///    Appends a line segment to this . 
        /// 
        public void AddLine(PointF pt1, PointF pt2) { 
            AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y); 
        }
 
        /// 
        /// 
        ///    Appends a line segment to this .
        ///  
        public void AddLine(float x1, float y1, float x2, float y2) {
            int status = SafeNativeMethods.Gdip.GdipAddPathLine(new HandleRef(this, nativePath), x1, y1, x2, y2); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    Appends a series of connected line
        ///    segments to the end of this . 
        ///  
        public void AddLines(PointF[] points) {
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
            int status = SafeNativeMethods.Gdip.GdipAddPathLine2(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length); 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally { 
                Marshal.FreeHGlobal(buf);
            } 

        }

        // int version 
        /// 
        ///  
        ///     
        ///       Appends a line segment to this .
        ///     
        /// 
        public void AddLine(Point pt1, Point pt2) {
            AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
        } 

        ///  
        ///  
        ///    
        ///       Appends a line segment to this . 
        ///    
        /// 
        public void AddLine(int x1, int y1, int x2, int y2) {
            int status = SafeNativeMethods.Gdip.GdipAddPathLineI(new HandleRef(this, nativePath), x1, y1, x2, y2); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        /// 
        /// 
        ///    
        ///       Appends a series of connected line segments to the end of this . 
        ///    
        ///  
        public void AddLines(Point[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathLine2I(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf); 
            }
        } 

        /*
         * Add an arc to the path object
         */ 
        // float version
        ///  
        ///  
        ///    
        ///       Appends an elliptical arc to the current 
        ///       figure.
        ///    
        /// 
        public void AddArc(RectangleF rect, float startAngle, float sweepAngle) { 
            AddArc(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
        } 
 
        /// 
        ///  
        ///    
        ///       Appends an elliptical arc to the current figure.
        ///    
        ///  
        public void AddArc(float x, float y, float width, float height,
                           float startAngle, float sweepAngle) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathArc(new HandleRef(this, nativePath), x, y, width, height, 
                                                startAngle, sweepAngle);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
        }
 
        // int version
        ///  
        ///  
        ///    
        ///       Appends an elliptical arc to the current figure. 
        ///    
        /// 
        public void AddArc(Rectangle rect, float startAngle, float sweepAngle) {
            AddArc(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle); 
        }
 
        ///  
        /// 
        ///     
        ///       Appends an elliptical arc to the current figure.
        ///    
        /// 
        public void AddArc(int x, int y, int width, int height, 
                           float startAngle, float sweepAngle) {
            int status = SafeNativeMethods.Gdip.GdipAddPathArcI(new HandleRef(this, nativePath), x, y, width, height, 
                                                 startAngle, sweepAngle); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        }

        /* 
        * Add Bezier curves to the path object
        */ 
        // float version 
        /// 
        ///  
        ///    
        ///       Adds a cubic Bzier curve to the current
        ///       figure.
        ///     
        /// 
        public void AddBezier(PointF pt1, PointF pt2, PointF pt3, PointF pt4) { 
            AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y); 
        }
 
        /// 
        /// 
        ///    
        ///       Adds a cubic Bzier curve to the current 
        ///       figure.
        ///     
        ///  
        public void AddBezier(float x1, float y1, float x2, float y2,
                              float x3, float y3, float x4, float y4) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathBezier(new HandleRef(this, nativePath), x1, y1, x2, y2,
                                                   x3, y3, x4, y4);

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a sequence of connected cubic Bzier
        ///       curves to the current figure.
        ///     
        /// 
        public void AddBeziers(PointF[] points) { 
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathBeziers(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        // int version
        /// 
        /// 
        ///     
        ///       Adds a cubic Bzier curve to the current figure.
        ///     
        ///  
        public void AddBezier(Point pt1, Point pt2, Point pt3, Point pt4) {
            AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y); 
        }

        /// 
        ///  
        ///    
        ///       Adds a cubic Bzier curve to the current 
        ///       figure. 
        ///    
        ///  
        public void AddBezier(int x1, int y1, int x2, int y2,
                              int x3, int y3, int x4, int y4) {
            int status = SafeNativeMethods.Gdip.GdipAddPathBezierI(new HandleRef(this, nativePath), x1, y1, x2, y2,
                                                    x3, y3, x4, y4); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        /// 
        /// 
        ///    
        ///       Adds a sequence of connected cubic Bzier curves to the 
        ///       current figure.
        ///     
        ///  
        public void AddBeziers(params Point[] points) {
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathBeziersI(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally { 
                Marshal.FreeHGlobal(buf);
            } 
        }

        /*
         * Add cardinal splines to the path object 
         */
        // float version 
        ///  
        /// 
        ///     
        ///       Adds a spline curve to the current figure.
        ///       A Cardinal spline curve is used because the curve travels through each of the
        ///       points in the array.
        ///     
        /// 
        public void AddCurve(PointF[] points) { 
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        /// 
        /// 
        ///    Adds a spline curve to the current figure.
        ///  
        public void AddCurve(PointF[] points, float tension) {
            if (points == null) 
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve2(new HandleRef(this, nativePath), new HandleRef(null, buf),
                                                   points.Length, tension);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        /// 
        /// 
        ///    
        ///       Adds a spline curve to the current figure. 
        ///    
        ///  
        public void AddCurve(PointF[] points, int offset, int numberOfSegments, 
                             float tension) {
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve3(new HandleRef(this, nativePath), new HandleRef(null, buf), 
                                                   points.Length, offset,
                                                   numberOfSegments, tension); 
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf);
            }
        }
 
        // int version
        ///  
        ///  
        ///    
        ///       Adds a spline curve to the current figure. A Cardinal spline curve is used 
        ///       because the curve travels through each of the points in the array.
        ///    
        /// 
        public void AddCurve(Point[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathCurveI(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally {
                Marshal.FreeHGlobal(buf); 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a spline curve to the current figure.
        ///    
        ///  
        public void AddCurve(Point[] points, float tension) {
            if (points == null) 
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve2I(new HandleRef(this, nativePath), new HandleRef(null, buf),
                                                    points.Length, tension);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        /// 
        /// 
        ///    
        ///       Adds a spline curve to the current figure. 
        ///    
        ///  
        public void AddCurve(Point[] points, int offset, int numberOfSegments, 
                             float tension) {
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve3I(new HandleRef(this, nativePath), new HandleRef(null, buf), 
                                                    points.Length, offset,
                                                    numberOfSegments, tension); 
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf);
            }
        }
 
        // float version
        ///  
        ///  
        ///    
        ///       Adds a closed curve to the current figure. A Cardinal spline curve is 
        ///       used because the curve travels through each of the points in the array.
        ///    
        /// 
        public void AddClosedCurve(PointF[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathClosedCurve(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally {
                Marshal.FreeHGlobal(buf); 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a closed curve to the current figure. A Cardinal spline curve is
        ///       used because the curve travels through each of the points in the array.
        ///     
        /// 
        public void AddClosedCurve(PointF[] points, float tension) { 
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathClosedCurve2(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length, tension);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        // int version
        /// 
        /// 
        ///     
        ///       Adds a closed curve to the current figure. A Cardinal spline curve is used
        ///       because the curve travels through each of the points in the array. 
        ///     
        /// 
        public void AddClosedCurve(Point[] points) { 
            if (points == null)
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathClosedCurveI(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            }
        }

        ///  
        /// 
        ///     
        ///       Adds a closed curve to the current figure. A Cardinal spline curve is used 
        ///       because the curve travels through each of the points in the array.
        ///     
        /// 
        public void AddClosedCurve(Point[] points, float tension) {
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathClosedCurve2I(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length, tension); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf);
            }
        } 

        ///  
        ///  
        ///    Adds a rectangle to the current figure.
        ///  
        public void AddRectangle(RectangleF rect) {
            int status = SafeNativeMethods.Gdip.GdipAddPathRectangle(new HandleRef(this, nativePath), rect.X, rect.Y,
                                                      rect.Width, rect.Height);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        } 

        ///  
        /// 
        ///    
        ///       Adds a series of rectangles to the current
        ///       figure. 
        ///    
        ///  
        public void AddRectangles(RectangleF[] rects) { 
            if (rects == null)
                throw new ArgumentNullException("rects"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertRectangleToMemory(rects);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathRectangles(new HandleRef(this, nativePath), new HandleRef(null, buf), rects.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf); 
            }
        } 

        // int version
        /// 
        ///  
        ///    
        ///       Adds a rectangle to the current figure. 
        ///     
        /// 
        public void AddRectangle(Rectangle rect) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathRectangleI(new HandleRef(this, nativePath), rect.X, rect.Y,
                                                       rect.Width, rect.Height);

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a series of rectangles to the current figure.
        ///    
        ///  
        public void AddRectangles(Rectangle[] rects) {
            if (rects == null) 
                throw new ArgumentNullException("rects"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertRectangleToMemory(rects);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathRectanglesI(new HandleRef(this, nativePath), new HandleRef(null, buf), rects.Length);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf);
            } 
        } 

        // float version 
        /// 
        /// 
        ///    Adds an ellipse to the current figure.
        ///  
        public void AddEllipse(RectangleF rect) {
            AddEllipse(rect.X, rect.Y, rect.Width, rect.Height); 
        } 

        /** 
         * Add an ellipse to the current path
         *
         * !!! Need to handle the status code returned
         *  by the native GDI+ APIs. 
         */
        ///  
        ///  
        ///    Adds an ellipse to the current figure.
        ///  
        public void AddEllipse(float x, float y, float width, float height) {
            int status = SafeNativeMethods.Gdip.GdipAddPathEllipse(new HandleRef(this, nativePath), x, y, width, height);

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        // int version
        ///  
        /// 
        ///    
        ///       Adds an ellipse to the current figure.
        ///     
        /// 
        public void AddEllipse(Rectangle rect) { 
            AddEllipse(rect.X, rect.Y, rect.Width, rect.Height); 
        }
 
        /**
         * Add an ellipse to the current path
         *
         * !!! Need to handle the status code returned 
         *  by the native GDI+ APIs.
         */ 
        ///  
        /// 
        ///     
        ///       Adds an ellipse to the current figure.
        ///    
        /// 
        public void AddEllipse(int x, int y, int width, int height) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathEllipseI(new HandleRef(this, nativePath), x, y, width, height);
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 

        /// 
        /// 
        ///     
        ///       Adds the outline of a pie shape to the
        ///       current figure. 
        ///     
        /// 
        public void AddPie(Rectangle rect, float startAngle, float sweepAngle) { 
            AddPie(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
        }

        // float version 
        /// 
        ///  
        ///     
        ///       Adds the outline of a pie shape to the current
        ///       figure. 
        ///    
        /// 
        public void AddPie(float x, float y, float width, float height,
                           float startAngle, float sweepAngle) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathPie(new HandleRef(this, nativePath), x, y, width, height,
                                                startAngle, sweepAngle); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        // int version
        ///  
        /// 
        ///     
        ///       Adds the outline of a pie shape to the current 
        ///       figure.
        ///     
        /// 
        public void AddPie(int x, int y, int width, int height,
                           float startAngle, float sweepAngle) {
            int status = SafeNativeMethods.Gdip.GdipAddPathPieI(new HandleRef(this, nativePath), x, y, width, height, 
                                                 startAngle, sweepAngle);
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 

        // float version
        /// 
        ///  
        ///    Adds a polygon to the current figure.
        ///  
        public void AddPolygon(PointF[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathPolygon(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf); 
            }
        } 

        // int version
        /// 
        ///  
        ///    Adds a polygon to the current figure.
        ///  
        public void AddPolygon(Point[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathPolygonI(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf); 
            }
        } 

        /// 
        /// 
        ///    Appends the specified  to this . 
        /// 
        public void AddPath(GraphicsPath addingPath, 
                            bool connect) 
        {
            if (addingPath == null) 
                throw new ArgumentNullException("addingPath");

            int status = SafeNativeMethods.Gdip.GdipAddPathPath(new HandleRef(this, nativePath), new HandleRef(addingPath, addingPath.nativePath), connect);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        } 

        /* 
         * Add text string to the path object
         *
         * @notes The final form of this API is yet to be defined.
         * @notes What are the choices for the format parameter? 
         */
 
        ///  
        /// 
        ///     
        ///       Adds a text string to the current figure.
        ///    
        /// 
        public void AddString(String s, FontFamily family, int style, float emSize, 
                              PointF origin, StringFormat format) {
            GPRECTF rectf = new GPRECTF(origin.X, origin.Y, 0, 0); 
 
            int status = SafeNativeMethods.Gdip.GdipAddPathString(new HandleRef(this, nativePath),
                                                   s, 
                                                   s.Length,
                                                   new HandleRef(family, (family != null) ? family.NativeFamily : IntPtr.Zero),
                                                   style,
                                                   emSize, 
                                                   ref rectf,
                                                   new HandleRef(format, (format != null) ? format.nativeFormat : IntPtr.Zero)); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    
        ///       Adds a text string to the current figure. 
        ///     
        /// 
        public void AddString(String s, FontFamily family, int style, float emSize, 
                              Point origin, StringFormat format) {
            GPRECT rect = new GPRECT(origin.X, origin.Y, 0, 0);

            int status = SafeNativeMethods.Gdip.GdipAddPathStringI(new HandleRef(this, nativePath), 
                                                    s,
                                                    s.Length, 
                                                    new HandleRef(family, (family != null) ? family.NativeFamily : IntPtr.Zero), 
                                                    style,
                                                    emSize, 
                                                    ref rect,
                                                    new HandleRef(format, (format != null) ? format.nativeFormat : IntPtr.Zero));

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a text string to the current figure.
        ///    
        ///  
        public void AddString(String s, FontFamily family, int style, float emSize,
                              RectangleF layoutRect, StringFormat format) { 
            GPRECTF rectf = new GPRECTF(layoutRect); 
            int status = SafeNativeMethods.Gdip.GdipAddPathString(new HandleRef(this, nativePath),
                                                   s, 
                                                   s.Length,
                                                   new HandleRef(family, (family != null) ? family.NativeFamily : IntPtr.Zero),
                                                   style,
                                                   emSize, 
                                                   ref rectf,
                                                   new HandleRef(format, (format != null) ? format.nativeFormat : IntPtr.Zero)); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    
        ///       Adds a text string to the current figure. 
        ///     
        /// 
        public void AddString(String s, FontFamily family, int style, float emSize, 
                              Rectangle layoutRect, StringFormat format) {
            GPRECT rect = new GPRECT(layoutRect);
            int status = SafeNativeMethods.Gdip.GdipAddPathStringI(new HandleRef(this, nativePath),
                                                   s, 
                                                   s.Length,
                                                   new HandleRef(family, (family != null) ? family.NativeFamily : IntPtr.Zero), 
                                                   style, 
                                                   emSize,
                                                   ref rect, 
                                                   new HandleRef(format, (format != null) ? format.nativeFormat : IntPtr.Zero));

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        ///  
        /// 
        ///    Applies a transform matrix to this . 
        /// 
        public void Transform(Matrix matrix) {
            if (matrix == null)
                throw new ArgumentNullException("matrix"); 

            // !! Is this an optimization?  We should catch this in GdipTransformPath 
            if (matrix.nativeMatrix == IntPtr.Zero) 
                return;
 
            int status = SafeNativeMethods.Gdip.GdipTransformPath(new HandleRef(this, nativePath),
                                                   new HandleRef(matrix, matrix.nativeMatrix));

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Returns a rectangle that bounds this .
        ///    
        ///  
        public RectangleF GetBounds() {
            return GetBounds(null); 
        } 

        ///  
        /// 
        ///    
        ///       Returns a rectangle that bounds this  when it
        ///       is transformed by the specified . 
        ///    
        ///  
        public RectangleF GetBounds(Matrix matrix) { 
            return GetBounds(matrix, null);
        } 

        /// 
        /// 
        ///     
        ///       Returns a rectangle that bounds this  when it is
        ///       transformed by the specified . and drawn with the specified . 
        ///     
        /// 
        public RectangleF GetBounds(Matrix matrix, Pen pen) { 
            GPRECTF gprectf = new GPRECTF();

            IntPtr nativeMatrix = IntPtr.Zero, nativePen = IntPtr.Zero;
 
            if (matrix != null)
                nativeMatrix = matrix.nativeMatrix; 
 
            if (pen != null)
                nativePen = pen.NativePen; 

            int status = SafeNativeMethods.Gdip.GdipGetPathWorldBounds(new HandleRef(this, nativePath),
                                                        ref gprectf,
                                                        new HandleRef(matrix, nativeMatrix), 
                                                        new HandleRef(pen, nativePen));
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return gprectf.ToRectangleF();
        }

        /* 
         * Flatten the path object
         */ 
 
        /// 
        ///  
        ///    Converts each curve in this  into a sequence of connected line
        ///    segments.
        /// 
        public void Flatten() { 
            Flatten(null);
        } 
 
        /// 
        ///  
        ///    Converts each curve in this  into a sequence of connected line
        ///    segments.
        /// 
        public void Flatten(Matrix matrix) { 
            Flatten(matrix, 0.25f);
        } 
 
        /// 
        ///  
        ///    Converts each curve in this  into a sequence of connected line
        ///    segments.
        /// 
        public void Flatten(Matrix matrix, float flatness) { 

            int status = SafeNativeMethods.Gdip.GdipFlattenPath(new HandleRef(this, nativePath), 
                                                           new HandleRef(matrix, (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix), 
                                                           flatness);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
        }
 

        /** 
         * Widen the path object 
         *
         * @notes We don't have an API yet. 
         *  Should we just take in a GeometricPen as parameter?
         */
        /// 
        ///  
        /// 
        public void Widen(Pen pen) { 
            float flatness = (float) 2.0 / (float) 3.0; 
            Widen(pen, (Matrix)null, flatness);
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public void Widen(Pen pen, Matrix matrix) { 
            float flatness = (float) 2.0 / (float) 3.0; 
            Widen(pen, matrix, flatness);
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public void Widen(Pen pen, 
                          Matrix matrix, 
                          float flatness)
        { 
            IntPtr nativeMatrix;

            if (matrix == null)
                nativeMatrix = IntPtr.Zero; 
            else
                nativeMatrix = matrix.nativeMatrix; 
 
            if (pen == null)
                throw new ArgumentNullException("pen"); 

            //

 

            int pointCount; 
            SafeNativeMethods.Gdip.GdipGetPointCount(new HandleRef(this, nativePath), out pointCount); 

            if(pointCount == 0) 
                return;

            int status = SafeNativeMethods.Gdip.GdipWidenPath(new HandleRef(this, nativePath),
                                new HandleRef(pen, pen.NativePen), 
                                new HandleRef(matrix, nativeMatrix),
                                flatness); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void Warp(PointF[] destPoints, RectangleF srcRect)
        { Warp(destPoints, srcRect, null); } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix matrix) 
        { Warp(destPoints, srcRect, matrix, WarpMode.Perspective); }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix matrix, 
                         WarpMode warpMode) 
        { Warp(destPoints, srcRect, matrix, warpMode, 0.25f); }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix matrix, 
                         WarpMode warpMode, float flatness) 
        {
            if (destPoints == null) 
                throw new ArgumentNullException("destPoints");

            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(destPoints);
            try { 
                int status = SafeNativeMethods.Gdip.GdipWarpPath(new HandleRef(this, nativePath),
                                              new HandleRef(matrix, (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix), 
                                              new HandleRef(null, buf), 
                                              destPoints.Length,
                                              srcRect.X, 
                                              srcRect.Y,
                                              srcRect.Width,
                                              srcRect.Height,
                                              warpMode, 
                                              flatness);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            }
        }

        /** 
         * Return the number of points in the current path
         */ 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public int PointCount {
            get {
                int count = 0; 

                int status = SafeNativeMethods.Gdip.GdipGetPointCount(new HandleRef(this, nativePath), out count); 
 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return count;
            }
        } 

        /** 
         * Return the path point type information 
         */
        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public byte[] PathTypes { 
            get {
                int count = PointCount; 
 
                byte[] types = new byte[count];
 
                int status = SafeNativeMethods.Gdip.GdipGetPathTypes(new HandleRef(this, nativePath), types, count);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return types; 
            } 
        }
 
        /*
         * Return the path point coordinate information
         * @notes Should there be PathData that contains types[] and points[]
         *        for get & set purposes. 
         */
        // float points 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public PointF[] PathPoints {
            get {
                int count = PointCount; 
                int size = (int) Marshal.SizeOf(typeof(GPPOINTF));
                IntPtr buf = Marshal.AllocHGlobal(count * size); 
                try { 
                    int status = SafeNativeMethods.Gdip.GdipGetPathPoints(new HandleRef(this, nativePath), new HandleRef(null, buf), count);
 
                    if (status != SafeNativeMethods.Gdip.Ok) {
                        throw SafeNativeMethods.Gdip.StatusException(status);
                    }
 
                    PointF[] points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(buf, count);
                    return points; 
                } finally { 
                    Marshal.FreeHGlobal(buf);
                } 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Drawing.Drawing2D { 
    using System.Runtime.InteropServices; 
    using System.Diagnostics;
    using System; 
    using Microsoft.Win32;
    using System.Drawing;
    using System.ComponentModel;
    using System.Drawing.Internal; 
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization; 
 
    /**
     * Represent a Path object 
     */
    /// 
    /// 
    ///    Represents a series of connected lines and 
    ///    curves.
    ///  
    [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
    public sealed class GraphicsPath : MarshalByRefObject, ICloneable, IDisposable {
 
        /*
         * handle to native path object
         */
        internal IntPtr nativePath; 

        /** 
         * Create a new path object with the default fill mode 
         */
        ///  
        /// 
        ///    
        ///       Initializes a new instance of the  class with a  of 
        ///       . 
        ///    
        ///  
        public GraphicsPath() : this(System.Drawing.Drawing2D.FillMode.Alternate) { } 

        /** 
         * Create a new path object with the specified fill mode
         */
        /// 
        ///  
        ///    Initializes a new instance of the  class with the specified .
        ///  
        public GraphicsPath(FillMode fillMode) { 
            IntPtr nativePath = IntPtr.Zero;
 
            int status = SafeNativeMethods.Gdip.GdipCreatePath((int)fillMode, out nativePath);

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 

            this.nativePath = nativePath; 
        } 

        // float version 
        /// 
        /// 
        ///    
        ///    Initializes a new instance of the 
        ///     array with the
        ///    specified  
        ///    and  arrays. 
        ///    
        ///  
        public GraphicsPath(PointF[] pts, byte[] types) :
          this(pts, types, System.Drawing.Drawing2D.FillMode.Alternate) {}

        ///  
        /// 
        ///     
        ///       Initializes a new instance of the  array with the 
        ///       specified  and  arrays and with the
        ///       specified . 
        ///    
        /// 
        public GraphicsPath(PointF[] pts, byte[] types, FillMode fillMode) {
            if (pts == null) 
                throw new ArgumentNullException("pts");
            IntPtr nativePath = IntPtr.Zero; 
 
            if (pts.Length != types.Length)
                throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.InvalidParameter); 

            int count = types.Length;
            IntPtr ptbuf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts);
            IntPtr typebuf = Marshal.AllocHGlobal(count); 
            try {
                Marshal.Copy(types, 0, typebuf, count); 
 
                int status = SafeNativeMethods.Gdip.GdipCreatePath2(new HandleRef(null, ptbuf), new HandleRef(null, typebuf), count,
                                                     (int)fillMode, out nativePath); 


                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(ptbuf); 
                Marshal.FreeHGlobal(typebuf); 
            }
 
            this.nativePath = nativePath;
        }

        // int version 
        /// 
        ///  
        ///     
        ///    Initializes a new instance of the
        ///     array with the 
        ///    specified 
        ///    and  arrays.
        ///    
        ///  
        public GraphicsPath(Point[] pts, byte[] types) :
          this(pts, types, System.Drawing.Drawing2D.FillMode.Alternate) {} 
 
        /// 
        ///  
        ///    
        ///       Initializes a new instance of the  array with the
        ///       specified  and  arrays and with the
        ///       specified . 
        ///    
        ///  
        public GraphicsPath(Point[] pts, byte[] types, FillMode fillMode) { 
            if (pts == null)
                throw new ArgumentNullException("pts"); 
            IntPtr nativePath = IntPtr.Zero;

            if (pts.Length != types.Length)
                throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.InvalidParameter); 

            int count = types.Length; 
            IntPtr ptbuf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts); 
            IntPtr typebuf = Marshal.AllocHGlobal(count);
            try { 
                Marshal.Copy(types, 0, typebuf, count);

                int status = SafeNativeMethods.Gdip.GdipCreatePath2I(new HandleRef(null, ptbuf), new HandleRef(null, typebuf), count,
                                                      (int)fillMode, out nativePath); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally { 
                Marshal.FreeHGlobal(ptbuf);
                Marshal.FreeHGlobal(typebuf); 
            }

            this.nativePath = nativePath;
        } 

        /** 
         * Make a copy of the current path object 
         */
        ///  
        /// 
        ///    Creates an exact copy of this .
        /// 
        public object Clone() { 
            IntPtr clonePath = IntPtr.Zero;
 
            int status = SafeNativeMethods.Gdip.GdipClonePath(new HandleRef(this, nativePath), out clonePath); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);

            return new GraphicsPath(clonePath, 0);
 
        }
 
        /** 
         * 'extra' parameter is necessary to avoid conflict with
         * other constructor GraphicsPath(int fillmode) 
         */

        private GraphicsPath(IntPtr nativePath, int extra) {
            if (nativePath == IntPtr.Zero) 
                throw new ArgumentNullException("nativePath");
 
            this.nativePath = nativePath; 
        }
 
        /**
         * Dispose of resources associated with the
         */
        ///  
        /// 
        ///    Eliminates resources for this . 
        ///  
        public void Dispose() {
            Dispose(true); 
            GC.SuppressFinalize(this);
        }
        void Dispose(bool disposing) {
            if (nativePath != IntPtr.Zero) { 
                 try{
#if DEBUG 
                    int status = 
#endif
                    SafeNativeMethods.Gdip.GdipDeletePath(new HandleRef(this, nativePath)); 
#if DEBUG
                    Debug.Assert(status == SafeNativeMethods.Gdip.Ok, "GDI+ returned an error status: " + status.ToString(CultureInfo.InvariantCulture));
#endif
                } 
                catch( Exception ex ){
                    if( ClientUtils.IsSecurityOrCriticalException( ex ) ) { 
                        throw; 
                    }
 
                    Debug.Fail( "Exception thrown during Dispose: " + ex.ToString() );
                }
                finally{
                     nativePath = IntPtr.Zero; 
                }
            } 
        } 

        ///  
        /// 
        ///    Eliminates resources for this .
        /// 
        ~GraphicsPath() { 
            Dispose(false);
        } 
 
        /**
         * Reset the path object to empty 
         */
        /// 
        /// 
        ///    Empties the  
        ///    and  arrays
        ///    and sets the  to 
        ///    . 
        /// 
        public void Reset() { 
            int status = SafeNativeMethods.Gdip.GdipResetPath(new HandleRef(this, nativePath));

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        /** 
         * Get path fill mode information
         */ 
        /// 
        /// 
        ///    Gets or sets a  that determines how the interiors of
        ///    shapes in this  are filled. 
        /// 
        public FillMode FillMode { 
            get { 
                int fillmode = 0;
 
                int status = SafeNativeMethods.Gdip.GdipGetPathFillMode(new HandleRef(this, nativePath), out fillmode);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return(FillMode) fillmode; 
            } 
            set {
                //validate the FillMode enum 
                //valid values are 0x0 to 0x1
                if (!ClientUtils.IsEnumValid(value, (int)value, (int)FillMode.Alternate, (int)FillMode.Winding))
                {
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(FillMode)); 
                }
 
                int status = SafeNativeMethods.Gdip.GdipSetPathFillMode(new HandleRef(this, nativePath), (int) value); 

                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            }
        }
 
        private PathData _GetPathData() {
 
            int ptSize = (int) Marshal.SizeOf(typeof(GPPOINTF)); 

            int numPts = PointCount; 

            PathData pathData = new PathData();
            pathData.Types = new byte[numPts];
 
            IntPtr memoryPathData = Marshal.AllocHGlobal(3*IntPtr.Size);
            IntPtr memoryPoints = Marshal.AllocHGlobal(ptSize*numPts); 
            try { 
                GCHandle typesHandle = GCHandle.Alloc(pathData.Types, GCHandleType.Pinned);
                try { 
                    IntPtr typesPtr = typesHandle.AddrOfPinnedObject();
                    //IntPtr typesPtr = Marshal.AddrOfArrayElement(pathData.Types, IntPtr.Zero);

                    Marshal.StructureToPtr(numPts, memoryPathData, false); 
                    Marshal.StructureToPtr(memoryPoints, (IntPtr)((long)memoryPathData+IntPtr.Size), false);
                    Marshal.StructureToPtr(typesPtr, (IntPtr)((long)memoryPathData+2*IntPtr.Size), false); 
 
                    int status = SafeNativeMethods.Gdip.GdipGetPathData(new HandleRef(this, nativePath), memoryPathData);
 
                    if (status != SafeNativeMethods.Gdip.Ok) {
                        throw SafeNativeMethods.Gdip.StatusException(status);
                    }
 
                    pathData.Points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(memoryPoints, numPts);
                } finally { 
                    typesHandle.Free(); 
                }
            } finally { 
                Marshal.FreeHGlobal(memoryPathData);
                Marshal.FreeHGlobal(memoryPoints);
            }
 
            return pathData;
        } 
 
        /// 
        ///  
        ///    Gets a  object that
        ///    encapsulates both the  and  arrays of this .
        /// 
        public PathData PathData { 
            get {
                return _GetPathData(); 
            } 
        }
 
        /// 
        /// 
        ///    
        ///       Starts a new figure without closing the 
        ///       current figure. All subsequent points added to the path are added to this new
        ///       figure. 
        ///     
        /// 
        public void StartFigure() { 
            int status = SafeNativeMethods.Gdip.GdipStartPathFigure(new HandleRef(this, nativePath));

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        ///  
        /// 
        ///    Closes the current figure and starts a new 
        ///    figure. If the current figure contains a sequence of connected lines and curves,
        ///    it closes the loop by connecting a line from the ending point to the starting
        ///    point.
        ///  
        public void CloseFigure() {
            int status = SafeNativeMethods.Gdip.GdipClosePathFigure(new HandleRef(this, nativePath)); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    Closes all open figures in a path and
        ///    starts a new figure. It closes each open figure by connecting a line from it's 
        ///    ending point to it's starting point. 
        /// 
        public void CloseAllFigures() { 
            int status = SafeNativeMethods.Gdip.GdipClosePathFigures(new HandleRef(this, nativePath));

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        ///  
        /// 
        ///     
        ///       Sets a marker on this  .
        ///    
        /// 
        public void SetMarkers() { 
            int status = SafeNativeMethods.Gdip.GdipSetPathMarker(new HandleRef(this, nativePath));
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 

        /// 
        /// 
        ///    Clears all markers from this . 
        /// 
        public void ClearMarkers() { 
            int status = SafeNativeMethods.Gdip.GdipClearPathMarkers(new HandleRef(this, nativePath)); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        }

        ///  
        /// 
        ///    Reverses the order of points in the  array of this . 
        ///  
        public void Reverse() {
            int status = SafeNativeMethods.Gdip.GdipReversePath(new HandleRef(this, nativePath)); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 

        ///  
        ///  
        ///    Gets the last point in the  array of this .
        ///  
        public PointF GetLastPoint() {
            GPPOINTF gppt = new GPPOINTF();

            int status = SafeNativeMethods.Gdip.GdipGetPathLastPoint(new HandleRef(this, nativePath), gppt); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 

            return gppt.ToPoint(); 
        }

        /*
         * Hit testing 
         */
 
        ///  
        /// 
        ///     
        ///       Indicates whether the specified point is contained
        ///       within this 
        ///       .
        ///     
        /// 
        public bool IsVisible(float x, float y) { 
            return IsVisible(new PointF(x,y), (Graphics)null); 
        }
 
        /// 
        /// 
        ///    
        ///       Indicates whether the specified point is contained 
        ///       within this .
        ///     
        ///  
        public bool IsVisible(PointF point) {
            return IsVisible(point, (Graphics)null); 
        }

        /// 
        ///  
        ///    
        ///       Indicates whether the specified point is contained within this  in the visible clip region of the 
        ///       specified . 
        ///    
        ///  
        public bool IsVisible(float x, float y, Graphics graphics) {
            return IsVisible(new PointF(x,y), graphics);
        }
 
        /// 
        ///  
        ///     
        ///       Indicates whether the specified point is contained within this .
        ///     
        /// 
        public bool IsVisible(PointF pt, Graphics graphics) {
            int isVisible;
 
            int status = SafeNativeMethods.Gdip.GdipIsVisiblePathPoint(new HandleRef(this, nativePath),
                                                        pt.X, 
                                                        pt.Y, 
                                                        new HandleRef(graphics, (graphics != null) ?
                                                            graphics.NativeGraphics : IntPtr.Zero), 
                                                        out isVisible);

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 

            return isVisible != 0; 
        } 

        ///  
        /// 
        ///    
        ///       Indicates whether the specified point is contained within this  .
        ///     
        /// 
        public bool IsVisible(int x, int y) { 
            return IsVisible(new Point(x,y), (Graphics)null); 
        }
 
        /// 
        /// 
        ///    
        ///       Indicates whether the specified point is contained within this . 
        ///    
        ///  
        public bool IsVisible(Point point) { 
            return IsVisible(point, (Graphics)null);
        } 

        /// 
        /// 
        ///     
        ///       Indicates whether the specified point is contained within this  in the visible clip region of the
        ///       specified . 
        ///     
        /// 
        public bool IsVisible(int x, int y, Graphics graphics) { 
            return IsVisible(new Point(x,y), graphics);
        }

        ///  
        /// 
        ///     
        ///       Indicates whether the specified point is contained within this . 
        ///    
        ///  
        public bool IsVisible(Point pt, Graphics graphics) {
            int isVisible;

            int status = SafeNativeMethods.Gdip.GdipIsVisiblePathPointI(new HandleRef(this, nativePath), 
                                                         pt.X,
                                                         pt.Y, 
                                                         new HandleRef(graphics, (graphics != null) ? 
                                                             graphics.NativeGraphics : IntPtr.Zero),
                                                         out isVisible); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return isVisible != 0;
        } 
 
        /// 
        ///  
        ///    Indicates whether an outline drawn by the
        ///    specified  at the specified location is contained
        ///    within this .
        ///  
        public bool IsOutlineVisible(float x, float y, Pen pen) {
            return IsOutlineVisible(new PointF(x,y), pen, (Graphics)null); 
        } 

        ///  
        /// 
        ///    
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this . 
        ///    
        ///  
        public bool IsOutlineVisible(PointF point, Pen pen) { 
            return IsOutlineVisible(point, pen, (Graphics)null);
        } 

        /// 
        /// 
        ///     
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this  and within the visible clip region of 
        ///       the specified . 
        ///    
        ///  
        public bool IsOutlineVisible(float x, float y, Pen pen, Graphics graphics) {
            return IsOutlineVisible(new PointF(x,y), pen, graphics);
        }
 
        /// 
        ///  
        ///     
        ///       Indicates whether an outline drawn by the specified
        ///     at the specified 
        ///       location is contained within this  and within the visible clip region of
        ///       the specified .
        ///    
        ///  
        public bool IsOutlineVisible(PointF pt, Pen pen, Graphics graphics) {
            int isVisible; 
 
            if (pen == null)
                throw new ArgumentNullException("pen"); 

            int status = SafeNativeMethods.Gdip.GdipIsOutlineVisiblePathPoint(new HandleRef(this, nativePath),
                                                               pt.X,
                                                               pt.Y, 
                                                               new HandleRef(pen, pen.NativePen),
                                                               new HandleRef(graphics, (graphics != null) ? 
                                                                   graphics.NativeGraphics : IntPtr.Zero), 
                                                               out isVisible);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            return isVisible != 0; 
        }
 
        ///  
        /// 
        ///     
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this .
        ///    
        ///  
        public bool IsOutlineVisible(int x, int y, Pen pen) {
            return IsOutlineVisible(new Point(x,y), pen, (Graphics)null); 
        } 

        ///  
        /// 
        ///    
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this . 
        ///    
        ///  
        public bool IsOutlineVisible(Point point, Pen pen) { 
            return IsOutlineVisible(point, pen, (Graphics)null);
        } 

        /// 
        /// 
        ///     
        ///       Indicates whether an outline drawn by the specified  at the
        ///       specified location is contained within this  and within the visible clip region of 
        ///       the specified . 
        ///    
        ///  
        public bool IsOutlineVisible(int x, int y, Pen pen, Graphics graphics) {
            return IsOutlineVisible(new Point(x,y), pen, graphics);
        }
 
        /// 
        ///  
        ///     
        ///       Indicates whether an outline drawn by the specified
        ///     at the specified 
        ///       location is contained within this  and within the visible clip region of
        ///       the specified .
        ///    
        ///  
        public bool IsOutlineVisible(Point pt, Pen pen, Graphics graphics) {
            int isVisible; 
 
            if (pen == null)
                throw new ArgumentNullException("pen"); 

            int status = SafeNativeMethods.Gdip.GdipIsOutlineVisiblePathPointI(new HandleRef(this, nativePath),
                                                                pt.X,
                                                                pt.Y, 
                                                                new HandleRef(pen, pen.NativePen),
                                                                new HandleRef(graphics, (graphics != null) ? 
                                                                    graphics.NativeGraphics : IntPtr.Zero), 
                                                                out isVisible);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            return isVisible != 0; 
        }
 
        /* 
         * Add lines to the path object
         */ 
        // float version
        /// 
        /// 
        ///    Appends a line segment to this . 
        /// 
        public void AddLine(PointF pt1, PointF pt2) { 
            AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y); 
        }
 
        /// 
        /// 
        ///    Appends a line segment to this .
        ///  
        public void AddLine(float x1, float y1, float x2, float y2) {
            int status = SafeNativeMethods.Gdip.GdipAddPathLine(new HandleRef(this, nativePath), x1, y1, x2, y2); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    Appends a series of connected line
        ///    segments to the end of this . 
        ///  
        public void AddLines(PointF[] points) {
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
            int status = SafeNativeMethods.Gdip.GdipAddPathLine2(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length); 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally { 
                Marshal.FreeHGlobal(buf);
            } 

        }

        // int version 
        /// 
        ///  
        ///     
        ///       Appends a line segment to this .
        ///     
        /// 
        public void AddLine(Point pt1, Point pt2) {
            AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
        } 

        ///  
        ///  
        ///    
        ///       Appends a line segment to this . 
        ///    
        /// 
        public void AddLine(int x1, int y1, int x2, int y2) {
            int status = SafeNativeMethods.Gdip.GdipAddPathLineI(new HandleRef(this, nativePath), x1, y1, x2, y2); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        /// 
        /// 
        ///    
        ///       Appends a series of connected line segments to the end of this . 
        ///    
        ///  
        public void AddLines(Point[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathLine2I(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf); 
            }
        } 

        /*
         * Add an arc to the path object
         */ 
        // float version
        ///  
        ///  
        ///    
        ///       Appends an elliptical arc to the current 
        ///       figure.
        ///    
        /// 
        public void AddArc(RectangleF rect, float startAngle, float sweepAngle) { 
            AddArc(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
        } 
 
        /// 
        ///  
        ///    
        ///       Appends an elliptical arc to the current figure.
        ///    
        ///  
        public void AddArc(float x, float y, float width, float height,
                           float startAngle, float sweepAngle) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathArc(new HandleRef(this, nativePath), x, y, width, height, 
                                                startAngle, sweepAngle);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
        }
 
        // int version
        ///  
        ///  
        ///    
        ///       Appends an elliptical arc to the current figure. 
        ///    
        /// 
        public void AddArc(Rectangle rect, float startAngle, float sweepAngle) {
            AddArc(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle); 
        }
 
        ///  
        /// 
        ///     
        ///       Appends an elliptical arc to the current figure.
        ///    
        /// 
        public void AddArc(int x, int y, int width, int height, 
                           float startAngle, float sweepAngle) {
            int status = SafeNativeMethods.Gdip.GdipAddPathArcI(new HandleRef(this, nativePath), x, y, width, height, 
                                                 startAngle, sweepAngle); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        }

        /* 
        * Add Bezier curves to the path object
        */ 
        // float version 
        /// 
        ///  
        ///    
        ///       Adds a cubic Bzier curve to the current
        ///       figure.
        ///     
        /// 
        public void AddBezier(PointF pt1, PointF pt2, PointF pt3, PointF pt4) { 
            AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y); 
        }
 
        /// 
        /// 
        ///    
        ///       Adds a cubic Bzier curve to the current 
        ///       figure.
        ///     
        ///  
        public void AddBezier(float x1, float y1, float x2, float y2,
                              float x3, float y3, float x4, float y4) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathBezier(new HandleRef(this, nativePath), x1, y1, x2, y2,
                                                   x3, y3, x4, y4);

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a sequence of connected cubic Bzier
        ///       curves to the current figure.
        ///     
        /// 
        public void AddBeziers(PointF[] points) { 
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathBeziers(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        // int version
        /// 
        /// 
        ///     
        ///       Adds a cubic Bzier curve to the current figure.
        ///     
        ///  
        public void AddBezier(Point pt1, Point pt2, Point pt3, Point pt4) {
            AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y); 
        }

        /// 
        ///  
        ///    
        ///       Adds a cubic Bzier curve to the current 
        ///       figure. 
        ///    
        ///  
        public void AddBezier(int x1, int y1, int x2, int y2,
                              int x3, int y3, int x4, int y4) {
            int status = SafeNativeMethods.Gdip.GdipAddPathBezierI(new HandleRef(this, nativePath), x1, y1, x2, y2,
                                                    x3, y3, x4, y4); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        /// 
        /// 
        ///    
        ///       Adds a sequence of connected cubic Bzier curves to the 
        ///       current figure.
        ///     
        ///  
        public void AddBeziers(params Point[] points) {
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathBeziersI(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally { 
                Marshal.FreeHGlobal(buf);
            } 
        }

        /*
         * Add cardinal splines to the path object 
         */
        // float version 
        ///  
        /// 
        ///     
        ///       Adds a spline curve to the current figure.
        ///       A Cardinal spline curve is used because the curve travels through each of the
        ///       points in the array.
        ///     
        /// 
        public void AddCurve(PointF[] points) { 
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        /// 
        /// 
        ///    Adds a spline curve to the current figure.
        ///  
        public void AddCurve(PointF[] points, float tension) {
            if (points == null) 
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve2(new HandleRef(this, nativePath), new HandleRef(null, buf),
                                                   points.Length, tension);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        /// 
        /// 
        ///    
        ///       Adds a spline curve to the current figure. 
        ///    
        ///  
        public void AddCurve(PointF[] points, int offset, int numberOfSegments, 
                             float tension) {
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve3(new HandleRef(this, nativePath), new HandleRef(null, buf), 
                                                   points.Length, offset,
                                                   numberOfSegments, tension); 
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf);
            }
        }
 
        // int version
        ///  
        ///  
        ///    
        ///       Adds a spline curve to the current figure. A Cardinal spline curve is used 
        ///       because the curve travels through each of the points in the array.
        ///    
        /// 
        public void AddCurve(Point[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathCurveI(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally {
                Marshal.FreeHGlobal(buf); 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a spline curve to the current figure.
        ///    
        ///  
        public void AddCurve(Point[] points, float tension) {
            if (points == null) 
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve2I(new HandleRef(this, nativePath), new HandleRef(null, buf),
                                                    points.Length, tension);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        /// 
        /// 
        ///    
        ///       Adds a spline curve to the current figure. 
        ///    
        ///  
        public void AddCurve(Point[] points, int offset, int numberOfSegments, 
                             float tension) {
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathCurve3I(new HandleRef(this, nativePath), new HandleRef(null, buf), 
                                                    points.Length, offset,
                                                    numberOfSegments, tension); 
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf);
            }
        }
 
        // float version
        ///  
        ///  
        ///    
        ///       Adds a closed curve to the current figure. A Cardinal spline curve is 
        ///       used because the curve travels through each of the points in the array.
        ///    
        /// 
        public void AddClosedCurve(PointF[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathClosedCurve(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally {
                Marshal.FreeHGlobal(buf); 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a closed curve to the current figure. A Cardinal spline curve is
        ///       used because the curve travels through each of the points in the array.
        ///     
        /// 
        public void AddClosedCurve(PointF[] points, float tension) { 
            if (points == null) 
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points); 
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathClosedCurve2(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length, tension);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            } 
        }
 
        // int version
        /// 
        /// 
        ///     
        ///       Adds a closed curve to the current figure. A Cardinal spline curve is used
        ///       because the curve travels through each of the points in the array. 
        ///     
        /// 
        public void AddClosedCurve(Point[] points) { 
            if (points == null)
                throw new ArgumentNullException("points");
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathClosedCurveI(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            }
        }

        ///  
        /// 
        ///     
        ///       Adds a closed curve to the current figure. A Cardinal spline curve is used 
        ///       because the curve travels through each of the points in the array.
        ///     
        /// 
        public void AddClosedCurve(Point[] points, float tension) {
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathClosedCurve2I(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length, tension); 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf);
            }
        } 

        ///  
        ///  
        ///    Adds a rectangle to the current figure.
        ///  
        public void AddRectangle(RectangleF rect) {
            int status = SafeNativeMethods.Gdip.GdipAddPathRectangle(new HandleRef(this, nativePath), rect.X, rect.Y,
                                                      rect.Width, rect.Height);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        } 

        ///  
        /// 
        ///    
        ///       Adds a series of rectangles to the current
        ///       figure. 
        ///    
        ///  
        public void AddRectangles(RectangleF[] rects) { 
            if (rects == null)
                throw new ArgumentNullException("rects"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertRectangleToMemory(rects);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathRectangles(new HandleRef(this, nativePath), new HandleRef(null, buf), rects.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf); 
            }
        } 

        // int version
        /// 
        ///  
        ///    
        ///       Adds a rectangle to the current figure. 
        ///     
        /// 
        public void AddRectangle(Rectangle rect) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathRectangleI(new HandleRef(this, nativePath), rect.X, rect.Y,
                                                       rect.Width, rect.Height);

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a series of rectangles to the current figure.
        ///    
        ///  
        public void AddRectangles(Rectangle[] rects) {
            if (rects == null) 
                throw new ArgumentNullException("rects"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertRectangleToMemory(rects);
            try { 
                int status = SafeNativeMethods.Gdip.GdipAddPathRectanglesI(new HandleRef(this, nativePath), new HandleRef(null, buf), rects.Length);
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf);
            } 
        } 

        // float version 
        /// 
        /// 
        ///    Adds an ellipse to the current figure.
        ///  
        public void AddEllipse(RectangleF rect) {
            AddEllipse(rect.X, rect.Y, rect.Width, rect.Height); 
        } 

        /** 
         * Add an ellipse to the current path
         *
         * !!! Need to handle the status code returned
         *  by the native GDI+ APIs. 
         */
        ///  
        ///  
        ///    Adds an ellipse to the current figure.
        ///  
        public void AddEllipse(float x, float y, float width, float height) {
            int status = SafeNativeMethods.Gdip.GdipAddPathEllipse(new HandleRef(this, nativePath), x, y, width, height);

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        // int version
        ///  
        /// 
        ///    
        ///       Adds an ellipse to the current figure.
        ///     
        /// 
        public void AddEllipse(Rectangle rect) { 
            AddEllipse(rect.X, rect.Y, rect.Width, rect.Height); 
        }
 
        /**
         * Add an ellipse to the current path
         *
         * !!! Need to handle the status code returned 
         *  by the native GDI+ APIs.
         */ 
        ///  
        /// 
        ///     
        ///       Adds an ellipse to the current figure.
        ///    
        /// 
        public void AddEllipse(int x, int y, int width, int height) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathEllipseI(new HandleRef(this, nativePath), x, y, width, height);
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 

        /// 
        /// 
        ///     
        ///       Adds the outline of a pie shape to the
        ///       current figure. 
        ///     
        /// 
        public void AddPie(Rectangle rect, float startAngle, float sweepAngle) { 
            AddPie(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
        }

        // float version 
        /// 
        ///  
        ///     
        ///       Adds the outline of a pie shape to the current
        ///       figure. 
        ///    
        /// 
        public void AddPie(float x, float y, float width, float height,
                           float startAngle, float sweepAngle) { 
            int status = SafeNativeMethods.Gdip.GdipAddPathPie(new HandleRef(this, nativePath), x, y, width, height,
                                                startAngle, sweepAngle); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        // int version
        ///  
        /// 
        ///     
        ///       Adds the outline of a pie shape to the current 
        ///       figure.
        ///     
        /// 
        public void AddPie(int x, int y, int width, int height,
                           float startAngle, float sweepAngle) {
            int status = SafeNativeMethods.Gdip.GdipAddPathPieI(new HandleRef(this, nativePath), x, y, width, height, 
                                                 startAngle, sweepAngle);
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 

        // float version
        /// 
        ///  
        ///    Adds a polygon to the current figure.
        ///  
        public void AddPolygon(PointF[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathPolygon(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf); 
            }
        } 

        // int version
        /// 
        ///  
        ///    Adds a polygon to the current figure.
        ///  
        public void AddPolygon(Point[] points) { 
            if (points == null)
                throw new ArgumentNullException("points"); 
            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
            try {
                int status = SafeNativeMethods.Gdip.GdipAddPathPolygonI(new HandleRef(this, nativePath), new HandleRef(null, buf), points.Length);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status);
            } finally { 
                Marshal.FreeHGlobal(buf); 
            }
        } 

        /// 
        /// 
        ///    Appends the specified  to this . 
        /// 
        public void AddPath(GraphicsPath addingPath, 
                            bool connect) 
        {
            if (addingPath == null) 
                throw new ArgumentNullException("addingPath");

            int status = SafeNativeMethods.Gdip.GdipAddPathPath(new HandleRef(this, nativePath), new HandleRef(addingPath, addingPath.nativePath), connect);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        } 

        /* 
         * Add text string to the path object
         *
         * @notes The final form of this API is yet to be defined.
         * @notes What are the choices for the format parameter? 
         */
 
        ///  
        /// 
        ///     
        ///       Adds a text string to the current figure.
        ///    
        /// 
        public void AddString(String s, FontFamily family, int style, float emSize, 
                              PointF origin, StringFormat format) {
            GPRECTF rectf = new GPRECTF(origin.X, origin.Y, 0, 0); 
 
            int status = SafeNativeMethods.Gdip.GdipAddPathString(new HandleRef(this, nativePath),
                                                   s, 
                                                   s.Length,
                                                   new HandleRef(family, (family != null) ? family.NativeFamily : IntPtr.Zero),
                                                   style,
                                                   emSize, 
                                                   ref rectf,
                                                   new HandleRef(format, (format != null) ? format.nativeFormat : IntPtr.Zero)); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    
        ///       Adds a text string to the current figure. 
        ///     
        /// 
        public void AddString(String s, FontFamily family, int style, float emSize, 
                              Point origin, StringFormat format) {
            GPRECT rect = new GPRECT(origin.X, origin.Y, 0, 0);

            int status = SafeNativeMethods.Gdip.GdipAddPathStringI(new HandleRef(this, nativePath), 
                                                    s,
                                                    s.Length, 
                                                    new HandleRef(family, (family != null) ? family.NativeFamily : IntPtr.Zero), 
                                                    style,
                                                    emSize, 
                                                    ref rect,
                                                    new HandleRef(format, (format != null) ? format.nativeFormat : IntPtr.Zero));

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Adds a text string to the current figure.
        ///    
        ///  
        public void AddString(String s, FontFamily family, int style, float emSize,
                              RectangleF layoutRect, StringFormat format) { 
            GPRECTF rectf = new GPRECTF(layoutRect); 
            int status = SafeNativeMethods.Gdip.GdipAddPathString(new HandleRef(this, nativePath),
                                                   s, 
                                                   s.Length,
                                                   new HandleRef(family, (family != null) ? family.NativeFamily : IntPtr.Zero),
                                                   style,
                                                   emSize, 
                                                   ref rectf,
                                                   new HandleRef(format, (format != null) ? format.nativeFormat : IntPtr.Zero)); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    
        ///       Adds a text string to the current figure. 
        ///     
        /// 
        public void AddString(String s, FontFamily family, int style, float emSize, 
                              Rectangle layoutRect, StringFormat format) {
            GPRECT rect = new GPRECT(layoutRect);
            int status = SafeNativeMethods.Gdip.GdipAddPathStringI(new HandleRef(this, nativePath),
                                                   s, 
                                                   s.Length,
                                                   new HandleRef(family, (family != null) ? family.NativeFamily : IntPtr.Zero), 
                                                   style, 
                                                   emSize,
                                                   ref rect, 
                                                   new HandleRef(format, (format != null) ? format.nativeFormat : IntPtr.Zero));

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }
 
        ///  
        /// 
        ///    Applies a transform matrix to this . 
        /// 
        public void Transform(Matrix matrix) {
            if (matrix == null)
                throw new ArgumentNullException("matrix"); 

            // !! Is this an optimization?  We should catch this in GdipTransformPath 
            if (matrix.nativeMatrix == IntPtr.Zero) 
                return;
 
            int status = SafeNativeMethods.Gdip.GdipTransformPath(new HandleRef(this, nativePath),
                                                   new HandleRef(matrix, matrix.nativeMatrix));

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        } 
 
        /// 
        ///  
        ///    
        ///       Returns a rectangle that bounds this .
        ///    
        ///  
        public RectangleF GetBounds() {
            return GetBounds(null); 
        } 

        ///  
        /// 
        ///    
        ///       Returns a rectangle that bounds this  when it
        ///       is transformed by the specified . 
        ///    
        ///  
        public RectangleF GetBounds(Matrix matrix) { 
            return GetBounds(matrix, null);
        } 

        /// 
        /// 
        ///     
        ///       Returns a rectangle that bounds this  when it is
        ///       transformed by the specified . and drawn with the specified . 
        ///     
        /// 
        public RectangleF GetBounds(Matrix matrix, Pen pen) { 
            GPRECTF gprectf = new GPRECTF();

            IntPtr nativeMatrix = IntPtr.Zero, nativePen = IntPtr.Zero;
 
            if (matrix != null)
                nativeMatrix = matrix.nativeMatrix; 
 
            if (pen != null)
                nativePen = pen.NativePen; 

            int status = SafeNativeMethods.Gdip.GdipGetPathWorldBounds(new HandleRef(this, nativePath),
                                                        ref gprectf,
                                                        new HandleRef(matrix, nativeMatrix), 
                                                        new HandleRef(pen, nativePen));
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return gprectf.ToRectangleF();
        }

        /* 
         * Flatten the path object
         */ 
 
        /// 
        ///  
        ///    Converts each curve in this  into a sequence of connected line
        ///    segments.
        /// 
        public void Flatten() { 
            Flatten(null);
        } 
 
        /// 
        ///  
        ///    Converts each curve in this  into a sequence of connected line
        ///    segments.
        /// 
        public void Flatten(Matrix matrix) { 
            Flatten(matrix, 0.25f);
        } 
 
        /// 
        ///  
        ///    Converts each curve in this  into a sequence of connected line
        ///    segments.
        /// 
        public void Flatten(Matrix matrix, float flatness) { 

            int status = SafeNativeMethods.Gdip.GdipFlattenPath(new HandleRef(this, nativePath), 
                                                           new HandleRef(matrix, (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix), 
                                                           flatness);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
        }
 

        /** 
         * Widen the path object 
         *
         * @notes We don't have an API yet. 
         *  Should we just take in a GeometricPen as parameter?
         */
        /// 
        ///  
        /// 
        public void Widen(Pen pen) { 
            float flatness = (float) 2.0 / (float) 3.0; 
            Widen(pen, (Matrix)null, flatness);
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public void Widen(Pen pen, Matrix matrix) { 
            float flatness = (float) 2.0 / (float) 3.0; 
            Widen(pen, matrix, flatness);
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public void Widen(Pen pen, 
                          Matrix matrix, 
                          float flatness)
        { 
            IntPtr nativeMatrix;

            if (matrix == null)
                nativeMatrix = IntPtr.Zero; 
            else
                nativeMatrix = matrix.nativeMatrix; 
 
            if (pen == null)
                throw new ArgumentNullException("pen"); 

            //

 

            int pointCount; 
            SafeNativeMethods.Gdip.GdipGetPointCount(new HandleRef(this, nativePath), out pointCount); 

            if(pointCount == 0) 
                return;

            int status = SafeNativeMethods.Gdip.GdipWidenPath(new HandleRef(this, nativePath),
                                new HandleRef(pen, pen.NativePen), 
                                new HandleRef(matrix, nativeMatrix),
                                flatness); 
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void Warp(PointF[] destPoints, RectangleF srcRect)
        { Warp(destPoints, srcRect, null); } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")] 
        public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix matrix) 
        { Warp(destPoints, srcRect, matrix, WarpMode.Perspective); }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix matrix, 
                         WarpMode warpMode) 
        { Warp(destPoints, srcRect, matrix, warpMode, 0.25f); }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix matrix, 
                         WarpMode warpMode, float flatness) 
        {
            if (destPoints == null) 
                throw new ArgumentNullException("destPoints");

            IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(destPoints);
            try { 
                int status = SafeNativeMethods.Gdip.GdipWarpPath(new HandleRef(this, nativePath),
                                              new HandleRef(matrix, (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix), 
                                              new HandleRef(null, buf), 
                                              destPoints.Length,
                                              srcRect.X, 
                                              srcRect.Y,
                                              srcRect.Width,
                                              srcRect.Height,
                                              warpMode, 
                                              flatness);
                if (status != SafeNativeMethods.Gdip.Ok) 
                    throw SafeNativeMethods.Gdip.StatusException(status); 
            } finally {
                Marshal.FreeHGlobal(buf); 
            }
        }

        /** 
         * Return the number of points in the current path
         */ 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public int PointCount {
            get {
                int count = 0; 

                int status = SafeNativeMethods.Gdip.GdipGetPointCount(new HandleRef(this, nativePath), out count); 
 
                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return count;
            }
        } 

        /** 
         * Return the path point type information 
         */
        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public byte[] PathTypes { 
            get {
                int count = PointCount; 
 
                byte[] types = new byte[count];
 
                int status = SafeNativeMethods.Gdip.GdipGetPathTypes(new HandleRef(this, nativePath), types, count);

                if (status != SafeNativeMethods.Gdip.Ok)
                    throw SafeNativeMethods.Gdip.StatusException(status); 

                return types; 
            } 
        }
 
        /*
         * Return the path point coordinate information
         * @notes Should there be PathData that contains types[] and points[]
         *        for get & set purposes. 
         */
        // float points 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public PointF[] PathPoints {
            get {
                int count = PointCount; 
                int size = (int) Marshal.SizeOf(typeof(GPPOINTF));
                IntPtr buf = Marshal.AllocHGlobal(count * size); 
                try { 
                    int status = SafeNativeMethods.Gdip.GdipGetPathPoints(new HandleRef(this, nativePath), new HandleRef(null, buf), count);
 
                    if (status != SafeNativeMethods.Gdip.Ok) {
                        throw SafeNativeMethods.Gdip.StatusException(status);
                    }
 
                    PointF[] points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(buf, count);
                    return points; 
                } finally { 
                    Marshal.FreeHGlobal(buf);
                } 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK