Add license and copyright to all source files in System.Drawing
[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                 // LAMESPEC: Documentation says "This property returns true if 
357                 // the Width, Height, X, and Y properties of this RectangleF all 
358                 // have values of zero; otherwise, false.". Reality returns TRUE if
359                 // width or height are equal 0          
360                 [Browsable (false)]
361                 public bool IsEmpty {
362                         get {
363                                 return ((width == 0) || (height == 0));
364                         }
365                 }
366
367                 /// <summary>
368                 ///     Left Property
369                 /// </summary>
370                 ///
371                 /// <remarks>
372                 ///     The X coordinate of the left edge of the Rectangle.
373                 ///     Read only.
374                 /// </remarks>
375                 
376                 [Browsable (false)]
377                 public int Left {
378                         get {
379                                 return X;
380                         }
381                 }
382
383                 /// <summary>
384                 ///     Location Property
385                 /// </summary>
386                 ///
387                 /// <remarks>
388                 ///     The Location of the top-left corner of the Rectangle.
389                 /// </remarks>
390                 
391                 [Browsable (false)]
392                 public Point Location {
393                         get {
394                                 return new Point (x, y);
395                         }
396                         set {
397                                 x = value.X;
398                                 y = value.Y;
399                         }
400                 }
401
402                 /// <summary>
403                 ///     Right Property
404                 /// </summary>
405                 ///
406                 /// <remarks>
407                 ///     The X coordinate of the right edge of the Rectangle.
408                 ///     Read only.
409                 /// </remarks>
410                 
411                 [Browsable (false)]
412                 public int Right {
413                         get {
414                                 return X + Width;
415                         }
416                 }
417
418                 /// <summary>
419                 ///     Size Property
420                 /// </summary>
421                 ///
422                 /// <remarks>
423                 ///     The Size of the Rectangle.
424                 /// </remarks>
425                 
426                 [Browsable (false)]
427                 public Size Size {
428                         get {
429                                 return new Size (Width, Height);
430                         }
431                         set {
432                                 Width = value.Width;
433                                 Height = value.Height;
434                         }
435                 }
436
437                 /// <summary>
438                 ///     Top Property
439                 /// </summary>
440                 ///
441                 /// <remarks>
442                 ///     The Y coordinate of the top edge of the Rectangle.
443                 ///     Read only.
444                 /// </remarks>
445                 
446                 [Browsable (false)]
447                 public int Top {
448                         get {
449                                 return y;
450                         }
451                 }
452
453                 /// <summary>
454                 ///     Width Property
455                 /// </summary>
456                 ///
457                 /// <remarks>
458                 ///     The Width of the Rectangle.
459                 /// </remarks>
460                 
461                 public int Width {
462                         get {
463                                 return width;
464                         }
465                         set {
466                                 width = value;
467                         }
468                 }
469
470                 /// <summary>
471                 ///     X Property
472                 /// </summary>
473                 ///
474                 /// <remarks>
475                 ///     The X coordinate of the Rectangle.
476                 /// </remarks>
477                 
478                 public int X {
479                         get {
480                                 return x;
481                         }
482                         set {
483                                 x = value;
484                         }
485                 }
486
487                 /// <summary>
488                 ///     Y Property
489                 /// </summary>
490                 ///
491                 /// <remarks>
492                 ///     The Y coordinate of the Rectangle.
493                 /// </remarks>
494                 
495                 public int Y {
496                         get {
497                                 return y;
498                         }
499                         set {
500                                 y = value;
501                         }
502                 }
503
504                 /// <summary>
505                 ///     Contains Method
506                 /// </summary>
507                 ///
508                 /// <remarks>
509                 ///     Checks if an x,y coordinate lies within this Rectangle.
510                 /// </remarks>
511                 
512                 public bool Contains (int x, int y)
513                 {
514                         return ((x >= Left) && (x <= Right) && 
515                                 (y >= Top) && (y <= Bottom));
516                 }
517
518                 /// <summary>
519                 ///     Contains Method
520                 /// </summary>
521                 ///
522                 /// <remarks>
523                 ///     Checks if a Point lies within this Rectangle.
524                 /// </remarks>
525                 
526                 public bool Contains (Point pt)
527                 {
528                         return Contains (pt.X, pt.Y);
529                 }
530
531                 /// <summary>
532                 ///     Contains Method
533                 /// </summary>
534                 ///
535                 /// <remarks>
536                 ///     Checks if a Rectangle lies entirely within this 
537                 ///     Rectangle.
538                 /// </remarks>
539                 
540                 public bool Contains (Rectangle rect)
541                 {
542                         return (rect == Intersect (this, rect));
543                 }
544
545                 /// <summary>
546                 ///     Equals Method
547                 /// </summary>
548                 ///
549                 /// <remarks>
550                 ///     Checks equivalence of this Rectangle and another object.
551                 /// </remarks>
552                 
553                 public override bool Equals (object o)
554                 {
555                         if (!(o is Rectangle))
556                                 return false;
557
558                         return (this == (Rectangle) o);
559                 }
560
561                 /// <summary>
562                 ///     GetHashCode Method
563                 /// </summary>
564                 ///
565                 /// <remarks>
566                 ///     Calculates a hashing value.
567                 /// </remarks>
568                 
569                 public override int GetHashCode ()
570                 {
571                         return (height + width) ^ x + y;
572                 }
573
574                 /// <summary>
575                 ///     IntersectsWith Method
576                 /// </summary>
577                 ///
578                 /// <remarks>
579                 ///     Checks if a Rectangle intersects with this one.
580                 /// </remarks>
581                 
582                 public bool IntersectsWith (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 dx, int dy)
597                 {
598                         x += dx;
599                         y += dy;
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 pt)
611                 {
612                         x += pt.X;
613                         y += pt.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 }