Rect.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Base / System / Windows / Rect.cs / 1 / Rect.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2001, 2002
//
//  File: Rect.cs 
//-----------------------------------------------------------------------------
using System; 
using System.Diagnostics; 
using System.ComponentModel;
using System.ComponentModel.Design.Serialization; 
using System.Reflection;
using System.Text;
using System.Collections;
using System.Globalization; 
using MS.Internal;
using System.Windows; 
using System.Windows.Media; 
using System.Runtime.InteropServices;
using System.Security; 
using System.Security.Permissions;

namespace System.Windows
{ 
    /// 
    /// Rect - The primitive which represents a rectangle.  Rects are stored as 
    /// X, Y (Location) and Width and Height (Size).  As a result, Rects cannot have negative 
    /// Width or Height.
    ///  
    public partial struct Rect
    {
        #region Constructors
 
        /// 
        /// Constructor which sets the initial values to the values of the parameters 
        ///  
        public Rect(Point location,
                    Size size) 
        {
            if (size.IsEmpty)
            {
                this = s_empty; 
            }
            else 
            { 
                _x = location._x;
                _y = location._y; 
                _width = size._width;
                _height = size._height;
            }
        } 

        ///  
        /// Constructor which sets the initial values to the values of the parameters. 
        /// Width and Height must be non-negative
        ///  
        public Rect(double x,
                    double y,
                    double width,
                    double height) 
        {
            if (width < 0 || height < 0) 
            { 
                throw new System.ArgumentException(SR.Get(SRID.Size_WidthAndHeightCannotBeNegative));
            } 

            _x    = x;
            _y     = y;
            _width   = width; 
            _height  = height;
        } 
 
        /// 
        /// Constructor which sets the initial values to bound the two points provided. 
        /// 
        public Rect(Point point1,
                    Point point2)
        { 
            _x = Math.Min(point1._x, point2._x);
            _y = Math.Min(point1._y, point2._y); 
 
            //  Max with 0 to prevent double weirdness from causing us to be (-epsilon..0)
            _width = Math.Max(Math.Max(point1._x, point2._x) - _x, 0); 
            _height = Math.Max(Math.Max(point1._y, point2._y) - _y, 0);
        }

        ///  
        /// Constructor which sets the initial values to bound the point provided and the point
        /// which results from point + vector. 
        ///  
        public Rect(Point point,
                    Vector vector): this(point, point+vector) 
        {
        }

        ///  
        /// Constructor which sets the initial values to bound the (0,0) point and the point
        /// that results from (0,0) + size. 
        ///  
        public Rect(Size size)
        { 
            if(size.IsEmpty)
            {
                this = s_empty;
            } 
            else
            { 
                _x = _y = 0; 
                _width = size.Width;
                _height = size.Height; 
            }
        }

        #endregion Constructors 

        #region Statics 
 
        /// 
        /// Empty - a static property which provides an Empty rectangle.  X and Y are positive-infinity 
        /// and Width and Height are negative infinity.  This is the only situation where Width or
        /// Height can be negative.
        /// 
        public static Rect Empty 
        {
            get 
            { 
                return s_empty;
            } 
        }

        #endregion Statics
 
        #region Public Properties
 
        ///  
        /// IsEmpty - this returns true if this rect is the Empty rectangle.
        /// Note: If width or height are 0 this Rectangle still contains a 0 or 1 dimensional set 
        /// of points, so this method should not be used to check for 0 area.
        /// 
        public bool IsEmpty
        { 
            get
            { 
                // The funny width and height tests are to handle NaNs 
                Debug.Assert((!(_width < 0) && !(_height < 0)) || (this == Empty));
 
                return _width < 0;
            }
        }
 
        /// 
        /// Location - The Point representing the origin of the Rectangle 
        ///  
        public Point Location
        { 
            get
            {
                return new Point(_x, _y);
            } 
            set
            { 
                if (IsEmpty) 
                {
                    throw new System.InvalidOperationException(SR.Get(SRID.Rect_CannotModifyEmptyRect)); 
                }

                _x = value._x;
                _y = value._y; 
            }
        } 
 
