[System.Runtime.Remoting] Adds System.Core reference for tests
[mono.git] / mcs / class / WindowsBase / System.Windows / Rect.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Chris Toshok <toshok@novell.com>
24 //      Sebastien Pouliot  <sebastien@ximian.com>
25 //
26
27 using System;
28 using System.ComponentModel;
29 using System.Globalization;
30 using System.Text;
31 using System.Windows.Converters;
32 using System.Windows.Markup;
33 using System.Windows.Media;
34
35 namespace System.Windows {
36
37         [Serializable]
38         [ValueSerializer (typeof (RectValueSerializer))]
39         [TypeConverter (typeof (RectConverter))]
40         public struct Rect : IFormattable
41         {
42                 public Rect (Size size)
43                 {
44                         _x = _y = 0.0;
45                         _width = size.Width;
46                         _height = size.Height;
47                 }
48
49                 public Rect (Point point, Vector vector) : this (point, Point.Add (point, vector))
50                 { }
51
52                 public Rect (Point point1, Point point2)
53                 {
54                         if (point1.X < point2.X) {
55                                 _x = point1.X;
56                                 _width = point2.X - point1.X;
57                         }
58                         else {
59                                 _x = point2.X;
60                                 _width = point1.X - point2.X;
61                         }
62
63                         if (point1.Y < point2.Y) {
64                                 _y = point1.Y;
65                                 _height = point2.Y - point1.Y;
66                         }
67                         else {
68                                 _y = point2.Y;
69                                 _height = point1.Y - point2.Y;
70                         }
71                 }
72
73                 public Rect (double x, double y, double width, double height)
74                 {
75                         if (width < 0 || height < 0)
76                                 throw new ArgumentException ("width and height must be non-negative.");
77                         this._x = x;
78                         this._y = y;
79                         this._width = width;
80                         this._height = height;
81                 }
82
83                 public Rect (Point location, Size size)
84                 {
85                         _x = location.X;
86                         _y = location.Y;
87                         _width = size.Width;
88                         _height = size.Height;
89                 }
90
91                 public bool Equals (Rect value)
92                 {
93                         return (_x == value.X &&
94                                 _y == value.Y &&
95                                 _width == value.Width &&
96                                 _height == value.Height);
97                 }
98
99                 public static bool operator != (Rect rect1, Rect rect2)
100                 {
101                         return !(rect1.Location == rect2.Location && rect1.Size == rect2.Size);
102                 }
103
104                 public static bool operator == (Rect rect1, Rect rect2)
105                 {
106                         return rect1.Location == rect2.Location && rect1.Size == rect2.Size;
107                 }
108
109                 public override bool Equals (object o)
110                 {
111                         if (!(o is Rect))
112                                 return false;
113
114                         return Equals ((Rect)o);
115                 }
116
117                 public static bool Equals (Rect rect1, Rect rect2)
118                 {
119                         return rect1.Equals (rect2);
120                 }
121
122                 public override int GetHashCode ()
123                 {
124                         throw new NotImplementedException ();
125                 }
126
127                 public bool Contains (Rect rect)
128                 {
129                         if (rect.Left < this.Left ||
130                             rect.Right > this.Right)
131                                 return false;
132
133                         if (rect.Top < this.Top ||
134                             rect.Bottom > this.Bottom)
135                                 return false;
136
137                         return true;
138                 }
139
140                 public bool Contains (double x, double y)
141                 {
142                         if (x < Left || x > Right)
143                                 return false;
144                         if (y < Top || y > Bottom)
145                                 return false;
146
147                         return true;
148                 }
149
150                 public bool Contains (Point point)
151                 {
152                         return Contains (point.X, point.Y);
153                 }
154
155                 public static Rect Inflate (Rect rect, double width, double height)
156                 {
157                         if (width < rect.Width * -2)
158                                 return Rect.Empty;
159                         if (height < rect.Height * -2)
160                                 return Rect.Empty;
161
162                         Rect result = rect;
163                         result.Inflate (width, height);
164                         return result;
165                 }
166
167                 public static Rect Inflate (Rect rect, Size size)
168                 {
169                         return Rect.Inflate (rect, size.Width, size.Height);
170                 }
171
172                 public void Inflate (double width, double height)
173                 {
174                         // XXX any error checking like in the static case?
175                         _x -= width;
176                         _y -= height;
177
178                         this._width += 2*width;
179                         this._height += 2*height;
180                 }
181
182                 public void Inflate (Size size)
183                 {
184                         Inflate (size.Width, size.Height);
185                 }
186
187                 public bool IntersectsWith(Rect rect)
188                 {
189                         return !((Left >= rect.Right) || (Right <= rect.Left) ||
190                             (Top >= rect.Bottom) || (Bottom <= rect.Top));
191                 }
192
193                 public void Intersect(Rect rect)
194                 {
195                         double _x = Math.Max (this._x, rect._x);
196                         double _y = Math.Max (this._y, rect._y);
197                         double _width = Math.Min (Right, rect.Right) - _x;
198                         double _height = Math.Min (Bottom, rect.Bottom) - _y; 
199
200                         if (_width < 0 || _height < 0) {
201                                 this._x = this._y = Double.PositiveInfinity;
202                                 this._width = this._height = Double.NegativeInfinity;
203                         }
204                         else {
205                                 this._x = _x;
206                                 this._y = _y;
207                                 this._width = _width;
208                                 this._height = _height;
209                         }
210                 }
211
212                 public static Rect Intersect(Rect rect1, Rect rect2)
213                 {
214                         Rect result = rect1;
215                         result.Intersect (rect2);
216                         return result;
217                 }
218
219                 public void Offset(double offsetX, double offsetY)
220                 {
221                         _x += offsetX;
222                         _y += offsetY;
223                 }
224
225                 public static Rect Offset(Rect rect, double offsetX, double offsetY)
226                 {
227                         Rect result = rect;
228                         result.Offset (offsetX, offsetY);
229                         return result;
230                 }
231
232                 public void Offset (Vector offsetVector)
233                 {
234                         _x += offsetVector.X;
235                         _y += offsetVector.Y;
236                 }
237
238                 public static Rect Offset (Rect rect, Vector offsetVector)
239                 {
240                         Rect result = rect;
241                         result.Offset (offsetVector);
242                         return result;
243                 }
244
245                 public void Scale(double scaleX, double scaleY)
246                 {
247                         _x *= scaleX;
248                         _y *= scaleY;
249                         _width *= scaleX;
250                         _height *= scaleY;
251                 }
252
253                 public void Transform (Matrix matrix)
254                 {
255                         throw new NotImplementedException ();
256                 }
257
258                 public static Rect Transform (Rect rect, Matrix matrix)
259                 {
260                         Rect result = rect;
261                         result.Transform (matrix);
262                         return result;
263                 }
264
265                 public static Rect Union(Rect rect1, Rect rect2)
266                 {
267                         Rect result = rect1;
268                         result.Union (rect2);
269                         return result;
270                 }
271
272                 public static Rect Union(Rect rect, Point point)
273                 {
274                         Rect result = rect;
275                         result.Union (point);
276                         return result;
277                 }
278                 
279                 public void Union(Rect rect)
280                 {
281                         var left = Math.Min (Left, rect.Left);
282                         var top = Math.Min (Top, rect.Top);
283                         var right = Math.Max (Right, rect.Right);
284                         var bottom = Math.Max (Bottom, rect.Bottom);
285                         
286                         _x = left;
287                         _y = top;
288                         _width = right - left;
289                         _height = bottom - top;
290                 }
291
292                 public void Union(Point point)
293                 {
294                         Union (new Rect (point, point));
295                 }
296
297                 public static Rect Parse (string source)
298                 {
299                         throw new NotImplementedException ();
300                 }
301
302                 public override string ToString ()
303                 {
304                         return ToString (null);
305                 }
306
307                 public string ToString (IFormatProvider provider)
308                 {
309                         return ToString (null, provider);
310                 }
311
312                 string IFormattable.ToString (string format, IFormatProvider provider)
313                 {
314                         return ToString (format, provider);
315                 }
316
317                 private string ToString (string format, IFormatProvider provider)
318                 {
319                         if (IsEmpty)
320                                 return "Empty";
321
322                         if (provider == null)
323                                 provider = CultureInfo.CurrentCulture;
324
325                         if (format == null)
326                                 format = string.Empty;
327
328                         string separator = ",";
329                         NumberFormatInfo numberFormat =
330                                 provider.GetFormat (typeof (NumberFormatInfo)) as NumberFormatInfo;
331                         if (numberFormat != null &&
332                             numberFormat.NumberDecimalSeparator == separator)
333                                 separator = ";";
334
335                         string rectFormat = String.Format (
336                                 "{{0:{0}}}{1}{{1:{0}}}{1}{{2:{0}}}{1}{{3:{0}}}",
337                                 format, separator);
338                         return String.Format (provider, rectFormat,
339                                 _x, _y, _width, _height);
340                 }
341
342                 public static Rect Empty { 
343                         get {
344                                 Rect r = new Rect ();
345                                 r._x = r._y = Double.PositiveInfinity;
346                                 r._width = r._height = Double.NegativeInfinity;
347                                 return r;
348                         } 
349                 }
350                 
351                 public bool IsEmpty { 
352                         get {
353                                 return (_x == Double.PositiveInfinity &&
354                                         _y == Double.PositiveInfinity &&
355                                         _width == Double.NegativeInfinity &&
356                                         _height == Double.NegativeInfinity);
357                         }
358                 }
359                 
360                 public Point Location { 
361                         get {
362                                 return new Point (_x, _y);
363                         }
364                         set {
365                                 if (IsEmpty)
366                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
367
368                                 _x = value.X;
369                                 _y = value.Y;
370                         }
371                 }
372                 
373                 public Size Size { 
374                         get { 
375                                 if (IsEmpty)
376                                         return Size.Empty; 
377                                 return new Size (_width, _height);
378                         }
379                         set {
380                                 if (IsEmpty)
381                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
382
383                                 _width = value.Width;
384                                 _height = value.Height;
385                         }
386                 }
387
388                 public double X {
389                         get { return _x; }
390                         set {
391                                 if (IsEmpty)
392                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
393
394                                 _x = value;
395                         }
396                 }
397
398                 public double Y {
399                         get { return _y; }
400                         set {
401                                 if (IsEmpty)
402                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
403
404                                 _y = value;
405                         }
406                 }
407
408                 public double Width {
409                         get { return _width; }
410                         set {
411                                 if (IsEmpty)
412                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
413
414                                 if (value < 0)
415                                         throw new ArgumentException ("width must be non-negative.");
416
417                                 _width = value;
418                         }
419                 }
420
421                 public double Height {
422                         get { return _height; }
423                         set {
424                                 if (IsEmpty)
425                                         throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
426
427                                 if (value < 0)
428                                         throw new ArgumentException ("height must be non-negative.");
429
430                                 _height = value;
431                         }
432                 }
433
434                 public double Left { 
435                         get { return _x; }
436                 }
437
438                 public double Top { 
439                         get { return _y; }
440                 }
441                 
442                 public double Right { 
443                         get { return _x + _width; }
444                 }
445                 
446                 public double Bottom { 
447                         get { return _y + _height; }
448                 }
449                 
450                 public Point TopLeft { 
451                         get { return new Point (Left, Top); }
452                 }
453                 
454                 public Point TopRight { 
455                         get { return new Point (Right, Top); }
456                 }
457                 
458                 public Point BottomLeft { 
459                         get { return new Point (Left, Bottom); }
460                 }
461
462                 public Point BottomRight { 
463                         get { return new Point (Right, Bottom); }
464                 }
465                 
466                 double _x;
467                 double _y;
468                 double _width;
469                 double _height;
470         }
471 }