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
- PartialCachingAttribute.cs
- KeyValuePairs.cs
- XmlSerializableWriter.cs
- SubMenuStyle.cs
- ToolStripSplitStackLayout.cs
- Token.cs
- Point3DCollectionConverter.cs
- ButtonBaseAdapter.cs
- FileDialogCustomPlace.cs
- DrawListViewSubItemEventArgs.cs
- TreeViewImageIndexConverter.cs
- SignatureConfirmationElement.cs
- xmlfixedPageInfo.cs
- ISFClipboardData.cs
- ViewStateAttachedPropertyFeature.cs
- DecodeHelper.cs
- Manipulation.cs
- PanelContainerDesigner.cs
- ETagAttribute.cs
- SqlStatistics.cs
- GreenMethods.cs
- SendMessageRecord.cs
- ShapingEngine.cs
- EntityDataSourceSelectingEventArgs.cs
- DesignerRegionCollection.cs
- CapabilitiesUse.cs
- TrustManager.cs
- DrawingAttributesDefaultValueFactory.cs
- TTSEngineTypes.cs
- TdsParserStaticMethods.cs
- SchemaImporter.cs
- ClockController.cs
- Int32KeyFrameCollection.cs
- Trace.cs
- RequestStatusBarUpdateEventArgs.cs
- SemanticValue.cs
- FileDocument.cs
- Canvas.cs
- RelationshipEnd.cs
- basenumberconverter.cs
- DataGridViewRowCollection.cs
- FixedPosition.cs
- SqlInternalConnection.cs
- WebPartEditVerb.cs
- MediaElementAutomationPeer.cs
- CacheMode.cs
- WebConfigurationManager.cs
- ErrorHandler.cs
- UnsettableComboBox.cs
- LinkConverter.cs
- UiaCoreApi.cs
- ActiveXHost.cs
- TypeConverterHelper.cs
- SizeAnimationBase.cs
- AsmxEndpointPickerExtension.cs
- SHA384.cs
- odbcmetadatacollectionnames.cs
- MemberDescriptor.cs
- TextSegment.cs
- PathData.cs
- StyleXamlTreeBuilder.cs
- ColorContextHelper.cs
- DiscoveryService.cs
- TextDecoration.cs
- XmlFormatExtensionPointAttribute.cs
- NumericUpDownAccelerationCollection.cs
- ProgressBar.cs
- IndexedGlyphRun.cs
- Image.cs
- BatchServiceHost.cs
- ExtensionWindowHeader.cs
- WindowsGraphicsWrapper.cs
- CatalogZoneDesigner.cs
- MethodImplAttribute.cs
- SchemaImporterExtensionsSection.cs
- SystemGatewayIPAddressInformation.cs
- PrintPreviewDialog.cs
- XPathNodePointer.cs
- ControlParameter.cs
- MdImport.cs
- BoolExpr.cs
- SymbolType.cs
- WeakEventTable.cs
- StringUtil.cs
- EncoderExceptionFallback.cs
- FilterableAttribute.cs
- SafeNativeHandle.cs
- CellParagraph.cs
- FormViewAutoFormat.cs
- SingleSelectRootGridEntry.cs
- MeasureData.cs
- SqlSelectStatement.cs
- ProfileSettingsCollection.cs
- DecimalConstantAttribute.cs
- OdbcConnectionHandle.cs
- FactoryRecord.cs
- InternalSafeNativeMethods.cs
- DockingAttribute.cs
- Debugger.cs
- IdentityManager.cs