        /// 
        /// Size - The Size representing the area of the Rectangle 
        /// 
        public Size Size
        {
            get 
            {
                if (IsEmpty) 
                    return Size.Empty; 
                return new Size(_width, _height);
            } 
            set
            {
                if (value.IsEmpty)
                { 
                    this = s_empty;
                } 
                else 
                {
                    if (IsEmpty) 
                    {
                        throw new System.InvalidOperationException(SR.Get(SRID.Rect_CannotModifyEmptyRect));
                    }
 
                    _width = value._width;
                    _height = value._height; 
                } 
            }
        } 

        /// 
        /// X - The X coordinate of the Location.
        /// If this is the empty rectangle, the value will be positive infinity. 
        /// If this rect is Empty, setting this property is illegal.
        ///  
        public double X 
        {
            get 
            {
                return _x;
            }
            set 
            {
                if (IsEmpty) 
                { 
                    throw new System.InvalidOperationException(SR.Get(SRID.Rect_CannotModifyEmptyRect));
                } 

                _x = value;
            }
 
        }
 
        ///  
        /// Y - The Y coordinate of the Location
        /// If this is the empty rectangle, the value will be positive infinity. 
        /// If this rect is Empty, setting this property is illegal.
        /// 
        public double Y
        { 
            get
            { 
                return _y; 
            }
            set 
            {
                if (IsEmpty)
                {
                    throw new System.InvalidOperationException(SR.Get(SRID.Rect_CannotModifyEmptyRect)); 
                }
 
                _y = value; 
            }
        } 

        /// 
        /// Width - The Width component of the Size.  This cannot be set to negative, and will only
        /// be negative if this is the empty rectangle, in which case it will be negative infinity. 
        /// If this rect is Empty, setting this property is illegal.
        ///  
        public double Width 
        {
            get 
            {
                return _width;
            }
            set 
            {
                if (IsEmpty) 
                { 
                    throw new System.InvalidOperationException(SR.Get(SRID.Rect_CannotModifyEmptyRect));
                } 

                if (value < 0)
                {
                    throw new System.ArgumentException(SR.Get(SRID.Size_WidthCannotBeNegative)); 
                }
 
                _width = value; 
            }
        } 

        /// 
        /// Height - The Height component of the Size.  This cannot be set to negative, and will only
        /// be negative if this is the empty rectangle, in which case it will be negative infinity. 
        /// If this rect is Empty, setting this property is illegal.
        ///  
        public double Height 
        {
            get 
            {
                return _height;
            }
            set 
            {
                if (IsEmpty) 
                { 
                    throw new System.InvalidOperationException(SR.Get(SRID.Rect_CannotModifyEmptyRect));
                } 

                if (value < 0)
                {
                    throw new System.ArgumentException(SR.Get(SRID.Size_HeightCannotBeNegative)); 
                }
 
                _height = value; 
            }
        } 

        /// 
        /// Left Property - This is a read-only alias for X
        /// If this is the empty rectangle, the value will be positive infinity. 
        /// 
        public double Left 
        { 
            get
            { 
                return _x;
            }
        }
 
        /// 
        /// Top Property - This is a read-only alias for Y 
        /// If this is the empty rectangle, the value will be positive infinity. 
        /// 
        public double Top 
        {
            get
            {
                return _y; 
            }
        } 
 
        /// 
        /// Right Property - This is a read-only alias for X + Width 
        /// If this is the empty rectangle, the value will be negative infinity.
        /// 
        public double Right
        { 
            get
            { 
                if (IsEmpty) 
                {
                    return Double.NegativeInfinity; 
                }

                return _x + _width;
            } 
        }
 
        ///  
        /// Bottom Property - This is a read-only alias for Y + Height
        /// If this is the empty rectangle, the value will be negative infinity. 
        /// 
        public double Bottom
        {
            get 
            {
                if (IsEmpty) 
                { 
                    return Double.NegativeInfinity;
                } 

                return _y + _height;
            }
        } 

        ///  
        /// TopLeft Property - This is a read-only alias for the Point which is at X, Y 
        /// If this is the empty rectangle, the value will be positive infinity, positive infinity.
        ///  
        public Point TopLeft
        {
            get
            { 
                return new Point(Left, Top);
            } 
        } 

