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
- VarInfo.cs
- WebPartRestoreVerb.cs
- LiteralControl.cs
- Block.cs
- Storyboard.cs
- BitmapEffectDrawingContent.cs
- Crypto.cs
- SwitchLevelAttribute.cs
- PbrsForward.cs
- ToolStripItemImageRenderEventArgs.cs
- AudioFileOut.cs
- ContentDisposition.cs
- DescriptionAttribute.cs
- EntityDataSourceChangingEventArgs.cs
- RuleConditionDialog.Designer.cs
- PerfProviderCollection.cs
- ResolvedKeyFrameEntry.cs
- ButtonBaseAdapter.cs
- Emitter.cs
- DrawListViewColumnHeaderEventArgs.cs
- StaticFileHandler.cs
- ScriptingWebServicesSectionGroup.cs
- RotateTransform3D.cs
- DataBindingCollection.cs
- MouseButtonEventArgs.cs
- EntityContainerAssociationSetEnd.cs
- SqlWorkflowPersistenceService.cs
- WriterOutput.cs
- BinaryObjectWriter.cs
- BaseProcessor.cs
- XmlEncodedRawTextWriter.cs
- DbConnectionPoolOptions.cs
- RuleElement.cs
- ScriptingWebServicesSectionGroup.cs
- FamilyMap.cs
- ReadOnlyCollectionBase.cs
- DataColumnMapping.cs
- InputDevice.cs
- SmiEventSink_DeferedProcessing.cs
- DrawingContextDrawingContextWalker.cs
- ButtonFieldBase.cs
- DescriptionAttribute.cs
- PathStreamGeometryContext.cs
- HtmlContainerControl.cs
- DataGridItemAutomationPeer.cs
- BaseDataList.cs
- PackageRelationship.cs
- Point3D.cs
- TextEditorCharacters.cs
- CodeRemoveEventStatement.cs
- TransactionInterop.cs
- mda.cs
- EmbeddedMailObjectsCollection.cs
- XmlSchemaComplexContentExtension.cs
- FocusChangedEventArgs.cs
- NestPullup.cs
- ConfigPathUtility.cs
- InputLanguageProfileNotifySink.cs
- DoubleIndependentAnimationStorage.cs
- DBConcurrencyException.cs
- XPathDocumentNavigator.cs
- CalendarDay.cs
- infer.cs
- RotateTransform.cs
- Set.cs
- Properties.cs
- CreateRefExpr.cs
- Stream.cs
- DEREncoding.cs
- basecomparevalidator.cs
- NavigationService.cs
- SimpleBitVector32.cs
- XmlConvert.cs
- glyphs.cs
- XmlAttributeCollection.cs
- TextTreeUndoUnit.cs
- QilExpression.cs
- LoopExpression.cs
- ContainsSearchOperator.cs
- followingquery.cs
- NavigationFailedEventArgs.cs
- SettingsSavedEventArgs.cs
- IList.cs
- ACE.cs
- ServiceHttpModule.cs
- XmlFormatExtensionPrefixAttribute.cs
- dataprotectionpermissionattribute.cs
- MemberHolder.cs
- StateMachine.cs
- RepeaterItemEventArgs.cs
- PointValueSerializer.cs
- DirectionalLight.cs
- ReadWriteObjectLock.cs
- PropertyGridEditorPart.cs
- SafeLibraryHandle.cs
- RowCache.cs
- RSAPKCS1SignatureFormatter.cs
- PopupEventArgs.cs
- WebHttpDispatchOperationSelector.cs
- HttpSessionStateBase.cs