EllipseGeometry.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / EllipseGeometry.cs / 1305600 / EllipseGeometry.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2001
//
//  File:       EllipseGeometry.cs 
//-----------------------------------------------------------------------------
 
using System; 
using MS.Internal;
using System.ComponentModel; 
using System.ComponentModel.Design.Serialization;
using System.Reflection;
using System.Collections;
using System.Text; 
using System.Globalization;
using System.Windows.Media; 
using System.Windows.Media.Composition; 
using System.Windows;
using System.Text.RegularExpressions; 
using System.Windows.Media.Animation;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security; 
using System.Security.Permissions;
using SR=MS.Internal.PresentationCore.SR; 
using SRID=MS.Internal.PresentationCore.SRID; 

namespace System.Windows.Media 
{
    /// 
    /// This is the Geometry class for Circles and Ellipses
    ///  
    public sealed partial class EllipseGeometry : Geometry
    { 
        #region Constructors 

        ///  
        ///
        /// 
        public EllipseGeometry()
        { 
        }
 
        ///  
        /// Constructor - sets the ellipse to the paramters with the given transformation
        ///  
        public EllipseGeometry(Rect rect)
        {
            if (rect.IsEmpty)
            { 
                throw new System.ArgumentException(SR.Get(SRID.Rect_Empty, "rect"));
            } 
 
            RadiusX = (rect.Right - rect.X) * (1.0 / 2.0);
            RadiusY = (rect.Bottom - rect.Y) * (1.0 / 2.0); 
            Center = new Point(rect.X + RadiusX, rect.Y + RadiusY);
        }

        ///  
        /// Constructor - sets the ellipse to the parameters
        ///  
        public EllipseGeometry( 
            Point center,
            double radiusX, 
            double radiusY)
        {
            Center = center;
            RadiusX = radiusX; 
            RadiusY = radiusY;
        } 
 
        /// 
        /// Constructor - sets the ellipse to the parameters 
        /// 
        public EllipseGeometry(
            Point center,
            double radiusX, 
            double radiusY,
            Transform transform) : this(center, radiusX, radiusY) 
        { 
            Transform = transform;
        } 

        #endregion

        ///  
        /// Gets the bounds of this Geometry as an axis-aligned bounding box
        ///  
        public override Rect Bounds 
        {
            get 
            {
                ReadPreamble();

                Rect boundsRect; 

                Transform transform = Transform; 
 
                if (transform == null || transform.IsIdentity)
                { 
                    Point currentCenter = Center;
                    Double currentRadiusX = RadiusX;
                    Double currentRadiusY = RadiusY;
 
                    boundsRect = new Rect(
                        currentCenter.X - Math.Abs(currentRadiusX), 
                        currentCenter.Y - Math.Abs(currentRadiusY), 
                        2.0 * Math.Abs(currentRadiusX),
                        2.0 * Math.Abs(currentRadiusY)); 
                }
                else
                {
                    // 
                    //
 
 

 

                    Matrix geometryMatrix;

                    Transform.GetTransformValue(transform, out geometryMatrix); 

                    boundsRect = EllipseGeometry.GetBoundsHelper( 
                        null /* no pen */, 
                        Matrix.Identity,
                        Center, 
                        RadiusX,
                        RadiusY,
                        geometryMatrix,
                        StandardFlatteningTolerance, 
                        ToleranceType.Absolute);
                } 
 
                return boundsRect;
            } 

        }

        ///  
        /// Returns the axis-aligned bounding rectangle when stroked with a pen, after applying
        /// the supplied transform (if non-null). 
        ///  
        internal override Rect GetBoundsInternal(Pen pen, Matrix matrix, double tolerance, ToleranceType type)
        { 
            Matrix geometryMatrix;

            Transform.GetTransformValue(Transform, out geometryMatrix);
 
            return EllipseGeometry.GetBoundsHelper(
                pen, 
                matrix, 
                Center,
                RadiusX, 
                RadiusY,
                geometryMatrix,
                tolerance,
                type); 
        }
 
