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:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
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.
20 // Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
23 // Chris Toshok <toshok@novell.com>
24 // Sebastien Pouliot <sebastien@ximian.com>
28 using System.ComponentModel;
29 using System.Globalization;
31 using System.Windows.Converters;
32 using System.Windows.Markup;
33 using System.Windows.Media;
35 namespace System.Windows {
38 [ValueSerializer (typeof (RectValueSerializer))]
39 [TypeConverter (typeof (RectConverter))]
40 public struct Rect : IFormattable
42 public Rect (Size size)
49 public Rect (Point point, Vector vector) : this (point, Point.Add (point, vector))
52 public Rect (Point point1, Point point2)
54 if (point1.X < point2.X) {
56 width = point2.X - point1.X;
60 width = point1.X - point2.X;
63 if (point1.Y < point2.Y) {
65 height = point2.Y - point1.Y;
69 height = point1.Y - point2.Y;
73 public Rect (double x, double y, double width, double height)
75 if (width < 0 || height < 0)
76 throw new ArgumentException ("width and height must be non-negative.");
83 public Rect (Point location, Size size)
91 public bool Equals (Rect rect)
93 return (x == rect.X &&
95 width == rect.Width &&
96 height == rect.Height);
99 public static bool operator != (Rect rect1, Rect rect2)
101 return !(rect1.Location == rect2.Location && rect1.Size == rect2.Size);
104 public static bool operator == (Rect rect1, Rect rect2)
106 return rect1.Location == rect2.Location && rect1.Size == rect2.Size;
109 public override bool Equals (object o)
114 return Equals ((Rect)o);
117 public static bool Equals (Rect rect1, Rect rect2)
119 return rect1.Equals (rect2);
122 public override int GetHashCode ()
124 throw new NotImplementedException ();
127 public bool Contains (Rect rect)
129 if (rect.Left < this.Left ||
130 rect.Right > this.Right)
133 if (rect.Top < this.Top ||
134 rect.Bottom > this.Bottom)
140 public bool Contains (double x, double y)
142 if (x < Left || x > Right)
144 if (y < Top || y > Bottom)
150 public bool Contains (Point p)
152 return Contains (p.X, p.Y);
155 public static Rect Inflate (Rect rect, double width, double height)
157 if (width < rect.Width * -2)
159 if (height < rect.Height * -2)
163 result.Inflate (width, height);
167 public static Rect Inflate (Rect rect, Size size)
169 return Rect.Inflate (rect, size.Width, size.Height);
172 public void Inflate (double width, double height)
174 // XXX any error checking like in the static case?
178 this.width += 2*width;
179 this.height += 2*height;
182 public void Inflate (Size size)
184 Inflate (size.Width, size.Height);
187 public bool IntersectsWith(Rect rect)
189 return !((Left >= rect.Right) || (Right <= rect.Left) ||
190 (Top >= rect.Bottom) || (Bottom <= rect.Top));
193 public void Intersect(Rect rect)
195 double _x = Math.Max (x, rect.x);
196 double _y = Math.Max (y, rect.y);
197 double _width = Math.Min (Right, rect.Right) - _x;
198 double _height = Math.Min (Bottom, rect.Bottom) - _y;
200 if (_width < 0 || _height < 0) {
201 x = y = Double.PositiveInfinity;
202 width = height = Double.NegativeInfinity;
212 public static Rect Intersect(Rect rect1, Rect rect2)
215 result.Intersect (rect2);
219 public void Offset(double offsetX, double offsetY)
225 public static Rect Offset(Rect rect, double offsetX, double offsetY)
228 result.Offset (offsetX, offsetY);
232 public void Offset (Vector offsetVector)
238 public static Rect Offset (Rect rect, Vector offsetVector)
241 result.Offset (offsetVector);
245 public void Scale(double scaleX, double scaleY)
253 public void Transform (Matrix matrix)
255 throw new NotImplementedException ();
258 public static Rect Transform (Rect rect, Matrix matrix)
261 result.Transform (matrix);
265 public static Rect Union(Rect rect1, Rect rect2)
268 result.Union (rect2);
272 public static Rect Union(Rect rect, Point point)
275 result.Union (point);
279 public void Union(Rect rect)
281 x = Math.Min (x, rect.x);
282 y = Math.Min (y, rect.y);
283 width = Math.Max (Right, rect.Right) - x;
284 height = Math.Max (Bottom, rect.Bottom) - y;
287 public void Union(Point point)
289 Union (new Rect (point, point));
292 public static Rect Parse (string source)
294 throw new NotImplementedException ();
297 public override string ToString ()
299 return ToString (null);
302 public string ToString (IFormatProvider provider)
304 return ToString (null, provider);
307 string IFormattable.ToString (string format, IFormatProvider provider)
309 return ToString (format, provider);
312 private string ToString (string format, IFormatProvider provider)
317 if (provider == null)
318 provider = CultureInfo.CurrentCulture;
321 format = string.Empty;
323 string separator = ",";
324 NumberFormatInfo numberFormat =
325 provider.GetFormat (typeof (NumberFormatInfo)) as NumberFormatInfo;
326 if (numberFormat != null &&
327 numberFormat.NumberDecimalSeparator == separator)
330 string rectFormat = String.Format (
331 "{{0:{0}}}{1}{{1:{0}}}{1}{{2:{0}}}{1}{{3:{0}}}",
333 return String.Format (provider, rectFormat,
334 x, y, width, height);
337 public static Rect Empty {
339 Rect r = new Rect ();
340 r.x = r.y = Double.PositiveInfinity;
341 r.width = r.height = Double.NegativeInfinity;
346 public bool IsEmpty {
348 return (x == Double.PositiveInfinity &&
349 y == Double.PositiveInfinity &&
350 width == Double.NegativeInfinity &&
351 height == Double.NegativeInfinity);
355 public Point Location {
357 return new Point (x, y);
361 throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
372 return new Size (width, height);
376 throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
379 height = value.Height;
387 throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
397 throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
403 public double Width {
404 get { return width; }
407 throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
410 throw new ArgumentException ("width must be non-negative.");
416 public double Height {
417 get { return height; }
420 throw new InvalidOperationException ("Cannot modify this property on the Empty Rect.");
423 throw new ArgumentException ("height must be non-negative.");
437 public double Right {
438 get { return x + width; }
441 public double Bottom {
442 get { return y + height; }
445 public Point TopLeft {
446 get { return new Point (Left, Top); }
449 public Point TopRight {
450 get { return new Point (Right, Top); }
453 public Point BottomLeft {
454 get { return new Point (Left, Bottom); }
457 public Point BottomRight {
458 get { return new Point (Right, Bottom); }