Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Media / RectangleGeometry.cs / 1 / RectangleGeometry.cs
//------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2001 // // File: RectangleGeometry.cs //----------------------------------------------------------------------------- using System; using MS.Internal; 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 SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Media { ////// This is the Geometry class for Rectangles and RoundedRectangles. /// public sealed partial class RectangleGeometry : Geometry { #region Constructors ////// /// public RectangleGeometry() { } ////// Constructor - sets the rounded rectangle to equal the passed in parameters /// public RectangleGeometry(Rect rect) { Rect = rect; } ////// Constructor - sets the rounded rectangle to equal the passed in parameters /// public RectangleGeometry(Rect rect, double radiusX, double radiusY) : this(rect) { RadiusX = radiusX; RadiusY = radiusY; } ////// /// /// /// /// /// public RectangleGeometry( Rect rect, double radiusX, double radiusY, Transform transform) : this(rect, 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; Rect currentRect = Rect; Transform transform = Transform; if (currentRect.IsEmpty) { boundsRect = Rect.Empty; } else if (transform == null || transform.IsIdentity) { boundsRect = currentRect; } else { double radiusX = RadiusX; double radiusY = RadiusY; if (radiusX == 0 && radiusY == 0) { boundsRect = currentRect; transform.TransformRect(ref boundsRect); } else { // // Transformed rounded rectangles are more tricky. // // Matrix geometryMatrix; Transform.GetTransformValue(transform, out geometryMatrix); boundsRect = RectangleGeometry.GetBoundsHelper( null /* no pen */, Matrix.Identity, currentRect, radiusX, radiusY, geometryMatrix, StandardFlatteningTolerance, ToleranceType.Absolute); } } return boundsRect; } } internal override bool AreClose(Geometry geometry) { RectangleGeometry rectGeometry2 = geometry as RectangleGeometry; if (rectGeometry2 != null) { RectangleGeometry rectGeometry1 = this; Rect rect1 = rectGeometry1.Rect; Rect rect2 = rectGeometry2.Rect; return ( DoubleUtil.AreClose(rect1.X, rect2.X) && DoubleUtil.AreClose(rect1.Y, rect2.Y) && DoubleUtil.AreClose(rect1.Width, rect2.Width) && DoubleUtil.AreClose(rect1.Height, rect2.Height) && DoubleUtil.AreClose(rectGeometry1.RadiusX, rectGeometry2.RadiusX) && DoubleUtil.AreClose(rectGeometry1.RadiusY, rectGeometry2.RadiusY) && (rectGeometry1.Transform == rectGeometry2.Transform) && (rectGeometry1.IsFrozen == rectGeometry2.IsFrozen) ); } return base.AreClose(geometry); } ////// 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 worldMatrix, double tolerance, ToleranceType type) { Matrix geometryMatrix; Transform.GetTransformValue(Transform, out geometryMatrix); return RectangleGeometry.GetBoundsHelper( pen, worldMatrix, Rect, RadiusX, RadiusY, geometryMatrix, tolerance, type); } ////// Critical - it calls a critical method, Geometry.GetBoundsHelper and has an unsafe block /// TreatAsSafe - returning a RectangleGeometry's bounds is considered safe /// [SecurityCritical, SecurityTreatAsSafe] internal static Rect GetBoundsHelper(Pen pen, Matrix worldMatrix, Rect rect, double radiusX, double radiusY, Matrix geometryMatrix, double tolerance, ToleranceType type) { Rect boundingRect; Debug.Assert(worldMatrix != null); Debug.Assert(geometryMatrix != null); if (rect.IsEmpty) { boundingRect = Rect.Empty; } else if ( (pen == null || pen.DoesNotContainGaps) && geometryMatrix.IsIdentity && worldMatrix.IsIdentity) { double strokeThickness = 0.0; boundingRect = rect; if (Pen.ContributesToBounds(pen)) { strokeThickness = Math.Abs(pen.Thickness); boundingRect.X -= 0.5*strokeThickness; boundingRect.Y -= 0.5*strokeThickness; boundingRect.Width += strokeThickness; boundingRect.Height += strokeThickness; } } else { unsafe { uint pointCount, segmentCount; GetCounts(rect, radiusX, radiusY, out pointCount, out segmentCount); // We've checked that rect isn't empty above Invariant.Assert(pointCount != 0); Point * pPoints = stackalloc Point[(int)pointCount]; RectangleGeometry.GetPointList(pPoints, pointCount, rect, radiusX, radiusY); fixed (byte *pTypes = RectangleGeometry.GetTypeList(rect, radiusX, radiusY)) { boundingRect = Geometry.GetBoundsHelper( pen, &worldMatrix, pPoints, pTypes, pointCount, segmentCount, &geometryMatrix, tolerance, type, false); // skip hollows - meaningless here, this is never a hollow } } } return boundingRect; } ////// 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) { if (IsEmpty()) { return false; } double radiusX = RadiusX; double radiusY = RadiusY; Rect rect = Rect; uint pointCount = GetPointCount(rect, radiusX, radiusY); uint segmentCount = GetSegmentCount(rect, radiusX, radiusY); unsafe { Point *pPoints = stackalloc Point[(int)pointCount]; RectangleGeometry.GetPointList(pPoints, pointCount, rect, radiusX, radiusY); fixed (byte* pTypes = GetTypeList(rect, radiusX, radiusY)) { return ContainsInternal( pen, hitPoint, tolerance, type, pPoints, pointCount, pTypes, segmentCount); } } } ////// Gets the area of this geometry /// /// The computational error tolerance /// The way the error tolerance will be interpreted - relative or absolute public override double GetArea(double tolerance, ToleranceType type) { ReadPreamble(); if (IsEmpty()) { return 0.0; } double radiusX = RadiusX; double radiusY = RadiusY; Rect rect = Rect; // Get the area of the bounding rectangle double area = Math.Abs(rect.Width * rect.Height); // correct it for the rounded corners area -= Math.Abs(radiusX * radiusY) * (4.0 - Math.PI); // Adjust to internal transformation Transform transform = Transform; if (!transform.IsIdentity) { area *= Math.Abs(transform.Value.Determinant); } return area; } internal override PathFigureCollection GetTransformedFigureCollection(Transform transform) { if (IsEmpty()) { return null; } // Combine the transform argument with the internal transform Matrix matrix = GetCombinedMatrix(transform); double radiusX = RadiusX; double radiusY = RadiusY; Rect rect = Rect; if (IsRounded(radiusX, radiusY)) { Point[] points = GetPointList(rect, radiusX, radiusY); // Transform if applicable. 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); double radiusX = RadiusX; double radiusY = RadiusY; Rect rect = Rect; ByteStreamGeometryContext ctx = new ByteStreamGeometryContext(); if (IsRounded(radiusX, radiusY)) { Point[] points = GetPointList(rect, radiusX, radiusY); ctx.BeginFigure(points[0], true /* is filled */, true /* is closed */); ctx.BezierTo(points[1], points[2], points[3], true /* is stroked */, false /* is smooth join */); ctx.LineTo(points[4], true /* is stroked */, false /* is smooth join */); ctx.BezierTo(points[5], points[6], points[7], true /* is stroked */, false /* is smooth join */); ctx.LineTo(points[8], true /* is stroked */, false /* is smooth join */); ctx.BezierTo(points[9], points[10], points[11], true /* is stroked */, false /* is smooth join */); ctx.LineTo(points[12], true /* is stroked */, false /* is smooth join */); ctx.BezierTo(points[13], points[14], points[15], true /* is stroked */, false /* is smooth join */); } else { ctx.BeginFigure(rect.TopLeft, true /* is filled */, true /* is closed */); ctx.LineTo(Rect.TopRight, true /* is stroked */, false /* is smooth join */); ctx.LineTo(Rect.BottomRight, true /* is stroked */, false /* is smooth join */); ctx.LineTo(Rect.BottomLeft, true /* is stroked */, false /* is smooth join */); } ctx.Close(); data.SerializedData = ctx.GetData(); return data; } ////// ////// /// Critical - Calls critical code /// TreatAsSafe - returning a RectangleGeometry's point list is considered safe /// [SecurityCritical, SecurityTreatAsSafe] private Point[] GetPointList(Rect rect, double radiusX, double radiusY) { uint pointCount = GetPointCount(rect, radiusX, radiusY); Point[] points = new Point[pointCount]; unsafe { fixed(Point *pPoints = points) { RectangleGeometry.GetPointList(pPoints, pointCount, rect, radiusX, radiusY); } } return points; } ////// Critical - Accepts pointer arguments /// [SecurityCritical] private unsafe static void GetPointList(Point * points, uint pointsCount, Rect rect, double radiusX, double radiusY) { if (IsRounded(radiusX, radiusY)) { // It is a rounded rectangle Invariant.Assert(pointsCount >= c_roundedPointCount); radiusX = Math.Min(rect.Width * (1.0 / 2.0), Math.Abs(radiusX)); radiusY = Math.Min(rect.Height * (1.0 / 2.0), Math.Abs(radiusY)); double bezierX = ((1.0 - EllipseGeometry.c_arcAsBezier) * radiusX); double bezierY = ((1.0 - EllipseGeometry.c_arcAsBezier) * radiusY); points[1].X = points[0].X = points[15].X = points[14].X = rect.X; points[2].X = points[13].X = rect.X + bezierX; points[3].X = points[12].X = rect.X + radiusX; points[4].X = points[11].X = rect.Right - radiusX; points[5].X = points[10].X = rect.Right - bezierX; points[6].X = points[7].X = points[8].X = points[9].X = rect.Right; points[2].Y = points[3].Y = points[4].Y = points[5].Y = rect.Y; points[1].Y = points[6].Y = rect.Y + bezierY; points[0].Y = points[7].Y = rect.Y + radiusY; points[15].Y = points[8].Y = rect.Bottom - radiusY; points[14].Y = points[9].Y = rect.Bottom - bezierY; points[13].Y = points[12].Y = points[11].Y = points[10].Y = rect.Bottom; points[16] = points[0]; } else { // The rectangle is not rounded Invariant.Assert(pointsCount >= c_squaredPointCount); points[0].X = points[3].X = points[4].X = rect.X; points[1].X = points[2].X = rect.Right; points[0].Y = points[1].Y = points[4].Y = rect.Y; points[2].Y = points[3].Y = rect.Bottom; } } private static byte[] GetTypeList(Rect rect, double radiusX, double radiusY) { if (rect.IsEmpty) { return null; } else if (IsRounded(radiusX, radiusY)) { return s_roundedPathTypes; } else { return s_squaredPathTypes; } } private uint GetPointCount(Rect rect, double radiusX, double radiusY) { if (rect.IsEmpty) { return 0; } else if (IsRounded(radiusX, radiusY)) { return c_roundedPointCount; } else { return c_squaredPointCount; } } private uint GetSegmentCount(Rect rect, double radiusX, double radiusY) { if (rect.IsEmpty) { return 0; } else if (IsRounded(radiusX, radiusY)) { return c_roundedSegmentCount; } else { return c_squaredSegmentCount; } } private static void GetCounts(Rect rect, double radiusX, double radiusY, out uint pointCount, out uint segmentCount) { if (rect.IsEmpty) { pointCount = 0; segmentCount = 0; } else if (IsRounded(radiusX, radiusY)) { // The rectangle is rounded pointCount = c_roundedPointCount; segmentCount = c_roundedSegmentCount; } else { pointCount = c_squaredPointCount; segmentCount = c_squaredSegmentCount; } } #region Public Methods ////// Returns true if this geometry is empty /// public override bool IsEmpty() { return Rect.IsEmpty; } ////// Returns true if this geometry may have curved segments /// public override bool MayHaveCurves() { return IsRounded(); } #endregion Public Methods #region InstanceData // Rouneded static private UInt32 c_roundedSegmentCount = 8; static private UInt32 c_roundedPointCount = 17; static private byte smoothBezier = (byte)MILCoreSegFlags.SegTypeBezier | (byte)MILCoreSegFlags.SegIsCurved | (byte)MILCoreSegFlags.SegSmoothJoin; static private byte smoothLine = (byte)MILCoreSegFlags.SegTypeLine | (byte)MILCoreSegFlags.SegSmoothJoin; static private byte[] s_roundedPathTypes = { (byte)MILCoreSegFlags.SegTypeBezier | (byte)MILCoreSegFlags.SegIsCurved | (byte)MILCoreSegFlags.SegSmoothJoin | (byte)MILCoreSegFlags.SegClosed, smoothLine, smoothBezier, smoothLine, smoothBezier, smoothLine, smoothBezier, smoothLine }; // Squared private const UInt32 c_squaredSegmentCount = 4; private const UInt32 c_squaredPointCount = 5; private static readonly byte[] s_squaredPathTypes = { (byte)MILCoreSegFlags.SegTypeLine | (byte)MILCoreSegFlags.SegClosed, (byte)MILCoreSegFlags.SegTypeLine, (byte)MILCoreSegFlags.SegTypeLine, (byte)MILCoreSegFlags.SegTypeLine }; #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2001 // // File: RectangleGeometry.cs //----------------------------------------------------------------------------- using System; using MS.Internal; 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 SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Media { ////// This is the Geometry class for Rectangles and RoundedRectangles. /// public sealed partial class RectangleGeometry : Geometry { #region Constructors ////// /// public RectangleGeometry() { } ////// Constructor - sets the rounded rectangle to equal the passed in parameters /// public RectangleGeometry(Rect rect) { Rect = rect; } ////// Constructor - sets the rounded rectangle to equal the passed in parameters /// public RectangleGeometry(Rect rect, double radiusX, double radiusY) : this(rect) { RadiusX = radiusX; RadiusY = radiusY; } ////// /// /// /// /// /// public RectangleGeometry( Rect rect, double radiusX, double radiusY, Transform transform) : this(rect, 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; Rect currentRect = Rect; Transform transform = Transform; if (currentRect.IsEmpty) { boundsRect = Rect.Empty; } else if (transform == null || transform.IsIdentity) { boundsRect = currentRect; } else { double radiusX = RadiusX; double radiusY = RadiusY; if (radiusX == 0 && radiusY == 0) { boundsRect = currentRect; transform.TransformRect(ref boundsRect); } else { // // Transformed rounded rectangles are more tricky. // // Matrix geometryMatrix; Transform.GetTransformValue(transform, out geometryMatrix); boundsRect = RectangleGeometry.GetBoundsHelper( null /* no pen */, Matrix.Identity, currentRect, radiusX, radiusY, geometryMatrix, StandardFlatteningTolerance, ToleranceType.Absolute); } } return boundsRect; } } internal override bool AreClose(Geometry geometry) { RectangleGeometry rectGeometry2 = geometry as RectangleGeometry; if (rectGeometry2 != null) { RectangleGeometry rectGeometry1 = this; Rect rect1 = rectGeometry1.Rect; Rect rect2 = rectGeometry2.Rect; return ( DoubleUtil.AreClose(rect1.X, rect2.X) && DoubleUtil.AreClose(rect1.Y, rect2.Y) && DoubleUtil.AreClose(rect1.Width, rect2.Width) && DoubleUtil.AreClose(rect1.Height, rect2.Height) && DoubleUtil.AreClose(rectGeometry1.RadiusX, rectGeometry2.RadiusX) && DoubleUtil.AreClose(rectGeometry1.RadiusY, rectGeometry2.RadiusY) && (rectGeometry1.Transform == rectGeometry2.Transform) && (rectGeometry1.IsFrozen == rectGeometry2.IsFrozen) ); } return base.AreClose(geometry); } ////// 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 worldMatrix, double tolerance, ToleranceType type) { Matrix geometryMatrix; Transform.GetTransformValue(Transform, out geometryMatrix); return RectangleGeometry.GetBoundsHelper( pen, worldMatrix, Rect, RadiusX, RadiusY, geometryMatrix, tolerance, type); } ////// Critical - it calls a critical method, Geometry.GetBoundsHelper and has an unsafe block /// TreatAsSafe - returning a RectangleGeometry's bounds is considered safe /// [SecurityCritical, SecurityTreatAsSafe] internal static Rect GetBoundsHelper(Pen pen, Matrix worldMatrix, Rect rect, double radiusX, double radiusY, Matrix geometryMatrix, double tolerance, ToleranceType type) { Rect boundingRect; Debug.Assert(worldMatrix != null); Debug.Assert(geometryMatrix != null); if (rect.IsEmpty) { boundingRect = Rect.Empty; } else if ( (pen == null || pen.DoesNotContainGaps) && geometryMatrix.IsIdentity && worldMatrix.IsIdentity) { double strokeThickness = 0.0; boundingRect = rect; if (Pen.ContributesToBounds(pen)) { strokeThickness = Math.Abs(pen.Thickness); boundingRect.X -= 0.5*strokeThickness; boundingRect.Y -= 0.5*strokeThickness; boundingRect.Width += strokeThickness; boundingRect.Height += strokeThickness; } } else { unsafe { uint pointCount, segmentCount; GetCounts(rect, radiusX, radiusY, out pointCount, out segmentCount); // We've checked that rect isn't empty above Invariant.Assert(pointCount != 0); Point * pPoints = stackalloc Point[(int)pointCount]; RectangleGeometry.GetPointList(pPoints, pointCount, rect, radiusX, radiusY); fixed (byte *pTypes = RectangleGeometry.GetTypeList(rect, radiusX, radiusY)) { boundingRect = Geometry.GetBoundsHelper( pen, &worldMatrix, pPoints, pTypes, pointCount, segmentCount, &geometryMatrix, tolerance, type, false); // skip hollows - meaningless here, this is never a hollow } } } return boundingRect; } ////// 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) { if (IsEmpty()) { return false; } double radiusX = RadiusX; double radiusY = RadiusY; Rect rect = Rect; uint pointCount = GetPointCount(rect, radiusX, radiusY); uint segmentCount = GetSegmentCount(rect, radiusX, radiusY); unsafe { Point *pPoints = stackalloc Point[(int)pointCount]; RectangleGeometry.GetPointList(pPoints, pointCount, rect, radiusX, radiusY); fixed (byte* pTypes = GetTypeList(rect, radiusX, radiusY)) { return ContainsInternal( pen, hitPoint, tolerance, type, pPoints, pointCount, pTypes, segmentCount); } } } ////// Gets the area of this geometry /// /// The computational error tolerance /// The way the error tolerance will be interpreted - relative or absolute public override double GetArea(double tolerance, ToleranceType type) { ReadPreamble(); if (IsEmpty()) { return 0.0; } double radiusX = RadiusX; double radiusY = RadiusY; Rect rect = Rect; // Get the area of the bounding rectangle double area = Math.Abs(rect.Width * rect.Height); // correct it for the rounded corners area -= Math.Abs(radiusX * radiusY) * (4.0 - Math.PI); // Adjust to internal transformation Transform transform = Transform; if (!transform.IsIdentity) { area *= Math.Abs(transform.Value.Determinant); } return area; } internal override PathFigureCollection GetTransformedFigureCollection(Transform transform) { if (IsEmpty()) { return null; } // Combine the transform argument with the internal transform Matrix matrix = GetCombinedMatrix(transform); double radiusX = RadiusX; double radiusY = RadiusY; Rect rect = Rect; if (IsRounded(radiusX, radiusY)) { Point[] points = GetPointList(rect, radiusX, radiusY); // Transform if applicable. 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); double radiusX = RadiusX; double radiusY = RadiusY; Rect rect = Rect; ByteStreamGeometryContext ctx = new ByteStreamGeometryContext(); if (IsRounded(radiusX, radiusY)) { Point[] points = GetPointList(rect, radiusX, radiusY); ctx.BeginFigure(points[0], true /* is filled */, true /* is closed */); ctx.BezierTo(points[1], points[2], points[3], true /* is stroked */, false /* is smooth join */); ctx.LineTo(points[4], true /* is stroked */, false /* is smooth join */); ctx.BezierTo(points[5], points[6], points[7], true /* is stroked */, false /* is smooth join */); ctx.LineTo(points[8], true /* is stroked */, false /* is smooth join */); ctx.BezierTo(points[9], points[10], points[11], true /* is stroked */, false /* is smooth join */); ctx.LineTo(points[12], true /* is stroked */, false /* is smooth join */); ctx.BezierTo(points[13], points[14], points[15], true /* is stroked */, false /* is smooth join */); } else { ctx.BeginFigure(rect.TopLeft, true /* is filled */, true /* is closed */); ctx.LineTo(Rect.TopRight, true /* is stroked */, false /* is smooth join */); ctx.LineTo(Rect.BottomRight, true /* is stroked */, false /* is smooth join */); ctx.LineTo(Rect.BottomLeft, true /* is stroked */, false /* is smooth join */); } ctx.Close(); data.SerializedData = ctx.GetData(); return data; } ////// ////// /// Critical - Calls critical code /// TreatAsSafe - returning a RectangleGeometry's point list is considered safe /// [SecurityCritical, SecurityTreatAsSafe] private Point[] GetPointList(Rect rect, double radiusX, double radiusY) { uint pointCount = GetPointCount(rect, radiusX, radiusY); Point[] points = new Point[pointCount]; unsafe { fixed(Point *pPoints = points) { RectangleGeometry.GetPointList(pPoints, pointCount, rect, radiusX, radiusY); } } return points; } ////// Critical - Accepts pointer arguments /// [SecurityCritical] private unsafe static void GetPointList(Point * points, uint pointsCount, Rect rect, double radiusX, double radiusY) { if (IsRounded(radiusX, radiusY)) { // It is a rounded rectangle Invariant.Assert(pointsCount >= c_roundedPointCount); radiusX = Math.Min(rect.Width * (1.0 / 2.0), Math.Abs(radiusX)); radiusY = Math.Min(rect.Height * (1.0 / 2.0), Math.Abs(radiusY)); double bezierX = ((1.0 - EllipseGeometry.c_arcAsBezier) * radiusX); double bezierY = ((1.0 - EllipseGeometry.c_arcAsBezier) * radiusY); points[1].X = points[0].X = points[15].X = points[14].X = rect.X; points[2].X = points[13].X = rect.X + bezierX; points[3].X = points[12].X = rect.X + radiusX; points[4].X = points[11].X = rect.Right - radiusX; points[5].X = points[10].X = rect.Right - bezierX; points[6].X = points[7].X = points[8].X = points[9].X = rect.Right; points[2].Y = points[3].Y = points[4].Y = points[5].Y = rect.Y; points[1].Y = points[6].Y = rect.Y + bezierY; points[0].Y = points[7].Y = rect.Y + radiusY; points[15].Y = points[8].Y = rect.Bottom - radiusY; points[14].Y = points[9].Y = rect.Bottom - bezierY; points[13].Y = points[12].Y = points[11].Y = points[10].Y = rect.Bottom; points[16] = points[0]; } else { // The rectangle is not rounded Invariant.Assert(pointsCount >= c_squaredPointCount); points[0].X = points[3].X = points[4].X = rect.X; points[1].X = points[2].X = rect.Right; points[0].Y = points[1].Y = points[4].Y = rect.Y; points[2].Y = points[3].Y = rect.Bottom; } } private static byte[] GetTypeList(Rect rect, double radiusX, double radiusY) { if (rect.IsEmpty) { return null; } else if (IsRounded(radiusX, radiusY)) { return s_roundedPathTypes; } else { return s_squaredPathTypes; } } private uint GetPointCount(Rect rect, double radiusX, double radiusY) { if (rect.IsEmpty) { return 0; } else if (IsRounded(radiusX, radiusY)) { return c_roundedPointCount; } else { return c_squaredPointCount; } } private uint GetSegmentCount(Rect rect, double radiusX, double radiusY) { if (rect.IsEmpty) { return 0; } else if (IsRounded(radiusX, radiusY)) { return c_roundedSegmentCount; } else { return c_squaredSegmentCount; } } private static void GetCounts(Rect rect, double radiusX, double radiusY, out uint pointCount, out uint segmentCount) { if (rect.IsEmpty) { pointCount = 0; segmentCount = 0; } else if (IsRounded(radiusX, radiusY)) { // The rectangle is rounded pointCount = c_roundedPointCount; segmentCount = c_roundedSegmentCount; } else { pointCount = c_squaredPointCount; segmentCount = c_squaredSegmentCount; } } #region Public Methods ////// Returns true if this geometry is empty /// public override bool IsEmpty() { return Rect.IsEmpty; } ////// Returns true if this geometry may have curved segments /// public override bool MayHaveCurves() { return IsRounded(); } #endregion Public Methods #region InstanceData // Rouneded static private UInt32 c_roundedSegmentCount = 8; static private UInt32 c_roundedPointCount = 17; static private byte smoothBezier = (byte)MILCoreSegFlags.SegTypeBezier | (byte)MILCoreSegFlags.SegIsCurved | (byte)MILCoreSegFlags.SegSmoothJoin; static private byte smoothLine = (byte)MILCoreSegFlags.SegTypeLine | (byte)MILCoreSegFlags.SegSmoothJoin; static private byte[] s_roundedPathTypes = { (byte)MILCoreSegFlags.SegTypeBezier | (byte)MILCoreSegFlags.SegIsCurved | (byte)MILCoreSegFlags.SegSmoothJoin | (byte)MILCoreSegFlags.SegClosed, smoothLine, smoothBezier, smoothLine, smoothBezier, smoothLine, smoothBezier, smoothLine }; // Squared private const UInt32 c_squaredSegmentCount = 4; private const UInt32 c_squaredPointCount = 5; private static readonly byte[] s_squaredPathTypes = { (byte)MILCoreSegFlags.SegTypeLine | (byte)MILCoreSegFlags.SegClosed, (byte)MILCoreSegFlags.SegTypeLine, (byte)MILCoreSegFlags.SegTypeLine, (byte)MILCoreSegFlags.SegTypeLine }; #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PerformanceCountersElement.cs
- DependencyPropertyKind.cs
- ValidationHelpers.cs
- CharUnicodeInfo.cs
- StubHelpers.cs
- MetadataArtifactLoaderXmlReaderWrapper.cs
- TreeWalkHelper.cs
- TimeSpanMinutesConverter.cs
- EventBuilder.cs
- HtmlString.cs
- IncrementalReadDecoders.cs
- TrustLevel.cs
- InlineCategoriesDocument.cs
- StringAttributeCollection.cs
- OleDbEnumerator.cs
- WebResourceUtil.cs
- SafeFileMapViewHandle.cs
- LowerCaseStringConverter.cs
- TileBrush.cs
- SafeNativeMemoryHandle.cs
- ProcessHost.cs
- DataServiceContext.cs
- SafeArrayRankMismatchException.cs
- WebPartUserCapability.cs
- OleDbPropertySetGuid.cs
- GridSplitterAutomationPeer.cs
- AnimationClockResource.cs
- XamlWriter.cs
- Quaternion.cs
- ConfigurationManagerHelper.cs
- ActivityCodeDomSerializer.cs
- TimeoutValidationAttribute.cs
- SiteIdentityPermission.cs
- HandlerBase.cs
- MultipartContentParser.cs
- CodeTypeParameterCollection.cs
- SystemColorTracker.cs
- TransactionManager.cs
- QilStrConcatenator.cs
- Size3D.cs
- PriorityRange.cs
- SmtpMail.cs
- DescendantBaseQuery.cs
- relpropertyhelper.cs
- GeneralTransform3DGroup.cs
- ConfigurationSection.cs
- ContextMarshalException.cs
- UnsafeNativeMethods.cs
- Pair.cs
- WhiteSpaceTrimStringConverter.cs
- SerializerDescriptor.cs
- TargetConverter.cs
- EditorPartCollection.cs
- EventsTab.cs
- ImageFormatConverter.cs
- LicFileLicenseProvider.cs
- Image.cs
- RsaSecurityTokenAuthenticator.cs
- SoapSchemaExporter.cs
- InvalidMessageContractException.cs
- InputReportEventArgs.cs
- SemanticValue.cs
- BitFlagsGenerator.cs
- ZipIOFileItemStream.cs
- ColumnMapProcessor.cs
- SQLGuidStorage.cs
- ValidationResult.cs
- Int32.cs
- QueryExpr.cs
- ReplyChannel.cs
- TreeChangeInfo.cs
- WindowExtensionMethods.cs
- CheckPair.cs
- StatusBarItemAutomationPeer.cs
- Decorator.cs
- ProfilePropertySettingsCollection.cs
- DbCommandDefinition.cs
- RegexCompiler.cs
- ParameterCollection.cs
- DecryptRequest.cs
- DiagnosticsConfiguration.cs
- DynamicMethod.cs
- BitmapFrameEncode.cs
- OutputCacheSettings.cs
- XamlValidatingReader.cs
- NativeRightsManagementAPIsStructures.cs
- NumericUpDownAcceleration.cs
- AuthenticationServiceManager.cs
- XmlNodeChangedEventManager.cs
- securitymgrsite.cs
- ToolboxItemCollection.cs
- KeyPressEvent.cs
- TextRunCacheImp.cs
- _SslStream.cs
- ChannelFactoryRefCache.cs
- OleDbParameterCollection.cs
- DataGridViewMethods.cs
- SmtpAuthenticationManager.cs
- XmlWhitespace.cs
- CompositeClientFormatter.cs