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
- Span.cs
- Utilities.cs
- XsdDuration.cs
- PipelineModuleStepContainer.cs
- TimeoutValidationAttribute.cs
- ConfigUtil.cs
- AmbientValueAttribute.cs
- Menu.cs
- MultipartIdentifier.cs
- SchemaElement.cs
- DataBoundControlActionList.cs
- ObjectDataSourceMethodEditor.cs
- CodeValidator.cs
- IdentityNotMappedException.cs
- TemplatePropertyEntry.cs
- RequestCachePolicyConverter.cs
- OracleDateTime.cs
- AsyncParams.cs
- DataSourceGeneratorException.cs
- ListViewGroup.cs
- IntSecurity.cs
- UnsafeNetInfoNativeMethods.cs
- SQLBinary.cs
- TimeoutValidationAttribute.cs
- WebServiceMethodData.cs
- CryptoStream.cs
- KeyInstance.cs
- ObjectListShowCommandsEventArgs.cs
- DocumentOrderQuery.cs
- Stroke.cs
- MaskedTextBox.cs
- Rectangle.cs
- InvokePattern.cs
- ProxyGenerationError.cs
- ApplicationFileCodeDomTreeGenerator.cs
- HtmlTableRowCollection.cs
- StrongNameUtility.cs
- MediaCommands.cs
- MILUtilities.cs
- UserControl.cs
- InstanceData.cs
- IxmlLineInfo.cs
- IdnElement.cs
- FileLoadException.cs
- SubMenuStyle.cs
- ConnectionStringsSection.cs
- WindowsEditBox.cs
- ProviderConnectionPointCollection.cs
- ItemCheckedEvent.cs
- WindowsAuthenticationEventArgs.cs
- XmlILConstructAnalyzer.cs
- EventToken.cs
- ListItemCollection.cs
- CodeAttributeArgument.cs
- DataSourceControl.cs
- ServicesUtilities.cs
- DbConnectionPool.cs
- ThreadPoolTaskScheduler.cs
- SecurityElement.cs
- XmlUnspecifiedAttribute.cs
- RankException.cs
- GeometryDrawing.cs
- XmlQueryType.cs
- MultipartContentParser.cs
- TargetControlTypeAttribute.cs
- HttpCachePolicyElement.cs
- OleDbParameterCollection.cs
- NotifyCollectionChangedEventArgs.cs
- CompilerParameters.cs
- HttpStreamFormatter.cs
- Attributes.cs
- ErrorRuntimeConfig.cs
- TypeHelpers.cs
- HttpResponseHeader.cs
- XmlQueryRuntime.cs
- PageAsyncTask.cs
- VectorAnimationUsingKeyFrames.cs
- FunctionDefinition.cs
- LogLogRecordEnumerator.cs
- SchemaRegistration.cs
- SplayTreeNode.cs
- streamingZipPartStream.cs
- PropertyTabChangedEvent.cs
- AppSettingsExpressionBuilder.cs
- ExpressionBinding.cs
- HtmlTableCellCollection.cs
- PrimitiveSchema.cs
- HtmlWindow.cs
- ConfigurationProperty.cs
- RegexBoyerMoore.cs
- VectorAnimationUsingKeyFrames.cs
- UMPAttributes.cs
- ValidationError.cs
- GeometryModel3D.cs
- SerializationException.cs
- PersonalizablePropertyEntry.cs
- ProfileSettingsCollection.cs
- Int32Collection.cs
- LocalizableResourceBuilder.cs
- ServiceManager.cs