New test.
[mono.git] / mcs / class / System.Drawing / System.Drawing.Drawing2D / GraphicsPath.cs
1 //
2 // System.Drawing.Drawing2D.GraphicsPath.cs
3 //
4 // Authors:
5 //
6 //   Miguel de Icaza (miguel@ximian.com)
7 //   Duncan Mak (duncan@ximian.com)
8 //   Jordi Mas i Hernandez (jordi@ximian.com)
9 //   Ravindra (rkumar@novell.com)
10 //   Sebastien Pouliot  <sebastien@ximian.com>
11 //
12 // Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.ComponentModel;
35 using System.Runtime.InteropServices;
36
37 namespace System.Drawing.Drawing2D
38 {
39         public sealed class GraphicsPath : MarshalByRefObject, ICloneable, IDisposable
40         {
41                 // 1/4 is the FlatnessDefault as defined in GdiPlusEnums.h
42                 private const float FlatnessDefault = 1.0f / 4.0f;
43
44                 internal IntPtr nativePath = IntPtr.Zero;
45
46                 GraphicsPath (IntPtr ptr)
47                 {
48                         nativePath = ptr;
49                 }
50
51                 public GraphicsPath ()
52                 {
53                         Status status = GDIPlus.GdipCreatePath (FillMode.Alternate, out nativePath);
54                         GDIPlus.CheckStatus (status);
55                 }
56
57                 public GraphicsPath (FillMode fillMode)
58                 {
59                         Status status = GDIPlus.GdipCreatePath (fillMode, out nativePath);
60                         GDIPlus.CheckStatus (status);
61                 }
62
63                 public GraphicsPath (Point[] pts, byte[] types)
64                         : this (pts, types, FillMode.Alternate)
65                 {
66                 }
67
68                 public GraphicsPath (PointF[] pts, byte[] types)
69                         : this (pts, types, FillMode.Alternate)
70                 {
71                 }
72
73                 public GraphicsPath (Point[] pts, byte[] types, FillMode fillMode)
74                 {
75                         if (pts == null)
76                                 throw new ArgumentNullException ("pts");
77                         if (pts.Length != types.Length)
78                                 throw new ArgumentException ("Invalid parameter passed. Number of points and types must be same.");
79
80                         Status status = GDIPlus.GdipCreatePath2I (pts, types, pts.Length, fillMode, out nativePath);
81                         GDIPlus.CheckStatus (status);
82                 }
83
84                 public GraphicsPath (PointF[] pts, byte[] types, FillMode fillMode)
85                 {
86                         if (pts == null)
87                                 throw new ArgumentNullException ("pts");
88                         if (pts.Length != types.Length)
89                                 throw new ArgumentException ("Invalid parameter passed. Number of points and types must be same.");
90
91                         Status status = GDIPlus.GdipCreatePath2 (pts, types, pts.Length, fillMode, out nativePath);
92                         GDIPlus.CheckStatus (status);
93                 }
94         
95                 public object Clone ()
96                 {
97                         IntPtr clone;
98
99                         Status status = GDIPlus.GdipClonePath (nativePath, out clone);
100                         GDIPlus.CheckStatus (status);                           
101
102                         return new GraphicsPath (clone);
103                 }
104
105                 public void Dispose ()
106                 {
107                         Dispose (true);
108                         System.GC.SuppressFinalize (this);
109                 }
110
111                 ~GraphicsPath ()
112                 {
113                         Dispose (false);
114                 }
115                 
116                 void Dispose (bool disposing)
117                 {
118                         Status status;
119                         if (nativePath != IntPtr.Zero) {
120                                 status = GDIPlus.GdipDeletePath (nativePath);
121                                 GDIPlus.CheckStatus (status);
122
123                                 nativePath = IntPtr.Zero;
124                         }
125                 }
126
127                 public FillMode FillMode {
128                         get {
129                                 FillMode mode;
130                                 Status status = GDIPlus.GdipGetPathFillMode (nativePath, out mode);
131                                 GDIPlus.CheckStatus (status);
132
133                                 return mode;
134                         }
135                         set {
136                                 if ((value < FillMode.Alternate) || (value > FillMode.Winding))
137                                         throw new InvalidEnumArgumentException ("FillMode", (int)value, typeof (FillMode));
138
139                                 Status status = GDIPlus.GdipSetPathFillMode (nativePath, value);
140                                 GDIPlus.CheckStatus (status);
141                         }
142                 }
143
144                 public PathData PathData {
145                         get {
146                                 int count;
147                                 Status status = GDIPlus.GdipGetPointCount (nativePath, out count);
148                                 GDIPlus.CheckStatus (status);
149
150                                 PointF [] points = new PointF [count];
151                                 byte [] types = new byte [count];
152
153                                 // status would fail if we ask points or types with a 0 count
154                                 // anyway that would only mean two unrequired unmanaged calls
155                                 if (count > 0) {
156                                         status = GDIPlus.GdipGetPathPoints (nativePath, points, count);
157                                         GDIPlus.CheckStatus (status);
158
159                                         status = GDIPlus.GdipGetPathTypes (nativePath, types, count);
160                                         GDIPlus.CheckStatus (status);
161                                 }
162
163                                 PathData pdata = new PathData ();
164                                 pdata.Points = points;
165                                 pdata.Types = types;
166                                 return pdata;
167                         }
168                 }
169
170                 public PointF [] PathPoints {
171                         get {
172                                 int count;
173                                 Status status = GDIPlus.GdipGetPointCount (nativePath, out count);
174                                 GDIPlus.CheckStatus (status);
175                                 if (count == 0)
176                                         throw new ArgumentException ("PathPoints");
177
178                                 PointF [] points = new PointF [count];
179                                 status = GDIPlus.GdipGetPathPoints (nativePath, points, count); 
180                                 GDIPlus.CheckStatus (status);                   
181
182                                 return points;
183                         }
184                 }
185
186                 public byte [] PathTypes {
187                         get {
188                                 int count;
189                                 Status status = GDIPlus.GdipGetPointCount (nativePath, out count);
190                                 GDIPlus.CheckStatus (status);
191                                 if (count == 0)
192                                         throw new ArgumentException ("PathTypes");
193
194                                 byte [] types = new byte [count];
195                                 status = GDIPlus.GdipGetPathTypes (nativePath, types, count);
196                                 GDIPlus.CheckStatus (status);
197
198                                 return types;
199                         }
200                 }
201
202                 public int PointCount {
203                         get {
204                                 int count;
205                                 Status status = GDIPlus.GdipGetPointCount (nativePath, out count);
206                                 GDIPlus.CheckStatus (status);
207
208                                 return count;
209                         }
210                 }
211
212                 internal IntPtr NativeObject {
213                         get {
214                                 return nativePath;
215                         }
216                         set {
217                                 nativePath = value;
218                         }
219                 }
220
221                 //
222                 // AddArc
223                 //
224                 public void AddArc (Rectangle rect, float start_angle, float sweep_angle)
225                 {
226                         Status status = GDIPlus.GdipAddPathArcI (nativePath, rect.X, rect.Y, rect.Width, rect.Height, start_angle, sweep_angle);
227                         GDIPlus.CheckStatus (status);                           
228                 }
229
230                 public void AddArc (RectangleF rect, float start_angle, float sweep_angle)
231                 {
232                         Status status = GDIPlus.GdipAddPathArc (nativePath, rect.X, rect.Y, rect.Width, rect.Height, start_angle, sweep_angle);
233                         GDIPlus.CheckStatus (status);                           
234                 }
235
236                 public void AddArc (int x, int y, int width, int height, float start_angle, float sweep_angle)
237                 {
238                         Status status = GDIPlus.GdipAddPathArcI (nativePath, x, y, width, height, start_angle, sweep_angle);
239                         GDIPlus.CheckStatus (status);                           
240                 }
241
242                 public void AddArc (float x, float y, float width, float height, float start_angle, float sweep_angle)
243                 {
244                         Status status = GDIPlus.GdipAddPathArc (nativePath, x, y, width, height, start_angle, sweep_angle);
245                         GDIPlus.CheckStatus (status);                           
246                 }
247
248                 //
249                 // AddBezier
250                 //
251                 public void AddBezier (Point pt1, Point pt2, Point pt3, Point pt4)
252                 {
253                         Status status = GDIPlus.GdipAddPathBezierI (nativePath, pt1.X, pt1.Y,
254                                         pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
255                                         
256                         GDIPlus.CheckStatus (status);                                                                         
257                 }
258
259                 public void AddBezier (PointF pt1, PointF pt2, PointF pt3, PointF pt4)
260                 {
261                         Status status = GDIPlus.GdipAddPathBezier (nativePath, pt1.X, pt1.Y,
262                                         pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
263                                         
264                         GDIPlus.CheckStatus (status);                                                                  
265                 }
266
267                 public void AddBezier (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
268                 {
269                         Status status = GDIPlus.GdipAddPathBezierI (nativePath, x1, y1, x2, y2, x3, y3, x4, y4);
270                         GDIPlus.CheckStatus (status);                           
271                 }
272
273                 public void AddBezier (float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
274                 {
275                         Status status = GDIPlus.GdipAddPathBezier (nativePath, x1, y1, x2, y2, x3, y3, x4, y4);
276                         GDIPlus.CheckStatus (status);                           
277                 }
278
279                 //
280                 // AddBeziers
281                 //
282                 public void AddBeziers (Point [] pts)
283                 {
284                         if (pts == null)
285                                 throw new ArgumentNullException ("pts");
286                         Status status = GDIPlus.GdipAddPathBeziersI (nativePath, pts, pts.Length);
287                         GDIPlus.CheckStatus (status);                           
288                 }
289
290                 public void AddBeziers (PointF [] pts)
291                 {
292                         if (pts == null)
293                                 throw new ArgumentNullException ("pts");
294                         Status status = GDIPlus.GdipAddPathBeziers (nativePath, pts, pts.Length);
295                         GDIPlus.CheckStatus (status);                           
296                 }
297
298                 //
299                 // AddEllipse
300                 //
301                 public void AddEllipse (RectangleF r)
302                 {
303                         Status status = GDIPlus.GdipAddPathEllipse (nativePath, r.X, r.Y, r.Width, r.Height);
304                         GDIPlus.CheckStatus (status);                           
305                 }
306                 
307                 public void AddEllipse (float x, float y, float width, float height)
308                 {
309                         Status status = GDIPlus.GdipAddPathEllipse (nativePath, x, y, width, height);
310                         GDIPlus.CheckStatus (status);                           
311                 }
312
313                 public void AddEllipse (Rectangle r)
314                 {
315                         Status status = GDIPlus.GdipAddPathEllipseI (nativePath, r.X, r.Y, r.Width, r.Height);
316                         GDIPlus.CheckStatus (status);                           
317                 }
318                 
319                 public void AddEllipse (int x, int y, int width, int height)
320                 {
321                         Status status = GDIPlus.GdipAddPathEllipseI (nativePath, x, y, width, height);
322                         GDIPlus.CheckStatus (status);                           
323                 }
324                 
325
326                 //
327                 // AddLine
328                 //
329                 public void AddLine (Point a, Point b)
330                 {
331                         Status status = GDIPlus.GdipAddPathLineI (nativePath, a.X, a.Y, b.X, b.Y);
332                         GDIPlus.CheckStatus (status);                           
333                 }
334
335                 public void AddLine (PointF a, PointF b)
336                 {
337                         Status status = GDIPlus.GdipAddPathLine (nativePath, a.X, a.Y, b.X,
338                                         b.Y);
339                                         
340                         GDIPlus.CheckStatus (status);                                                                  
341                 }
342
343                 public void AddLine (int x1, int y1, int x2, int y2)
344                 {
345                         Status status = GDIPlus.GdipAddPathLineI (nativePath, x1, y1, x2, y2);
346                         GDIPlus.CheckStatus (status);                           
347                 }
348
349                 public void AddLine (float x1, float y1, float x2, float y2)
350                 {
351                         Status status = GDIPlus.GdipAddPathLine (nativePath, x1, y1, x2,
352                                         y2);                
353                                         
354                         GDIPlus.CheckStatus (status);                                                                  
355                 }
356
357                 //
358                 // AddLines
359                 //
360                 public void AddLines (Point[] points)
361                 {
362                         if (points == null)
363                                 throw new ArgumentNullException ("points");
364                         if (points.Length == 0)
365                                 throw new ArgumentException ("points");
366
367                         Status status = GDIPlus.GdipAddPathLine2I (nativePath, points, points.Length);
368                         GDIPlus.CheckStatus (status);                           
369                 }
370
371                 public void AddLines (PointF[] points)
372                 {
373                         if (points == null)
374                                 throw new ArgumentNullException ("points");
375                         if (points.Length == 0)
376                                 throw new ArgumentException ("points");
377
378                         Status status = GDIPlus.GdipAddPathLine2 (nativePath, points, points.Length);
379                         GDIPlus.CheckStatus (status);                           
380                 }
381         
382                 //
383                 // AddPie
384                 //
385                 public void AddPie (Rectangle rect, float startAngle, float sweepAngle)
386                 {
387                         Status status = GDIPlus.GdipAddPathPie (
388                                 nativePath, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
389                         GDIPlus.CheckStatus (status);                           
390                 }
391
392                 public void AddPie (int x, int y, int width, int height, float startAngle, float sweepAngle)
393                 {
394                         Status status = GDIPlus.GdipAddPathPieI (nativePath, x, y, width, height, startAngle, sweepAngle);
395                         GDIPlus.CheckStatus (status);                           
396                 }
397
398                 public void AddPie (float x, float y, float width, float height, float startAngle, float sweepAngle)
399                 {
400                         Status status = GDIPlus.GdipAddPathPie (nativePath, x, y, width, height, startAngle, sweepAngle);                
401                         GDIPlus.CheckStatus (status);                           
402                 }
403
404                 //
405                 // AddPolygon
406                 //
407                 public void AddPolygon (Point [] points)
408                 {
409                         if (points == null)
410                                 throw new ArgumentNullException ("points");
411
412                         Status status = GDIPlus.GdipAddPathPolygonI (nativePath, points, points.Length);
413                         GDIPlus.CheckStatus (status);                           
414                 }
415
416                 public void AddPolygon (PointF [] points)
417                 {
418                         if (points == null)
419                                 throw new ArgumentNullException ("points");
420
421                         Status status = GDIPlus.GdipAddPathPolygon (nativePath, points, points.Length);
422                         GDIPlus.CheckStatus (status);                           
423                 }
424
425                 //
426                 // AddRectangle
427                 //
428                 public void AddRectangle (Rectangle rect)
429                 {
430                         Status status = GDIPlus.GdipAddPathRectangleI (nativePath, rect.X, rect.Y, rect.Width, rect.Height);
431                         GDIPlus.CheckStatus (status);                           
432                 }
433
434                 public void AddRectangle (RectangleF rect)
435                 {
436                         Status status = GDIPlus.GdipAddPathRectangle (nativePath, rect.X, rect.Y, rect.Width, rect.Height);
437                         GDIPlus.CheckStatus (status);                           
438                 }
439
440                 //
441                 // AddRectangles
442                 //
443                 public void AddRectangles (Rectangle [] rects)
444                 {
445                         if (rects == null)
446                                 throw new ArgumentNullException ("rects");
447                         if (rects.Length == 0)
448                                 throw new ArgumentException ("rects");
449
450                         Status status = GDIPlus.GdipAddPathRectanglesI (nativePath, rects, rects.Length);
451                         GDIPlus.CheckStatus (status);                           
452                 }
453
454                 public void AddRectangles (RectangleF [] rects)
455                 {
456                         if (rects == null)
457                                 throw new ArgumentNullException ("rects");
458                         if (rects.Length == 0)
459                                 throw new ArgumentException ("rects");
460
461                         Status status = GDIPlus.GdipAddPathRectangles (nativePath, rects, rects.Length);
462                         GDIPlus.CheckStatus (status);                           
463                 }
464
465                 //
466                 // AddPath
467                 //
468                 public void AddPath (GraphicsPath addingPath, bool connect)
469                 {
470                         if (addingPath == null)
471                                 throw new ArgumentNullException ("addingPath");
472
473                         Status status = GDIPlus.GdipAddPathPath (nativePath, addingPath.nativePath, connect);
474                         GDIPlus.CheckStatus (status);                           
475                 }
476
477                 public PointF GetLastPoint ()
478                 {
479                         PointF pt;
480                         Status status = GDIPlus.GdipGetPathLastPoint (nativePath, out pt);
481                         GDIPlus.CheckStatus (status);                           
482
483                         return pt;
484                 }
485
486                 //
487                 // AddClosedCurve
488                 //
489                 public void AddClosedCurve (Point [] points)
490                 {
491                         if (points == null)
492                                 throw new ArgumentNullException ("points");
493
494                         Status status = GDIPlus.GdipAddPathClosedCurveI (nativePath, points, points.Length);
495                         GDIPlus.CheckStatus (status);                           
496                 }
497
498                 public void AddClosedCurve (PointF [] points)
499                 {
500                         if (points == null)
501                                 throw new ArgumentNullException ("points");
502
503                         Status status = GDIPlus.GdipAddPathClosedCurve (nativePath, points, points.Length);
504                         GDIPlus.CheckStatus (status);                           
505                 }
506
507                 public void AddClosedCurve (Point [] points, float tension)
508                 {
509                         if (points == null)
510                                 throw new ArgumentNullException ("points");
511
512                         Status status = GDIPlus.GdipAddPathClosedCurve2I (nativePath, points, points.Length, tension);
513                         GDIPlus.CheckStatus (status);                           
514                 }
515
516                 public void AddClosedCurve (PointF [] points, float tension)
517                 {
518                         if (points == null)
519                                 throw new ArgumentNullException ("points");
520
521                         Status status = GDIPlus.GdipAddPathClosedCurve2 (nativePath, points, points.Length, tension);
522                         GDIPlus.CheckStatus (status);                           
523                 }
524
525                 //
526                 // AddCurve
527                 //
528                 public void AddCurve (Point [] points)
529                 {
530                         if (points == null)
531                                 throw new ArgumentNullException ("points");
532
533                         Status status = GDIPlus.GdipAddPathCurveI (nativePath, points, points.Length);
534                         GDIPlus.CheckStatus (status);                           
535                 }
536                 
537                 public void AddCurve (PointF [] points)
538                 {
539                         if (points == null)
540                                 throw new ArgumentNullException ("points");
541
542                         Status status = GDIPlus.GdipAddPathCurve (nativePath, points, points.Length);
543                         GDIPlus.CheckStatus (status);                           
544                 }
545                 
546                 public void AddCurve (Point [] points, float tension)
547                 {
548                         if (points == null)
549                                 throw new ArgumentNullException ("points");
550
551                         Status status = GDIPlus.GdipAddPathCurve2I (nativePath, points, points.Length, tension);
552                         GDIPlus.CheckStatus (status);                           
553                 }
554                 
555                 public void AddCurve (PointF [] points, float tension)
556                 {
557                         if (points == null)
558                                 throw new ArgumentNullException ("points");
559
560                         Status status = GDIPlus.GdipAddPathCurve2 (nativePath, points, points.Length, tension);
561                         GDIPlus.CheckStatus (status);                           
562                 }
563
564                 public void AddCurve (Point [] points, int offset, int numberOfSegments, float tension)
565                 {
566                         if (points == null)
567                                 throw new ArgumentNullException ("points");
568
569                         Status status = GDIPlus.GdipAddPathCurve3I (nativePath, points, points.Length,
570                                         offset, numberOfSegments, tension);
571                                         
572                         GDIPlus.CheckStatus (status);                                                                  
573                 }
574                 
575                 public void AddCurve (PointF [] points, int offset, int numberOfSegments, float tension)
576                 {
577                         if (points == null)
578                                 throw new ArgumentNullException ("points");
579
580                         Status status = GDIPlus.GdipAddPathCurve3 (nativePath, points, points.Length,
581                                         offset, numberOfSegments, tension);
582                                         
583                         GDIPlus.CheckStatus (status);                                                                  
584                 }
585                         
586                 public void Reset ()
587                 {
588                         Status status = GDIPlus.GdipResetPath (nativePath);
589                         GDIPlus.CheckStatus (status);                           
590                 }
591
592                 public void Reverse ()
593                 {
594                         Status status = GDIPlus.GdipReversePath (nativePath);
595                         GDIPlus.CheckStatus (status);                           
596                 }
597
598                 public void Transform (Matrix matrix)
599                 {
600                         if (matrix == null)
601                                 throw new ArgumentNullException ("matrix");
602
603                         Status status = GDIPlus.GdipTransformPath (nativePath, matrix.nativeMatrix);
604                         GDIPlus.CheckStatus (status);                           
605                 }
606                 
607                 [MonoTODO ("StringFormat isn't supported inside libgdiplus")]
608                 public void AddString (string s, FontFamily family, int style, float emSize, Point origin, StringFormat format)
609                 {
610                         Rectangle layout = new Rectangle ();
611                         layout.X = origin.X;
612                         layout.Y = origin.Y;
613                         AddString (s, family, style, emSize, layout, format);
614                 }
615
616                 [MonoTODO ("StringFormat isn't supported inside libgdiplus")]
617                 public void AddString (string s, FontFamily family, int style, float emSize, PointF origin, StringFormat format)
618                 {
619                         RectangleF layout = new RectangleF ();
620                         layout.X = origin.X;
621                         layout.Y = origin.Y;
622                         AddString (s, family, style, emSize, layout, format);
623                 }
624
625                 [MonoTODO ("layoutRect and StringFormat aren't supported inside libgdiplus")]
626                 public void AddString (string s, FontFamily family, int style, float emSize, Rectangle layoutRect, StringFormat format)
627                 {
628                         if (family == null)
629                                 throw new ArgumentException ("family");
630
631                         IntPtr sformat = (format == null) ? IntPtr.Zero : format.NativeObject;
632                         // note: the NullReferenceException on s.Length is the expected (MS) exception
633                         Status status = GDIPlus.GdipAddPathStringI (nativePath, s, s.Length, family.NativeObject, style, emSize, ref layoutRect, sformat);
634                         GDIPlus.CheckStatus (status);
635                 }
636
637                 [MonoTODO ("layoutRect and StringFormat aren't supported inside libgdiplus")]
638                 public void AddString (string s, FontFamily family, int style, float emSize, RectangleF layoutRect, StringFormat format)
639                 {
640                         if (family == null)
641                                 throw new ArgumentException ("family");
642
643                         IntPtr sformat = (format == null) ? IntPtr.Zero : format.NativeObject;
644                         // note: the NullReferenceException on s.Length is the expected (MS) exception
645                         Status status = GDIPlus.GdipAddPathString (nativePath, s, s.Length, family.NativeObject, style, emSize, ref layoutRect, sformat);
646                         GDIPlus.CheckStatus (status);
647                 }
648
649                 public void ClearMarkers()               
650                 {
651                         Status s = GDIPlus.GdipClearPathMarkers (nativePath);
652
653                         GDIPlus.CheckStatus (s);
654                 }
655                 
656                 public void CloseAllFigures()
657                 {
658                         Status s = GDIPlus.GdipClosePathFigures (nativePath);
659
660                         GDIPlus.CheckStatus (s);
661                 }       
662                 
663                 public void CloseFigure()
664                 {
665                         Status s = GDIPlus.GdipClosePathFigure (nativePath);
666
667                         GDIPlus.CheckStatus (s);
668                 } 
669
670                 public void Flatten ()
671                 {
672                         Flatten (null, FlatnessDefault); 
673                 }       
674   
675                 public void Flatten (Matrix matrix)
676                 {
677                         Flatten (matrix, FlatnessDefault);
678                 }
679                 
680                 public void Flatten (Matrix matrix, float flatness)
681                 {
682                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
683                         Status status = GDIPlus.GdipFlattenPath (nativePath, m, flatness);
684
685                         GDIPlus.CheckStatus (status);
686                 }               
687                 
688                 public RectangleF GetBounds ()
689                 {
690                         return GetBounds (null, null);
691                 }               
692
693                 public RectangleF GetBounds (Matrix matrix)
694                 {
695                         return GetBounds (matrix, null);
696                 }
697
698                 public RectangleF GetBounds (Matrix matrix, Pen pen)
699                 {
700                         RectangleF retval;
701                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
702                         IntPtr p = (pen == null) ? IntPtr.Zero : pen.nativeObject;
703                         
704                         Status s = GDIPlus.GdipGetPathWorldBounds (nativePath, out retval, m, p);
705
706                         GDIPlus.CheckStatus (s);
707
708                         return retval;
709                 }
710
711                 public bool IsOutlineVisible (Point point, Pen pen)
712                 {
713                         return IsOutlineVisible (point.X, point.Y, pen, null);
714                 }               
715                 
716                 public bool IsOutlineVisible (PointF point, Pen pen)
717                 {
718                         return IsOutlineVisible (point.X, point.Y, pen, null);
719                 } 
720                 
721                 public bool IsOutlineVisible (int x, int y, Pen pen)
722                 {
723                         return IsOutlineVisible (x, y, pen, null);
724                 }
725
726                 public bool IsOutlineVisible (float x, float y, Pen pen)
727                 {
728                         return IsOutlineVisible (x, y, pen, null);
729                 }               
730                 
731                 [MonoTODO ("Graphics parameter is currently ignored in libgdiplus")]
732                 public bool IsOutlineVisible (Point pt, Pen pen, Graphics graphics)
733                 {
734                         return IsOutlineVisible (pt.X, pt.Y, pen, graphics);
735                 }               
736                 
737                 [MonoTODO ("Graphics parameter is currently ignored in libgdiplus")]
738                 public bool IsOutlineVisible (PointF pt, Pen pen, Graphics graphics)
739                 {
740                         return IsOutlineVisible (pt.X, pt.Y, pen, graphics);
741                 }               
742                                 
743                 [MonoTODO ("Graphics parameter is currently ignored in libgdiplus")]
744                 public bool IsOutlineVisible (int x, int y, Pen pen, Graphics graphics)
745                 {
746                         if (pen == null)
747                                 throw new ArgumentNullException ("pen");
748
749                         bool result;
750                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
751                         
752                         Status s = GDIPlus.GdipIsOutlineVisiblePathPointI (nativePath, x, y, pen.nativeObject, g, out result);
753                         GDIPlus.CheckStatus (s);
754
755                         return result;
756                 }               
757
758                 [MonoTODO ("Graphics parameter is currently ignored in libgdiplus")]
759                 public bool IsOutlineVisible (float x, float y, Pen pen, Graphics graphics)
760                 {
761                         if (pen == null)
762                                 throw new ArgumentNullException ("pen");
763
764                         bool result;
765                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
766                         
767                         Status s = GDIPlus.GdipIsOutlineVisiblePathPoint (nativePath, x, y, pen.nativeObject, g, out result);
768                         GDIPlus.CheckStatus (s);
769
770                         return result;
771                 }               
772                 
773                 public bool IsVisible (Point point)
774                 {
775                         return IsVisible (point.X, point.Y, null);
776                 }               
777                 
778                 public bool IsVisible (PointF point)
779                 {
780                         return IsVisible (point.X, point.Y, null);
781                 }               
782                 
783                 public bool IsVisible (int x, int y)
784                 {
785                         return IsVisible (x, y, null);
786                 }
787
788                 public bool IsVisible (float x, float y)
789                 {
790                         return IsVisible (x, y, null);
791                 }                               
792                 
793                 [MonoTODO ("Graphics parameter is currently ignored in libgdiplus")]
794                 public bool IsVisible (Point pt, Graphics graphics)
795                 {
796                         return IsVisible (pt.X, pt.Y, graphics);
797                 }               
798                 
799                 [MonoTODO ("Graphics parameter is currently ignored in libgdiplus")]
800                 public bool IsVisible (PointF pt, Graphics graphics)
801                 {
802                         return IsVisible (pt.X, pt.Y, graphics);
803                 }               
804                                 
805                 [MonoTODO ("Graphics parameter is currently ignored in libgdiplus")]
806                 public bool IsVisible (int x, int y, Graphics graphics)
807                 {
808                         bool retval;
809
810                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
811
812                         Status s = GDIPlus.GdipIsVisiblePathPointI (nativePath, x, y, g, out retval);
813
814                         GDIPlus.CheckStatus (s);
815
816                         return retval;
817                 }               
818                 
819                 [MonoTODO ("Graphics parameter is currently ignored in libgdiplus")]
820                 public bool IsVisible (float x, float y, Graphics graphics)
821                 {
822                         bool retval;
823
824                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
825
826                         Status s = GDIPlus.GdipIsVisiblePathPoint (nativePath, x, y, g, out retval);
827
828                         GDIPlus.CheckStatus (s);
829
830                         return retval;
831                 }               
832                 
833                 public void SetMarkers ()
834                 {
835                         Status s = GDIPlus.GdipSetPathMarker (nativePath);
836
837                         GDIPlus.CheckStatus (s);
838                 }
839                 
840                 public void StartFigure()
841                 {
842                         Status s = GDIPlus.GdipStartPathFigure (nativePath);
843
844                         GDIPlus.CheckStatus (s);
845                 }               
846                 
847                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
848                 public void Warp (PointF[] destPoints, RectangleF srcRect)
849                 {
850                         Warp (destPoints, srcRect, null, WarpMode.Perspective, FlatnessDefault);
851                 }               
852
853                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
854                 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix)
855                 {
856                         Warp (destPoints, srcRect, matrix, WarpMode.Perspective, FlatnessDefault);
857                 }               
858
859                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
860                 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix, WarpMode warpMode)
861                 {
862                         Warp (destPoints, srcRect, matrix, warpMode, FlatnessDefault);
863                 }               
864
865                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
866                 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix,  WarpMode warpMode, float flatness)
867                 {
868                         if (destPoints == null)
869                                 throw new ArgumentNullException ("destPoints");
870
871                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
872
873                         Status s = GDIPlus.GdipWarpPath (nativePath, m, destPoints, destPoints.Length,
874                                         srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, warpMode, flatness);
875
876                         GDIPlus.CheckStatus (s);
877                 }
878                 
879                 [MonoTODO ("GdipWidenPath isn't implemented in libgdiplus")]
880                 public void Widen (Pen pen)
881                 {
882                         Widen (pen, null, FlatnessDefault);
883                 }               
884                 
885                 [MonoTODO ("GdipWidenPath isn't implemented in libgdiplus")]
886                 public void Widen (Pen pen, Matrix matrix)
887                 {       
888                         Widen (pen, matrix, FlatnessDefault);
889                 }               
890                 
891                 [MonoTODO ("GdipWidenPath isn't implemented in libgdiplus")]
892                 public void Widen (Pen pen, Matrix matrix, float flatness)
893                 {
894                         if (pen == null)
895                                 throw new ArgumentNullException ("pen");
896 #if NET_2_0
897                         if (PointCount == 0)
898                                 return;
899 #endif
900                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
901
902                         Status s = GDIPlus.GdipWidenPath (nativePath, pen.nativeObject, m, flatness);
903                         GDIPlus.CheckStatus (s);
904                 } 
905         }
906 }