Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / MS / Internal / Ink / StylusShape.cs / 1 / StylusShape.cs
//------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------- using MS.Utility; using System; using System.IO; using System.Windows; using System.Windows.Media; using MS.Internal; using MS.Internal.Ink; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Ink { ////// Defines the style of pen tip for rendering. /// ////// The Stylus size and coordinates are in units equal to 1/96th of an inch. /// The default in V1 the default width is 1 pixel. This is 53 himetric units. /// There are 2540 himetric units per inch. /// This means that 53 high metric units is equivalent to 53/2540*96 in avalon. /// public abstract class StylusShape { #region Fields private double m_width; private double m_height; private double m_rotation; private Point[] m_vertices; private StylusTip m_tip; private Matrix _transform = Matrix.Identity; #endregion #region Constructors internal StylusShape(){} ////// constructor for a StylusShape. /// internal StylusShape(StylusTip tip, double width, double height, double rotation) { if (Double.IsNaN(width) || Double.IsInfinity(width) || width < DrawingAttributes.MinWidth || width > DrawingAttributes.MaxWidth) { throw new ArgumentOutOfRangeException("width"); } if (Double.IsNaN(height) || Double.IsInfinity(height) || height < DrawingAttributes.MinHeight || height > DrawingAttributes.MaxHeight) { throw new ArgumentOutOfRangeException("height"); } if (Double.IsNaN(rotation) || Double.IsInfinity(rotation)) { throw new ArgumentOutOfRangeException("rotation"); } if (!StylusTipHelper.IsDefined(tip)) { throw new ArgumentOutOfRangeException("tip"); } // // mod rotation to 360 (720 to 0, 361 to 1, -270 to 90) // m_width = width; m_height = height; m_rotation = rotation == 0 ? 0 : rotation % 360; m_tip = tip; if (tip == StylusTip.Rectangle) { ComputeRectangleVertices(); } } #endregion #region Public properties ////// Width of the non-rotated shape. /// public double Width { get { return m_width; } } ////// Height of the non-rotated shape. /// public double Height { get { return m_height; } } ////// The shape's rotation angle. The rotation is done about the origin (0,0). /// public double Rotation { get { return m_rotation; } } ////// GetVerticesAsVectors /// ///internal Vector[] GetVerticesAsVectors() { Vector[] vertices; if (null != m_vertices) { // For a Rectangle vertices = new Vector[m_vertices.Length]; if (_transform.IsIdentity) { for (int i = 0; i < vertices.Length; i++) { vertices[i] = (Vector)m_vertices[i]; } } else { for (int i = 0; i < vertices.Length; i++) { vertices[i] = _transform.Transform((Vector)m_vertices[i]); } // A transform might make the vertices in counter-clockwise order // Fix it if this is the case. FixCounterClockwiseVertices(vertices); } } else { // For ellipse // The transform is already applied on these points. Point[] p = GetBezierControlPoints(); vertices = new Vector[p.Length]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = (Vector)p[i]; } } return vertices; } #endregion #region Misc. internal API /// /// This is the transform on the StylusShape /// internal Matrix Transform { get { return _transform; } set { System.Diagnostics.Debug.Assert(value.HasInverse); _transform = value; } } ////// A helper property. /// internal bool IsEllipse { get { return (null == m_vertices); } } ////// A helper property. /// internal bool IsPolygon { get { return (null != m_vertices); } } ////// Generally, there's no need for the shape's bounding box. /// We use it to approximate v2 shapes with a rectangle for v1. /// internal Rect BoundingBox { get { Rect bbox; if (this.IsPolygon) { bbox = Rect.Empty; foreach (Point vertex in m_vertices) { bbox.Union(vertex); } } // else //if (DoubleUtil.IsZero(m_rotation) || DoubleUtil.AreClose(m_width, m_height)) { bbox = new Rect(-(m_width * 0.5), -(m_height * 0.5), m_width, m_height); } //else //{ // throw new NotImplementedException("Rotated ellipse"); //} return bbox; } } #endregion #region Implementation helpers ///TBS private void ComputeRectangleVertices() { Point topLeft = new Point(-(m_width * 0.5), -(m_height * 0.5)); m_vertices = new Point[4] { topLeft, topLeft + new Vector(m_width, 0), topLeft + new Vector(m_width, m_height), topLeft + new Vector(0, m_height)}; if (false == DoubleUtil.IsZero(m_rotation)) { Matrix rotationTransform = Matrix.Identity; rotationTransform.Rotate(m_rotation); rotationTransform.Transform(m_vertices); } } ///A transform might make the vertices in counter-clockwise order Fix it if this is the case. private void FixCounterClockwiseVertices(Vector[] vertices) { // The private method should only called for Rectangle case. System.Diagnostics.Debug.Assert(vertices.Length == 4); Point prevVertex = (Point)vertices[vertices.Length - 1]; int counterClockIndex = 0, clockWiseIndex = 0; for (int i = 0; i < vertices.Length; i++) { Point vertex = (Point) vertices[i]; Vector edge = vertex - prevVertex; // Verify that the next vertex is on the right side off the edge vector. double det = Vector.Determinant(edge, (Point)vertices[(i + 1) % vertices.Length] - (Point)vertex); if (0 > det) { counterClockIndex++; } else if (0 < det) { clockWiseIndex++; } prevVertex = vertex; } // Assert the transform will make it either clockwise or counter-clockwise. System.Diagnostics.Debug.Assert(clockWiseIndex == vertices.Length || counterClockIndex == vertices.Length); if (counterClockIndex == vertices.Length) { // Make it Clockwise int lastIndex = vertices.Length -1; for (int j = 0; j < vertices.Length/2; j++) { Vector tmp = vertices[j]; vertices[j] = vertices[lastIndex - j]; vertices[lastIndex-j] = tmp; } } } private Point[] GetBezierControlPoints() { System.Diagnostics.Debug.Assert(m_tip == StylusTip.Ellipse); // Approximating a 1/4 circle with a Bezier curve (borrowed from Avalon's EllipseGeometry.cs) const double ArcAsBezier = 0.5522847498307933984; // =(\/2 - 1)*4/3 double radiusX = m_width / 2; double radiusY = m_height / 2; double borderMagicX = radiusX * ArcAsBezier; double borderMagicY = radiusY * ArcAsBezier; Point[] controlPoints = new Point[] { new Point( -radiusX, -borderMagicY), new Point(-borderMagicX, -radiusY), new Point( 0, -radiusY), new Point( borderMagicX, -radiusY), new Point( radiusX, -borderMagicY), new Point( radiusX, 0), new Point( radiusX, borderMagicY), new Point( borderMagicX, radiusY), new Point( 0, radiusY), new Point(-borderMagicX, radiusY), new Point( -radiusX, borderMagicY), new Point( -radiusX, 0)}; // Matrix transform = Matrix.Identity; if (m_rotation != 0) { transform.Rotate(m_rotation); } if (_transform.IsIdentity == false) { transform *= _transform; } if (transform.IsIdentity == false) { for (int i = 0; i < controlPoints.Length; i++) { controlPoints[i] = transform.Transform(controlPoints[i]); } } return controlPoints; } #endregion } ////// Class for an elliptical StylusShape /// public sealed class EllipseStylusShape : StylusShape { ////// Constructor for an elliptical StylusShape /// /// /// public EllipseStylusShape(double width, double height) :this(width, height, 0f) { } ////// Constructor for an ellptical StylusShape ,with roation in degree /// /// /// /// public EllipseStylusShape(double width, double height, double rotation) : base(StylusTip.Ellipse, width, height, rotation) { } } ////// Class for a rectangle StylusShape /// public sealed class RectangleStylusShape : StylusShape { ////// Constructor /// /// /// public RectangleStylusShape(double width, double height) : this(width, height, 0f) { } ////// Constructor with rogation in degree /// /// /// /// public RectangleStylusShape(double width, double height, double rotation) : base(StylusTip.Rectangle, width, height, rotation) { } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------- using MS.Utility; using System; using System.IO; using System.Windows; using System.Windows.Media; using MS.Internal; using MS.Internal.Ink; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Ink { ////// Defines the style of pen tip for rendering. /// ////// The Stylus size and coordinates are in units equal to 1/96th of an inch. /// The default in V1 the default width is 1 pixel. This is 53 himetric units. /// There are 2540 himetric units per inch. /// This means that 53 high metric units is equivalent to 53/2540*96 in avalon. /// public abstract class StylusShape { #region Fields private double m_width; private double m_height; private double m_rotation; private Point[] m_vertices; private StylusTip m_tip; private Matrix _transform = Matrix.Identity; #endregion #region Constructors internal StylusShape(){} ////// constructor for a StylusShape. /// internal StylusShape(StylusTip tip, double width, double height, double rotation) { if (Double.IsNaN(width) || Double.IsInfinity(width) || width < DrawingAttributes.MinWidth || width > DrawingAttributes.MaxWidth) { throw new ArgumentOutOfRangeException("width"); } if (Double.IsNaN(height) || Double.IsInfinity(height) || height < DrawingAttributes.MinHeight || height > DrawingAttributes.MaxHeight) { throw new ArgumentOutOfRangeException("height"); } if (Double.IsNaN(rotation) || Double.IsInfinity(rotation)) { throw new ArgumentOutOfRangeException("rotation"); } if (!StylusTipHelper.IsDefined(tip)) { throw new ArgumentOutOfRangeException("tip"); } // // mod rotation to 360 (720 to 0, 361 to 1, -270 to 90) // m_width = width; m_height = height; m_rotation = rotation == 0 ? 0 : rotation % 360; m_tip = tip; if (tip == StylusTip.Rectangle) { ComputeRectangleVertices(); } } #endregion #region Public properties ////// Width of the non-rotated shape. /// public double Width { get { return m_width; } } ////// Height of the non-rotated shape. /// public double Height { get { return m_height; } } ////// The shape's rotation angle. The rotation is done about the origin (0,0). /// public double Rotation { get { return m_rotation; } } ////// GetVerticesAsVectors /// ///internal Vector[] GetVerticesAsVectors() { Vector[] vertices; if (null != m_vertices) { // For a Rectangle vertices = new Vector[m_vertices.Length]; if (_transform.IsIdentity) { for (int i = 0; i < vertices.Length; i++) { vertices[i] = (Vector)m_vertices[i]; } } else { for (int i = 0; i < vertices.Length; i++) { vertices[i] = _transform.Transform((Vector)m_vertices[i]); } // A transform might make the vertices in counter-clockwise order // Fix it if this is the case. FixCounterClockwiseVertices(vertices); } } else { // For ellipse // The transform is already applied on these points. Point[] p = GetBezierControlPoints(); vertices = new Vector[p.Length]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = (Vector)p[i]; } } return vertices; } #endregion #region Misc. internal API /// /// This is the transform on the StylusShape /// internal Matrix Transform { get { return _transform; } set { System.Diagnostics.Debug.Assert(value.HasInverse); _transform = value; } } ////// A helper property. /// internal bool IsEllipse { get { return (null == m_vertices); } } ////// A helper property. /// internal bool IsPolygon { get { return (null != m_vertices); } } ////// Generally, there's no need for the shape's bounding box. /// We use it to approximate v2 shapes with a rectangle for v1. /// internal Rect BoundingBox { get { Rect bbox; if (this.IsPolygon) { bbox = Rect.Empty; foreach (Point vertex in m_vertices) { bbox.Union(vertex); } } // else //if (DoubleUtil.IsZero(m_rotation) || DoubleUtil.AreClose(m_width, m_height)) { bbox = new Rect(-(m_width * 0.5), -(m_height * 0.5), m_width, m_height); } //else //{ // throw new NotImplementedException("Rotated ellipse"); //} return bbox; } } #endregion #region Implementation helpers ///TBS private void ComputeRectangleVertices() { Point topLeft = new Point(-(m_width * 0.5), -(m_height * 0.5)); m_vertices = new Point[4] { topLeft, topLeft + new Vector(m_width, 0), topLeft + new Vector(m_width, m_height), topLeft + new Vector(0, m_height)}; if (false == DoubleUtil.IsZero(m_rotation)) { Matrix rotationTransform = Matrix.Identity; rotationTransform.Rotate(m_rotation); rotationTransform.Transform(m_vertices); } } ///A transform might make the vertices in counter-clockwise order Fix it if this is the case. private void FixCounterClockwiseVertices(Vector[] vertices) { // The private method should only called for Rectangle case. System.Diagnostics.Debug.Assert(vertices.Length == 4); Point prevVertex = (Point)vertices[vertices.Length - 1]; int counterClockIndex = 0, clockWiseIndex = 0; for (int i = 0; i < vertices.Length; i++) { Point vertex = (Point) vertices[i]; Vector edge = vertex - prevVertex; // Verify that the next vertex is on the right side off the edge vector. double det = Vector.Determinant(edge, (Point)vertices[(i + 1) % vertices.Length] - (Point)vertex); if (0 > det) { counterClockIndex++; } else if (0 < det) { clockWiseIndex++; } prevVertex = vertex; } // Assert the transform will make it either clockwise or counter-clockwise. System.Diagnostics.Debug.Assert(clockWiseIndex == vertices.Length || counterClockIndex == vertices.Length); if (counterClockIndex == vertices.Length) { // Make it Clockwise int lastIndex = vertices.Length -1; for (int j = 0; j < vertices.Length/2; j++) { Vector tmp = vertices[j]; vertices[j] = vertices[lastIndex - j]; vertices[lastIndex-j] = tmp; } } } private Point[] GetBezierControlPoints() { System.Diagnostics.Debug.Assert(m_tip == StylusTip.Ellipse); // Approximating a 1/4 circle with a Bezier curve (borrowed from Avalon's EllipseGeometry.cs) const double ArcAsBezier = 0.5522847498307933984; // =(\/2 - 1)*4/3 double radiusX = m_width / 2; double radiusY = m_height / 2; double borderMagicX = radiusX * ArcAsBezier; double borderMagicY = radiusY * ArcAsBezier; Point[] controlPoints = new Point[] { new Point( -radiusX, -borderMagicY), new Point(-borderMagicX, -radiusY), new Point( 0, -radiusY), new Point( borderMagicX, -radiusY), new Point( radiusX, -borderMagicY), new Point( radiusX, 0), new Point( radiusX, borderMagicY), new Point( borderMagicX, radiusY), new Point( 0, radiusY), new Point(-borderMagicX, radiusY), new Point( -radiusX, borderMagicY), new Point( -radiusX, 0)}; // Matrix transform = Matrix.Identity; if (m_rotation != 0) { transform.Rotate(m_rotation); } if (_transform.IsIdentity == false) { transform *= _transform; } if (transform.IsIdentity == false) { for (int i = 0; i < controlPoints.Length; i++) { controlPoints[i] = transform.Transform(controlPoints[i]); } } return controlPoints; } #endregion } ////// Class for an elliptical StylusShape /// public sealed class EllipseStylusShape : StylusShape { ////// Constructor for an elliptical StylusShape /// /// /// public EllipseStylusShape(double width, double height) :this(width, height, 0f) { } ////// Constructor for an ellptical StylusShape ,with roation in degree /// /// /// /// public EllipseStylusShape(double width, double height, double rotation) : base(StylusTip.Ellipse, width, height, rotation) { } } ////// Class for a rectangle StylusShape /// public sealed class RectangleStylusShape : StylusShape { ////// Constructor /// /// /// public RectangleStylusShape(double width, double height) : this(width, height, 0f) { } ////// Constructor with rogation in degree /// /// /// /// public RectangleStylusShape(double width, double height, double rotation) : base(StylusTip.Rectangle, width, height, rotation) { } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- StorageComplexTypeMapping.cs
- CallId.cs
- documentsequencetextpointer.cs
- BamlLocalizableResourceKey.cs
- DataGridView.cs
- MemoryFailPoint.cs
- DefaultHttpHandler.cs
- DesignerTextViewAdapter.cs
- LoadMessageLogger.cs
- _SingleItemRequestCache.cs
- Roles.cs
- XmlSecureResolver.cs
- QilValidationVisitor.cs
- System.Data_BID.cs
- FigureParaClient.cs
- Crc32.cs
- ToolStripSplitStackLayout.cs
- RegisteredExpandoAttribute.cs
- QueryTask.cs
- StyleSheetDesigner.cs
- Figure.cs
- HttpStreamXmlDictionaryWriter.cs
- cryptoapiTransform.cs
- ToolStripItemCollection.cs
- Parser.cs
- COAUTHINFO.cs
- SafeLibraryHandle.cs
- ClientApiGenerator.cs
- OutputScopeManager.cs
- QueryOutputWriter.cs
- RegionInfo.cs
- BitmapImage.cs
- ReadOnlyDictionary.cs
- PointAnimationBase.cs
- ApplicationDirectory.cs
- DeviceContext2.cs
- RegexCode.cs
- SpellerError.cs
- Point.cs
- EntitySetBaseCollection.cs
- PropertyMappingExceptionEventArgs.cs
- MultiDataTrigger.cs
- CDSsyncETWBCLProvider.cs
- EqualityComparer.cs
- XmlChildNodes.cs
- tibetanshape.cs
- XmlSchemaSimpleContentRestriction.cs
- X509InitiatorCertificateServiceElement.cs
- KnownColorTable.cs
- CodeTypeMemberCollection.cs
- MsmqProcessProtocolHandler.cs
- Transform.cs
- SoapWriter.cs
- ImmutableAssemblyCacheEntry.cs
- ProfileParameter.cs
- DataGridViewLinkColumn.cs
- NonVisualControlAttribute.cs
- ContextMarshalException.cs
- ContextDataSourceView.cs
- MenuCommand.cs
- LocalServiceSecuritySettingsElement.cs
- RelationshipNavigation.cs
- DataGridViewComboBoxCell.cs
- CalendarDesigner.cs
- PointCollectionValueSerializer.cs
- Internal.cs
- RemoteWebConfigurationHost.cs
- EventToken.cs
- CounterSetInstanceCounterDataSet.cs
- WebHttpSecurityElement.cs
- CorrelationService.cs
- MetadataException.cs
- WebPartConnectionsCloseVerb.cs
- WindowsScroll.cs
- BlockCollection.cs
- ResXDataNode.cs
- Scripts.cs
- ProtocolProfile.cs
- StreamUpdate.cs
- DesignOnlyAttribute.cs
- InkCanvasSelectionAdorner.cs
- DispatcherBuilder.cs
- _LocalDataStoreMgr.cs
- IpcChannel.cs
- DataRowCollection.cs
- StrongNamePublicKeyBlob.cs
- SoapAttributeOverrides.cs
- UriScheme.cs
- WindowsGraphicsWrapper.cs
- InvalidCastException.cs
- CapiNative.cs
- LeaseManager.cs
- ScrollBar.cs
- COM2IDispatchConverter.cs
- ProvidersHelper.cs
- DynamicActionMessageFilter.cs
- OleDbParameter.cs
- QueryComponents.cs
- ContainerParaClient.cs
- NativeMethods.cs