        ///  
        /// TopRight Property - This is a read-only alias for the Point which is at X + Width, Y
        /// If this is the empty rectangle, the value will be negative infinity, positive infinity.
        /// 
        public Point TopRight 
        {
            get 
            { 
                return new Point(Right, Top);
            } 
        }

        /// 
        /// BottomLeft Property - This is a read-only alias for the Point which is at X, Y + Height 
        /// If this is the empty rectangle, the value will be positive infinity, negative infinity.
        ///  
        public Point BottomLeft 
        {
            get 
            {
                return new Point(Left, Bottom);
            }
        } 

        ///  
        /// BottomRight Property - This is a read-only alias for the Point which is at X + Width, Y + Height 
        /// If this is the empty rectangle, the value will be negative infinity, negative infinity.
        ///  
        public Point BottomRight
        {
            get
            { 
                return new Point(Right, Bottom);
            } 
        } 
        #endregion Public Properties
 
        #region Public Methods

        /// 
        /// Contains - Returns true if the Point is within the rectangle, inclusive of the edges. 
        /// Returns false otherwise.
        ///  
        ///  The point which is being tested  
        /// 
        /// Returns true if the Point is within the rectangle. 
        /// Returns false otherwise
        /// 
        public bool Contains(Point point)
        { 
            return Contains(point._x, point._y);
        } 
 
        /// 
        /// Contains - Returns true if the Point represented by x,y is within the rectangle inclusive of the edges. 
        /// Returns false otherwise.
        /// 
        ///  X coordinate of the point which is being tested 
        ///  Y coordinate of the point which is being tested  
        /// 
        /// Returns true if the Point represented by x,y is within the rectangle. 
        /// Returns false otherwise. 
        /// 
        public bool Contains(double x, double y) 
        {
            if (IsEmpty)
            {
                return false; 
            }
 
            return ContainsInternal(x,y); 
        }
 
        /// 
        /// Contains - Returns true if the Rect non-Empty and is entirely contained within the
        /// rectangle, inclusive of the edges.
        /// Returns false otherwise 
        /// 
        public bool Contains(Rect rect) 
        { 
            if (IsEmpty || rect.IsEmpty)
            { 
                return false;
            }

            return (_x <= rect._x && 
                    _y <= rect._y &&
                    _x+_width >= rect._x+rect._width && 
                    _y+_height >= rect._y+rect._height ); 
        }
 
        /// 
        /// IntersectsWith - Returns true if the Rect intersects with this rectangle
        /// Returns false otherwise.
        /// Note that if one edge is coincident, this is considered an intersection. 
        /// 
        ///  
        /// Returns true if the Rect intersects with this rectangle 
        /// Returns false otherwise.
        /// or Height 
        /// 
        ///  Rect 
        public bool IntersectsWith(Rect rect)
        { 
            if (IsEmpty || rect.IsEmpty)
            { 
                return false; 
            }
 
            return (rect.Left <= Right) &&
                   (rect.Right >= Left) &&
                   (rect.Top <= Bottom) &&
                   (rect.Bottom >= Top); 
        }
 
        ///  
        /// Intersect - Update this rectangle to be the intersection of this and rect
        /// If either this or rect are Empty, the result is Empty as well. 
        /// 
        ///  The rect to intersect with this 
        public void Intersect(Rect rect)
        { 
            if (!this.IntersectsWith(rect))
            { 
                this = Empty; 
            }
            else 
            {
                double left   = Math.Max(Left, rect.Left);
                double top    = Math.Max(Top, rect.Top);
 
                //  Max with 0 to prevent double weirdness from causing us to be (-epsilon..0)
                _width = Math.Max(Math.Min(Right, rect.Right) - left, 0); 
                _height = Math.Max(Math.Min(Bottom, rect.Bottom) - top, 0); 

                _x = left; 
                _y = top;
            }
        }
 
        /// 
        /// Intersect - Return the result of the intersection of rect1 and rect2. 
        /// If either this or rect are Empty, the result is Empty as well. 
        /// 
        public static Rect Intersect(Rect rect1, Rect rect2) 
        {
            rect1.Intersect(rect2);
            return rect1;
        } 

