GraphicsPath.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / CommonUI / System / Drawing / Advanced / GraphicsPath.cs / 1 / GraphicsPath.cs

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

/*************************************************************************\ 
* 
* Copyright (c) 1998-1999, Microsoft Corp.  All Rights Reserved.
* 
* Module Name:
*
*   GraphicsPath.cs
* 
* Abstract:
* 
*   COM+ wrapper for GDI+ path objects 
*
* Revision History: 
*
*   12/14/1998 davidx
*       Created it.
* 
\**************************************************************************/
 
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.
                        

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