[System.Drawing] Add ifdefs to source code used by Xamarin.iOS/Mac to make it compile...
[mono.git] / mcs / class / System.Drawing / System.Drawing / Rectangle.cs
1 //
2 // System.Drawing.Rectangle.cs
3 //
4 // Author:
5 //   Mike Kestner (mkestner@speakeasy.net)
6 //
7 // Copyright (C) 2001 Mike Kestner
8 // Copyright (C) 2004 Novell, Inc.  http://www.novell.com 
9 //
10
11 //
12 // Copyright (C) 2004 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;
35 using System.Runtime.InteropServices;
36 using System.ComponentModel;
37
38 namespace System.Drawing
39 {
40         [Serializable]
41         [ComVisible (true)]
42 #if !MONOTOUCH && !MONOMAC
43         [TypeConverter (typeof (RectangleConverter))]
44 #endif
45         public struct Rectangle
46         {
47                 private int x, y, width, height;
48
49                 /// <summary>
50                 ///     Empty Shared Field
51                 /// </summary>
52                 ///
53                 /// <remarks>
54                 ///     An uninitialized Rectangle Structure.
55                 /// </remarks>
56                 
57                 public static readonly Rectangle Empty;
58
59
60                 /// <summary>
61                 ///     Ceiling Shared Method
62                 /// </summary>
63                 ///
64                 /// <remarks>
65                 ///     Produces a Rectangle structure from a RectangleF 
66                 ///     structure by taking the ceiling of the X, Y, Width,
67                 ///     and Height properties.
68                 /// </remarks>
69                 
70                 public static Rectangle Ceiling (RectangleF value)
71                 {
72                         int x, y, w, h;
73                         checked {
74                                 x = (int) Math.Ceiling (value.X);
75                                 y = (int) Math.Ceiling (value.Y);
76                                 w = (int) Math.Ceiling (value.Width);
77                                 h = (int) Math.Ceiling (value.Height);
78                         }
79
80                         return new Rectangle (x, y, w, h);
81                 }
82
83                 /// <summary>
84                 ///     FromLTRB Shared Method
85                 /// </summary>
86                 ///
87                 /// <remarks>
88                 ///     Produces a Rectangle structure from left, top, right,
89                 ///     and bottom coordinates.
90                 /// </remarks>
91                 
92                 public static Rectangle FromLTRB (int left, int top,
93                                                   int right, int bottom)
94                 {
95                         return new Rectangle (left, top, right - left,
96                                               bottom - top);
97                 }
98
99                 /// <summary>
100                 ///     Inflate Shared Method
101                 /// </summary>
102                 ///
103                 /// <remarks>
104                 ///     Produces a new Rectangle by inflating an existing 
105                 ///     Rectangle by the specified coordinate values.
106                 /// </remarks>
107                 
108                 public static Rectangle Inflate (Rectangle rect, int x, int y)
109                 {
110                         Rectangle r = new Rectangle (rect.Location, rect.Size);
111                         r.Inflate (x, y);
112                         return r;
113                 }
114
115                 /// <summary>
116                 ///     Inflate Method
117                 /// </summary>
118                 ///
119                 /// <remarks>
120                 ///     Inflates the Rectangle by a specified width and height.
121                 /// </remarks>
122                 
123                 public void Inflate (int width, int height)
124                 {
125                         Inflate (new Size (width, height));
126                 }
127
128                 /// <summary>
129                 ///     Inflate Method
130                 /// </summary>
131                 ///
132                 /// <remarks>
133                 ///     Inflates the Rectangle by a specified Size.
134                 /// </remarks>
135                 
136                 public void Inflate (Size size)
137                 {
138                         x -= size.Width;
139                         y -= size.Height;
140                         Width += size.Width * 2;
141                         Height += size.Height * 2;
142                 }
143
144                 /// <summary>
145                 ///     Intersect Shared Method
146                 /// </summary>
147                 ///
148                 /// <remarks>
149                 ///     Produces a new Rectangle by intersecting 2 existing 
150                 ///     Rectangles. Returns null if there is no intersection.
151                 /// </remarks>
152                 
153                 public static Rectangle Intersect (Rectangle a, Rectangle b)
154                 {
155                         // MS.NET returns a non-empty rectangle if the two rectangles
156                         // touch each other
157                         if (!a.IntersectsWithInclusive (b))
158                                 return Empty;
159
160                         return Rectangle.FromLTRB (
161                                 Math.Max (a.Left, b.Left),
162                                 Math.Max (a.Top, b.Top),
163                                 Math.Min (a.Right, b.Right),
164                                 Math.Min (a.Bottom, b.Bottom));
165                 }
166
167                 /// <summary>
168                 ///     Intersect Method
169                 /// </summary>
170                 ///
171                 /// <remarks>
172                 ///     Replaces the Rectangle with the intersection of itself
173                 ///     and another Rectangle.
174                 /// </remarks>
175                 
176                 public void Intersect (Rectangle rect)
177                 {
178                         this = Rectangle.Intersect (this, rect);
179                 }
180
181                 /// <summary>
182                 ///     Round Shared Method
183                 /// </summary>
184                 ///
185                 /// <remarks>
186                 ///     Produces a Rectangle structure from a RectangleF by
187                 ///     rounding the X, Y, Width, and Height properties.
188                 /// </remarks>
189                 
190                 public static Rectangle Round (RectangleF value)
191                 {
192                         int x, y, w, h;
193                         checked {
194                                 x = (int) Math.Round (value.X);
195                                 y = (int) Math.Round (value.Y);
196                                 w = (int) Math.Round (value.Width);
197                                 h = (int) Math.Round (value.Height);
198                         }
199
200                         return new Rectangle (x, y, w, h);
201                 }
202
203                 /// <summary>
204                 ///     Truncate Shared Method
205                 /// </summary>
206                 ///
207                 /// <remarks>
208                 ///     Produces a Rectangle structure from a RectangleF by
209                 ///     truncating the X, Y, Width, and Height properties.
210                 /// </remarks>
211                 
212                 // LAMESPEC: Should this be floor, or a pure cast to int?
213
214                 public static Rectangle Truncate (RectangleF value)
215                 {
216                         int x, y, w, h;
217                         checked {
218                                 x = (int) value.X;
219                                 y = (int) value.Y;
220                                 w = (int) value.Width;
221                                 h = (int) value.Height;
222                         }
223
224                         return new Rectangle (x, y, w, h);
225                 }
226
227                 /// <summary>
228                 ///     Union Shared Method
229                 /// </summary>
230                 ///
231                 /// <remarks>
232                 ///     Produces a new Rectangle from the union of 2 existing 
233                 ///     Rectangles.
234                 /// </remarks>
235                 
236                 public static Rectangle Union (Rectangle a, Rectangle b)
237                 {
238                         return FromLTRB (Math.Min (a.Left, b.Left),
239                                          Math.Min (a.Top, b.Top),
240                                          Math.Max (a.Right, b.Right),
241                                          Math.Max (a.Bottom, b.Bottom));
242                 }
243
244                 /// <summary>
245                 ///     Equality Operator
246                 /// </summary>
247                 ///
248                 /// <remarks>
249                 ///     Compares two Rectangle objects. The return value is
250                 ///     based on the equivalence of the Location and Size 
251                 ///     properties of the two Rectangles.
252                 /// </remarks>
253
254                 public static bool operator == (Rectangle left, Rectangle right)
255                 {
256                         return ((left.Location == right.Location) && 
257                                 (left.Size == right.Size));
258                 }
259                 
260                 /// <summary>
261                 ///     Inequality Operator
262                 /// </summary>
263                 ///
264                 /// <remarks>
265                 ///     Compares two Rectangle objects. The return value is
266                 ///     based on the equivalence of the Location and Size 
267                 ///     properties of the two Rectangles.
268                 /// </remarks>
269
270                 public static bool operator != (Rectangle left, Rectangle right)
271                 {
272                         return ((left.Location != right.Location) || 
273                                 (left.Size != right.Size));
274                 }
275                 
276
277                 // -----------------------
278                 // Public Constructors
279                 // -----------------------
280
281                 /// <summary>
282                 ///     Rectangle Constructor
283                 /// </summary>
284                 ///
285                 /// <remarks>
286                 ///     Creates a Rectangle from Point and Size values.
287                 /// </remarks>
288                 
289                 public Rectangle (Point location, Size size)
290                 {
291                         x = location.X;
292                         y = location.Y;
293                         width = size.Width;
294                         height = size.Height;
295                 }
296
297                 /// <summary>
298                 ///     Rectangle Constructor
299                 /// </summary>
300                 ///
301                 /// <remarks>
302                 ///     Creates a Rectangle from a specified x,y location and
303                 ///     width and height values.
304                 /// </remarks>
305                 
306                 public Rectangle (int x, int y, int width, int height)
307                 {
308                         this.x = x;
309                         this.y = y;
310                         this.width = width;
311                         this.height = height;
312                 }
313
314
315
316                 /// <summary>
317                 ///     Bottom Property
318                 /// </summary>
319                 ///
320                 /// <remarks>
321                 ///     The Y coordinate of the bottom edge of the Rectangle.
322                 ///     Read only.
323                 /// </remarks>
324                 
325                 [Browsable (false)]
326                 public int Bottom {
327                         get {
328                                 return y + height;
329                         }
330                 }
331
332                 /// <summary>
333                 ///     Height Property
334                 /// </summary>
335                 ///
336                 /// <remarks>
337                 ///     The Height of the Rectangle.
338                 /// </remarks>
339                 
340                 public int Height {
341                         get {
342                                 return height;
343                         }
344                         set {
345                                 height = value;
346                         }
347                 }
348
349                 /// <summary>
350                 ///     IsEmpty Property
351                 /// </summary>
352                 ///
353                 /// <remarks>
354                 ///     Indicates if the width or height are zero. Read only.
355                 /// </remarks>          
356                 [Browsable (false)]
357                 public bool IsEmpty {
358                         get {
359                                 return ((x == 0) && (y == 0) && (width == 0) && (height == 0));
360                         }
361                 }
362
363                 /// <summary>
364                 ///     Left Property
365                 /// </summary>
366                 ///
367                 /// <remarks>
368                 ///     The X coordinate of the left edge of the Rectangle.
369                 ///     Read only.
370                 /// </remarks>
371                 
372                 [Browsable (false)]
373                 public int Left {
374                         get {
375                                 return X;
376                         }
377                 }
378
379                 /// <summary>
380                 ///     Location Property
381                 /// </summary>
382                 ///
383                 /// <remarks>
384                 ///     The Location of the top-left corner of the Rectangle.
385                 /// </remarks>
386                 
387                 [Browsable (false)]
388                 public Point Location {
389                         get {
390                                 return new Point (x, y);
391                         }
392                         set {
393                                 x = value.X;
394                                 y = value.Y;
395                         }
396                 }
397
398                 /// <summary>
399                 ///     Right Property
400                 /// </summary>
401                 ///
402                 /// <remarks>
403                 ///     The X coordinate of the right edge of the Rectangle.
404                 ///     Read only.
405                 /// </remarks>
406                 
407                 [Browsable (false)]
408                 public int Right {
409                         get {
410                                 return X + Width;
411                         }
412                 }
413
414                 /// <summary>
415                 ///     Size Property
416                 /// </summary>
417                 ///
418                 /// <remarks>
419                 ///     The Size of the Rectangle.
420                 /// </remarks>
421                 
422                 [Browsable (false)]
423                 public Size Size {
424                         get {
425                                 return new Size (Width, Height);
426                         }
427                         set {
428                                 Width = value.Width;
429                                 Height = value.Height;
430                         }
431                 }
432
433                 /// <summary>
434                 ///     Top Property
435                 /// </summary>
436                 ///
437                 /// <remarks>
438                 ///     The Y coordinate of the top edge of the Rectangle.
439                 ///     Read only.
440                 /// </remarks>
441                 
442                 [Browsable (false)]
443                 public int Top {
444                         get {
445                                 return y;
446                         }
447                 }
448
449                 /// <summary>
450                 ///     Width Property
451                 /// </summary>
452                 ///
453                 /// <remarks>
454                 ///     The Width of the Rectangle.
455                 /// </remarks>
456                 
457                 public int Width {
458                         get {
459                                 return width;
460                         }
461                         set {
462                                 width = value;
463                         }
464                 }
465
466                 /// <summary>
467                 ///     X Property
468                 /// </summary>
469                 ///
470                 /// <remarks>
471                 ///     The X coordinate of the Rectangle.
472                 /// </remarks>
473                 
474                 public int X {
475                         get {
476                                 return x;
477                         }
478                         set {
479                                 x = value;
480                         }
481                 }
482
483                 /// <summary>
484                 ///     Y Property
485                 /// </summary>
486                 ///
487                 /// <remarks>
488                 ///     The Y coordinate of the Rectangle.
489                 /// </remarks>
490                 
491                 public int Y {
492                         get {
493                                 return y;
494                         }
495                         set {
496                                 y = value;
497                         }
498                 }
499
500                 /// <summary>
501                 ///     Contains Method
502                 /// </summary>
503                 ///
504                 /// <remarks>
505                 ///     Checks if an x,y coordinate lies within this Rectangle.
506                 /// </remarks>
507                 
508                 public bool Contains (int x, int y)
509                 {
510                         return ((x >= Left) && (x < Right) && 
511                                 (y >= Top) && (y < Bottom));
512                 }
513
514                 /// <summary>
515                 ///     Contains Method
516                 /// </summary>
517                 ///
518                 /// <remarks>
519                 ///     Checks if a Point lies within this Rectangle.
520                 /// </remarks>
521                 
522                 public bool Contains (Point pt)
523                 {
524                         return Contains (pt.X, pt.Y);
525                 }
526
527                 /// <summary>
528                 ///     Contains Method
529                 /// </summary>
530                 ///
531                 /// <remarks>
532                 ///     Checks if a Rectangle lies entirely within this 
533                 ///     Rectangle.
534                 /// </remarks>
535                 
536                 public bool Contains (Rectangle rect)
537                 {
538                         return (rect == Intersect (this, rect));
539                 }
540
541                 /// <summary>
542                 ///     Equals Method
543                 /// </summary>
544                 ///
545                 /// <remarks>
546                 ///     Checks equivalence of this Rectangle and another object.
547                 /// </remarks>
548                 
549                 public override bool Equals (object obj)
550                 {
551                         if (!(obj is Rectangle))
552                                 return false;
553
554                         return (this == (Rectangle) obj);
555                 }
556
557                 /// <summary>
558                 ///     GetHashCode Method
559                 /// </summary>
560                 ///
561                 /// <remarks>
562                 ///     Calculates a hashing value.
563                 /// </remarks>
564                 
565                 public override int GetHashCode ()
566                 {
567                         return (height + width) ^ x + y;
568                 }
569
570                 /// <summary>
571                 ///     IntersectsWith Method
572                 /// </summary>
573                 ///
574                 /// <remarks>
575                 ///     Checks if a Rectangle intersects with this one.
576                 /// </remarks>
577                 
578                 public bool IntersectsWith (Rectangle rect)
579                 {
580                         return !((Left >= rect.Right) || (Right <= rect.Left) ||
581                             (Top >= rect.Bottom) || (Bottom <= rect.Top));
582                 }
583
584                 private bool IntersectsWithInclusive (Rectangle r)
585                 {
586                         return !((Left > r.Right) || (Right < r.Left) ||
587                             (Top > r.Bottom) || (Bottom < r.Top));
588                 }
589
590                 /// <summary>
591                 ///     Offset Method
592                 /// </summary>
593                 ///
594                 /// <remarks>
595                 ///     Moves the Rectangle a specified distance.
596                 /// </remarks>
597
598                 public void Offset (int x, int y)
599                 {
600                         this.x += x;
601                         this.y += y;
602                 }
603                 
604                 /// <summary>
605                 ///     Offset Method
606                 /// </summary>
607                 ///
608                 /// <remarks>
609                 ///     Moves the Rectangle a specified distance.
610                 /// </remarks>
611
612                 public void Offset (Point pos)
613                 {
614                         x += pos.X;
615                         y += pos.Y;
616                 }
617                 
618                 /// <summary>
619                 ///     ToString Method
620                 /// </summary>
621                 ///
622                 /// <remarks>
623                 ///     Formats the Rectangle as a string in (x,y,w,h) notation.
624                 /// </remarks>
625                 
626                 public override string ToString ()
627                 {
628                         return String.Format ("{{X={0},Y={1},Width={2},Height={3}}}",
629                                                  x, y, width, height);
630                 }
631
632         }
633 }