        ///  
        /// Critical - it calls a critical method, Geometry.GetBoundsHelper and has an unsafe block
        /// TreatAsSafe - returning an EllipseGeometry's bounds is considered safe 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal static Rect GetBoundsHelper(Pen pen, Matrix worldMatrix, Point center, double radiusX, double radiusY,
                                             Matrix geometryMatrix, double tolerance, ToleranceType type) 
        {
            Rect rect; 
 
            Debug.Assert(worldMatrix != null);
            Debug.Assert(geometryMatrix != null); 

            if ( (pen == null || pen.DoesNotContainGaps) &&
                worldMatrix.IsIdentity && geometryMatrix.IsIdentity)
            { 
                double strokeThickness = 0.0;
 
                if (Pen.ContributesToBounds(pen)) 
                {
                    strokeThickness = Math.Abs(pen.Thickness); 
                }

                rect = new Rect(
                    center.X - Math.Abs(radiusX)-0.5*strokeThickness, 
                    center.Y - Math.Abs(radiusY)-0.5*strokeThickness,
                    2.0 * Math.Abs(radiusX)+strokeThickness, 
                    2.0 * Math.Abs(radiusY)+strokeThickness); 
            }
            else 
            {
                unsafe
                {
                    Point * pPoints = stackalloc Point[(int)c_pointCount]; 
                    EllipseGeometry.GetPointList(pPoints, c_pointCount, center, radiusX, radiusY);
 
                    fixed (byte *pTypes = EllipseGeometry.s_roundedPathTypes) 
                    {
                        rect = Geometry.GetBoundsHelper( 
                            pen,
                            &worldMatrix,
                            pPoints,
                            pTypes, 
                            c_pointCount,
                            c_segmentCount, 
                            &geometryMatrix, 
                            tolerance,
                            type, 
                            false); // skip hollows - meaningless here, this is never a hollow
                    }
                }
            } 

            return rect; 
        } 

        ///  
        /// Critical - contains unsafe block and calls critical method Geometry.ContainsInternal.
        /// TreatAsSafe - as this doesn't expose anything sensitive.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override bool ContainsInternal(Pen pen, Point hitPoint, double tolerance, ToleranceType type)
        { 
            unsafe 
            {
                Point *pPoints = stackalloc Point[(int)GetPointCount()]; 
                EllipseGeometry.GetPointList(pPoints, GetPointCount(), Center, RadiusX, RadiusY);

                fixed (byte* pTypes = GetTypeList())
                { 
                    return ContainsInternal(
                        pen, 
                        hitPoint, 
                        tolerance,
                        type, 
                        pPoints,
                        GetPointCount(),
                        pTypes,
                        GetSegmentCount()); 
                }
            } 
        } 

        #region Public Methods 

        /// 
        /// Returns true if this geometry is empty
        ///  
        public override bool IsEmpty()
        { 
            return false; 
        }
 
        /// 
        /// Returns true if this geometry may have curved segments
        /// 
        public override bool MayHaveCurves() 
        {
            return true; 
        } 

        ///  
        /// Gets the area of this geometry
        /// 
        /// The computational error tolerance
        /// The way the error tolerance will be interpreted - realtive or absolute 
        public override double GetArea(double tolerance, ToleranceType type)
        { 
            ReadPreamble(); 

            double area = Math.Abs(RadiusX * RadiusY) * Math.PI; 

            // Adjust to internal transformation
            Transform transform = Transform;
            if (transform != null && !transform.IsIdentity) 
            {
                area *= Math.Abs(transform.Value.Determinant); 
            } 

            return area; 
        }

        #endregion Public Methods
 
