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