Switch to compiler-tester
[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                 /// <summary>
58                 ///     Ceiling Shared Method
59                 /// </summary>
60                 ///
61                 /// <remarks>
62                 ///     Produces a Rectangle structure from a RectangleF 
63                 ///     structure by taking the ceiling of the X, Y, Width,
64                 ///     and Height properties.
65                 /// </remarks>
66                 
67                 public static Rectangle Ceiling (RectangleF value)
68                 {
69                         int x, y, w, h;
70                         checked {
71                                 x = (int) Math.Ceiling (value.X);
72                                 y = (int) Math.Ceiling (value.Y);
73                                 w = (int) Math.Ceiling (value.Width);
74                                 h = (int) Math.Ceiling (value.Height);
75                         }
76
77                         return new Rectangle (x, y, w, h);
78                 }
79
80                 /// <summary>
81                 ///     FromLTRB Shared Method
82                 /// </summary>
83                 ///
84                 /// <remarks>
85                 ///     Produces a Rectangle structure from left, top, right,
86                 ///     and bottom coordinates.
87                 /// </remarks>
88                 
89                 public static Rectangle FromLTRB (int left, int top,
90                                                   int right, int bottom)
91                 {
92                         return new Rectangle (left, top, right - left,
93                                               bottom - top);
94                 }
95
96                 /// <summary>
97                 ///     Inflate Shared Method
98                 /// </summary>
99                 ///
100                 /// <remarks>
101                 ///     Produces a new Rectangle by inflating an existing 
102                 ///     Rectangle by the specified coordinate values.
103                 /// </remarks>
104                 
105                 public static Rectangle Inflate (Rectangle rect, int x, int y)
106                 {
107                         Rectangle r = new Rectangle (rect.Location, rect.Size);
108                         r.Inflate (x, y);
109                         return r;
110                 }
111
112                 /// <summary>
113                 ///     Inflate Method
114                 /// </summary>
115                 ///
116                 /// <remarks>
117                 ///     Inflates the Rectangle by a specified width and height.
118                 /// </remarks>
119                 
120                 public void Inflate (int width, int height)
121                 {
122                         Inflate (new Size (width, height));
123                 }
124
125                 /// <summary>
126                 ///     Inflate Method
127                 /// </summary>
128                 ///
129                 /// <remarks>
130                 ///     Inflates the Rectangle by a specified Size.
131                 /// </remarks>
132                 
133                 public void Inflate (Size sz)
134                 {
135                         x -= sz.Width;
136                         y -= sz.Height;
137                         Width += sz.Width * 2;
138                         Height += sz.Height * 2;
139                 }
140
141                 /// <summary>
142                 ///     Intersect Shared Method
143                 /// </summary>
144                 ///
145                 /// <remarks>
146                 ///     Produces a new Rectangle by intersecting 2 existing 
147                 ///     Rectangles. Returns null if there is no intersection.
148                 /// </remarks>
149                 
150                 public static Rectangle Intersect (Rectangle r1, Rectangle r2)
151                 {
152                         Rectangle r = new Rectangle (r1.Location, r1.Size);
153                         r.Intersect (r2);
154                         return r;
155                 }
156
157                 /// <summary>
158                 ///     Intersect Method
159                 /// </summary>
160                 ///
161                 /// <remarks>
162                 ///     Replaces the Rectangle with the intersection of itself
163                 ///     and another Rectangle.
164                 /// </remarks>
165                 
166                 public void Intersect (Rectangle r)
167                 {
168                         if (!IntersectsWith (r)) {
169                                 x = 0;
170                                 y = 0;
171                                 width = 0;
172                                 height = 0;
173                         }
174
175                         x = Math.Max (Left, r.Left);
176                         y = Math.Max (Top, r.Top);
177                         width = Math.Min (Right, r.Right) - X;
178                         height = Math.Min (Bottom, r.Bottom) - Y;
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 r1, Rectangle r2)
237                 {
238                         return FromLTRB (Math.Min (r1.Left, r2.Left),
239                                          Math.Min (r1.Top, r2.Top),
240                                          Math.Max (r1.Right, r2.Right),
241                                          Math.Max (r1.Bottom, r2.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 r1, Rectangle r2)
255                 {
256                         return ((r1.Location == r2.Location) && 
257                                 (r1.Size == r2.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 r1, Rectangle r2)
271                 {
272                         return ((r1.Location != r2.Location) || 
273                                 (r1.Size != r2.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 loc, Size sz)
290                 {
291                         x = loc.X;
292                         y = loc.Y;
293                         width = sz.Width;
294                         height = sz.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 o)
550                 {
551                         if (!(o is Rectangle))
552                                 return false;
553
554                         return (this == (Rectangle) o);
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 r)
579                 {
580                         return !((Left >= r.Right) || (Right <= r.Left) ||
581                             (Top >= r.Bottom) || (Bottom <= r.Top));
582                 }
583
584                 /// <summary>
585                 ///     Offset Method
586                 /// </summary>
587                 ///
588                 /// <remarks>
589                 ///     Moves the Rectangle a specified distance.
590                 /// </remarks>
591
592                 public void Offset (int dx, int dy)
593                 {
594                         x += dx;
595                         y += dy;
596                 }
597                 
598                 /// <summary>
599                 ///     Offset Method
600                 /// </summary>
601                 ///
602                 /// <remarks>
603                 ///     Moves the Rectangle a specified distance.
604                 /// </remarks>
605
606                 public void Offset (Point pt)
607                 {
608                         x += pt.X;
609                         y += pt.Y;
610                 }
611                 
612                 /// <summary>
613                 ///     ToString Method
614                 /// </summary>
615                 ///
616                 /// <remarks>
617                 ///     Formats the Rectangle as a string in (x,y,w,h) notation.
618                 /// </remarks>
619                 
620                 public override string ToString ()
621                 {
622                         return String.Format ("{{X={0},Y={1},Width={2},Height={3}}}",
623                                                  x, y, width, height);
624                 }
625
626         }
627 }