Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / Ink / StylusShape.cs / 1305600 / 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
- LogFlushAsyncResult.cs
- TextCompositionManager.cs
- ClientScriptManagerWrapper.cs
- RecommendedAsConfigurableAttribute.cs
- Dynamic.cs
- SurrogateSelector.cs
- ObjectSet.cs
- LineGeometry.cs
- DateTimeOffsetAdapter.cs
- SqlClientPermission.cs
- TrackingMemoryStream.cs
- PropertySet.cs
- SmiSettersStream.cs
- NativeCppClassAttribute.cs
- PermissionSetTriple.cs
- DrawItemEvent.cs
- BeginGetFileNameFromUserRequest.cs
- DataGridCommandEventArgs.cs
- WindowsTreeView.cs
- AssemblyFilter.cs
- XmlWriterSettings.cs
- CompiledQueryCacheKey.cs
- LocalFileSettingsProvider.cs
- BackStopAuthenticationModule.cs
- NameObjectCollectionBase.cs
- DefaultBindingPropertyAttribute.cs
- Delay.cs
- ExpressionVisitor.cs
- BinaryObjectReader.cs
- SiteOfOriginPart.cs
- GeometryDrawing.cs
- Wizard.cs
- DrawListViewColumnHeaderEventArgs.cs
- TextBoxBase.cs
- TextViewBase.cs
- CatalogUtil.cs
- DispatchChannelSink.cs
- ErrorStyle.cs
- COM2PropertyDescriptor.cs
- XmlConvert.cs
- SequentialUshortCollection.cs
- EntityViewGenerationAttribute.cs
- EventRouteFactory.cs
- XmlMtomReader.cs
- XmlDocumentFragment.cs
- DeclarationUpdate.cs
- CodeAttributeArgumentCollection.cs
- Version.cs
- XPathDocumentNavigator.cs
- EntityParameterCollection.cs
- InvalidOleVariantTypeException.cs
- LogPolicy.cs
- Nullable.cs
- XmlNodeChangedEventManager.cs
- AutomationPropertyInfo.cs
- MediaElementAutomationPeer.cs
- MediaContext.cs
- CodeDirectiveCollection.cs
- Set.cs
- SerializationEventsCache.cs
- loginstatus.cs
- TimeoutConverter.cs
- ResourceExpressionBuilder.cs
- UnionCqlBlock.cs
- BindingManagerDataErrorEventArgs.cs
- NameValueSectionHandler.cs
- ClientApiGenerator.cs
- Transaction.cs
- SrgsOneOf.cs
- StateItem.cs
- HttpApplication.cs
- JournalEntryStack.cs
- SecurityDocument.cs
- TypeConverterHelper.cs
- cache.cs
- XamlNamespaceHelper.cs
- FixedSOMSemanticBox.cs
- StandardOleMarshalObject.cs
- ValueHandle.cs
- DelayedRegex.cs
- PropagatorResult.cs
- ZipIOFileItemStream.cs
- SizeFConverter.cs
- PathGeometry.cs
- SaveFileDialog.cs
- ParserStreamGeometryContext.cs
- Environment.cs
- QilChoice.cs
- IMembershipProvider.cs
- SchemaTableOptionalColumn.cs
- PointLightBase.cs
- GridViewSelectEventArgs.cs
- WindowsIPAddress.cs
- CustomTypeDescriptor.cs
- HybridWebProxyFinder.cs
- SerializationEventsCache.cs
- DocumentGrid.cs
- WbmpConverter.cs
- IisTraceListener.cs
- RegexGroupCollection.cs