0da90f4e7de19161a8cc0174503a04c52edbe366
[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]
614                 public void AddString (string s, FontFamily family, int style,  float emSize,  Point origin,   StringFormat format)
615                 {
616                         throw new NotImplementedException ();
617                 }       
618                 
619                 [MonoTODO]
620                 public void AddString (string s,  FontFamily family,  int style,  float emSize,  PointF origin,   StringFormat format)
621                 {
622                         throw new NotImplementedException ();
623                 }       
624                 
625                 [MonoTODO]
626                 public void AddString (string s, FontFamily family, int style, float emSize,  Rectangle layoutRect, StringFormat format)
627                 {
628                         throw new NotImplementedException ();
629                 }       
630                 
631                 [MonoTODO]
632                 public void AddString (string s, FontFamily family, int style, float emSize,  RectangleF layoutRect,   StringFormat format)
633                 {
634                         throw new NotImplementedException ();
635                 }       
636                 
637                 public void ClearMarkers()               
638                 {
639                         Status s = GDIPlus.GdipClearPathMarkers (nativePath);
640
641                         GDIPlus.CheckStatus (s);
642                 }
643                 
644                 public void CloseAllFigures()
645                 {
646                         Status s = GDIPlus.GdipClosePathFigures (nativePath);
647
648                         GDIPlus.CheckStatus (s);
649                 }       
650                 
651                 public void CloseFigure()
652                 {
653                         Status s = GDIPlus.GdipClosePathFigure (nativePath);
654
655                         GDIPlus.CheckStatus (s);
656                 } 
657
658                 public void Flatten ()
659                 {
660                         Flatten (null, FlatnessDefault); 
661                 }       
662   
663                 public void Flatten (Matrix matrix)
664                 {
665                         Flatten (matrix, FlatnessDefault);
666                 }
667                 
668                 public void Flatten (Matrix matrix, float flatness)
669                 {
670                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
671                         Status status = GDIPlus.GdipFlattenPath (nativePath, m, flatness);
672
673                         GDIPlus.CheckStatus (status);
674                 }               
675                 
676                 public RectangleF GetBounds ()
677                 {
678                         return GetBounds (null, null);
679                 }               
680
681                 public RectangleF GetBounds (Matrix matrix)
682                 {
683                         return GetBounds (matrix, null);
684                 }
685
686                 [MonoTODO ("GdipGetPathWorldBounds doesn't support pens in libgdiplus (missing GdipWidenPath)")]
687                 public RectangleF GetBounds (Matrix matrix, Pen pen)
688                 {
689                         RectangleF retval;
690                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
691                         IntPtr p = (pen == null) ? IntPtr.Zero : pen.nativeObject;
692                         
693                         Status s = GDIPlus.GdipGetPathWorldBounds (nativePath, out retval, m, p);
694
695                         GDIPlus.CheckStatus (s);
696
697                         return retval;
698                 }
699
700                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
701                 public bool IsOutlineVisible (Point point, Pen pen)
702                 {
703                         return IsOutlineVisible (point.X, point.Y, pen, null);
704                 }               
705                 
706                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
707                 public bool IsOutlineVisible (PointF point, Pen pen)
708                 {
709                         return IsOutlineVisible (point.X, point.Y, pen, null);
710                 } 
711                 
712                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
713                 public bool IsOutlineVisible (int x, int y, Pen pen)
714                 {
715                         return IsOutlineVisible (x, y, pen, null);
716                 }
717
718                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
719                 public bool IsOutlineVisible (float x, float y, Pen pen)
720                 {
721                         return IsOutlineVisible (x, y, pen, null);
722                 }               
723                 
724                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
725                 public bool IsOutlineVisible (Point pt, Pen pen, Graphics graphics)
726                 {
727                         return IsOutlineVisible (pt.X, pt.Y, pen, graphics);
728                 }               
729                 
730                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
731                 public bool IsOutlineVisible (PointF pt, Pen pen, Graphics graphics)
732                 {
733                         return IsOutlineVisible (pt.X, pt.Y, pen, graphics);
734                 }               
735                                 
736                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
737                 public bool IsOutlineVisible (int x, int y, Pen pen, Graphics graphics)
738                 {
739                         bool result;
740                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
741                         
742                         Status s = GDIPlus.GdipIsOutlineVisiblePathPointI (nativePath, x, y, g, out result);
743                         GDIPlus.CheckStatus (s);
744
745                         return result;
746                 }               
747
748                 [MonoTODO ("GdipIsOutlineVisiblePathPoint[I] isn't implemented in libgdiplus")]
749                 public bool IsOutlineVisible (float x, float y, Pen pen, Graphics graphics)
750                 {
751                         bool result;
752                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
753                         
754                         Status s = GDIPlus.GdipIsOutlineVisiblePathPoint (nativePath, x, y, g, out result);
755                         GDIPlus.CheckStatus (s);
756
757                         return result;
758                 }               
759                 
760                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
761                 public bool IsVisible (Point point)
762                 {
763                         return IsVisible (point.X, point.Y, null);
764                 }               
765                 
766                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
767                 public bool IsVisible (PointF point)
768                 {
769                         return IsVisible (point.X, point.Y, null);
770                 }               
771                 
772                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
773                 public bool IsVisible (int x, int y)
774                 {
775                         return IsVisible (x, y, null);
776                 }
777
778                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
779                 public bool IsVisible (float x, float y)
780                 {
781                         return IsVisible (x, y, null);
782                 }                               
783                 
784                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
785                 public bool IsVisible (Point pt, Graphics graphics)
786                 {
787                         return IsVisible (pt.X, pt.Y, graphics);
788                 }               
789                 
790                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
791                 public bool IsVisible (PointF pt, Graphics graphics)
792                 {
793                         return IsVisible (pt.X, pt.Y, graphics);
794                 }               
795                                 
796                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
797                 public bool IsVisible (int x, int y, Graphics graphics)
798                 {
799                         bool retval;
800
801                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
802
803                         Status s = GDIPlus.GdipIsVisiblePathPointI (nativePath, x, y, g, out retval);
804
805                         GDIPlus.CheckStatus (s);
806
807                         return retval;
808                 }               
809                 
810                 [MonoTODO ("GdipIsVisiblePathPoint[I] isn't implemented in libgdiplus")]
811                 public bool IsVisible (float x, float y, Graphics graphics)
812                 {
813                         bool retval;
814
815                         IntPtr g = (graphics == null) ? IntPtr.Zero : graphics.nativeObject;
816
817                         Status s = GDIPlus.GdipIsVisiblePathPoint (nativePath, x, y, g, out retval);
818
819                         GDIPlus.CheckStatus (s);
820
821                         return retval;
822                 }               
823                 
824                 public void SetMarkers ()
825                 {
826                         Status s = GDIPlus.GdipSetPathMarker (nativePath);
827
828                         GDIPlus.CheckStatus (s);
829                 }
830                 
831                 public void StartFigure()
832                 {
833                         Status s = GDIPlus.GdipStartPathFigure (nativePath);
834
835                         GDIPlus.CheckStatus (s);
836                 }               
837                 
838                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
839                 public void Warp (PointF[] destPoints, RectangleF srcRect)
840                 {
841                         Warp (destPoints, srcRect, null, WarpMode.Perspective, FlatnessDefault);
842                 }               
843
844                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
845                 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix)
846                 {
847                         Warp (destPoints, srcRect, matrix, WarpMode.Perspective, FlatnessDefault);
848                 }               
849
850                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
851                 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix, WarpMode warpMode)
852                 {
853                         Warp (destPoints, srcRect, matrix, warpMode, FlatnessDefault);
854                 }               
855
856                 [MonoTODO ("GdipWarpPath isn't implemented in libgdiplus")]
857                 public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix,  WarpMode warpMode, float flatness)
858                 {
859                         if (destPoints == null)
860                                 throw new ArgumentNullException ("destPoints");
861
862                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
863
864                         Status s = GDIPlus.GdipWarpPath (nativePath, m, destPoints, destPoints.Length,
865                                         srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, warpMode, flatness);
866
867                         GDIPlus.CheckStatus (s);
868                 }
869                 
870                 [MonoTODO ("GdipWidenPath isn't implemented in libgdiplus")]
871                 public void Widen (Pen pen)
872                 {
873                         Widen (pen, null, FlatnessDefault);
874                 }               
875                 
876                 [MonoTODO ("GdipWidenPath isn't implemented in libgdiplus")]
877                 public void Widen (Pen pen, Matrix matrix)
878                 {       
879                         Widen (pen, matrix, FlatnessDefault);
880                 }               
881                 
882                 [MonoTODO ("GdipWidenPath isn't implemented in libgdiplus")]
883                 public void Widen (Pen pen, Matrix matrix, float flatness)
884                 {
885                         IntPtr p = (pen == null) ? IntPtr.Zero : pen.nativeObject;
886                         IntPtr m = (matrix == null) ? IntPtr.Zero : matrix.nativeMatrix;
887
888                         Status s = GDIPlus.GdipWidenPath (nativePath, p, m, flatness);
889
890                         GDIPlus.CheckStatus (s);
891                 } 
892         }
893 }