fix typo
[mcs.git] / class / System.Drawing / System.Drawing / Region.cs
blobd22370566f51f3e499c11bf08127fb9f88c9389e
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,2006 Novell, Inc. http://www.novell.com
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.
31 using System.Drawing.Drawing2D;
32 using System.Runtime.InteropServices;
33 using System.Security.Permissions;
35 namespace System.Drawing
37 #if !NET_2_0
38 [ComVisible (false)]
39 #endif
40 public sealed class Region : MarshalByRefObject, IDisposable
42 private IntPtr nativeRegion = IntPtr.Zero;
44 public Region()
46 Status status = GDIPlus.GdipCreateRegion (out nativeRegion);
47 GDIPlus.CheckStatus (status);
50 internal Region(IntPtr native)
52 nativeRegion = native;
55 public Region (GraphicsPath path)
57 if (path == null)
58 throw new ArgumentNullException ("path");
59 Status status = GDIPlus.GdipCreateRegionPath (path.NativeObject, out nativeRegion);
60 GDIPlus.CheckStatus (status);
63 public Region (Rectangle rect)
65 Status status = GDIPlus.GdipCreateRegionRectI (ref rect, out nativeRegion);
66 GDIPlus.CheckStatus (status);
69 public Region (RectangleF rect)
71 Status status = GDIPlus.GdipCreateRegionRect (ref rect, out nativeRegion);
72 GDIPlus.CheckStatus (status);
75 public Region (RegionData rgnData)
77 if (rgnData == null)
78 throw new ArgumentNullException ("rgnData");
79 // a NullReferenceException can be throw for rgnData.Data.Length (if rgnData.Data is null) just like MS
80 if (rgnData.Data.Length == 0)
81 throw new ArgumentException ("rgnData");
82 Status status = GDIPlus.GdipCreateRegionRgnData (rgnData.Data, rgnData.Data.Length, out nativeRegion);
83 GDIPlus.CheckStatus (status);
86 //
87 // Union
90 public void Union (GraphicsPath path)
92 if (path == null)
93 throw new ArgumentNullException ("path");
94 Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Union);
95 GDIPlus.CheckStatus (status);
99 public void Union (Rectangle rect)
101 Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Union);
102 GDIPlus.CheckStatus (status);
105 public void Union (RectangleF rect)
107 Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Union);
108 GDIPlus.CheckStatus (status);
111 public void Union (Region region)
113 if (region == null)
114 throw new ArgumentNullException ("region");
115 Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Union);
116 GDIPlus.CheckStatus (status);
121 // Intersect
123 public void Intersect (GraphicsPath path)
125 if (path == null)
126 throw new ArgumentNullException ("path");
127 Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Intersect);
128 GDIPlus.CheckStatus (status);
131 public void Intersect (Rectangle rect)
133 Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Intersect);
134 GDIPlus.CheckStatus (status);
137 public void Intersect (RectangleF rect)
139 Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Intersect);
140 GDIPlus.CheckStatus (status);
143 public void Intersect (Region region)
145 if (region == null)
146 throw new ArgumentNullException ("region");
147 Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Intersect);
148 GDIPlus.CheckStatus (status);
152 // Complement
154 public void Complement (GraphicsPath path)
156 if (path == null)
157 throw new ArgumentNullException ("path");
158 Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Complement);
159 GDIPlus.CheckStatus (status);
162 public void Complement (Rectangle rect)
164 Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Complement);
165 GDIPlus.CheckStatus (status);
168 public void Complement (RectangleF rect)
170 Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Complement);
171 GDIPlus.CheckStatus (status);
174 public void Complement (Region region)
176 if (region == null)
177 throw new ArgumentNullException ("region");
178 Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Complement);
179 GDIPlus.CheckStatus (status);
183 // Exclude
185 public void Exclude (GraphicsPath path)
187 if (path == null)
188 throw new ArgumentNullException ("path");
189 Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Exclude);
190 GDIPlus.CheckStatus (status);
193 public void Exclude (Rectangle rect)
195 Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Exclude);
196 GDIPlus.CheckStatus (status);
199 public void Exclude (RectangleF rect)
201 Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Exclude);
202 GDIPlus.CheckStatus (status);
205 public void Exclude (Region region)
207 if (region == null)
208 throw new ArgumentNullException ("region");
209 Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Exclude);
210 GDIPlus.CheckStatus (status);
214 // Xor
216 public void Xor (GraphicsPath path)
218 if (path == null)
219 throw new ArgumentNullException ("path");
220 Status status = GDIPlus.GdipCombineRegionPath (nativeRegion, path.NativeObject, CombineMode.Xor);
221 GDIPlus.CheckStatus (status);
224 public void Xor (Rectangle rect)
226 Status status = GDIPlus.GdipCombineRegionRectI (nativeRegion, ref rect, CombineMode.Xor);
227 GDIPlus.CheckStatus (status);
230 public void Xor (RectangleF rect)
232 Status status = GDIPlus.GdipCombineRegionRect (nativeRegion, ref rect, CombineMode.Xor);
233 GDIPlus.CheckStatus (status);
236 public void Xor (Region region)
238 if (region == null)
239 throw new ArgumentNullException ("region");
240 Status status = GDIPlus.GdipCombineRegionRegion (nativeRegion, region.NativeObject, CombineMode.Xor);
241 GDIPlus.CheckStatus (status);
245 // GetBounds
247 public RectangleF GetBounds (Graphics g)
249 if (g == null)
250 throw new ArgumentNullException ("g");
252 RectangleF rect = new Rectangle();
254 Status status = GDIPlus.GdipGetRegionBounds (nativeRegion, g.NativeObject, ref rect);
255 GDIPlus.CheckStatus (status);
257 return rect;
261 // Translate
263 public void Translate (int dx, int dy)
265 Status status = GDIPlus.GdipTranslateRegionI (nativeRegion, dx, dy);
266 GDIPlus.CheckStatus (status);
269 public void Translate (float dx, float dy)
271 Status status = GDIPlus.GdipTranslateRegion (nativeRegion, dx, dy);
272 GDIPlus.CheckStatus (status);
276 // IsVisible
278 public bool IsVisible (int x, int y, Graphics g)
280 IntPtr ptr = (g == null) ? IntPtr.Zero : g.NativeObject;
281 bool result;
283 Status status = GDIPlus.GdipIsVisibleRegionPointI (nativeRegion, x, y, ptr, out result);
284 GDIPlus.CheckStatus (status);
286 return result;
289 public bool IsVisible (int x, int y, int width, int height)
291 bool result;
293 Status status = GDIPlus.GdipIsVisibleRegionRectI (nativeRegion, x, y,
294 width, height, IntPtr.Zero, out result);
296 GDIPlus.CheckStatus (status);
298 return result;
301 public bool IsVisible (int x, int y, int width, int height, Graphics g)
303 IntPtr ptr = (g == null) ? IntPtr.Zero : g.NativeObject;
304 bool result;
306 Status status = GDIPlus.GdipIsVisibleRegionRectI (nativeRegion, x, y,
307 width, height, ptr, out result);
309 GDIPlus.CheckStatus (status);
311 return result;
314 public bool IsVisible (Point point)
316 bool result;
318 Status status = GDIPlus.GdipIsVisibleRegionPointI (nativeRegion, point.X, point.Y,
319 IntPtr.Zero, out result);
321 GDIPlus.CheckStatus (status);
323 return result;
326 public bool IsVisible (PointF point)
328 bool result;
330 Status status = GDIPlus.GdipIsVisibleRegionPoint (nativeRegion, point.X, point.Y,
331 IntPtr.Zero, out result);
333 GDIPlus.CheckStatus (status);
335 return result;
338 public bool IsVisible (Point point, Graphics g)
340 IntPtr ptr = (g == null) ? IntPtr.Zero : g.NativeObject;
341 bool result;
343 Status status = GDIPlus.GdipIsVisibleRegionPointI (nativeRegion, point.X, point.Y,
344 ptr, out result);
346 GDIPlus.CheckStatus (status);
348 return result;
351 public bool IsVisible (PointF point, Graphics g)
353 IntPtr ptr = (g == null) ? IntPtr.Zero : g.NativeObject;
354 bool result;
356 Status status = GDIPlus.GdipIsVisibleRegionPoint (nativeRegion, point.X, point.Y,
357 ptr, out result);
359 GDIPlus.CheckStatus (status);
361 return result;
364 public bool IsVisible (Rectangle rect)
366 bool result;
368 Status status = GDIPlus.GdipIsVisibleRegionRectI (nativeRegion, rect.X, rect.Y,
369 rect.Width, rect.Height, IntPtr.Zero, out result);
371 GDIPlus.CheckStatus (status);
373 return result;
376 public bool IsVisible (RectangleF rect)
378 bool result;
380 Status status = GDIPlus.GdipIsVisibleRegionRect (nativeRegion, rect.X, rect.Y,
381 rect.Width, rect.Height, IntPtr.Zero, out result);
383 GDIPlus.CheckStatus (status);
385 return result;
388 public bool IsVisible (Rectangle rect, Graphics g)
390 IntPtr ptr = (g == null) ? IntPtr.Zero : g.NativeObject;
391 bool result;
393 Status status = GDIPlus.GdipIsVisibleRegionRectI (nativeRegion, rect.X, rect.Y,
394 rect.Width, rect.Height, ptr, out result);
396 GDIPlus.CheckStatus (status);
398 return result;
401 public bool IsVisible (RectangleF rect, Graphics g)
403 IntPtr ptr = (g == null) ? IntPtr.Zero : g.NativeObject;
404 bool result;
406 Status status = GDIPlus.GdipIsVisibleRegionRect (nativeRegion, rect.X, rect.Y,
407 rect.Width, rect.Height, ptr, out result);
409 GDIPlus.CheckStatus (status);
411 return result;
414 public bool IsVisible (float x, float y)
416 bool result;
418 Status status = GDIPlus.GdipIsVisibleRegionPoint (nativeRegion, x, y, IntPtr.Zero, out result);
419 GDIPlus.CheckStatus (status);
421 return result;
424 public bool IsVisible (float x, float y, Graphics g)
426 IntPtr ptr = (g == null) ? IntPtr.Zero : g.NativeObject;
427 bool result;
429 Status status = GDIPlus.GdipIsVisibleRegionPoint (nativeRegion, x, y, ptr, out result);
430 GDIPlus.CheckStatus (status);
432 return result;
435 public bool IsVisible (float x, float y, float width, float height)
437 bool result;
439 Status status = GDIPlus.GdipIsVisibleRegionRect (nativeRegion, x, y, width, height, IntPtr.Zero, out result);
440 GDIPlus.CheckStatus (status);
442 return result;
445 public bool IsVisible (float x, float y, float width, float height, Graphics g)
447 IntPtr ptr = (g == null) ? IntPtr.Zero : g.NativeObject;
448 bool result;
450 Status status = GDIPlus.GdipIsVisibleRegionRect (nativeRegion, x, y, width, height, ptr, out result);
451 GDIPlus.CheckStatus (status);
453 return result;
458 // Miscellaneous
461 public bool IsEmpty(Graphics g)
463 if (g == null)
464 throw new ArgumentNullException ("g");
466 bool result;
468 Status status = GDIPlus.GdipIsEmptyRegion (nativeRegion, g.NativeObject, out result);
469 GDIPlus.CheckStatus (status);
471 return result;
474 public bool IsInfinite(Graphics g)
476 if (g == null)
477 throw new ArgumentNullException ("g");
479 bool result;
481 Status status = GDIPlus.GdipIsInfiniteRegion (nativeRegion, g.NativeObject, out result);
482 GDIPlus.CheckStatus (status);
484 return result;
487 public void MakeEmpty()
489 Status status = GDIPlus.GdipSetEmpty (nativeRegion);
490 GDIPlus.CheckStatus (status);
493 public void MakeInfinite()
495 Status status = GDIPlus.GdipSetInfinite (nativeRegion);
496 GDIPlus.CheckStatus (status);
499 public bool Equals(Region region, Graphics g)
501 if (region == null)
502 throw new ArgumentNullException ("region");
503 if (g == null)
504 throw new ArgumentNullException ("g");
506 bool result;
508 Status status = GDIPlus.GdipIsEqualRegion (nativeRegion, region.NativeObject,
509 g.NativeObject, out result);
511 GDIPlus.CheckStatus (status);
513 return result;
516 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
517 public static Region FromHrgn (IntPtr hrgn)
519 if (hrgn == IntPtr.Zero)
520 throw new ArgumentException ("hrgn");
522 IntPtr handle;
523 Status status = GDIPlus.GdipCreateRegionHrgn (hrgn, out handle);
524 GDIPlus.CheckStatus (status);
526 return new Region (handle);
530 public IntPtr GetHrgn (Graphics g)
532 // Our WindowsForms implementation uses null to avoid
533 // creating a Graphics context when not needed
534 #if false
535 // this is MS behaviour
536 if (g == null)
537 throw new ArgumentNullException ("g");
538 #else
539 // this is an hack for MWF (libgdiplus would reject that)
540 if (g == null)
541 return nativeRegion;
542 #endif
543 IntPtr handle = IntPtr.Zero;
544 Status status = GDIPlus.GdipGetRegionHRgn (nativeRegion, g.NativeObject, ref handle);
545 GDIPlus.CheckStatus (status);
546 return handle;
550 public RegionData GetRegionData()
552 int size, filled;
554 Status status = GDIPlus.GdipGetRegionDataSize (nativeRegion, out size);
555 GDIPlus.CheckStatus (status);
557 byte[] buff = new byte [size];
559 status = GDIPlus.GdipGetRegionData (nativeRegion, buff, size, out filled);
560 GDIPlus.CheckStatus (status);
562 RegionData rgndata = new RegionData();
563 rgndata.Data = buff;
565 return rgndata;
569 public RectangleF[] GetRegionScans(Matrix matrix)
571 if (matrix == null)
572 throw new ArgumentNullException ("matrix");
574 int cnt;
576 Status status = GDIPlus.GdipGetRegionScansCount (nativeRegion, out cnt, matrix.NativeObject);
577 GDIPlus.CheckStatus (status);
579 if (cnt == 0)
580 return new RectangleF[0];
582 RectangleF[] rects = new RectangleF [cnt];
583 int size = Marshal.SizeOf (rects[0]);
585 IntPtr dest = Marshal.AllocHGlobal (size * cnt);
586 try {
587 status = GDIPlus.GdipGetRegionScans (nativeRegion, dest, out cnt, matrix.NativeObject);
588 GDIPlus.CheckStatus (status);
590 finally {
591 // note: Marshal.FreeHGlobal is called from GDIPlus.FromUnManagedMemoryToRectangles
592 GDIPlus.FromUnManagedMemoryToRectangles (dest, rects);
594 return rects;
597 public void Transform(Matrix matrix)
599 if (matrix == null)
600 throw new ArgumentNullException ("matrix");
602 Status status = GDIPlus.GdipTransformRegion (nativeRegion, matrix.NativeObject);
603 GDIPlus.CheckStatus (status);
606 public Region Clone()
608 IntPtr cloned;
610 Status status = GDIPlus.GdipCloneRegion (nativeRegion, out cloned);
611 GDIPlus.CheckStatus (status);
613 return new Region (cloned);
616 public void Dispose ()
618 DisposeHandle ();
619 System.GC.SuppressFinalize (this);
622 private void DisposeHandle ()
624 if (nativeRegion != IntPtr.Zero) {
625 GDIPlus.GdipDeleteRegion (nativeRegion);
626 nativeRegion = IntPtr.Zero;
630 ~Region ()
632 DisposeHandle ();
635 internal IntPtr NativeObject
637 get{
638 return nativeRegion;
640 set {
641 nativeRegion = value;
644 #if NET_2_0
645 // why is this a instance method ? and not static ?
646 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
647 public void ReleaseHrgn (IntPtr regionHandle)
649 if (regionHandle == IntPtr.Zero)
650 throw new ArgumentNullException ("regionHandle");
652 Status status = Status.Ok;
653 if (GDIPlus.RunningOnUnix ()) {
654 // for libgdiplus HRGN == GpRegion*
655 status = GDIPlus.GdipDeleteRegion (regionHandle);
656 } else {
657 // ... but on Windows HRGN are (old) GDI objects
658 if (!GDIPlus.DeleteObject (regionHandle))
659 status = Status.InvalidParameter;
661 GDIPlus.CheckStatus (status);
663 #endif