        ///  
        /// Union - Update this rectangle to be the union of this and rect. 
        /// 
        public void Union(Rect rect) 
        {
            if (IsEmpty)
            {
                this = rect; 
            }
            else if (!rect.IsEmpty) 
            { 
                double left = Math.Min(Left, rect.Left);
                double top = Math.Min(Top, rect.Top); 


                // We need this check so that the math does not result in NaN
                if ((rect.Width == Double.PositiveInfinity) || (Width == Double.PositiveInfinity)) 
                {
                    _width = Double.PositiveInfinity; 
                } 
                else
                { 
                    //  Max with 0 to prevent double weirdness from causing us to be (-epsilon..0)
                    double maxRight = Math.Max(Right, rect.Right);
                    _width = Math.Max(maxRight - left, 0);
                } 

                // We need this check so that the math does not result in NaN 
                if ((rect.Height == Double.PositiveInfinity) || (Height == Double.PositiveInfinity)) 
                {
                    _height = Double.PositiveInfinity; 
                }
                else
                {
                    //  Max with 0 to prevent double weirdness from causing us to be (-epsilon..0) 
                    double maxBottom = Math.Max(Bottom, rect.Bottom);
                    _height = Math.Max(maxBottom - top, 0); 
                } 

                _x = left; 
                _y = top;
            }
        }
 
        /// 
        /// Union - Return the result of the union of rect1 and rect2. 
        ///  
        public static Rect Union(Rect rect1, Rect rect2)
        { 
            rect1.Union(rect2);
            return rect1;
        }
 
        /// 
        /// Union - Update this rectangle to be the union of this and point. 
        ///  
        public void Union(Point point)
        { 
            Union(new Rect(point, point));
        }

        ///  
        /// Union - Return the result of the union of rect and point.
        ///  
        public static Rect Union(Rect rect, Point point) 
        {
            rect.Union(new Rect(point, point)); 
            return rect;
        }

        ///  
        /// Offset - translate the Location by the offset provided.
        /// If this is Empty, this method is illegal. 
        ///  
        public void Offset(Vector offsetVector)
        { 
            if (IsEmpty)
            {
                throw new System.InvalidOperationException(SR.Get(SRID.Rect_CannotCallMethod));
            } 

            _x += offsetVector._x; 
            _y += offsetVector._y; 
        }
 
        /// 
        /// Offset - translate the Location by the offset provided
        /// If this is Empty, this method is illegal.
        ///  
        public void Offset(double offsetX, double offsetY)
        { 
            if (IsEmpty) 
            {
                throw new System.InvalidOperationException(SR.Get(SRID.Rect_CannotCallMethod)); 
            }

            _x += offsetX;
            _y += offsetY; 
        }
 
        ///  
        /// Offset - return the result of offsetting rect by the offset provided
        /// If this is Empty, this method is illegal. 
        /// 
        public static Rect Offset(Rect rect, Vector offsetVector)
        {
            rect.Offset(offsetVector.X, offsetVector.Y); 
            return rect;
        } 
 
        /// 
        /// Offset - return the result of offsetting rect by the offset provided 
        /// If this is Empty, this method is illegal.
        /// 
        public static Rect Offset(Rect rect, double offsetX, double offsetY)
        { 
            rect.Offset(offsetX, offsetY);
            return rect; 
        } 

        ///  
        /// Inflate - inflate the bounds by the size provided, in all directions
        /// If this is Empty, this method is illegal.
        /// 
        public void Inflate(Size size) 
        {
            Inflate(size._width, size._height); 
        } 

