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