Allow mono-wrapper executable to be overridden by environment
[mono.git] / mcs / class / System.Drawing / System.Drawing / RectangleF.cs
1 //
2 // System.Drawing.RectangleF.cs
3 //
4 // Author:
5 //   Mike Kestner (mkestner@speakeasy.net)
6 //
7 // Copyright (C) 2001 Mike Kestner
8 // Copyright (C) 2004, 2007 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System;
31 using System.ComponentModel;
32
33 namespace System.Drawing
34 {
35         [Serializable]
36         public struct RectangleF
37         {
38                 private float x, y, width, height;
39
40                 /// <summary>
41                 ///     Empty Shared Field
42                 /// </summary>
43                 ///
44                 /// <remarks>
45                 ///     An uninitialized RectangleF Structure.
46                 /// </remarks>
47                 
48                 public static readonly RectangleF Empty;
49
50
51                 /// <summary>
52                 ///     FromLTRB Shared Method
53                 /// </summary>
54                 ///
55                 /// <remarks>
56                 ///     Produces a RectangleF structure from left, top, right,
57                 ///     and bottom coordinates.
58                 /// </remarks>
59                 
60                 public static RectangleF FromLTRB (float left, float top,
61                                                    float right, float bottom)
62                 {
63                         return new RectangleF (left, top, right - left, bottom - top);
64                 }
65
66                 /// <summary>
67                 ///     Inflate Shared Method
68                 /// </summary>
69                 ///
70                 /// <remarks>
71                 ///     Produces a new RectangleF by inflating an existing 
72                 ///     RectangleF by the specified coordinate values.
73                 /// </remarks>
74                 
75                 public static RectangleF Inflate (RectangleF rect, 
76                                                   float x, float y)
77                 {
78                         RectangleF ir = new RectangleF (rect.X, rect.Y, rect.Width, rect.Height);
79                         ir.Inflate (x, y);
80                         return ir;
81                 }
82
83                 /// <summary>
84                 ///     Inflate Method
85                 /// </summary>
86                 ///
87                 /// <remarks>
88                 ///     Inflates the RectangleF by a specified width and height.
89                 /// </remarks>
90                 
91                 public void Inflate (float x, float y)
92                 {
93                         Inflate (new SizeF (x, y));
94                 }
95
96                 /// <summary>
97                 ///     Inflate Method
98                 /// </summary>
99                 ///
100                 /// <remarks>
101                 ///     Inflates the RectangleF by a specified Size.
102                 /// </remarks>
103                 
104                 public void Inflate (SizeF size)
105                 {
106                         x -= size.Width;
107                         y -= size.Height;
108                         width += size.Width * 2;
109                         height += size.Height * 2;                        
110                 }
111
112                 /// <summary>
113                 ///     Intersect Shared Method
114                 /// </summary>
115                 ///
116                 /// <remarks>
117                 ///     Produces a new RectangleF by intersecting 2 existing 
118                 ///     RectangleFs. Returns null if there is no intersection.
119                 /// </remarks>
120                 
121                 public static RectangleF Intersect (RectangleF a, 
122                                                     RectangleF b)
123                 {
124                         // MS.NET returns a non-empty rectangle if the two rectangles
125                         // touch each other
126                         if (!a.IntersectsWithInclusive (b))
127                                 return Empty;
128
129                         return FromLTRB (
130                                 Math.Max (a.Left, b.Left),
131                                 Math.Max (a.Top, b.Top),
132                                 Math.Min (a.Right, b.Right),
133                                 Math.Min (a.Bottom, b.Bottom));
134                 }
135
136                 /// <summary>
137                 ///     Intersect Method
138                 /// </summary>
139                 ///
140                 /// <remarks>
141                 ///     Replaces the RectangleF with the intersection of itself
142                 ///     and another RectangleF.
143                 /// </remarks>
144                 
145                 public void Intersect (RectangleF rect)
146                 {
147                         this = RectangleF.Intersect (this, rect);
148                 }
149
150                 /// <summary>
151                 ///     Union Shared Method
152                 /// </summary>
153                 ///
154                 /// <remarks>
155                 ///     Produces a new RectangleF from the union of 2 existing 
156                 ///     RectangleFs.
157                 /// </remarks>
158                 
159                 public static RectangleF Union (RectangleF a, RectangleF b)
160                 {
161                         return FromLTRB (Math.Min (a.Left, b.Left),
162                                          Math.Min (a.Top, b.Top),
163                                          Math.Max (a.Right, b.Right),
164                                          Math.Max (a.Bottom, b.Bottom));
165                 }
166
167                 /// <summary>
168                 ///     Equality Operator
169                 /// </summary>
170                 ///
171                 /// <remarks>
172                 ///     Compares two RectangleF objects. The return value is
173                 ///     based on the equivalence of the Location and Size 
174                 ///     properties of the two RectangleFs.
175                 /// </remarks>
176
177                 public static bool operator == (RectangleF left, RectangleF right)
178                 {
179                         return (left.X == right.X) && (left.Y == right.Y) &&
180                                 (left.Width == right.Width) && (left.Height == right.Height);
181                 }
182                 
183                 /// <summary>
184                 ///     Inequality Operator
185                 /// </summary>
186                 ///
187                 /// <remarks>
188                 ///     Compares two RectangleF objects. The return value is
189                 ///     based on the equivalence of the Location and Size 
190                 ///     properties of the two RectangleFs.
191                 /// </remarks>
192
193                 public static bool operator != (RectangleF left, RectangleF right)
194                 {
195                         return (left.X != right.X) || (left.Y != right.Y) ||
196                                 (left.Width != right.Width) || (left.Height != right.Height);
197                 }
198                 
199                 /// <summary>
200                 ///     Rectangle to RectangleF Conversion
201                 /// </summary>
202                 ///
203                 /// <remarks>
204                 ///     Converts a Rectangle object to a RectangleF.
205                 /// </remarks>
206
207                 public static implicit operator RectangleF (Rectangle r)
208                 {
209                         return new RectangleF (r.X, r.Y, r.Width, r.Height);
210                 }
211                 
212
213                 // -----------------------
214                 // Public Constructors
215                 // -----------------------
216
217                 /// <summary>
218                 ///     RectangleF Constructor
219                 /// </summary>
220                 ///
221                 /// <remarks>
222                 ///     Creates a RectangleF from PointF and SizeF values.
223                 /// </remarks>
224                 
225                 public RectangleF (PointF location, SizeF size)
226                 {
227                         x = location.X;
228                         y = location.Y;
229                         width = size.Width;
230                         height = size.Height;
231                 }
232
233                 /// <summary>
234                 ///     RectangleF Constructor
235                 /// </summary>
236                 ///
237                 /// <remarks>
238                 ///     Creates a RectangleF from a specified x,y location and
239                 ///     width and height values.
240                 /// </remarks>
241                 
242                 public RectangleF (float x, float y, float width, float height)
243                 {
244                         this.x = x;
245                         this.y = y;
246                         this.width = width;
247                         this.height = height;
248                 }
249
250
251
252                 /// <summary>
253                 ///     Bottom Property
254                 /// </summary>
255                 ///
256                 /// <remarks>
257                 ///     The Y coordinate of the bottom edge of the RectangleF.
258                 ///     Read only.
259                 /// </remarks>
260                 
261                 [Browsable (false)]
262                 public float Bottom {
263                         get {
264                                 return Y + Height;
265                         }
266                 }
267
268                 /// <summary>
269                 ///     Height Property
270                 /// </summary>
271                 ///
272                 /// <remarks>
273                 ///     The Height of the RectangleF.
274                 /// </remarks>
275                 
276                 public float Height {
277                         get {
278                                 return height;
279                         }
280                         set {
281                                 height = value;
282                         }
283                 }
284
285                 /// <summary>
286                 ///     IsEmpty Property
287                 /// </summary>
288                 ///
289                 /// <remarks>
290                 ///     Indicates if the width or height are zero. Read only.
291                 /// </remarks>
292                 //              
293                 [Browsable (false)]
294                 public bool IsEmpty {
295                         get {
296                                 return (width <= 0 || height <= 0);
297                         }
298                 }
299
300                 /// <summary>
301                 ///     Left Property
302                 /// </summary>
303                 ///
304                 /// <remarks>
305                 ///     The X coordinate of the left edge of the RectangleF.
306                 ///     Read only.
307                 /// </remarks>
308                 
309                 [Browsable (false)]
310                 public float Left {
311                         get {
312                                 return X;
313                         }
314                 }
315
316                 /// <summary>
317                 ///     Location Property
318                 /// </summary>
319                 ///
320                 /// <remarks>
321                 ///     The Location of the top-left corner of the RectangleF.
322                 /// </remarks>
323                 
324                 [Browsable (false)]
325                 public PointF Location {
326                         get {
327                                 return new PointF (x, y);
328                         }
329                         set {
330                                 x = value.X;
331                                 y = value.Y;
332                         }
333                 }
334
335                 /// <summary>
336                 ///     Right Property
337                 /// </summary>
338                 ///
339                 /// <remarks>
340                 ///     The X coordinate of the right edge of the RectangleF.
341                 ///     Read only.
342                 /// </remarks>
343                 
344                 [Browsable (false)]
345                 public float Right {
346                         get {
347                                 return X + Width;
348                         }
349                 }
350
351                 /// <summary>
352                 ///     Size Property
353                 /// </summary>
354                 ///
355                 /// <remarks>
356                 ///     The Size of the RectangleF.
357                 /// </remarks>
358                 
359                 [Browsable (false)]
360                 public SizeF Size {
361                         get {
362                                 return new SizeF (width, height);
363                         }
364                         set {
365                                 width = value.Width;
366                                 height = value.Height;
367                         }
368                 }
369
370                 /// <summary>
371                 ///     Top Property
372                 /// </summary>
373                 ///
374                 /// <remarks>
375                 ///     The Y coordinate of the top edge of the RectangleF.
376                 ///     Read only.
377                 /// </remarks>
378                 
379                 [Browsable (false)]
380                 public float Top {
381                         get {
382                                 return Y;
383                         }
384                 }
385
386                 /// <summary>
387                 ///     Width Property
388                 /// </summary>
389                 ///
390                 /// <remarks>
391                 ///     The Width of the RectangleF.
392                 /// </remarks>
393                 
394                 public float Width {
395                         get {
396                                 return width;
397                         }
398                         set {
399                                 width = value;
400                         }
401                 }
402
403                 /// <summary>
404                 ///     X Property
405                 /// </summary>
406                 ///
407                 /// <remarks>
408                 ///     The X coordinate of the RectangleF.
409                 /// </remarks>
410                 
411                 public float X {
412                         get {
413                                 return x;
414                         }
415                         set {
416                                 x = value;
417                         }
418                 }
419
420                 /// <summary>
421                 ///     Y Property
422                 /// </summary>
423                 ///
424                 /// <remarks>
425                 ///     The Y coordinate of the RectangleF.
426                 /// </remarks>
427                 
428                 public float Y {
429                         get {
430                                 return y;
431                         }
432                         set {
433                                 y = value;
434                         }
435                 }
436
437                 /// <summary>
438                 ///     Contains Method
439                 /// </summary>
440                 ///
441                 /// <remarks>
442                 ///     Checks if an x,y coordinate lies within this RectangleF.
443                 /// </remarks>
444                 
445                 public bool Contains (float x, float y)
446                 {
447                         return ((x >= Left) && (x < Right) && 
448                                 (y >= Top) && (y < Bottom));
449                 }
450
451                 /// <summary>
452                 ///     Contains Method
453                 /// </summary>
454                 ///
455                 /// <remarks>
456                 ///     Checks if a Point lies within this RectangleF.
457                 /// </remarks>
458                 
459                 public bool Contains (PointF pt)
460                 {
461                         return Contains (pt.X, pt.Y);
462                 }
463
464                 /// <summary>
465                 ///     Contains Method
466                 /// </summary>
467                 ///
468                 /// <remarks>
469                 ///     Checks if a RectangleF lies entirely within this 
470                 ///     RectangleF.
471                 /// </remarks>
472                 
473                 public bool Contains (RectangleF rect)
474                 {
475                         return X <= rect.X && Right >= rect.Right && Y <= rect.Y && Bottom >= rect.Bottom;
476                 }
477
478                 /// <summary>
479                 ///     Equals Method
480                 /// </summary>
481                 ///
482                 /// <remarks>
483                 ///     Checks equivalence of this RectangleF and an object.
484                 /// </remarks>
485                 
486                 public override bool Equals (object obj)
487                 {
488                         if (!(obj is RectangleF))
489                                 return false;
490
491                         return (this == (RectangleF) obj);
492                 }
493
494                 /// <summary>
495                 ///     GetHashCode Method
496                 /// </summary>
497                 ///
498                 /// <remarks>
499                 ///     Calculates a hashing value.
500                 /// </remarks>
501                 
502                 public override int GetHashCode ()
503                 {
504                         return (int) (x + y + width + height);
505                 }
506
507                 /// <summary>
508                 ///     IntersectsWith Method
509                 /// </summary>
510                 ///
511                 /// <remarks>
512                 ///     Checks if a RectangleF intersects with this one.
513                 /// </remarks>
514
515                 public bool IntersectsWith (RectangleF rect)
516                 {
517                         return !((Left >= rect.Right) || (Right <= rect.Left) ||
518                             (Top >= rect.Bottom) || (Bottom <= rect.Top));
519                 }
520
521                 private bool IntersectsWithInclusive (RectangleF r)
522                 {
523                         return !((Left > r.Right) || (Right < r.Left) ||
524                             (Top > r.Bottom) || (Bottom < r.Top));
525                 }
526
527                 /// <summary>
528                 ///     Offset Method
529                 /// </summary>
530                 ///
531                 /// <remarks>
532                 ///     Moves the RectangleF a specified distance.
533                 /// </remarks>
534
535                 public void Offset (float x, float y)
536                 {
537                         X += x;
538                         Y += y;
539                 }
540                 
541                 /// <summary>
542                 ///     Offset Method
543                 /// </summary>
544                 ///
545                 /// <remarks>
546                 ///     Moves the RectangleF a specified distance.
547                 /// </remarks>
548
549                 public void Offset (PointF pos)
550                 {
551                         Offset (pos.X, pos.Y);
552                 }
553                 
554                 /// <summary>
555                 ///     ToString Method
556                 /// </summary>
557                 ///
558                 /// <remarks>
559                 ///     Formats the RectangleF in (x,y,w,h) notation.
560                 /// </remarks>
561                 
562                 public override string ToString ()
563                 {
564                         return String.Format ("{{X={0},Y={1},Width={2},Height={3}}}",
565                                                  x, y, width, height);
566                 }
567
568         }
569 }