        ///  
        /// Inflate - inflate the bounds by the size provided, in all directions.
        /// If -width is > Width / 2 or -height is > Height / 2, this Rect becomes Empty
        /// If this is Empty, this method is illegal.
        ///  
        public void Inflate(double width, double height)
        { 
            if (IsEmpty) 
            {
                throw new System.InvalidOperationException(SR.Get(SRID.Rect_CannotCallMethod)); 
            }

            _x -= width;
            _y -= height; 

            // Do two additions rather than multiplication by 2 to avoid spurious overflow 
            // That is: (A + 2 * B) != ((A + B) + B) if 2*B overflows. 
            // Note that multiplication by 2 might work in this case because A should start
            // positive & be "clamped" to positive after, but consider A = Inf & B = -MAX. 
            _width += width;
            _width += width;
            _height += height;
            _height += height; 

            // We catch the case of inflation by less than -width/2 or -height/2 here.  This also 
            // maintains the invariant that either the Rect is Empty or _width and _height are 
            // non-negative, even if the user parameters were NaN, though this isn't strictly maintained
            // by other methods. 
            if ( !(_width >= 0 && _height >= 0) )
            {
                this = s_empty;
            } 
        }
 
        ///  
        /// Inflate - return the result of inflating rect by the size provided, in all directions
        /// If this is Empty, this method is illegal. 
        /// 
        public static Rect Inflate(Rect rect, Size size)
        {
            rect.Inflate(size._width, size._height); 
            return rect;
        } 
 
        /// 
        /// Inflate - return the result of inflating rect by the size provided, in all directions 
        /// If this is Empty, this method is illegal.
        /// 
        public static Rect Inflate(Rect rect, double width, double height)
        { 
            rect.Inflate(width, height);
            return rect; 
        } 

        ///  
        /// Returns the bounds of the transformed rectangle.
        /// The Empty Rect is not affected by this call.
        /// 
        ///  
        /// The rect which results from the transformation.
        ///  
        ///  The Rect to transform.  
        ///  The Matrix by which to transform. 
        public static Rect Transform(Rect rect, Matrix matrix) 
        {
            MatrixUtil.TransformRect(ref rect, ref matrix);
            return rect;
        } 

        ///  
        /// Updates rectangle to be the bounds of the original value transformed 
        /// by the matrix.
        /// The Empty Rect is not affected by this call. 
        /// 
        ///  Matrix 
        public void Transform(Matrix matrix)
        { 
            MatrixUtil.TransformRect(ref this, ref matrix);
        } 
 
        /// 
        /// Scale the rectangle in the X and Y directions 
        /// 
        ///  The scale in X 
        ///  The scale in Y 
        public void Scale(double scaleX, double scaleY) 
        {
            if (IsEmpty) 
            { 
                return;
            } 

            _x *= scaleX;
            _y *= scaleY;
            _width *= scaleX; 
            _height *= scaleY;
 
            // If the scale in the X dimension is negative, we need to normalize X and Width 
            if (scaleX < 0)
            { 
                // Make X the left-most edge again
                _x += _width;

                // and make Width positive 
                _width *= -1;
            } 
 
            // Do the same for the Y dimension
            if (scaleY < 0) 
            {
                // Make Y the top-most edge again
                _y += _height;
 
                // and make Height positive
                _height *= -1; 
            } 
        }
 
        #endregion Public Methods

        #region Private Methods
 
        /// 
        /// ContainsInternal - Performs just the "point inside" logic 
        ///  
        /// 
        /// bool - true if the point is inside the rect 
        /// 
        ///  The x-coord of the point to test 
        ///  The y-coord of the point to test 
        private bool ContainsInternal(double x, double y) 
        {
            // We include points on the edge as "contained". 
            // We do "x - _width <= _x" instead of "x <= _x + _width" 
            // so that this check works when _width is PositiveInfinity
            // and _x is NegativeInfinity. 
            return ((x >= _x) && (x - _width <= _x) &&
                    (y >= _y) && (y - _height <= _y));
        }
 
        static private Rect CreateEmptyRect()
        { 
            Rect rect = new Rect(); 
            // We can't set these via the property setters because negatives widths
            // are rejected in those APIs. 
            rect._x = Double.PositiveInfinity;
            rect._y = Double.PositiveInfinity;
            rect._width = Double.NegativeInfinity;
            rect._height = Double.NegativeInfinity; 
            return rect;
        } 
 
        #endregion Private Methods
 
        #region Private Fields

        private readonly static Rect s_empty = CreateEmptyRect();
 
        #endregion Private Fields
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK