2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System.Drawing / System.Drawing / Region.cs
1 //
2 // System.Drawing.Region.cs
3 //
4 // Author:
5 //      Miguel de Icaza (miguel@ximian.com)
6 //      Jordi Mas i Hernandez (jordi@ximian.com)
7 //
8 // Copyright (C) 2003 Ximian, Inc. http://www.ximian.com
9 // Copyright (C) 2004 Novell, Inc. http://www.novell.com
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System;
32 using System.Drawing.Drawing2D;
33 using System.Runtime.InteropServices;
34
35 namespace System.Drawing
36 {
37         [ComVisible (false)]
38         public sealed class Region : MarshalByRefObject, IDisposable
39         {
40                 private IntPtr nativeRegion = IntPtr.Zero;
41                 
42                 public Region()
43                 {                  
44                         Status status = GDIPlus.GdipCreateRegion (out nativeRegion);
45                         GDIPlus.CheckStatus (status);
46                 }
47
48                 internal Region(IntPtr native)
49                 {
50                         nativeRegion = native; 
51                 }
52                 
53                 
54                 public Region (GraphicsPath path)
55                 {       
56                         Status status = GDIPlus.GdipCreateRegionPath (path.NativeObject, out nativeRegion);
57                         GDIPlus.CheckStatus (status);
58                 }
59
60                 public Region (Rectangle rect)                
61                 {
62                         Status status = GDIPlus.GdipCreateRegionRectI (ref rect, out nativeRegion);
63                         GDIPlus.CheckStatus (status);
64                 }
65
66                 public Region (RectangleF rect)
67                 {
68                         Status status = GDIPlus.GdipCreateRegionRect (ref rect, out nativeRegion);
69                         GDIPlus.CheckStatus (status);
70                 }
71
72                 [MonoTODO]
73                 public Region (RegionData region_data)
74                 {
75                         throw new NotImplementedException ();
76                 }
77                 
78                 //                                                                                                     
79                 // Union
80                 //
81
82                 public void Union (GraphicsPath path)
83                 {
84                         Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Union);
85                         GDIPlus.CheckStatus (status);                        
86                 }
87
88
89                 public void Union (Rectangle rect)
90                 {                                    
91                         Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Union);
92                         GDIPlus.CheckStatus (status);
93                 }
94
95                 public void Union (RectangleF rect)
96                 {
97                         Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Union);
98                         GDIPlus.CheckStatus (status);
99                 }
100
101                 public void Union (Region region)
102                 {
103                         Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Union);
104                         GDIPlus.CheckStatus (status);
105                 }                                                                                         
106
107                 
108                 //
109                 // Intersect
110                 //
111                 public void Intersect (GraphicsPath path)
112                 {
113                         Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Intersect);
114                         GDIPlus.CheckStatus (status);  
115                 }
116
117                 public void Intersect (Rectangle rect)
118                 {
119                         Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Intersect);
120                         GDIPlus.CheckStatus (status);
121                 }
122
123                 public void Intersect (RectangleF rect)
124                 {
125                         Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Intersect);
126                         GDIPlus.CheckStatus (status);
127                 }
128
129                 public void Intersect (Region region)
130                 {
131                         Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Intersect);
132                         GDIPlus.CheckStatus (status);
133                 }
134
135                 //
136                 // Complement
137                 //
138                 public void Complement (GraphicsPath path)
139                 {
140                         Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Complement);
141                         GDIPlus.CheckStatus (status);  
142                 }
143
144                 public void Complement (Rectangle rect)
145                 {
146                         Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Complement);
147                         GDIPlus.CheckStatus (status);
148                 }
149
150                 public void Complement (RectangleF rect)
151                 {
152                         Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Complement);
153                         GDIPlus.CheckStatus (status);
154                 }
155
156                 public void Complement (Region region)
157                 {
158                         Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Complement);
159                         GDIPlus.CheckStatus (status);
160                 }
161
162                 //
163                 // Exclude
164                 //
165                 public void Exclude (GraphicsPath path)
166                 {
167                         Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Exclude);
168                         GDIPlus.CheckStatus (status);                                                   
169                 }
170
171                 public void Exclude (Rectangle rect)
172                 {
173                         Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Exclude);
174                         GDIPlus.CheckStatus (status);
175                 }
176
177                 public void Exclude (RectangleF rect)
178                 {
179                         Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Exclude);
180                         GDIPlus.CheckStatus (status);
181                 }
182
183                 public void Exclude (Region region)
184                 {
185                         Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Exclude);
186                         GDIPlus.CheckStatus (status);
187                 }
188
189                 //
190                 // Xor
191                 //
192                 public void Xor (GraphicsPath path)
193                 {
194                         Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Xor);
195                         GDIPlus.CheckStatus (status);  
196                 }
197
198                 public void Xor (Rectangle rect)
199                 {
200                         Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Xor);
201                         GDIPlus.CheckStatus (status);
202                 }
203
204                 public void Xor (RectangleF rect)
205                 {
206                         Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Xor);
207                         GDIPlus.CheckStatus (status);
208                 }
209
210                 public void Xor (Region region)
211                 {
212                         Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Xor);
213                         GDIPlus.CheckStatus (status); 
214                 }
215
216                 //
217                 // GetBounds
218                 //
219                 public RectangleF GetBounds (Graphics graphics)
220                 {
221                         RectangleF rect = new Rectangle();
222                         
223                         Status status = GDIPlus.GdipGetRegionBounds (nativeRegion, graphics.NativeObject, ref rect);
224                         GDIPlus.CheckStatus (status);
225
226                         return rect;
227                 }
228
229                 //
230                 // Translate
231                 //
232                 public void Translate (int dx, int dy)
233                 {
234                         Status status = GDIPlus.GdipTranslateRegionI (nativeRegion, dx, dy);
235                         GDIPlus.CheckStatus (status);   
236                 }
237
238                 public void Translate (float dx, float dy)
239                 {
240                         Status status = GDIPlus.GdipTranslateRegion (nativeRegion, dx, dy);
241                         GDIPlus.CheckStatus (status);
242                 }
243
244                 //
245                 // IsVisible
246                 //
247                 public bool IsVisible (int x, int y, Graphics g)
248                 {
249                         bool result;
250                         
251                         Status status = GDIPlus.GdipIsVisibleRegionPointI (nativeRegion, x, y, g.NativeObject, out result);
252                         GDIPlus.CheckStatus (status);
253
254                         return result;
255                 }
256
257                 public bool IsVisible (int x, int y, int width, int height)
258                 {
259                         bool result;
260
261                         Status status = GDIPlus.GdipIsVisibleRegionRectI (nativeRegion, x, y,
262                                 width, height, IntPtr.Zero, out result);
263
264                         GDIPlus.CheckStatus (status);
265
266                         return result;
267                 }
268
269                 public bool IsVisible (int x, int y, int width, int height, Graphics g)
270                 {
271                         bool result;
272
273                         Status status = GDIPlus.GdipIsVisibleRegionRectI (nativeRegion, x, y,
274                                 width, height, g.NativeObject, out result);
275
276                         GDIPlus.CheckStatus (status);
277
278                         return result;
279                 }
280
281                 public bool IsVisible (Point point)
282                 {
283                         bool result;
284
285                         Status status = GDIPlus.GdipIsVisibleRegionPointI (nativeRegion, point.X, point.Y,
286                                 IntPtr.Zero, out result);
287                                 
288                         GDIPlus.CheckStatus (status);
289
290                         return result;
291                 }
292
293                 public bool IsVisible (PointF point)
294                 {
295                        bool result;
296
297                         Status status = GDIPlus.GdipIsVisibleRegionPoint (nativeRegion, point.X, point.Y,
298                                 IntPtr.Zero, out result);
299
300                         GDIPlus.CheckStatus (status);
301
302                         return result;
303                 }
304
305                 public bool IsVisible (Point point, Graphics g)
306                 {
307                         bool result;
308
309                         Status status = GDIPlus.GdipIsVisibleRegionPointI (nativeRegion, point.X, point.Y,
310                                 g.NativeObject, out result);
311
312                         GDIPlus.CheckStatus (status);
313
314                         return result;                                                      
315                 }
316
317                 public bool IsVisible (PointF point, Graphics g)
318                 {
319                         bool result;
320
321                         Status status = GDIPlus.GdipIsVisibleRegionPoint (nativeRegion, point.X, point.Y,
322                                 g.NativeObject, out result);
323
324                         GDIPlus.CheckStatus (status);
325
326                         return result;
327                 }
328
329                 public bool IsVisible (Rectangle rect)
330                 {
331                         bool result;
332
333                         Status status = GDIPlus.GdipIsVisibleRegionRectI (nativeRegion, rect.X, rect.Y,
334                                 rect.Width, rect.Height, IntPtr.Zero, out result);
335
336                         GDIPlus.CheckStatus (status);
337
338                         return result;
339                 }
340
341                 public bool IsVisible (RectangleF rect)
342                 {
343                         bool result;
344
345                         Status status = GDIPlus.GdipIsVisibleRegionRect (nativeRegion, rect.X, rect.Y,
346                                 rect.Width, rect.Height, IntPtr.Zero, out result);
347
348                         GDIPlus.CheckStatus (status);
349
350                         return result;
351                 }
352
353                 public bool IsVisible (Rectangle rect, Graphics g)
354                 {
355                         bool result;
356
357                         Status status = GDIPlus.GdipIsVisibleRegionRectI (nativeRegion, rect.X, rect.Y,
358                                 rect.Width, rect.Height, g.NativeObject, out result);
359                         
360                         GDIPlus.CheckStatus (status);
361
362                         return result;
363                 }
364
365                 public bool IsVisible (RectangleF rect, Graphics g)
366                 {
367                       bool result;
368
369                         Status status = GDIPlus.GdipIsVisibleRegionRect (nativeRegion, rect.X, rect.Y,
370                                 rect.Width, rect.Height, g.NativeObject, out result);
371                                 
372                         GDIPlus.CheckStatus (status);
373
374                         return result;
375                 }
376
377                 public bool IsVisible (float x, float y)
378                 {
379                         bool result;
380
381                         Status status = GDIPlus.GdipIsVisibleRegionPoint (nativeRegion, x, y, IntPtr.Zero, out result);
382                         GDIPlus.CheckStatus (status);
383
384                         return result;
385                 }
386
387                 public bool IsVisible (float x, float y, Graphics g)
388                 {
389                         bool result;
390
391                         Status status = GDIPlus.GdipIsVisibleRegionPoint (nativeRegion, x, y, g.NativeObject, out result);
392                         GDIPlus.CheckStatus (status);
393
394                         return result;
395                 }
396
397                 public bool IsVisible (float x, float y, float width, float height)
398                 {
399                         bool result;
400                         
401                         Status status = GDIPlus.GdipIsVisibleRegionRect (nativeRegion, x, y, width, height, IntPtr.Zero, out result);
402                         GDIPlus.CheckStatus (status);
403
404                         return result;
405                 }
406
407                 public bool IsVisible (float x, float y, float width, float height, Graphics g) 
408                 {
409                         bool result;
410
411                         Status status = GDIPlus.GdipIsVisibleRegionRect (nativeRegion, x, y, width, height, g.NativeObject, out result);
412                         GDIPlus.CheckStatus (status);
413
414                         return result;
415                 }
416
417
418                 //
419                 // Miscellaneous
420                 //
421
422                 public bool IsEmpty(Graphics g)
423                 {
424                         bool result;               
425
426                         Status status = GDIPlus.GdipIsEmptyRegion (nativeRegion, g.NativeObject, out result);
427                         GDIPlus.CheckStatus (status);
428
429                         return result;                        
430                 }
431
432                 public bool IsInfinite(Graphics g)
433                 {
434                         bool result;
435
436                         Status status = GDIPlus.GdipIsInfiniteRegion (nativeRegion, g.NativeObject, out result);
437                         GDIPlus.CheckStatus (status);
438
439                         return result;  
440                 }
441
442                 public void MakeEmpty()
443                 {
444                         Status status = GDIPlus.GdipSetEmpty (nativeRegion);
445                         GDIPlus.CheckStatus (status);               
446                 }
447
448                 public void MakeInfinite()
449                 {
450                         Status status = GDIPlus.GdipSetInfinite (nativeRegion);
451                         GDIPlus.CheckStatus (status);                      
452                 }
453                 
454                 public bool Equals(Region region, Graphics g)
455                 {
456                         bool result;
457                         
458                         Status status = GDIPlus.GdipIsEqualRegion (nativeRegion, region.NativeObject,
459                            g.NativeObject, out result);                                   
460                            
461                         GDIPlus.CheckStatus (status);                      
462                         
463                         return result;                  
464                 }
465                 
466                 
467                 public static Region FromHrgn(IntPtr hrgn)
468                 {
469                         return new Region (hrgn);
470                 }
471                 
472                 
473                 public IntPtr GetHrgn(Graphics g)
474                 {
475                         return nativeRegion;
476                 }
477                 
478                 
479                 public RegionData GetRegionData()
480                 {
481                         int size, filled;                       
482                         
483                         Status status = GDIPlus.GdipGetRegionDataSize (nativeRegion, out size);                  
484                         GDIPlus.CheckStatus (status);                      
485                         
486                         byte[] buff = new byte [size];                  
487                         
488                         status = GDIPlus.GdipGetRegionData (nativeRegion, buff, size, out filled);
489                         GDIPlus.CheckStatus (status);                      
490                         
491                         RegionData rgndata = new RegionData();
492                         rgndata.Data = buff;
493                         
494                         return rgndata;
495                 }
496                 
497                 
498                 public RectangleF[] GetRegionScans(Matrix matrix)
499                 {
500                         int cnt;                        
501                         
502                         Status status = GDIPlus.GdipGetRegionScansCount (nativeRegion, out cnt, matrix.NativeObject);                  
503                         GDIPlus.CheckStatus (status);                                 
504                         
505                         if (cnt == 0)
506                                 return new RectangleF[0];
507                                                 
508                         RectangleF[] rects = new RectangleF [cnt];                                      
509                         int size = Marshal.SizeOf (rects[0]);                  
510                         
511                         IntPtr dest = Marshal.AllocHGlobal (size * cnt);                        
512                         
513                         status = GDIPlus.GdipGetRegionScans (nativeRegion, dest, out cnt, matrix.NativeObject);
514                         GDIPlus.CheckStatus (status);                   
515                         
516                         GDIPlus.FromUnManagedMemoryToRectangles (dest, rects);                  
517                         return rects;                   
518                 }               
519                 
520                 public void Transform(Matrix matrix)
521                 {
522                         Status status = GDIPlus.GdipTransformRegion (nativeRegion, matrix.NativeObject);
523                         GDIPlus.CheckStatus (status);                                                   
524                 }               
525                 
526                 public Region Clone()
527                 {
528                         IntPtr cloned;
529                                 
530                         Status status = GDIPlus.GdipCloneRegion (nativeRegion, out cloned);
531                         GDIPlus.CheckStatus (status);
532                                 
533                         return new Region (cloned); 
534                 }
535
536                 public void Dispose ()
537                 {
538                         Dispose (true);
539                         System.GC.SuppressFinalize (this);
540                 }
541
542                 void Dispose (bool disposing)
543                 {
544                         if (disposing) {
545                                 GDIPlus.GdipDeleteRegion (nativeRegion);
546                                 nativeRegion = IntPtr.Zero;
547                         }
548                 }
549
550                 ~Region ()
551                 {
552                         Dispose (false);
553                 }
554
555                 internal IntPtr NativeObject
556                 {
557                         get{
558                                 return nativeRegion;
559                         }
560                         set     {
561                                 nativeRegion = value;
562                         }
563                 }
564
565         
566         }
567 }