Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / Input / Stylus / StylusPoint.cs / 1 / StylusPoint.cs
//------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------
using System;
using System.Windows;
using System.Diagnostics;
using System.Windows.Input;
using System.Windows.Media;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using MS.Utility;
using MS.Internal;
using SR = MS.Internal.PresentationCore.SR;
using SRID = MS.Internal.PresentationCore.SRID;
namespace System.Windows.Input
{
///
/// Represents a single sampling point from a stylus input device
///
public struct StylusPoint : IEquatable
{
internal static readonly float DefaultPressure = 0.5f;
private double _x;
private double _y;
private float _pressureFactor;
private int[] _additionalValues;
private StylusPointDescription _stylusPointDescription;
#region Constructors
///
/// StylusPoint
///
/// x
/// y
public StylusPoint(double x, double y)
: this(x, y, DefaultPressure, null, null, false, false)
{
}
///
/// StylusPoint
///
/// x
/// y
/// pressureFactor
public StylusPoint(double x, double y, float pressureFactor)
: this(x, y, pressureFactor, null, null, false, true)
{
}
///
/// StylusPoint
///
/// x
/// y
/// pressureFactor
/// stylusPointDescription
/// additionalValues
public StylusPoint(double x, double y, float pressureFactor, StylusPointDescription stylusPointDescription, int[] additionalValues)
: this(x, y, pressureFactor, stylusPointDescription, additionalValues, true, true)
{
}
///
/// internal ctor
///
internal StylusPoint(
double x,
double y,
float pressureFactor,
StylusPointDescription stylusPointDescription,
int[] additionalValues,
bool validateAdditionalData,
bool validatePressureFactor)
{
if (Double.IsNaN(x))
{
throw new ArgumentOutOfRangeException("x", SR.Get(SRID.InvalidStylusPointXYNaN));
}
if (Double.IsNaN(y))
{
throw new ArgumentOutOfRangeException("y", SR.Get(SRID.InvalidStylusPointXYNaN));
}
//we don't validate pressure when called by StylusPointDescription.Reformat
if (validatePressureFactor &&
(pressureFactor == Single.NaN || pressureFactor < 0.0f || pressureFactor > 1.0f))
{
throw new ArgumentOutOfRangeException("pressureFactor", SR.Get(SRID.InvalidPressureValue));
}
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_x = GetClampedXYValue(x);
_y = GetClampedXYValue(y);
_stylusPointDescription = stylusPointDescription;
_additionalValues = additionalValues;
_pressureFactor = pressureFactor;
if (validateAdditionalData)
{
//
// called from the public verbose ctor
//
if (null == stylusPointDescription)
{
throw new ArgumentNullException("stylusPointDescription");
}
//
// additionalValues can be null if PropertyCount == 3 (X, Y, P)
//
if (stylusPointDescription.PropertyCount > StylusPointDescription.RequiredCountOfProperties &&
null == additionalValues)
{
throw new ArgumentNullException("additionalValues");
}
if (additionalValues != null)
{
ReadOnlyCollection properties
= stylusPointDescription.GetStylusPointProperties();
int expectedAdditionalValues = properties.Count - StylusPointDescription.RequiredCountOfProperties; //for x, y, pressure
if (additionalValues.Length != expectedAdditionalValues)
{
throw new ArgumentException(SR.Get(SRID.InvalidAdditionalDataForStylusPoint), "additionalValues");
}
//
// any buttons passed in must each be in their own int. We need to
// pack them all into one int here
//
int[] newAdditionalValues =
new int[stylusPointDescription.GetExpectedAdditionalDataCount()];
_additionalValues = newAdditionalValues;
for (int i = StylusPointDescription.RequiredCountOfProperties, j = 0; i < properties.Count; i++, j++)
{
//
// use SetPropertyValue, it validates buttons, but does not copy the
// int[] on writes (since we pass the bool flag)
//
SetPropertyValue(properties[i], additionalValues[j], false/*copy on write*/);
}
}
}
}
#endregion Constructors
///
/// The Maximum X or Y value supported for backwards compatibility with previous inking platforms
///
public static readonly double MaxXY = 81164736.28346430d;
///
/// The Minimum X or Y value supported for backwards compatibility with previous inking platforms
///
public static readonly double MinXY = -81164736.32125960d;
///
/// X
///
public double X
{
get { return _x; }
set
{
if (Double.IsNaN(value))
{
throw new ArgumentOutOfRangeException("X", SR.Get(SRID.InvalidStylusPointXYNaN));
}
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_x = GetClampedXYValue(value);
}
}
///
/// Y
///
public double Y
{
get { return _y; }
set
{
if (Double.IsNaN(value))
{
throw new ArgumentOutOfRangeException("Y", SR.Get(SRID.InvalidStylusPointXYNaN));
}
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_y = GetClampedXYValue(value);
}
}
///
/// PressureFactor. A value between 0.0 (no pressure) and 1.0 (max pressure)
///
public float PressureFactor
{
get
{
//
// note that pressure can be stored a > 1 or < 0.
// we need to clamp if this is the case
//
if (_pressureFactor > 1.0f)
{
return 1.0f;
}
if (_pressureFactor < 0.0f)
{
return 0.0f;
}
return _pressureFactor;
}
set
{
if (value < 0.0f || value > 1.0f)
{
throw new ArgumentOutOfRangeException("PressureFactor", SR.Get(SRID.InvalidPressureValue));
}
_pressureFactor = value;
}
}
///
/// Describes the properties this StylusPoint contains
///
public StylusPointDescription Description
{
get
{
if (null == _stylusPointDescription)
{
// this can happen when you call new StylusPoint()
// a few of the ctor's lazy init this as well
_stylusPointDescription = new StylusPointDescription();
}
return _stylusPointDescription;
}
internal set
{
//
// called by StylusPointCollection.Add / Set
// to replace the StylusPoint.Description with the collections.
//
Debug.Assert(value != null &&
StylusPointDescription.AreCompatible(value, this.Description));
_stylusPointDescription = value;
}
}
///
/// Returns true if this StylusPoint supports the specified property
///
/// The StylusPointProperty to see if this StylusPoint supports
public bool HasProperty(StylusPointProperty stylusPointProperty)
{
return this.Description.HasProperty(stylusPointProperty);
}
///
/// Provides read access to all stylus properties
///
/// The StylusPointPropertyIds of the property to retrieve
public int GetPropertyValue(StylusPointProperty stylusPointProperty)
{
if (null == stylusPointProperty)
{
throw new ArgumentNullException("stylusPointProperty");
}
if (stylusPointProperty.Id == StylusPointPropertyIds.X)
{
return (int)_x;
}
else if (stylusPointProperty.Id == StylusPointPropertyIds.Y)
{
return (int)_y;
}
else if (stylusPointProperty.Id == StylusPointPropertyIds.NormalPressure)
{
StylusPointPropertyInfo info =
this.Description.GetPropertyInfo(StylusPointProperties.NormalPressure);
int max = info.Maximum;
return (int)(_pressureFactor * (float)max);
}
else
{
int propertyIndex = this.Description.GetPropertyIndex(stylusPointProperty.Id);
if (-1 == propertyIndex)
{
throw new ArgumentException(SR.Get(SRID.InvalidStylusPointProperty), "stylusPointProperty");
}
if (stylusPointProperty.IsButton)
{
//
// we get button data from a single int in the array
//
int buttonData = _additionalValues[_additionalValues.Length - 1];
int buttonBitPosition = this.Description.GetButtonBitPosition(stylusPointProperty);
int bit = 1 << buttonBitPosition;
if ((buttonData & bit) != 0)
{
return 1;
}
else
{
return 0;
}
}
else
{
return _additionalValues[propertyIndex - 3];
}
}
}
///
/// Allows supported properties to be set
///
/// The property to set, it must exist on this StylusPoint
/// value
public void SetPropertyValue(StylusPointProperty stylusPointProperty, int value)
{
SetPropertyValue(stylusPointProperty, value, true);
}
///
/// Optimization that lets the ctor call setvalue repeatly without causing a copy of the int[]
///
/// stylusPointProperty
/// value
///
internal void SetPropertyValue(StylusPointProperty stylusPointProperty, int value, bool copyBeforeWrite)
{
if (null == stylusPointProperty)
{
throw new ArgumentNullException("stylusPointProperty");
}
if (stylusPointProperty.Id == StylusPointPropertyIds.X)
{
double dVal = (double)value;
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_x = GetClampedXYValue(dVal);
}
else if (stylusPointProperty.Id == StylusPointPropertyIds.Y)
{
double dVal = (double)value;
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_y = GetClampedXYValue(dVal);
}
else if (stylusPointProperty.Id == StylusPointPropertyIds.NormalPressure)
{
StylusPointPropertyInfo info =
this.Description.GetPropertyInfo(StylusPointProperties.NormalPressure);
int min = info.Minimum;
int max = info.Maximum;
if (max == 0)
{
_pressureFactor = 0.0f;
}
else
{
_pressureFactor = (float)(Convert.ToSingle(min + value) / Convert.ToSingle(max));
}
}
else
{
int propertyIndex = this.Description.GetPropertyIndex(stylusPointProperty.Id);
if (-1 == propertyIndex)
{
throw new ArgumentException(SR.Get(SRID.InvalidStylusPointProperty), "propertyId");
}
if (stylusPointProperty.IsButton)
{
if (value < 0 || value > 1)
{
throw new ArgumentOutOfRangeException(SR.Get(SRID.InvalidMinMaxForButton), "value");
}
if (copyBeforeWrite)
{
CopyAdditionalData();
}
//
// we get button data from a single int in the array
//
int buttonData = _additionalValues[_additionalValues.Length - 1];
int buttonBitPosition = this.Description.GetButtonBitPosition(stylusPointProperty);
int bit = 1 << buttonBitPosition;
if (value == 0)
{
//turn the bit off
buttonData &= ~bit;
}
else
{
//turn the bit on
buttonData |= bit;
}
_additionalValues[_additionalValues.Length - 1] = buttonData;
}
else
{
if (copyBeforeWrite)
{
CopyAdditionalData();
}
_additionalValues[propertyIndex - 3] = value;
}
}
}
///
/// Explicit cast converter between StylusPoint and Point
///
/// stylusPoint
public static explicit operator Point(StylusPoint stylusPoint)
{
return new Point(stylusPoint.X, stylusPoint.Y);
}
///
/// Allows languages that don't support operator overloading
/// to convert to a point
///
public Point ToPoint()
{
return new Point(this.X, this.Y);
}
///
/// Compares two StylusPoint instances for exact equality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which are logically equal may fail.
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
/// Descriptions must match for equality to succeed and additional values must match
///
///
/// bool - true if the two Stylus instances are exactly equal, false otherwise
///
/// The first StylusPoint to compare
/// The second StylusPoint to compare
public static bool operator ==(StylusPoint stylusPoint1, StylusPoint stylusPoint2)
{
return StylusPoint.Equals(stylusPoint1, stylusPoint2);
}
///
/// Compares two StylusPoint instances for exact inequality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which are logically equal may fail.
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
///
///
/// bool - true if the two Stylus instances are exactly inequal, false otherwise
///
/// The first StylusPoint to compare
/// The second StylusPoint to compare
public static bool operator !=(StylusPoint stylusPoint1, StylusPoint stylusPoint2)
{
return !StylusPoint.Equals(stylusPoint1, stylusPoint2);
}
///
/// Compares two StylusPoint instances for exact equality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which are logically equal may fail.
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
/// Descriptions must match for equality to succeed and additional values must match
///
///
/// bool - true if the two Stylus instances are exactly equal, false otherwise
///
/// The first StylusPoint to compare
/// The second StylusPoint to compare
public static bool Equals(StylusPoint stylusPoint1, StylusPoint stylusPoint2)
{
//
// do the cheap comparison first
//
bool membersEqual =
stylusPoint1._x == stylusPoint2._x &&
stylusPoint1._y == stylusPoint2._y &&
stylusPoint1._pressureFactor == stylusPoint2._pressureFactor;
if (!membersEqual)
{
return false;
}
//
// before we go checking the descriptions... check to see if both additionalData's are null
// we can infer that the SPD's are just X,Y,P and that they are compatible.
//
if (stylusPoint1._additionalValues == null &&
stylusPoint2._additionalValues == null)
{
Debug.Assert(StylusPointDescription.AreCompatible(stylusPoint1.Description, stylusPoint2.Description));
return true;
}
//
// ok, the members are equal. compare the description and then additional data
//
if (object.ReferenceEquals(stylusPoint1.Description, stylusPoint2.Description) ||
StylusPointDescription.AreCompatible(stylusPoint1.Description, stylusPoint2.Description))
{
//
// descriptions match and there are equal numbers of additional values
// let's check the values
//
for (int x = 0; x < stylusPoint1._additionalValues.Length; x++)
{
if (stylusPoint1._additionalValues[x] != stylusPoint2._additionalValues[x])
{
return false;
}
}
//
// Ok, ok already, we're equal
//
return true;
}
return false;
}
///
/// Compares two StylusPoint instances for exact equality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which are logically equal may fail.
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
/// Descriptions must match for equality to succeed and additional values must match
///
///
/// bool - true if the object is an instance of StylusPoint and if it's equal to "this".
///
/// The object to compare to "this"
public override bool Equals(object o)
{
if ((null == o) || !(o is StylusPoint))
{
return false;
}
StylusPoint value = (StylusPoint)o;
return StylusPoint.Equals(this, value);
}
///
/// Equals - compares this StylusPoint with the passed in object. In this equality
/// Double.NaN is equal to itself, unlike in numeric equality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which
/// are logically equal may fail.
///
///
/// bool - true if "value" is equal to "this".
///
/// The StylusPoint to compare to "this"
public bool Equals(StylusPoint value)
{
return StylusPoint.Equals(this, value);
}
///
/// Returns the HashCode for this StylusPoint
///
///
/// int - the HashCode for this StylusPoint
///
public override int GetHashCode()
{
int hash =
_x.GetHashCode() ^
_y.GetHashCode() ^
_pressureFactor.GetHashCode();
if (_stylusPointDescription != null)
{
hash ^= _stylusPointDescription.GetHashCode();
}
if (_additionalValues != null)
{
for (int x = 0; x < _additionalValues.Length; x++)
{
hash ^= _additionalValues[x]; //don't call GetHashCode on integers, it just returns the int
}
}
return hash;
}
///
/// Used by the StylusPointCollection.ToHimetricArray method
///
///
internal int[] GetAdditionalData()
{
//return a direct ref
return _additionalValues;
}
///
/// Internal helper used by SPC.Reformat to preserve the pressureFactor
///
internal float GetUntruncatedPressureFactor()
{
return _pressureFactor;
}
///
/// GetPacketData - returns avalon space packet data with true pressure if it exists
///
internal int[] GetPacketData()
{
int count = 2; //x, y
if (_additionalValues != null)
{
count += _additionalValues.Length;
}
if (this.Description.ContainsTruePressure)
{
count++;
}
int[] data = new int[count];
data[0] = (int)_x;
data[1] = (int)_y;
int startIndex = 2;
if (this.Description.ContainsTruePressure)
{
startIndex = 3;
data[2] = GetPropertyValue(StylusPointProperties.NormalPressure);
}
if (_additionalValues != null)
{
for (int x = 0; x < _additionalValues.Length; x++)
{
data[x + startIndex] = _additionalValues[x];
}
}
return data;
}
///
/// Internal helper to determine if a stroke has default pressure
/// This is used by ISF serialization to not serialize pressure
///
internal bool HasDefaultPressure
{
get
{
return (_pressureFactor == DefaultPressure);
}
}
///
/// Used by the SetPropertyData to make a copy of the data
/// before modifying it. This is required so that we don't
/// have two StylusPoint's sharing the same int[]
/// which can happen when you call: StylusPoint p = otherStylusPoint
/// because the CLR just does a memberwise copy
///
///
private void CopyAdditionalData()
{
if (null != _additionalValues)
{
int[] newData = new int[_additionalValues.Length];
for (int x = 0; x < _additionalValues.Length; x++)
{
newData[x] = _additionalValues[x];
}
_additionalValues = newData;
}
}
///
/// Private helper that returns a double clamped to MaxXY or MinXY
/// We only accept values in this range to support ISF serialization
///
private static double GetClampedXYValue(double xyValue)
{
if (xyValue > MaxXY)
{
return MaxXY;
}
if (xyValue < MinXY)
{
return MinXY;
}
return xyValue;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------
using System;
using System.Windows;
using System.Diagnostics;
using System.Windows.Input;
using System.Windows.Media;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using MS.Utility;
using MS.Internal;
using SR = MS.Internal.PresentationCore.SR;
using SRID = MS.Internal.PresentationCore.SRID;
namespace System.Windows.Input
{
///
/// Represents a single sampling point from a stylus input device
///
public struct StylusPoint : IEquatable
{
internal static readonly float DefaultPressure = 0.5f;
private double _x;
private double _y;
private float _pressureFactor;
private int[] _additionalValues;
private StylusPointDescription _stylusPointDescription;
#region Constructors
///
/// StylusPoint
///
/// x
/// y
public StylusPoint(double x, double y)
: this(x, y, DefaultPressure, null, null, false, false)
{
}
///
/// StylusPoint
///
/// x
/// y
/// pressureFactor
public StylusPoint(double x, double y, float pressureFactor)
: this(x, y, pressureFactor, null, null, false, true)
{
}
///
/// StylusPoint
///
/// x
/// y
/// pressureFactor
/// stylusPointDescription
/// additionalValues
public StylusPoint(double x, double y, float pressureFactor, StylusPointDescription stylusPointDescription, int[] additionalValues)
: this(x, y, pressureFactor, stylusPointDescription, additionalValues, true, true)
{
}
///
/// internal ctor
///
internal StylusPoint(
double x,
double y,
float pressureFactor,
StylusPointDescription stylusPointDescription,
int[] additionalValues,
bool validateAdditionalData,
bool validatePressureFactor)
{
if (Double.IsNaN(x))
{
throw new ArgumentOutOfRangeException("x", SR.Get(SRID.InvalidStylusPointXYNaN));
}
if (Double.IsNaN(y))
{
throw new ArgumentOutOfRangeException("y", SR.Get(SRID.InvalidStylusPointXYNaN));
}
//we don't validate pressure when called by StylusPointDescription.Reformat
if (validatePressureFactor &&
(pressureFactor == Single.NaN || pressureFactor < 0.0f || pressureFactor > 1.0f))
{
throw new ArgumentOutOfRangeException("pressureFactor", SR.Get(SRID.InvalidPressureValue));
}
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_x = GetClampedXYValue(x);
_y = GetClampedXYValue(y);
_stylusPointDescription = stylusPointDescription;
_additionalValues = additionalValues;
_pressureFactor = pressureFactor;
if (validateAdditionalData)
{
//
// called from the public verbose ctor
//
if (null == stylusPointDescription)
{
throw new ArgumentNullException("stylusPointDescription");
}
//
// additionalValues can be null if PropertyCount == 3 (X, Y, P)
//
if (stylusPointDescription.PropertyCount > StylusPointDescription.RequiredCountOfProperties &&
null == additionalValues)
{
throw new ArgumentNullException("additionalValues");
}
if (additionalValues != null)
{
ReadOnlyCollection properties
= stylusPointDescription.GetStylusPointProperties();
int expectedAdditionalValues = properties.Count - StylusPointDescription.RequiredCountOfProperties; //for x, y, pressure
if (additionalValues.Length != expectedAdditionalValues)
{
throw new ArgumentException(SR.Get(SRID.InvalidAdditionalDataForStylusPoint), "additionalValues");
}
//
// any buttons passed in must each be in their own int. We need to
// pack them all into one int here
//
int[] newAdditionalValues =
new int[stylusPointDescription.GetExpectedAdditionalDataCount()];
_additionalValues = newAdditionalValues;
for (int i = StylusPointDescription.RequiredCountOfProperties, j = 0; i < properties.Count; i++, j++)
{
//
// use SetPropertyValue, it validates buttons, but does not copy the
// int[] on writes (since we pass the bool flag)
//
SetPropertyValue(properties[i], additionalValues[j], false/*copy on write*/);
}
}
}
}
#endregion Constructors
///
/// The Maximum X or Y value supported for backwards compatibility with previous inking platforms
///
public static readonly double MaxXY = 81164736.28346430d;
///
/// The Minimum X or Y value supported for backwards compatibility with previous inking platforms
///
public static readonly double MinXY = -81164736.32125960d;
///
/// X
///
public double X
{
get { return _x; }
set
{
if (Double.IsNaN(value))
{
throw new ArgumentOutOfRangeException("X", SR.Get(SRID.InvalidStylusPointXYNaN));
}
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_x = GetClampedXYValue(value);
}
}
///
/// Y
///
public double Y
{
get { return _y; }
set
{
if (Double.IsNaN(value))
{
throw new ArgumentOutOfRangeException("Y", SR.Get(SRID.InvalidStylusPointXYNaN));
}
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_y = GetClampedXYValue(value);
}
}
///
/// PressureFactor. A value between 0.0 (no pressure) and 1.0 (max pressure)
///
public float PressureFactor
{
get
{
//
// note that pressure can be stored a > 1 or < 0.
// we need to clamp if this is the case
//
if (_pressureFactor > 1.0f)
{
return 1.0f;
}
if (_pressureFactor < 0.0f)
{
return 0.0f;
}
return _pressureFactor;
}
set
{
if (value < 0.0f || value > 1.0f)
{
throw new ArgumentOutOfRangeException("PressureFactor", SR.Get(SRID.InvalidPressureValue));
}
_pressureFactor = value;
}
}
///
/// Describes the properties this StylusPoint contains
///
public StylusPointDescription Description
{
get
{
if (null == _stylusPointDescription)
{
// this can happen when you call new StylusPoint()
// a few of the ctor's lazy init this as well
_stylusPointDescription = new StylusPointDescription();
}
return _stylusPointDescription;
}
internal set
{
//
// called by StylusPointCollection.Add / Set
// to replace the StylusPoint.Description with the collections.
//
Debug.Assert(value != null &&
StylusPointDescription.AreCompatible(value, this.Description));
_stylusPointDescription = value;
}
}
///
/// Returns true if this StylusPoint supports the specified property
///
/// The StylusPointProperty to see if this StylusPoint supports
public bool HasProperty(StylusPointProperty stylusPointProperty)
{
return this.Description.HasProperty(stylusPointProperty);
}
///
/// Provides read access to all stylus properties
///
/// The StylusPointPropertyIds of the property to retrieve
public int GetPropertyValue(StylusPointProperty stylusPointProperty)
{
if (null == stylusPointProperty)
{
throw new ArgumentNullException("stylusPointProperty");
}
if (stylusPointProperty.Id == StylusPointPropertyIds.X)
{
return (int)_x;
}
else if (stylusPointProperty.Id == StylusPointPropertyIds.Y)
{
return (int)_y;
}
else if (stylusPointProperty.Id == StylusPointPropertyIds.NormalPressure)
{
StylusPointPropertyInfo info =
this.Description.GetPropertyInfo(StylusPointProperties.NormalPressure);
int max = info.Maximum;
return (int)(_pressureFactor * (float)max);
}
else
{
int propertyIndex = this.Description.GetPropertyIndex(stylusPointProperty.Id);
if (-1 == propertyIndex)
{
throw new ArgumentException(SR.Get(SRID.InvalidStylusPointProperty), "stylusPointProperty");
}
if (stylusPointProperty.IsButton)
{
//
// we get button data from a single int in the array
//
int buttonData = _additionalValues[_additionalValues.Length - 1];
int buttonBitPosition = this.Description.GetButtonBitPosition(stylusPointProperty);
int bit = 1 << buttonBitPosition;
if ((buttonData & bit) != 0)
{
return 1;
}
else
{
return 0;
}
}
else
{
return _additionalValues[propertyIndex - 3];
}
}
}
///
/// Allows supported properties to be set
///
/// The property to set, it must exist on this StylusPoint
/// value
public void SetPropertyValue(StylusPointProperty stylusPointProperty, int value)
{
SetPropertyValue(stylusPointProperty, value, true);
}
///
/// Optimization that lets the ctor call setvalue repeatly without causing a copy of the int[]
///
/// stylusPointProperty
/// value
///
internal void SetPropertyValue(StylusPointProperty stylusPointProperty, int value, bool copyBeforeWrite)
{
if (null == stylusPointProperty)
{
throw new ArgumentNullException("stylusPointProperty");
}
if (stylusPointProperty.Id == StylusPointPropertyIds.X)
{
double dVal = (double)value;
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_x = GetClampedXYValue(dVal);
}
else if (stylusPointProperty.Id == StylusPointPropertyIds.Y)
{
double dVal = (double)value;
//
// only accept values between MaxXY and MinXY
// we don't throw when passed a value outside of that range, we just silently trunctate
//
_y = GetClampedXYValue(dVal);
}
else if (stylusPointProperty.Id == StylusPointPropertyIds.NormalPressure)
{
StylusPointPropertyInfo info =
this.Description.GetPropertyInfo(StylusPointProperties.NormalPressure);
int min = info.Minimum;
int max = info.Maximum;
if (max == 0)
{
_pressureFactor = 0.0f;
}
else
{
_pressureFactor = (float)(Convert.ToSingle(min + value) / Convert.ToSingle(max));
}
}
else
{
int propertyIndex = this.Description.GetPropertyIndex(stylusPointProperty.Id);
if (-1 == propertyIndex)
{
throw new ArgumentException(SR.Get(SRID.InvalidStylusPointProperty), "propertyId");
}
if (stylusPointProperty.IsButton)
{
if (value < 0 || value > 1)
{
throw new ArgumentOutOfRangeException(SR.Get(SRID.InvalidMinMaxForButton), "value");
}
if (copyBeforeWrite)
{
CopyAdditionalData();
}
//
// we get button data from a single int in the array
//
int buttonData = _additionalValues[_additionalValues.Length - 1];
int buttonBitPosition = this.Description.GetButtonBitPosition(stylusPointProperty);
int bit = 1 << buttonBitPosition;
if (value == 0)
{
//turn the bit off
buttonData &= ~bit;
}
else
{
//turn the bit on
buttonData |= bit;
}
_additionalValues[_additionalValues.Length - 1] = buttonData;
}
else
{
if (copyBeforeWrite)
{
CopyAdditionalData();
}
_additionalValues[propertyIndex - 3] = value;
}
}
}
///
/// Explicit cast converter between StylusPoint and Point
///
/// stylusPoint
public static explicit operator Point(StylusPoint stylusPoint)
{
return new Point(stylusPoint.X, stylusPoint.Y);
}
///
/// Allows languages that don't support operator overloading
/// to convert to a point
///
public Point ToPoint()
{
return new Point(this.X, this.Y);
}
///
/// Compares two StylusPoint instances for exact equality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which are logically equal may fail.
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
/// Descriptions must match for equality to succeed and additional values must match
///
///
/// bool - true if the two Stylus instances are exactly equal, false otherwise
///
/// The first StylusPoint to compare
/// The second StylusPoint to compare
public static bool operator ==(StylusPoint stylusPoint1, StylusPoint stylusPoint2)
{
return StylusPoint.Equals(stylusPoint1, stylusPoint2);
}
///
/// Compares two StylusPoint instances for exact inequality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which are logically equal may fail.
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
///
///
/// bool - true if the two Stylus instances are exactly inequal, false otherwise
///
/// The first StylusPoint to compare
/// The second StylusPoint to compare
public static bool operator !=(StylusPoint stylusPoint1, StylusPoint stylusPoint2)
{
return !StylusPoint.Equals(stylusPoint1, stylusPoint2);
}
///
/// Compares two StylusPoint instances for exact equality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which are logically equal may fail.
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
/// Descriptions must match for equality to succeed and additional values must match
///
///
/// bool - true if the two Stylus instances are exactly equal, false otherwise
///
/// The first StylusPoint to compare
/// The second StylusPoint to compare
public static bool Equals(StylusPoint stylusPoint1, StylusPoint stylusPoint2)
{
//
// do the cheap comparison first
//
bool membersEqual =
stylusPoint1._x == stylusPoint2._x &&
stylusPoint1._y == stylusPoint2._y &&
stylusPoint1._pressureFactor == stylusPoint2._pressureFactor;
if (!membersEqual)
{
return false;
}
//
// before we go checking the descriptions... check to see if both additionalData's are null
// we can infer that the SPD's are just X,Y,P and that they are compatible.
//
if (stylusPoint1._additionalValues == null &&
stylusPoint2._additionalValues == null)
{
Debug.Assert(StylusPointDescription.AreCompatible(stylusPoint1.Description, stylusPoint2.Description));
return true;
}
//
// ok, the members are equal. compare the description and then additional data
//
if (object.ReferenceEquals(stylusPoint1.Description, stylusPoint2.Description) ||
StylusPointDescription.AreCompatible(stylusPoint1.Description, stylusPoint2.Description))
{
//
// descriptions match and there are equal numbers of additional values
// let's check the values
//
for (int x = 0; x < stylusPoint1._additionalValues.Length; x++)
{
if (stylusPoint1._additionalValues[x] != stylusPoint2._additionalValues[x])
{
return false;
}
}
//
// Ok, ok already, we're equal
//
return true;
}
return false;
}
///
/// Compares two StylusPoint instances for exact equality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which are logically equal may fail.
/// Furthermore, using this equality operator, Double.NaN is not equal to itself.
/// Descriptions must match for equality to succeed and additional values must match
///
///
/// bool - true if the object is an instance of StylusPoint and if it's equal to "this".
///
/// The object to compare to "this"
public override bool Equals(object o)
{
if ((null == o) || !(o is StylusPoint))
{
return false;
}
StylusPoint value = (StylusPoint)o;
return StylusPoint.Equals(this, value);
}
///
/// Equals - compares this StylusPoint with the passed in object. In this equality
/// Double.NaN is equal to itself, unlike in numeric equality.
/// Note that double values can acquire error when operated upon, such that
/// an exact comparison between two values which
/// are logically equal may fail.
///
///
/// bool - true if "value" is equal to "this".
///
/// The StylusPoint to compare to "this"
public bool Equals(StylusPoint value)
{
return StylusPoint.Equals(this, value);
}
///
/// Returns the HashCode for this StylusPoint
///
///
/// int - the HashCode for this StylusPoint
///
public override int GetHashCode()
{
int hash =
_x.GetHashCode() ^
_y.GetHashCode() ^
_pressureFactor.GetHashCode();
if (_stylusPointDescription != null)
{
hash ^= _stylusPointDescription.GetHashCode();
}
if (_additionalValues != null)
{
for (int x = 0; x < _additionalValues.Length; x++)
{
hash ^= _additionalValues[x]; //don't call GetHashCode on integers, it just returns the int
}
}
return hash;
}
///
/// Used by the StylusPointCollection.ToHimetricArray method
///
///
internal int[] GetAdditionalData()
{
//return a direct ref
return _additionalValues;
}
///
/// Internal helper used by SPC.Reformat to preserve the pressureFactor
///
internal float GetUntruncatedPressureFactor()
{
return _pressureFactor;
}
///
/// GetPacketData - returns avalon space packet data with true pressure if it exists
///
internal int[] GetPacketData()
{
int count = 2; //x, y
if (_additionalValues != null)
{
count += _additionalValues.Length;
}
if (this.Description.ContainsTruePressure)
{
count++;
}
int[] data = new int[count];
data[0] = (int)_x;
data[1] = (int)_y;
int startIndex = 2;
if (this.Description.ContainsTruePressure)
{
startIndex = 3;
data[2] = GetPropertyValue(StylusPointProperties.NormalPressure);
}
if (_additionalValues != null)
{
for (int x = 0; x < _additionalValues.Length; x++)
{
data[x + startIndex] = _additionalValues[x];
}
}
return data;
}
///
/// Internal helper to determine if a stroke has default pressure
/// This is used by ISF serialization to not serialize pressure
///
internal bool HasDefaultPressure
{
get
{
return (_pressureFactor == DefaultPressure);
}
}
///
/// Used by the SetPropertyData to make a copy of the data
/// before modifying it. This is required so that we don't
/// have two StylusPoint's sharing the same int[]
/// which can happen when you call: StylusPoint p = otherStylusPoint
/// because the CLR just does a memberwise copy
///
///
private void CopyAdditionalData()
{
if (null != _additionalValues)
{
int[] newData = new int[_additionalValues.Length];
for (int x = 0; x < _additionalValues.Length; x++)
{
newData[x] = _additionalValues[x];
}
_additionalValues = newData;
}
}
///
/// Private helper that returns a double clamped to MaxXY or MinXY
/// We only accept values in this range to support ISF serialization
///
private static double GetClampedXYValue(double xyValue)
{
if (xyValue > MaxXY)
{
return MaxXY;
}
if (xyValue < MinXY)
{
return MinXY;
}
return xyValue;
}
}
}
// 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
- CompiledQuery.cs
- SQLInt32.cs
- SpeakInfo.cs
- CodeMemberField.cs
- EntityTypeEmitter.cs
- Journaling.cs
- IndicFontClient.cs
- basevalidator.cs
- WebPermission.cs
- SequentialActivityDesigner.cs
- OrderedDictionary.cs
- Propagator.Evaluator.cs
- DecodeHelper.cs
- CompModHelpers.cs
- WmlSelectionListAdapter.cs
- Evidence.cs
- FunctionMappingTranslator.cs
- BoundPropertyEntry.cs
- LiteralControl.cs
- XmlWhitespace.cs
- ColumnClickEvent.cs
- PersistenceTypeAttribute.cs
- WebPartEditorCancelVerb.cs
- ApplicationSettingsBase.cs
- MenuItemStyleCollection.cs
- TextDecorationCollection.cs
- UiaCoreTypesApi.cs
- UnmanagedMarshal.cs
- HtmlInputText.cs
- AliasedSlot.cs
- Int16.cs
- AnonymousIdentificationSection.cs
- GifBitmapEncoder.cs
- CodeConstructor.cs
- DataObject.cs
- EventLog.cs
- ListViewInsertedEventArgs.cs
- RtfControlWordInfo.cs
- SortQuery.cs
- ObsoleteAttribute.cs
- MonitoringDescriptionAttribute.cs
- AppDomainFactory.cs
- AttributeCollection.cs
- InkCollectionBehavior.cs
- WindowsRichEdit.cs
- LinkedResource.cs
- RowParagraph.cs
- RootBrowserWindow.cs
- TransformerInfo.cs
- ArcSegment.cs
- XmlSchemaNotation.cs
- StreamFormatter.cs
- DataPagerFieldCollection.cs
- SchemaImporterExtensionElementCollection.cs
- DataGridViewSelectedCellCollection.cs
- StickyNoteHelper.cs
- DataControlCommands.cs
- InstanceDescriptor.cs
- HtmlContainerControl.cs
- SpeechSynthesizer.cs
- CopyNamespacesAction.cs
- FontInfo.cs
- HttpFileCollection.cs
- WindowsSpinner.cs
- BitmapMetadata.cs
- streamingZipPartStream.cs
- QilFactory.cs
- UidPropertyAttribute.cs
- SynchronizationContext.cs
- XmlUrlResolver.cs
- Selector.cs
- SQLInt32Storage.cs
- BitmapCacheBrush.cs
- RelationshipEndMember.cs
- Visual3D.cs
- HttpResponseHeader.cs
- TraceUtility.cs
- ReverseComparer.cs
- PiiTraceSource.cs
- GeneralTransform.cs
- Root.cs
- mactripleDES.cs
- Literal.cs
- ExternalCalls.cs
- URI.cs
- EraserBehavior.cs
- EncryptedPackageFilter.cs
- ThicknessConverter.cs
- SystemIcons.cs
- XmlSchemaFacet.cs
- QueryExtender.cs
- SystemFonts.cs
- BitmapEffectDrawingContextState.cs
- EntryPointNotFoundException.cs
- ProfilePropertyMetadata.cs
- Enum.cs
- Msec.cs
- FixedSOMTableCell.cs
- ExpressionConverter.cs
- FixedFlowMap.cs