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) { ReadOnlyCollectionproperties = 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) { ReadOnlyCollectionproperties = 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
- SendSecurityHeader.cs
- DataTableExtensions.cs
- QilSortKey.cs
- DBConnection.cs
- XomlCompilerHelpers.cs
- DbConnectionPoolCounters.cs
- SectionInput.cs
- UnmanagedHandle.cs
- WebFormDesignerActionService.cs
- FormatPage.cs
- TypeToTreeConverter.cs
- PartialCachingAttribute.cs
- ListViewItemSelectionChangedEvent.cs
- TabRenderer.cs
- SspiWrapper.cs
- ButtonBaseAutomationPeer.cs
- XmlTypeMapping.cs
- MessageDesigner.cs
- SecurityKeyUsage.cs
- Site.cs
- GatewayDefinition.cs
- CommandDevice.cs
- InternalRelationshipCollection.cs
- SqlDataSourceSelectingEventArgs.cs
- XsltInput.cs
- StructuredTypeEmitter.cs
- WebPartVerbsEventArgs.cs
- FirstQueryOperator.cs
- UnicodeEncoding.cs
- InputLanguageManager.cs
- HtmlInputButton.cs
- StylusEventArgs.cs
- ShaderRenderModeValidation.cs
- Matrix3DConverter.cs
- MdImport.cs
- MessageDesigner.cs
- FileDialogCustomPlace.cs
- UpdateProgress.cs
- BevelBitmapEffect.cs
- RadioButton.cs
- ProfilePropertySettingsCollection.cs
- DefaultValueConverter.cs
- HttpSessionStateBase.cs
- DesignerDataView.cs
- EventToken.cs
- CustomTypeDescriptor.cs
- Part.cs
- MenuStrip.cs
- Group.cs
- ComboBoxItem.cs
- IntSecurity.cs
- ExpandCollapseProviderWrapper.cs
- FrugalList.cs
- ProtocolsConfigurationHandler.cs
- Ref.cs
- WindowsToolbar.cs
- DataGridViewLayoutData.cs
- Deserializer.cs
- Help.cs
- Int32Converter.cs
- SqlException.cs
- CroppedBitmap.cs
- SerialPinChanges.cs
- controlskin.cs
- DataGridViewCellValueEventArgs.cs
- Roles.cs
- ManifestResourceInfo.cs
- RequestCache.cs
- OdbcDataAdapter.cs
- SrgsElementList.cs
- LinqDataSourceStatusEventArgs.cs
- PageParserFilter.cs
- Nullable.cs
- TypeInitializationException.cs
- SafeNativeMethods.cs
- CopyNodeSetAction.cs
- SqlCacheDependency.cs
- ProviderConnectionPoint.cs
- SuppressIldasmAttribute.cs
- FunctionNode.cs
- RegistryPermission.cs
- ChannelProtectionRequirements.cs
- Clause.cs
- SmiGettersStream.cs
- StylusPointProperty.cs
- ButtonBase.cs
- StringBuilder.cs
- Int32AnimationBase.cs
- DataServiceEntityAttribute.cs
- RolePrincipal.cs
- UnmanagedMarshal.cs
- SqlLiftIndependentRowExpressions.cs
- XmlLanguageConverter.cs
- DataContractAttribute.cs
- ReturnEventArgs.cs
- TimeoutTimer.cs
- SimpleWebHandlerParser.cs
- SQLStringStorage.cs
- FormsAuthenticationCredentials.cs
- PrintEvent.cs