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