2006-03-22 Sebastien Pouliot <sebastien@ximian.com>
[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                                 status = GDIPlus.GdipGetPathPoints (nativePath, points, count); 
152                                 GDIPlus.CheckStatus (status);                   
153
154                                 byte [] types = new byte [count];
155                                 status = GDIPlus.GdipGetPathTypes (nativePath, types, count);
156                                 GDIPlus.CheckStatus (status);
157
158                                 PathData pdata = new PathData ();
159                                 pdata.Points = points;
160                                 pdata.Types = types;
161                                 return pdata;
162                         }
163                 }
164
165                 public PointF [] PathPoints {
166                         get {
167                                 int count;
168                                 Status status = GDIPlus.GdipGetPointCount (nativePath, out count);
169                                 GDIPlus.CheckStatus (status);
170                                 if (count == 0)
171                                         throw new ArgumentException ("PathPoints");
172
173                                 PointF [] points = new PointF [count];
174                                 status = GDIPlus.GdipGetPathPoints (nativePath, points, count); 
175                                 GDIPlus.CheckStatus (status);                   
176
177                                 return points;
178                         }
179                 }
180
181                 public byte [] PathTypes {
182                         get {
183                                 int count;
184                                 Status status = GDIPlus.GdipGetPointCount (nativePath, out count);
185                                 GDIPlus.CheckStatus (status);
186                                 if (count == 0)
187                                         throw new ArgumentException ("PathTypes");
188
189                                 byte [] types = new byte [count];
190                                 status = GDIPlus.GdipGetPathTypes (nativePath, types, count);
191                                 GDIPlus.CheckStatus (status);
192
193                                 return types;
194                         }
195                 }
196
197                 public int PointCount {
198                         get {
199                                 int count;
200                                 Status status = GDIPlus.GdipGetPointCount (nativePath, out count);
201                                 GDIPlus.CheckStatus (status);
202
203                                 return count;
204                         }
205                 }
206
207                 internal IntPtr NativeObject {
208                         get {
209                                 return nativePath;
210                         }
211                         set {
212                                 nativePath = value;
213                         }
214                 }
215
216                 //
217                 // AddArc
218                 //
219                 public void AddArc (Rectangle rect, float start_angle, float sweep_angle)
220                 {
221                         Status status = GDIPlus.GdipAddPathArcI (nativePath, rect.X, rect.Y, rect.Width, rect.Height, start_angle, sweep_angle);
222                         GDIPlus.CheckStatus (status);                           
223                 }
224
225                 public void AddArc (RectangleF rect, float start_angle, float sweep_angle)
226                 {
227                         Status status = GDIPlus.GdipAddPathArc (nativePath, rect.X, rect.Y, rect.Width, rect.Height, start_angle, sweep_angle);
228                         GDIPlus.CheckStatus (status);                           
229                 }
230
231                 public void AddArc (int x, int y, int width, int height, float start_angle, float sweep_angle)
232                 {
233                         Status status = GDIPlus.GdipAddPathArcI (nativePath, x, y, width, height, start_angle, sweep_angle);
234                         GDIPlus.CheckStatus (status);                           
235                 }
236
237                 public void AddArc (float x, float y, float width, float height, float start_angle, float sweep_angle)
238                 {
239                         Status status = GDIPlus.GdipAddPathArc (nativePath, x, y, width, height, start_angle, sweep_angle);
240                         GDIPlus.CheckStatus (status);                           
241                 }
242
243                 //
244                 // AddBezier
245                 //
246                 public void AddBezier (Point pt1, Point pt2, Point pt3, Point pt4)
247                 {
248                         Status status = GDIPlus.GdipAddPathBezierI (nativePath, pt1.X, pt1.Y,
249                                         pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
250                                         
251                         GDIPlus.CheckStatus (status);                                                                         
252                 }
253
254                 public void AddBezier (PointF pt1, PointF pt2, PointF pt3, PointF pt4)
255                 {
256                         Status status = GDIPlus.GdipAddPathBezier (nativePath, pt1.X, pt1.Y,
257                                         pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
258                                         
259                         GDIPlus.CheckStatus (status);                                                                  
260                 }
261
262                 public void AddBezier (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
263                 {
264                         Status status = GDIPlus.GdipAddPathBezierI (nativePath, x1, y1, x2, y2, x3, y3, x4, y4);
265                         GDIPlus.CheckStatus (status);                           
266                 }
267
268                 public void AddBezier (float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
269                 {
270                         Status status = GDIPlus.GdipAddPathBezier (nativePath, x1, y1, x2, y2, x3, y3, x4, y4);
271                         GDIPlus.CheckStatus (status);                           
272                 }
273
274                 //
275                 // AddBeziers
276                 //
277                 public void AddBeziers (Point [] pts)
278                 {
279                         if (pts == null)
280                                 throw new ArgumentNullException ("pts");
281                         Status status = GDIPlus.GdipAddPathBeziersI (nativePath, pts, pts.Length);
282                         GDIPlus.CheckStatus (status);                           
283                 }
284
285                 public void AddBeziers (PointF [] pts)
286                 {
287                         if (pts == null)
288                                 throw new ArgumentNullException ("pts");
289                         Status status = GDIPlus.GdipAddPathBeziers (nativePath, pts, pts.Length);
290                         GDIPlus.CheckStatus (status);                           
291                 }
292
293                 //
294                 // AddEllipse
295                 //
296                 public void AddEllipse (RectangleF r)
297                 {
298                         Status status = GDIPlus.GdipAddPathEllipse (nativePath, r.X, r.Y, r.Width, r.Height);
299                         GDIPlus.CheckStatus (status);                           
300                 }
301                 
302                 public void AddEllipse (float x, float y, float width, float height)
303                 {
304                         Status status = GDIPlus.GdipAddPathEllipse (nativePath, x, y, width, height);
305                         GDIPlus.CheckStatus (status);                           
306                 }
307
308                 public void AddEllipse (Rectangle r)
309                 {
310                         Status status = GDIPlus.GdipAddPathEllipseI (nativePath, r.X, r.Y, r.Width, r.Height);
311                         GDIPlus.CheckStatus (status);                           
312                 }
313                 
314                 public void AddEllipse (int x, int y, int width, int height)
315                 {
316                         Status status = GDIPlus.GdipAddPathEllipseI (nativePath, x, y, width, height);
317                         GDIPlus.CheckStatus (status);                           
318                 }
319                 
320
321                 //
322                 // AddLine
323                 //
324                 public void AddLine (Point a, Point b)
325                 {
326                         Status status = GDIPlus.GdipAddPathLineI (nativePath, a.X, a.Y, b.X, b.Y);
327                         GDIPlus.CheckStatus (status);                           
328                 }
329
330                 public void AddLine (PointF a, PointF b)
331                 {
332                         Status status = GDIPlus.GdipAddPathLine (nativePath, a.X, a.Y, b.X,
333                                         b.Y);
334                                         
335                         GDIPlus.CheckStatus (status);                                                                  
336                 }
337
338                 public void AddLine (int x1, int y1, int x2, int y2)
339                 {
340                         Status status = GDIPlus.GdipAddPathLineI (nativePath, x1, y1, x2, y2);
341                         GDIPlus.CheckStatus (status);                           
342                 }
343
344                 public void AddLine (float x1, float y1, float x2, float y2)
345                 {
346                         Status status = GDIPlus.GdipAddPathLine (nativePath, x1, y1, x2,
347                                         y2);                
348                                         
349                         GDIPlus.CheckStatus (status);                                                                  
350                 }
351
352                 //
353                 // AddLines
354                 //
355                 public void AddLines (Point [] points)
356                 {
357                         if (points == null)
358                                 throw new ArgumentNullException ("points");
359                         if (points.Length == 0)
360                                 throw new ArgumentException ("points");
361
362                         int length = points.Length;
363                         for (int i = 0; i < length - 1; i++) {
364                                 int j = i + 1;
365                                 Status status = GDIPlus.GdipAddPathLineI (
366                                         nativePath, points [i].X, points [i].Y, points [j].X, points [j].Y);
367                                 GDIPlus.CheckStatus (status);                           
368                         }
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                         int length = points.Length;
379
380                         for (int i = 0; i < length - 1; i++) {
381                                 int j = i + 1;
382                                 Status status = GDIPlus.GdipAddPathLine (
383                                         nativePath, points [i].X, points [i].Y, points [j].X, points [j].Y);
384                                 GDIPlus.CheckStatus (status);                           
385                         }
386                 }
387         
388                 //
389                 // AddPie
390                 //
391                 public void AddPie (Rectangle rect, float startAngle, float sweepAngle)
392                 {
393                         Status status = GDIPlus.GdipAddPathPie (
394                                 nativePath, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
395                         GDIPlus.CheckStatus (status);                           
396                 }
397
398                 public void AddPie (int x, int y, int width, int height, float startAngle, float sweepAngle)
399                 {
400                         Status status = GDIPlus.GdipAddPathPieI (nativePath, x, y, width, height, startAngle, sweepAngle);
401                         GDIPlus.CheckStatus (status);                           
402                 }
403
404                 public void AddPie (float x, float y, float width, float height, float startAngle, float sweepAngle)
405                 {
406                         Status status = GDIPlus.GdipAddPathPie (nativePath, x, y, width, height, startAngle, sweepAngle);                
407                         GDIPlus.CheckStatus (status);                           
408                 }
409
410                 //
411                 // AddPolygon
412                 //
413                 public void AddPolygon (Point [] points)
414                 {
415                         if (points == null)
416                                 throw new ArgumentNullException ("points");
417
418                         Status status = GDIPlus.GdipAddPathPolygonI (nativePath, points, points.Length);
419                         GDIPlus.CheckStatus (status);                           
420                 }
421
422                 public void AddPolygon (PointF [] points)
423                 {
424                         if (points == null)
425                                 throw new ArgumentNullException ("points");
426
427                         Status status = GDIPlus.GdipAddPathPolygon (nativePath, points, points.Length);
428                         GDIPlus.CheckStatus (status);                           
429                 }
430
431                 //
432                 // AddRectangle
433                 //
434                 public void AddRectangle (Rectangle rect)
435                 {
436                         Status status = GDIPlus.GdipAddPathRectangleI (nativePath, rect.X, rect.Y, rect.Width, rect.Height);
437                         GDIPlus.CheckStatus (status);                           
438                 }
439
440                 public void AddRectangle (RectangleF rect)
441                 {
442                         Status status = GDIPlus.GdipAddPathRectangle (nativePath, rect.X, rect.Y, rect.Width, rect.Height);
443                         GDIPlus.CheckStatus (status);                           
444                 }
445
446                 //
447                 // AddRectangles
448                 //
449                 public void AddRectangles (Rectangle [] rects)
450                 {
451                         if (rects == null)
452                                 throw new ArgumentNullException ("rects");
453                         if (rects.Length == 0)
454                                 throw new ArgumentException ("rects");
455
456                         Status status = GDIPlus.GdipAddPathRectanglesI (nativePath, rects, rects.Length);
457                         GDIPlus.CheckStatus (status);                           
458                 }
459
460                 public void AddRectangles (RectangleF [] rects)
461                 {
462                         if (rects == null)
463                                 throw new ArgumentNullException ("rects");
464                         if (rects.Length == 0)
465                                 throw new ArgumentException ("rects");
466
467                         Status status = GDIPlus.GdipAddPathRectangles (nativePath, rects, rects.Length);
468                         GDIPlus.CheckStatus (status);                           
469                 }
470
471                 //
472                 // AddPath
473                 //
474                 public void AddPath (GraphicsPath addingPath, bool connect)
475                 {
476                         if (addingPath == null)
477                                 throw new ArgumentNullException ("addingPath");
478
479                         Status status = GDIPlus.GdipAddPathPath (nativePath, addingPath.nativePath, connect);
480                         GDIPlus.CheckStatus (status);                           
481                 }
482
483                 public PointF GetLastPoint ()
484                 {
485                         PointF pt;
486                         Status status = GDIPlus.GdipGetPathLastPoint (nativePath, out pt);
487                         GDIPlus.CheckStatus (status);                           
488
489                         return pt;
490                 }
491
492                 //
493                 // AddClosedCurve
494                 //
495                 public void AddClosedCurve (Point [] points)
496                 {
497                         if (points == null)
498                                 throw new ArgumentNullException ("points");
499
500                         Status status = GDIPlus.GdipAddPathClosedCurveI (nativePath, points, points.Length);
501                         GDIPlus.CheckStatus (status);                           
502                 }
503
504                 public void AddClosedCurve (PointF [] points)
505                 {
506                         if (points == null)
507                                 throw new ArgumentNullException ("points");
508
509                         Status status = GDIPlus.GdipAddPathClosedCurve (nativePath, points, points.Length);
510                         GDIPlus.CheckStatus (status);                           
511                 }
512
513                 public void AddClosedCurve (Point [] points, float tension)
514                 {
515                         if (points == null)
516                                 throw new ArgumentNullException ("points");
517
518                         Status status = GDIPlus.GdipAddPathClosedCurve2I (nativePath, points, points.Length, tension);
519                         GDIPlus.CheckStatus (status);                           
520                 }
521
522                 public void AddClosedCurve (PointF [] points, float tension)
523                 {
524                         if (points == null)
525                                 throw new ArgumentNullException ("points");
526
527                         Status status = GDIPlus.GdipAddPathClosedCurve2 (nativePath, points, points.Length, tension);
528                         GDIPlus.CheckStatus (status);                           
529                 }
530
531                 //
532                 // AddCurve
533                 //
534                 public void AddCurve (Point [] points)
535                 {
536                         if (points == null)
537                                 throw new ArgumentNullException ("points");
538
539                         Status status = GDIPlus.GdipAddPathCurveI (nativePath, points, points.Length);
540                         GDIPlus.CheckStatus (status);                           
541                 }
542                 
543                 public void AddCurve (PointF [] points)
544                 {
545                         if (points == null)
546                                 throw new ArgumentNullException ("points");
547
548                         Status status = GDIPlus.GdipAddPathCurve (nativePath, points, points.Length);
549                         GDIPlus.CheckStatus (status);                           
550                 }
551                 
552                 public void AddCurve (Point [] points, float tension)
553                 {
554                         if (points == null)
555                                 throw new ArgumentNullException ("points");
556
557                         Status status = GDIPlus.GdipAddPathCurve2I (nativePath, points, points.Length, tension);
558                         GDIPlus.CheckStatus (status);                           
559                 }
560                 
561                 public void AddCurve (PointF [] points, float tension)
562                 {
563                         if (points == null)
564                                 throw new ArgumentNullException ("points");
565
566                         Status status = GDIPlus.GdipAddPathCurve2 (nativePath, points, points.Length, tension);
567                         GDIPlus.CheckStatus (status);                           
568                 }
569
570                 public void AddCurve (Point [] points, int offset, int numberOfSegments, float tension)
571                 {
572                         if (points == null)
573                                 throw new ArgumentNullException ("points");
574
575                         Status status = GDIPlus.GdipAddPathCurve3I (nativePath, points, points.Length,
576                                         offset, numberOfSegments, tension);
577                                         
578                         GDIPlus.CheckStatus (status);                                                                  
579                 }
580                 
581                 public void AddCurve (PointF [] points, int offset, int numberOfSegments, float tension)
582                 {
583                         if (points == null)
584                                 throw new ArgumentNullException ("points");
585
586                         Status status = GDIPlus.GdipAddPathCurve3 (nativePath, points, points.Length,
587                                         offset, numberOfSegments, tension);
588                                         
589                         GDIPlus.CheckStatus (status);                                                                  
590                 }
591                         
592                 public void Reset ()
593                 {
594                         Status status = GDIPlus.GdipResetPath (nativePath);
595                         GDIPlus.CheckStatus (status);                           
596                 }
597
598                 public void Reverse ()
599                 {
600                         Status status = GDIPlus.GdipReversePath (nativePath);
601                         GDIPlus.CheckStatus (status);                           
602                 }
603
604                 public void Transform (Matrix matrix)
605                 {
606                         if (matrix == null)
607                                 throw new ArgumentNullException ("matrix");
608
609                         Status status = GDIPlus.GdipTransformPath (nativePath, matrix.nativeMatrix);
610                         GDIPlus.CheckStatus (status);                           
611                 }
612                 
613                 [MonoTODO ("GdipAddStringI isn't implemented in libgdiplus")]
614                 public void AddString (string s, FontFamily family, int style, float emSize, Point origin, StringFormat format)
615                 {
616                         Rectangle layout;
617                         layout.X = origin.X;
618                         layout.Y = origin.Y;
619                         AddString (s, family, style, emSize, layout, format);
620                 }
621
622                 [MonoTODO ("GdipAddString isn't implemented in libgdiplus")]
623                 public void AddString (string s, FontFamily family, int style, float emSize, PointF origin, StringFormat format)
624                 {
625                         RectangleF layout;
626                         layout.X = origin.X;
627                         layout.Y = origin.Y;
628                         AddString (s, family, style, emSize, layout, format);
629                 }
630
631                 [MonoTODO ("GdipAddStringI isn't implemented in libgdiplus")]
632                 public void AddString (string s, FontFamily family, int style, float emSize, Rectangle layoutRect, StringFormat format)
633                 {
634                         if (s == null)
635                                 throw new ArgumentNullException ("s");
636
637                         IntPtr ffamily = (family == null) ? IntPtr.Zero : family.NativeObject;
638                         IntPtr sformat = (format == null) ? IntPtr.Zero : format.NativeObject;
639
640                         Status status = GDIPlus.GdipAddStringI (nativePath, s, s.Length, ffamily, style, emSize, ref layoutRect, sformat);
641                         GDIPlus.CheckStatus (status);
642                 }
643
644                 [MonoTODO ("GdipAddString isn't implemented in libgdiplus")]
645                 public void AddString (string s, FontFamily family, int style, float emSize, RectangleF layoutRect, StringFormat format)
646                 {
647                         if (s == null)
648                                 throw new ArgumentNullException ("s");
649
650                         IntPtr ffamily = (family == null) ? IntPtr.Zero : family.NativeObject;
651                         IntPtr sformat = (format == null) ? IntPtr.Zero : format.NativeObject;
652
653                         Status status = GDIPlus.GdipAddString (nativePath, s, s.Length, ffamily, style, emSize, ref layoutRect, sformat);
654                         GDIPlus.CheckStatus (status);
655                 }
656
657                 public void ClearMarkers()               
658                 {
659                         Status s = GDIPlus.GdipClearPathMarkers (nativePath);
660
661                         GDIPlus.CheckStatus (s);
662                 }
663                 
664                 public void CloseAllFigures()
665                 {
666                         Status s = GDIPlus.GdipClosePathFigures (nativePath);
667
668                         GDIPlus.CheckStatus (s);
669                 }       
670                 
671                 public void CloseFigure()
672                 {
673                         Status s = GDIPlus.GdipClosePathFigure (nativePath);
674
675                         GDIPlus.CheckStatus (s);
676                 } 
677
678                 public void Flatten ()
679                 {
680                         Flatten (null, FlatnessDefault); 
681                 }       
682   
683                 public void Flatten (Matrix matrix)
684                 {
685                         Flatten (matrix, FlatnessDefault);
686                 }
687                 
688                 public void Flatten (Matrix matrix, float flatness)
689                 {
690                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
691                         Status status = GDIPlus.GdipFlattenPath (nativePath, m, flatness);
692
693                         GDIPlus.CheckStatus (status);
694                 }               
695                 
696                 public RectangleF GetBounds ()
697                 {
698                         return GetBounds (null, null);
699                 }               
700
701                 public RectangleF GetBounds (Matrix matrix)
702                 {
703                         return GetBounds (matrix, null);
704                 }
705
706                 [MonoTODO ("GdipGetPathWorldBounds doesn't support pens in libgdiplus (missing GdipWidenPath)")]
707                 public RectangleF GetBounds (Matrix matrix, Pen pen)
708                 {
709                         RectangleF retval;
710                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
711                         IntPtr p = (pen == null) ? IntPtr.Zero : pen.nativeObject;
712                         
713                         Status s = GDIPlus.GdipGetPathWorldBounds (nativePath, out retval, m, p);
714
715                         GDIPlus.CheckStatus (s);
716
717                         return retval;
718                 }
719
720                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
721                 public bool IsOutlineVisible (Point point, Pen pen)
722                 {
723                         return IsOutlineVisible (point.X, point.Y, pen, null);
724                 }               
725                 
726                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
727                 public bool IsOutlineVisible (PointF point, Pen pen)
728                 {
729                         return IsOutlineVisible (point.X, point.Y, pen, null);
730                 } 
731                 
732                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
733                 public bool IsOutlineVisible (int x, int y, Pen pen)
734                 {
735                         return IsOutlineVisible (x, y, pen, null);
736                 }
737
738                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
739                 public bool IsOutlineVisible (float x, float y, Pen pen)
740                 {
741                         return IsOutlineVisible (x, y, pen, null);
742                 }               
743                 
744                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
745                 public bool IsOutlineVisible (Point pt, Pen pen, Graphics graphics)
746                 {
747                         return IsOutlineVisible (pt.X, pt.Y, pen, graphics);
748                 }               
749                 
750                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
751                 public bool IsOutlineVisible (PointF pt, Pen pen, Graphics graphics)
752                 {
753                         return IsOutlineVisible (pt.X, pt.Y, pen, graphics);
754                 }               
755                                 
756                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
757                 public bool IsOutlineVisible (int x, int y, Pen pen, Graphics graphics)
758                 {
759                         bool result;
760                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
761                         
762                         Status s = GDIPlus.GdipIsOutlineVisiblePathPointI (nativePath, x, y, g, out result);
763                         GDIPlus.CheckStatus (s);
764
765                         return result;
766                 }               
767
768                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
769                 public bool IsOutlineVisible (float x, float y, Pen pen, Graphics graphics)
770                 {
771                         bool result;
772                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
773                         
774                         Status s = GDIPlus.GdipIsOutlineVisiblePathPoint (nativePath, x, y, g, out result);
775                         GDIPlus.CheckStatus (s);
776
777                         return result;
778                 }               
779                 
780                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
781                 public bool IsVisible (Point point)
782                 {
783                         return IsVisible (point.X, point.Y, null);
784                 }               
785                 
786                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
787                 public bool IsVisible (PointF point)
788                 {
789                         return IsVisible (point.X, point.Y, null);
790                 }               
791                 
792                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
793                 public bool IsVisible (int x, int y)
794                 {
795                         return IsVisible (x, y, null);
796                 }
797
798                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
799                 public bool IsVisible (float x, float y)
800                 {
801                         return IsVisible (x, y, null);
802                 }                               
803                 
804                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
805                 public bool IsVisible (Point pt, Graphics graphics)
806                 {
807                         return IsVisible (pt.X, pt.Y, graphics);
808                 }               
809                 
810                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
811                 public bool IsVisible (PointF pt, Graphics graphics)
812                 {
813                         return IsVisible (pt.X, pt.Y, graphics);
814                 }               
815                                 
816                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
817                 public bool IsVisible (int x, int y, Graphics graphics)
818                 {
819                         bool retval;
820
821                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
822
823                         Status s = GDIPlus.GdipIsVisiblePathPointI (nativePath, x, y, g, out retval);
824
825                         GDIPlus.CheckStatus (s);
826
827                         return retval;
828                 }               
829                 
830                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
831                 public bool IsVisible (float x, float y, Graphics graphics)
832                 {
833                         bool retval;
834
835                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
836
837                         Status s = GDIPlus.GdipIsVisiblePathPoint (nativePath, x, y, g, out retval);
838
839                         GDIPlus.CheckStatus (s);
840
841                         return retval;
842                 }               
843                 
844                 public void SetMarkers ()
845                 {
846                         Status s = GDIPlus.GdipSetPathMarker (nativePath);
847
848                         GDIPlus.CheckStatus (s);
849                 }
850                 
851                 public void StartFigure()
852                 {
853                         Status s = GDIPlus.GdipStartPathFigure (nativePath);
854
855                         GDIPlus.CheckStatus (s);
856                 }               
857                 
858                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
859                 public void Warp (PointF[] destPoints, RectangleF srcRect)
860                 {
861                         Warp (destPoints, srcRect, null, WarpMode.Perspective, FlatnessDefault);
862                 }               
863
864                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
865                 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix)
866                 {
867                         Warp (destPoints, srcRect, matrix, WarpMode.Perspective, FlatnessDefault);
868                 }               
869
870                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
871                 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix, WarpMode warpMode)
872                 {
873                         Warp (destPoints, srcRect, matrix, warpMode, FlatnessDefault);
874                 }               
875
876                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
877                 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix,  WarpMode warpMode, float flatness)
878                 {
879                         if (destPoints == null)
880                                 throw new ArgumentNullException ("destPoints");
881
882                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
883
884                         Status s = GDIPlus.GdipWarpPath (nativePath, m, destPoints, destPoints.Length,
885                                         srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, warpMode, flatness);
886
887                         GDIPlus.CheckStatus (s);
888                 }
889                 
890                 [MonoTODO ("GdipWidenPath isn't implemented in libgdiplus")]
891                 public void Widen (Pen pen)
892                 {
893                         Widen (pen, null, FlatnessDefault);
894                 }               
895                 
896                 [MonoTODO ("GdipWidenPath isn't implemented in libgdiplus")]
897                 public void Widen (Pen pen, Matrix matrix)
898                 {       
899                         Widen (pen, matrix, FlatnessDefault);
900                 }               
901                 
902                 [MonoTODO ("GdipWidenPath isn't implemented in libgdiplus")]
903                 public void Widen (Pen pen, Matrix matrix, float flatness)
904                 {
905                         IntPtr p = (pen == null) ? IntPtr.Zero : pen.nativeObject;
906                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
907
908                         Status s = GDIPlus.GdipWidenPath (nativePath, p, m, flatness);
909
910                         GDIPlus.CheckStatus (s);
911                 } 
912         }
913 }