        internal override PathFigureCollection GetTransformedFigureCollection(Transform transform)
        { 
            Point [] points = GetPointList(); 

            // Get the combined transform argument with the internal transform 
            Matrix matrix = GetCombinedMatrix(transform);
            if (!matrix.IsIdentity)
            {
                for (int i=0; i
        /// GetAsPathGeometry - return a PathGeometry version of this Geometry 
        /// 
        internal override PathGeometry GetAsPathGeometry()
        {
            PathStreamGeometryContext ctx = new PathStreamGeometryContext(FillRule.EvenOdd, Transform); 
            PathGeometry.ParsePathGeometryData(GetPathGeometryData(), ctx);
 
            return ctx.GetPathGeometry(); 
        }
 
        /// 
        /// GetPathGeometryData - returns a byte[] which contains this Geometry represented
        /// as a path geometry's serialized format.
        ///  
        internal override PathGeometryData GetPathGeometryData()
        { 
            if (IsObviouslyEmpty()) 
            {
                return Geometry.GetEmptyPathGeometryData(); 
            }

            PathGeometryData data = new PathGeometryData();
            data.FillRule = FillRule.EvenOdd; 
            data.Matrix = CompositionResourceManager.TransformToMilMatrix3x2D(Transform);
 
            Point[] points = GetPointList(); 

            ByteStreamGeometryContext ctx = new ByteStreamGeometryContext(); 

            ctx.BeginFigure(points[0], true /* is filled */, true /* is closed */);

            // i == 0, 3, 6, 9 
            for (int i = 0; i < 12; i += 3)
            { 
                ctx.BezierTo(points[i + 1], points[i + 2], points[i + 3], true /* is stroked */, true /* is smooth join */); 
            }
 
            ctx.Close();
            data.SerializedData = ctx.GetData();

            return data; 
        }
 
        ///  
        /// 
        ///  
        /// 
        /// Critical - Calls critical code
        /// TreatAsSafe - returning a EllipseGeometry's point list is considered safe
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private Point[] GetPointList() 
        { 
            Point[] points = new Point[GetPointCount()];
 
            unsafe
            {
                fixed(Point *pPoints = points)
                { 
                    EllipseGeometry.GetPointList(pPoints, GetPointCount(), Center, RadiusX, RadiusY);
                } 
            } 

            return points; 
        }

        /// 
        /// Critical - Accepts pointer arguments 
        /// 
        [SecurityCritical] 
        private unsafe static void GetPointList(Point * points, uint pointsCount, Point center, double radiusX, double radiusY) 
        {
            Invariant.Assert(pointsCount >= c_pointCount); 

            radiusX = Math.Abs(radiusX);
            radiusY = Math.Abs(radiusY);
 
            // Set the X coordinates
            double mid = radiusX * c_arcAsBezier; 
 
            points[0].X = points[1].X = points[11].X = points[12].X = center.X + radiusX;
            points[2].X = points[10].X = center.X + mid; 
            points[3].X = points[9].X = center.X;
            points[4].X = points[8].X = center.X - mid;
            points[5].X = points[6].X = points[7].X = center.X - radiusX;
 
            // Set the Y coordinates
            mid = radiusY * c_arcAsBezier; 
 
            points[2].Y = points[3].Y = points[4].Y = center.Y + radiusY;
            points[1].Y = points[5].Y = center.Y + mid; 
            points[0].Y = points[6].Y = points[12].Y = center.Y;
            points[7].Y = points[11].Y = center.Y - mid;
            points[8].Y = points[9].Y = points[10].Y = center.Y - radiusY;
        } 

        private byte[] GetTypeList() { return s_roundedPathTypes; } 
        private uint GetPointCount() { return c_pointCount; } 
        private uint GetSegmentCount() { return c_segmentCount; }
 
        #region Static Data

        // Approximating a 1/4 circle with a Bezier curve                _
        internal const double c_arcAsBezier = 0.5522847498307933984; // =( \/2 - 1)*4/3 

        private const UInt32 c_segmentCount = 4; 
        private const UInt32 c_pointCount = 13; 

        private const byte c_smoothBezier = (byte)MILCoreSegFlags.SegTypeBezier  | 
                                              (byte)MILCoreSegFlags.SegIsCurved    |
                                              (byte)MILCoreSegFlags.SegSmoothJoin;

        private static readonly byte[] s_roundedPathTypes = { 
            (byte)MILCoreSegFlags.SegTypeBezier |
            (byte)MILCoreSegFlags.SegIsCurved   | 
            (byte)MILCoreSegFlags.SegSmoothJoin | 
            (byte)MILCoreSegFlags.SegClosed,
            c_smoothBezier, 
            c_smoothBezier,
            c_smoothBezier
        };
 
        #endregion
    } 
} 


// 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