2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.Drawing / System.Drawing / Rectangle.cs
blob1ba6fd32a0b12bb702a23dae6913fcf7eb6592bb
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 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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.
34 using System;
35 using System.Runtime.InteropServices;
36 using System.ComponentModel;
38 namespace System.Drawing
40 [Serializable]
41 [ComVisible (true)]
42 [TypeConverter (typeof (RectangleConverter))]
43 public struct Rectangle
45 private int x, y, width, height;
47 /// <summary>
48 /// Empty Shared Field
49 /// </summary>
50 ///
51 /// <remarks>
52 /// An uninitialized Rectangle Structure.
53 /// </remarks>
55 public static readonly Rectangle Empty;
57 #if TARGET_JVM
58 internal java.awt.Rectangle NativeObject {
59 get {
60 return new java.awt.Rectangle(X,Y,Width,Height);
63 #endif
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>
75 public static Rectangle Ceiling (RectangleF value)
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);
85 return new Rectangle (x, y, w, h);
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>
97 public static Rectangle FromLTRB (int left, int top,
98 int right, int bottom)
100 return new Rectangle (left, top, right - left,
101 bottom - top);
104 /// <summary>
105 /// Inflate Shared Method
106 /// </summary>
108 /// <remarks>
109 /// Produces a new Rectangle by inflating an existing
110 /// Rectangle by the specified coordinate values.
111 /// </remarks>
113 public static Rectangle Inflate (Rectangle rect, int x, int y)
115 Rectangle r = new Rectangle (rect.Location, rect.Size);
116 r.Inflate (x, y);
117 return r;
120 /// <summary>
121 /// Inflate Method
122 /// </summary>
124 /// <remarks>
125 /// Inflates the Rectangle by a specified width and height.
126 /// </remarks>
128 public void Inflate (int width, int height)
130 Inflate (new Size (width, height));
133 /// <summary>
134 /// Inflate Method
135 /// </summary>
137 /// <remarks>
138 /// Inflates the Rectangle by a specified Size.
139 /// </remarks>
141 public void Inflate (Size size)
143 x -= size.Width;
144 y -= size.Height;
145 Width += size.Width * 2;
146 Height += size.Height * 2;
149 /// <summary>
150 /// Intersect Shared Method
151 /// </summary>
153 /// <remarks>
154 /// Produces a new Rectangle by intersecting 2 existing
155 /// Rectangles. Returns null if there is no intersection.
156 /// </remarks>
158 public static Rectangle Intersect (Rectangle a, Rectangle b)
160 // MS.NET returns a non-empty rectangle if the two rectangles
161 // touch each other
162 if (!a.IntersectsWithInclusive (b))
163 return Empty;
165 return Rectangle.FromLTRB (
166 Math.Max (a.Left, b.Left),
167 Math.Max (a.Top, b.Top),
168 Math.Min (a.Right, b.Right),
169 Math.Min (a.Bottom, b.Bottom));
172 /// <summary>
173 /// Intersect Method
174 /// </summary>
176 /// <remarks>
177 /// Replaces the Rectangle with the intersection of itself
178 /// and another Rectangle.
179 /// </remarks>
181 public void Intersect (Rectangle rect)
183 this = Rectangle.Intersect (this, rect);
186 /// <summary>
187 /// Round Shared Method
188 /// </summary>
190 /// <remarks>
191 /// Produces a Rectangle structure from a RectangleF by
192 /// rounding the X, Y, Width, and Height properties.
193 /// </remarks>
195 public static Rectangle Round (RectangleF value)
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);
205 return new Rectangle (x, y, w, h);
208 /// <summary>
209 /// Truncate Shared Method
210 /// </summary>
212 /// <remarks>
213 /// Produces a Rectangle structure from a RectangleF by
214 /// truncating the X, Y, Width, and Height properties.
215 /// </remarks>
217 // LAMESPEC: Should this be floor, or a pure cast to int?
219 public static Rectangle Truncate (RectangleF value)
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;
229 return new Rectangle (x, y, w, h);
232 /// <summary>
233 /// Union Shared Method
234 /// </summary>
236 /// <remarks>
237 /// Produces a new Rectangle from the union of 2 existing
238 /// Rectangles.
239 /// </remarks>
241 public static Rectangle Union (Rectangle a, Rectangle b)
243 return FromLTRB (Math.Min (a.Left, b.Left),
244 Math.Min (a.Top, b.Top),
245 Math.Max (a.Right, b.Right),
246 Math.Max (a.Bottom, b.Bottom));
249 /// <summary>
250 /// Equality Operator
251 /// </summary>
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>
259 public static bool operator == (Rectangle left, Rectangle right)
261 return ((left.Location == right.Location) &&
262 (left.Size == right.Size));
265 /// <summary>
266 /// Inequality Operator
267 /// </summary>
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>
275 public static bool operator != (Rectangle left, Rectangle right)
277 return ((left.Location != right.Location) ||
278 (left.Size != right.Size));
282 // -----------------------
283 // Public Constructors
284 // -----------------------
286 /// <summary>
287 /// Rectangle Constructor
288 /// </summary>
290 /// <remarks>
291 /// Creates a Rectangle from Point and Size values.
292 /// </remarks>
294 public Rectangle (Point location, Size size)
296 x = location.X;
297 y = location.Y;
298 width = size.Width;
299 height = size.Height;
302 /// <summary>
303 /// Rectangle Constructor
304 /// </summary>
306 /// <remarks>
307 /// Creates a Rectangle from a specified x,y location and
308 /// width and height values.
309 /// </remarks>
311 public Rectangle (int x, int y, int width, int height)
313 this.x = x;
314 this.y = y;
315 this.width = width;
316 this.height = height;
321 /// <summary>
322 /// Bottom Property
323 /// </summary>
325 /// <remarks>
326 /// The Y coordinate of the bottom edge of the Rectangle.
327 /// Read only.
328 /// </remarks>
330 [Browsable (false)]
331 public int Bottom {
332 get {
333 return y + height;
337 /// <summary>
338 /// Height Property
339 /// </summary>
341 /// <remarks>
342 /// The Height of the Rectangle.
343 /// </remarks>
345 public int Height {
346 get {
347 return height;
349 set {
350 height = value;
354 /// <summary>
355 /// IsEmpty Property
356 /// </summary>
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));
368 /// <summary>
369 /// Left Property
370 /// </summary>
372 /// <remarks>
373 /// The X coordinate of the left edge of the Rectangle.
374 /// Read only.
375 /// </remarks>
377 [Browsable (false)]
378 public int Left {
379 get {
380 return X;
384 /// <summary>
385 /// Location Property
386 /// </summary>
388 /// <remarks>
389 /// The Location of the top-left corner of the Rectangle.
390 /// </remarks>
392 [Browsable (false)]
393 public Point Location {
394 get {
395 return new Point (x, y);
397 set {
398 x = value.X;
399 y = value.Y;
403 /// <summary>
404 /// Right Property
405 /// </summary>
407 /// <remarks>
408 /// The X coordinate of the right edge of the Rectangle.
409 /// Read only.
410 /// </remarks>
412 [Browsable (false)]
413 public int Right {
414 get {
415 return X + Width;
419 /// <summary>
420 /// Size Property
421 /// </summary>
423 /// <remarks>
424 /// The Size of the Rectangle.
425 /// </remarks>
427 [Browsable (false)]
428 public Size Size {
429 get {
430 return new Size (Width, Height);
432 set {
433 Width = value.Width;
434 Height = value.Height;
438 /// <summary>
439 /// Top Property
440 /// </summary>
442 /// <remarks>
443 /// The Y coordinate of the top edge of the Rectangle.
444 /// Read only.
445 /// </remarks>
447 [Browsable (false)]
448 public int Top {
449 get {
450 return y;
454 /// <summary>
455 /// Width Property
456 /// </summary>
458 /// <remarks>
459 /// The Width of the Rectangle.
460 /// </remarks>
462 public int Width {
463 get {
464 return width;
466 set {
467 width = value;
471 /// <summary>
472 /// X Property
473 /// </summary>
475 /// <remarks>
476 /// The X coordinate of the Rectangle.
477 /// </remarks>
479 public int X {
480 get {
481 return x;
483 set {
484 x = value;
488 /// <summary>
489 /// Y Property
490 /// </summary>
492 /// <remarks>
493 /// The Y coordinate of the Rectangle.
494 /// </remarks>
496 public int Y {
497 get {
498 return y;
500 set {
501 y = value;
505 /// <summary>
506 /// Contains Method
507 /// </summary>
509 /// <remarks>
510 /// Checks if an x,y coordinate lies within this Rectangle.
511 /// </remarks>
513 public bool Contains (int x, int y)
515 return ((x >= Left) && (x < Right) &&
516 (y >= Top) && (y < Bottom));
519 /// <summary>
520 /// Contains Method
521 /// </summary>
523 /// <remarks>
524 /// Checks if a Point lies within this Rectangle.
525 /// </remarks>
527 public bool Contains (Point pt)
529 return Contains (pt.X, pt.Y);
532 /// <summary>
533 /// Contains Method
534 /// </summary>
536 /// <remarks>
537 /// Checks if a Rectangle lies entirely within this
538 /// Rectangle.
539 /// </remarks>
541 public bool Contains (Rectangle rect)
543 return (rect == Intersect (this, rect));
546 /// <summary>
547 /// Equals Method
548 /// </summary>
550 /// <remarks>
551 /// Checks equivalence of this Rectangle and another object.
552 /// </remarks>
554 public override bool Equals (object obj)
556 if (!(obj is Rectangle))
557 return false;
559 return (this == (Rectangle) obj);
562 /// <summary>
563 /// GetHashCode Method
564 /// </summary>
566 /// <remarks>
567 /// Calculates a hashing value.
568 /// </remarks>
570 public override int GetHashCode ()
572 return (height + width) ^ x + y;
575 /// <summary>
576 /// IntersectsWith Method
577 /// </summary>
579 /// <remarks>
580 /// Checks if a Rectangle intersects with this one.
581 /// </remarks>
583 public bool IntersectsWith (Rectangle rect)
585 return !((Left >= rect.Right) || (Right <= rect.Left) ||
586 (Top >= rect.Bottom) || (Bottom <= rect.Top));
589 private bool IntersectsWithInclusive (Rectangle r)
591 return !((Left > r.Right) || (Right < r.Left) ||
592 (Top > r.Bottom) || (Bottom < r.Top));
595 /// <summary>
596 /// Offset Method
597 /// </summary>
599 /// <remarks>
600 /// Moves the Rectangle a specified distance.
601 /// </remarks>
603 public void Offset (int x, int y)
605 this.x += x;
606 this.y += y;
609 /// <summary>
610 /// Offset Method
611 /// </summary>
613 /// <remarks>
614 /// Moves the Rectangle a specified distance.
615 /// </remarks>
617 public void Offset (Point pos)
619 x += pos.X;
620 y += pos.Y;
623 /// <summary>
624 /// ToString Method
625 /// </summary>
627 /// <remarks>
628 /// Formats the Rectangle as a string in (x,y,w,h) notation.
629 /// </remarks>
631 public override string ToString ()
633 return String.Format ("{{X={0},Y={1},Width={2},Height={3}}}",
634 x, y, width, height);