Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Core / CSharp / System / Windows / Input / Stylus / StylusPointCollection.cs / 1 / StylusPointCollection.cs
//------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------- using System; using System.Windows; using System.ComponentModel; using System.Windows.Ink; using MS.Internal.Ink.InkSerializedFormat; using System.Windows.Input; using System.Windows.Media; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using MS.Utility; using SR = MS.Internal.PresentationCore.SR; using SRID = MS.Internal.PresentationCore.SRID; namespace System.Windows.Input { ////// StylusPointCollection /// public class StylusPointCollection : Collection{ private StylusPointDescription _stylusPointDescription; /// /// Changed event, anytime the data in this collection changes, this event is raised /// public event EventHandler Changed; ////// Internal only changed event used by Stroke to prevent zero count strokes /// internal event CancelEventHandler CountGoingToZero; ////// StylusPointCollection /// public StylusPointCollection() { _stylusPointDescription = new StylusPointDescription(); } ////// StylusPointCollection /// /// initialCapacity public StylusPointCollection(int initialCapacity) : this() { if (initialCapacity < 0) { throw new ArgumentException("initialCapacity"); } ((List)this.Items).Capacity = initialCapacity; } /// /// StylusPointCollection /// /// stylusPointDescription public StylusPointCollection(StylusPointDescription stylusPointDescription) { if (null == stylusPointDescription) { throw new ArgumentNullException(); } _stylusPointDescription = stylusPointDescription; } ////// StylusPointCollection /// /// stylusPointDescription /// initialCapacity public StylusPointCollection(StylusPointDescription stylusPointDescription, int initialCapacity) : this (stylusPointDescription) { if (initialCapacity < 0) { throw new ArgumentException("initialCapacity"); } ((List)this.Items).Capacity = initialCapacity; } /// /// StylusPointCollection /// /// stylusPoints public StylusPointCollection(IEnumerablestylusPoints) //: this() //don't call the base ctor, we want to use the first sp { if (stylusPoints == null) { throw new ArgumentNullException("stylusPoints"); } List points = new List (stylusPoints); if (points.Count == 0) { throw new ArgumentException(SR.Get(SRID.InvalidStylusPointConstructionZeroLengthCollection), "stylusPoints"); } // // set our packet description to the first in the array // _stylusPointDescription = points[0].Description; ((List )this.Items).Capacity = points.Count; for (int x = 0; x < points.Count; x++) { this.Add(points[x]); } } /// /// StylusPointCollection /// /// points public StylusPointCollection(IEnumerablepoints) : this() { if (points == null) { throw new ArgumentNullException("points"); } List stylusPoints = new List (); foreach (Point point in points) { //this can throw (since point.X or Y can be beyond our range) //don't add to our internal collection until after we instance //all of the styluspoints and we know the ranges are valid stylusPoints.Add(new StylusPoint(point.X, point.Y)); } if (stylusPoints.Count == 0) { throw new ArgumentException(SR.Get(SRID.InvalidStylusPointConstructionZeroLengthCollection), "points"); } ((List )this.Items).Capacity = stylusPoints.Count; ((List )this.Items).AddRange(stylusPoints); } /// /// Internal ctor called by input with a raw int[] /// /// stylusPointDescription /// rawPacketData /// tabletToView /// tabletToView internal StylusPointCollection(StylusPointDescription stylusPointDescription, int[] rawPacketData, GeneralTransform tabletToView, Matrix tabletToViewMatrix) { if (null == stylusPointDescription) { throw new ArgumentNullException(); } _stylusPointDescription = stylusPointDescription; int lengthPerPoint = stylusPointDescription.GetInputArrayLengthPerPoint(); int logicalPointCount = rawPacketData.Length / lengthPerPoint; Debug.Assert(0 == rawPacketData.Length % lengthPerPoint, "Invalid assumption about packet length, there shouldn't be any remainder"); // // set our capacity and validate // ((List)this.Items).Capacity = logicalPointCount; for (int count = 0, i = 0; count < logicalPointCount; count++, i += lengthPerPoint) { //first, determine the x, y values by xf-ing them Point p = new Point(rawPacketData[i], rawPacketData[i + 1]); if (tabletToView != null) { tabletToView.TryTransform(p, out p); } else { p = tabletToViewMatrix.Transform(p); } int startIndex = 2; bool containsTruePressure = stylusPointDescription.ContainsTruePressure; if (containsTruePressure) { //don't copy pressure in the int[] for extra data startIndex++; } int[] data = null; int dataLength = lengthPerPoint - startIndex; if (dataLength > 0) { //copy the rest of the data data = new int[dataLength]; for (int localIndex = 0, rawArrayIndex = i + startIndex; localIndex < data.Length; localIndex++, rawArrayIndex++) { data[localIndex] = rawPacketData[rawArrayIndex]; } } StylusPoint newPoint = new StylusPoint(p.X, p.Y, StylusPoint.DefaultPressure, _stylusPointDescription, data, false, false); if (containsTruePressure) { //use the algoritm to set pressure in StylusPoint int pressure = rawPacketData[i + 2]; newPoint.SetPropertyValue(StylusPointProperties.NormalPressure, pressure); } //this does not go through our protected virtuals ((List )this.Items).Add(newPoint); } } /// /// Adds the StylusPoints in the StylusPointCollection to this StylusPointCollection /// /// stylusPoints public void Add(StylusPointCollection stylusPoints) { //note that we don't raise an exception if stylusPoints.Count == 0 if (null == stylusPoints) { throw new ArgumentNullException("stylusPoints"); } if (!StylusPointDescription.AreCompatible(stylusPoints.Description, _stylusPointDescription)) { throw new ArgumentException(SR.Get(SRID.IncompatibleStylusPointDescriptions), "stylusPoints"); } // cache count outside of the loop, so if this SPC is ever passed // we don't loop forever int count = stylusPoints.Count; for (int x = 0; x < count; x++) { StylusPoint stylusPoint = stylusPoints[x]; stylusPoint.Description = _stylusPointDescription; //this does not go through our protected virtuals ((List)this.Items).Add(stylusPoint); } if (stylusPoints.Count > 0) { OnChanged(EventArgs.Empty); } } /// /// Read only access to the StylusPointDescription shared by the StylusPoints in this collection /// public StylusPointDescription Description { get { if (null == _stylusPointDescription) { _stylusPointDescription = new StylusPointDescription(); } return _stylusPointDescription; } } ////// called by base class Collection<T> when the list is being cleared; /// raises a CollectionChanged event to any listeners /// protected override sealed void ClearItems() { if (CanGoToZero()) { base.ClearItems(); OnChanged(EventArgs.Empty); } else { throw new InvalidOperationException(SR.Get(SRID.InvalidStylusPointCollectionZeroCount)); } } ////// called by base class Collection<T> when an item is removed from list; /// raises a CollectionChanged event to any listeners /// protected override sealed void RemoveItem(int index) { if (this.Count > 1 || CanGoToZero()) { base.RemoveItem(index); OnChanged(EventArgs.Empty); } else { throw new InvalidOperationException(SR.Get(SRID.InvalidStylusPointCollectionZeroCount)); } } ////// called by base class Collection<T> when an item is added to list; /// raises a CollectionChanged event to any listeners /// protected override sealed void InsertItem(int index, StylusPoint stylusPoint) { if (!StylusPointDescription.AreCompatible(stylusPoint.Description, _stylusPointDescription)) { throw new ArgumentException(SR.Get(SRID.IncompatibleStylusPointDescriptions), "stylusPoint"); } stylusPoint.Description = _stylusPointDescription; base.InsertItem(index, stylusPoint); OnChanged(EventArgs.Empty); } ////// called by base class Collection<T> when an item is set in list; /// raises a CollectionChanged event to any listeners /// protected override sealed void SetItem(int index, StylusPoint stylusPoint) { if (!StylusPointDescription.AreCompatible(stylusPoint.Description, _stylusPointDescription)) { throw new ArgumentException(SR.Get(SRID.IncompatibleStylusPointDescriptions), "stylusPoint"); } stylusPoint.Description = _stylusPointDescription; base.SetItem(index, stylusPoint); OnChanged(EventArgs.Empty); } ////// Clone /// public StylusPointCollection Clone() { return this.Clone(System.Windows.Media.Transform.Identity, this.Description, this.Count); } ////// Explicit cast converter between StylusPointCollection and Point[] /// /// stylusPoints public static explicit operator Point[](StylusPointCollection stylusPoints) { if (stylusPoints == null) { return null; } Point[] points = new Point[stylusPoints.Count]; for (int i = 0; i < stylusPoints.Count; i++) { points[i] = new Point(stylusPoints[i].X, stylusPoints[i].Y); } return points; } ////// Clone and truncate /// /// The maximum count of points to clone (used by GestureRecognizer) ///internal StylusPointCollection Clone(int count) { if (count > this.Count || count < 1) { throw new ArgumentOutOfRangeException("count"); } return this.Clone(System.Windows.Media.Transform.Identity, this.Description, count); } /// /// Clone with a transform, used by input /// internal StylusPointCollection Clone(GeneralTransform transform, StylusPointDescription descriptionToUse) { return this.Clone(transform, descriptionToUse, this.Count); } ////// Private clone implementation /// private StylusPointCollection Clone(GeneralTransform transform, StylusPointDescription descriptionToUse, int count) { Debug.Assert(count <= this.Count); // // We don't need to copy our _stylusPointDescription because it is immutable // and we don't need to copy our StylusPoints, because they are structs. // StylusPointCollection newCollection = new StylusPointCollection(descriptionToUse, count); bool isIdentity = (transform is Transform) ? ((Transform)transform).IsIdentity : false; for (int x = 0; x < count; x++) { if (isIdentity) { ((List)newCollection.Items).Add(this[x]); } else { Point point = new Point(); StylusPoint stylusPoint = this[x]; point.X = stylusPoint.X; point.Y = stylusPoint.Y; transform.TryTransform(point, out point); stylusPoint.X = point.X; stylusPoint.Y = point.Y; ((List )newCollection.Items).Add(stylusPoint); } } return newCollection; } /// /// Protected virtual for raising changed notification /// /// protected virtual void OnChanged(EventArgs e) { if (e == null) { throw new ArgumentNullException("e"); } if (this.Changed != null) { this.Changed(this, e); } } ////// Transform the StylusPoints in this collection by the specified transform /// /// transform internal void Transform(GeneralTransform transform) { Point point = new Point(); for (int i = 0; i < this.Count; i++) { StylusPoint stylusPoint = this[i]; point.X = stylusPoint.X; point.Y = stylusPoint.Y; transform.TryTransform(point, out point); stylusPoint.X = point.X; stylusPoint.Y = point.Y; //this does not go through our protected virtuals ((List)this.Items)[i] = stylusPoint; } if (this.Count > 0) { this.OnChanged(EventArgs.Empty); } } /// /// Reformat /// /// subsetToReformatTo public StylusPointCollection Reformat(StylusPointDescription subsetToReformatTo) { return Reformat(subsetToReformatTo, System.Windows.Media.Transform.Identity); } ////// Helper that transforms and scales in one go /// internal StylusPointCollection Reformat(StylusPointDescription subsetToReformatTo, GeneralTransform transform) { if (!subsetToReformatTo.IsSubsetOf(this.Description)) { throw new ArgumentException(SR.Get(SRID.InvalidStylusPointDescriptionSubset), "subsetToReformatTo"); } StylusPointDescription subsetToReformatToWithCurrentMetrics = StylusPointDescription.GetCommonDescription(subsetToReformatTo, this.Description); //preserve metrics from this spd if (StylusPointDescription.AreCompatible(this.Description, subsetToReformatToWithCurrentMetrics) && (transform is Transform) && ((Transform)transform).IsIdentity) { //subsetToReformatTo might have different x, y, p metrics return this.Clone(transform, subsetToReformatToWithCurrentMetrics); } // // we really need to reformat this... // StylusPointCollection newCollection = new StylusPointCollection(subsetToReformatToWithCurrentMetrics, this.Count); int additionalDataCount = subsetToReformatToWithCurrentMetrics.GetExpectedAdditionalDataCount(); ReadOnlyCollectionproperties = subsetToReformatToWithCurrentMetrics.GetStylusPointProperties(); bool isIdentity = (transform is Transform) ? ((Transform)transform).IsIdentity : false; for (int i = 0; i < this.Count; i++) { StylusPoint stylusPoint = this[i]; double xCoord = stylusPoint.X; double yCoord = stylusPoint.Y; float pressure = stylusPoint.GetUntruncatedPressureFactor(); if (!isIdentity) { Point p = new Point(xCoord, yCoord); transform.TryTransform(p, out p); xCoord = p.X; yCoord = p.Y; } int[] newData = null; if (additionalDataCount > 0) { //don't init, we'll do that below newData = new int[additionalDataCount]; } StylusPoint newStylusPoint = new StylusPoint(xCoord, yCoord, pressure, subsetToReformatToWithCurrentMetrics, newData, false, false); //start at 3, skipping x, y, pressure for (int x = StylusPointDescription.RequiredCountOfProperties/*3*/; x < properties.Count; x++) { int value = stylusPoint.GetPropertyValue(properties[x]); newStylusPoint.SetPropertyValue(properties[x], value, false/*copy on write*/); } //bypass validation ((List )newCollection.Items).Add(newStylusPoint); } return newCollection; } /// /// Returns this StylusPointCollection as a flat integer array in the himetric coordiate space /// ///public int[] ToHiMetricArray() { // // X and Y are in Avalon units, we need to convert to HIMETRIC // int lengthPerPoint = this.Description.GetOutputArrayLengthPerPoint(); int[] output = new int[lengthPerPoint * this.Count]; for (int i = 0, x = 0; i < this.Count; i++, x += lengthPerPoint) { StylusPoint stylusPoint = this[i]; output[x] = (int)Math.Round(stylusPoint.X * StrokeCollectionSerializer.AvalonToHimetricMultiplier); output[x + 1] = (int)Math.Round(stylusPoint.Y * StrokeCollectionSerializer.AvalonToHimetricMultiplier); output[x + 2] = stylusPoint.GetPropertyValue(StylusPointProperties.NormalPressure); if (lengthPerPoint > StylusPointDescription.RequiredCountOfProperties/*3*/) { int[] additionalData = stylusPoint.GetAdditionalData(); int countToCopy = lengthPerPoint - StylusPointDescription.RequiredCountOfProperties;/*3*/ Debug.Assert(additionalData.Length == countToCopy); for (int y = 0; y < countToCopy; y++) { output[x + y + 3] = additionalData[y]; } } } return output; } /// /// ToISFReadyArrays - Returns an array of arrays of packet values: /// /// int[] /// - int[x,x,x,x,x,x] /// - int[y,y,y,y,y,y] /// - int[p,p,p,p,p,p] /// /// For ISF serialization /// /// Also returns if any non-default pressures were found or the metric for /// pressure was non-default /// /// internal void ToISFReadyArrays(out int[][]output, out bool shouldPersistPressure) { Debug.Assert(this.Count != 0, "Why are we serializing an empty StylusPointCollection???"); // // X and Y are in Avalon units, we need to convert to HIMETRIC // // // int lengthPerPoint = this.Description.GetOutputArrayLengthPerPoint(); if (this.Description.ButtonCount > 0) { //don't serialize button data. See Windows OS Bugs 1413460 for details lengthPerPoint--; } output = new int[lengthPerPoint][]; for (int x = 0; x < lengthPerPoint; x++) { output[x] = new int[this.Count]; } // // we serialize pressure if // 1) The StylusPointPropertyInfo for pressure is not the default // 2) There is at least one non-default pressure value in this SPC // StylusPointPropertyInfo pressureInfo = this.Description.GetPropertyInfo(StylusPointPropertyIds.NormalPressure); shouldPersistPressure = !StylusPointPropertyInfo.AreCompatible(pressureInfo, StylusPointPropertyInfoDefaults.NormalPressure); for (int b = 0; b < this.Count; b++) { StylusPoint stylusPoint = this[b]; output[0][b] = (int)Math.Round(stylusPoint.X * StrokeCollectionSerializer.AvalonToHimetricMultiplier); output[1][b] = (int)Math.Round(stylusPoint.Y * StrokeCollectionSerializer.AvalonToHimetricMultiplier); output[2][b] = stylusPoint.GetPropertyValue(StylusPointProperties.NormalPressure); // // it's not necessary to check HasDefaultPressure if // allDefaultPressures is already set // if (!shouldPersistPressure && !stylusPoint.HasDefaultPressure) { shouldPersistPressure = true; } if (lengthPerPoint > StylusPointDescription.RequiredCountOfProperties) { int[] additionalData = stylusPoint.GetAdditionalData(); int countToCopy = lengthPerPoint - StylusPointDescription.RequiredCountOfProperties;/*3*/ Debug.Assert( this.Description.ButtonCount > 0 ? additionalData.Length -1 == countToCopy : additionalData.Length == countToCopy); for (int y = 0; y < countToCopy; y++) { output[y + 3][b] = additionalData[y]; } } } } ////// Private helper use to consult with any listening strokes if it is safe to go to zero count /// ///private bool CanGoToZero() { if (null == this.CountGoingToZero) { // // no one is listening // return true; } CancelEventArgs e = new CancelEventArgs(); e.Cancel = false; // // call the listeners // this.CountGoingToZero(this, e); Debug.Assert(e.Cancel, "This event should always be cancelled"); return !e.Cancel; } } } // 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.ComponentModel; using System.Windows.Ink; using MS.Internal.Ink.InkSerializedFormat; using System.Windows.Input; using System.Windows.Media; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using MS.Utility; using SR = MS.Internal.PresentationCore.SR; using SRID = MS.Internal.PresentationCore.SRID; namespace System.Windows.Input { ////// StylusPointCollection /// public class StylusPointCollection : Collection{ private StylusPointDescription _stylusPointDescription; /// /// Changed event, anytime the data in this collection changes, this event is raised /// public event EventHandler Changed; ////// Internal only changed event used by Stroke to prevent zero count strokes /// internal event CancelEventHandler CountGoingToZero; ////// StylusPointCollection /// public StylusPointCollection() { _stylusPointDescription = new StylusPointDescription(); } ////// StylusPointCollection /// /// initialCapacity public StylusPointCollection(int initialCapacity) : this() { if (initialCapacity < 0) { throw new ArgumentException("initialCapacity"); } ((List)this.Items).Capacity = initialCapacity; } /// /// StylusPointCollection /// /// stylusPointDescription public StylusPointCollection(StylusPointDescription stylusPointDescription) { if (null == stylusPointDescription) { throw new ArgumentNullException(); } _stylusPointDescription = stylusPointDescription; } ////// StylusPointCollection /// /// stylusPointDescription /// initialCapacity public StylusPointCollection(StylusPointDescription stylusPointDescription, int initialCapacity) : this (stylusPointDescription) { if (initialCapacity < 0) { throw new ArgumentException("initialCapacity"); } ((List)this.Items).Capacity = initialCapacity; } /// /// StylusPointCollection /// /// stylusPoints public StylusPointCollection(IEnumerablestylusPoints) //: this() //don't call the base ctor, we want to use the first sp { if (stylusPoints == null) { throw new ArgumentNullException("stylusPoints"); } List points = new List (stylusPoints); if (points.Count == 0) { throw new ArgumentException(SR.Get(SRID.InvalidStylusPointConstructionZeroLengthCollection), "stylusPoints"); } // // set our packet description to the first in the array // _stylusPointDescription = points[0].Description; ((List )this.Items).Capacity = points.Count; for (int x = 0; x < points.Count; x++) { this.Add(points[x]); } } /// /// StylusPointCollection /// /// points public StylusPointCollection(IEnumerablepoints) : this() { if (points == null) { throw new ArgumentNullException("points"); } List stylusPoints = new List (); foreach (Point point in points) { //this can throw (since point.X or Y can be beyond our range) //don't add to our internal collection until after we instance //all of the styluspoints and we know the ranges are valid stylusPoints.Add(new StylusPoint(point.X, point.Y)); } if (stylusPoints.Count == 0) { throw new ArgumentException(SR.Get(SRID.InvalidStylusPointConstructionZeroLengthCollection), "points"); } ((List )this.Items).Capacity = stylusPoints.Count; ((List )this.Items).AddRange(stylusPoints); } /// /// Internal ctor called by input with a raw int[] /// /// stylusPointDescription /// rawPacketData /// tabletToView /// tabletToView internal StylusPointCollection(StylusPointDescription stylusPointDescription, int[] rawPacketData, GeneralTransform tabletToView, Matrix tabletToViewMatrix) { if (null == stylusPointDescription) { throw new ArgumentNullException(); } _stylusPointDescription = stylusPointDescription; int lengthPerPoint = stylusPointDescription.GetInputArrayLengthPerPoint(); int logicalPointCount = rawPacketData.Length / lengthPerPoint; Debug.Assert(0 == rawPacketData.Length % lengthPerPoint, "Invalid assumption about packet length, there shouldn't be any remainder"); // // set our capacity and validate // ((List)this.Items).Capacity = logicalPointCount; for (int count = 0, i = 0; count < logicalPointCount; count++, i += lengthPerPoint) { //first, determine the x, y values by xf-ing them Point p = new Point(rawPacketData[i], rawPacketData[i + 1]); if (tabletToView != null) { tabletToView.TryTransform(p, out p); } else { p = tabletToViewMatrix.Transform(p); } int startIndex = 2; bool containsTruePressure = stylusPointDescription.ContainsTruePressure; if (containsTruePressure) { //don't copy pressure in the int[] for extra data startIndex++; } int[] data = null; int dataLength = lengthPerPoint - startIndex; if (dataLength > 0) { //copy the rest of the data data = new int[dataLength]; for (int localIndex = 0, rawArrayIndex = i + startIndex; localIndex < data.Length; localIndex++, rawArrayIndex++) { data[localIndex] = rawPacketData[rawArrayIndex]; } } StylusPoint newPoint = new StylusPoint(p.X, p.Y, StylusPoint.DefaultPressure, _stylusPointDescription, data, false, false); if (containsTruePressure) { //use the algoritm to set pressure in StylusPoint int pressure = rawPacketData[i + 2]; newPoint.SetPropertyValue(StylusPointProperties.NormalPressure, pressure); } //this does not go through our protected virtuals ((List )this.Items).Add(newPoint); } } /// /// Adds the StylusPoints in the StylusPointCollection to this StylusPointCollection /// /// stylusPoints public void Add(StylusPointCollection stylusPoints) { //note that we don't raise an exception if stylusPoints.Count == 0 if (null == stylusPoints) { throw new ArgumentNullException("stylusPoints"); } if (!StylusPointDescription.AreCompatible(stylusPoints.Description, _stylusPointDescription)) { throw new ArgumentException(SR.Get(SRID.IncompatibleStylusPointDescriptions), "stylusPoints"); } // cache count outside of the loop, so if this SPC is ever passed // we don't loop forever int count = stylusPoints.Count; for (int x = 0; x < count; x++) { StylusPoint stylusPoint = stylusPoints[x]; stylusPoint.Description = _stylusPointDescription; //this does not go through our protected virtuals ((List)this.Items).Add(stylusPoint); } if (stylusPoints.Count > 0) { OnChanged(EventArgs.Empty); } } /// /// Read only access to the StylusPointDescription shared by the StylusPoints in this collection /// public StylusPointDescription Description { get { if (null == _stylusPointDescription) { _stylusPointDescription = new StylusPointDescription(); } return _stylusPointDescription; } } ////// called by base class Collection<T> when the list is being cleared; /// raises a CollectionChanged event to any listeners /// protected override sealed void ClearItems() { if (CanGoToZero()) { base.ClearItems(); OnChanged(EventArgs.Empty); } else { throw new InvalidOperationException(SR.Get(SRID.InvalidStylusPointCollectionZeroCount)); } } ////// called by base class Collection<T> when an item is removed from list; /// raises a CollectionChanged event to any listeners /// protected override sealed void RemoveItem(int index) { if (this.Count > 1 || CanGoToZero()) { base.RemoveItem(index); OnChanged(EventArgs.Empty); } else { throw new InvalidOperationException(SR.Get(SRID.InvalidStylusPointCollectionZeroCount)); } } ////// called by base class Collection<T> when an item is added to list; /// raises a CollectionChanged event to any listeners /// protected override sealed void InsertItem(int index, StylusPoint stylusPoint) { if (!StylusPointDescription.AreCompatible(stylusPoint.Description, _stylusPointDescription)) { throw new ArgumentException(SR.Get(SRID.IncompatibleStylusPointDescriptions), "stylusPoint"); } stylusPoint.Description = _stylusPointDescription; base.InsertItem(index, stylusPoint); OnChanged(EventArgs.Empty); } ////// called by base class Collection<T> when an item is set in list; /// raises a CollectionChanged event to any listeners /// protected override sealed void SetItem(int index, StylusPoint stylusPoint) { if (!StylusPointDescription.AreCompatible(stylusPoint.Description, _stylusPointDescription)) { throw new ArgumentException(SR.Get(SRID.IncompatibleStylusPointDescriptions), "stylusPoint"); } stylusPoint.Description = _stylusPointDescription; base.SetItem(index, stylusPoint); OnChanged(EventArgs.Empty); } ////// Clone /// public StylusPointCollection Clone() { return this.Clone(System.Windows.Media.Transform.Identity, this.Description, this.Count); } ////// Explicit cast converter between StylusPointCollection and Point[] /// /// stylusPoints public static explicit operator Point[](StylusPointCollection stylusPoints) { if (stylusPoints == null) { return null; } Point[] points = new Point[stylusPoints.Count]; for (int i = 0; i < stylusPoints.Count; i++) { points[i] = new Point(stylusPoints[i].X, stylusPoints[i].Y); } return points; } ////// Clone and truncate /// /// The maximum count of points to clone (used by GestureRecognizer) ///internal StylusPointCollection Clone(int count) { if (count > this.Count || count < 1) { throw new ArgumentOutOfRangeException("count"); } return this.Clone(System.Windows.Media.Transform.Identity, this.Description, count); } /// /// Clone with a transform, used by input /// internal StylusPointCollection Clone(GeneralTransform transform, StylusPointDescription descriptionToUse) { return this.Clone(transform, descriptionToUse, this.Count); } ////// Private clone implementation /// private StylusPointCollection Clone(GeneralTransform transform, StylusPointDescription descriptionToUse, int count) { Debug.Assert(count <= this.Count); // // We don't need to copy our _stylusPointDescription because it is immutable // and we don't need to copy our StylusPoints, because they are structs. // StylusPointCollection newCollection = new StylusPointCollection(descriptionToUse, count); bool isIdentity = (transform is Transform) ? ((Transform)transform).IsIdentity : false; for (int x = 0; x < count; x++) { if (isIdentity) { ((List)newCollection.Items).Add(this[x]); } else { Point point = new Point(); StylusPoint stylusPoint = this[x]; point.X = stylusPoint.X; point.Y = stylusPoint.Y; transform.TryTransform(point, out point); stylusPoint.X = point.X; stylusPoint.Y = point.Y; ((List )newCollection.Items).Add(stylusPoint); } } return newCollection; } /// /// Protected virtual for raising changed notification /// /// protected virtual void OnChanged(EventArgs e) { if (e == null) { throw new ArgumentNullException("e"); } if (this.Changed != null) { this.Changed(this, e); } } ////// Transform the StylusPoints in this collection by the specified transform /// /// transform internal void Transform(GeneralTransform transform) { Point point = new Point(); for (int i = 0; i < this.Count; i++) { StylusPoint stylusPoint = this[i]; point.X = stylusPoint.X; point.Y = stylusPoint.Y; transform.TryTransform(point, out point); stylusPoint.X = point.X; stylusPoint.Y = point.Y; //this does not go through our protected virtuals ((List)this.Items)[i] = stylusPoint; } if (this.Count > 0) { this.OnChanged(EventArgs.Empty); } } /// /// Reformat /// /// subsetToReformatTo public StylusPointCollection Reformat(StylusPointDescription subsetToReformatTo) { return Reformat(subsetToReformatTo, System.Windows.Media.Transform.Identity); } ////// Helper that transforms and scales in one go /// internal StylusPointCollection Reformat(StylusPointDescription subsetToReformatTo, GeneralTransform transform) { if (!subsetToReformatTo.IsSubsetOf(this.Description)) { throw new ArgumentException(SR.Get(SRID.InvalidStylusPointDescriptionSubset), "subsetToReformatTo"); } StylusPointDescription subsetToReformatToWithCurrentMetrics = StylusPointDescription.GetCommonDescription(subsetToReformatTo, this.Description); //preserve metrics from this spd if (StylusPointDescription.AreCompatible(this.Description, subsetToReformatToWithCurrentMetrics) && (transform is Transform) && ((Transform)transform).IsIdentity) { //subsetToReformatTo might have different x, y, p metrics return this.Clone(transform, subsetToReformatToWithCurrentMetrics); } // // we really need to reformat this... // StylusPointCollection newCollection = new StylusPointCollection(subsetToReformatToWithCurrentMetrics, this.Count); int additionalDataCount = subsetToReformatToWithCurrentMetrics.GetExpectedAdditionalDataCount(); ReadOnlyCollectionproperties = subsetToReformatToWithCurrentMetrics.GetStylusPointProperties(); bool isIdentity = (transform is Transform) ? ((Transform)transform).IsIdentity : false; for (int i = 0; i < this.Count; i++) { StylusPoint stylusPoint = this[i]; double xCoord = stylusPoint.X; double yCoord = stylusPoint.Y; float pressure = stylusPoint.GetUntruncatedPressureFactor(); if (!isIdentity) { Point p = new Point(xCoord, yCoord); transform.TryTransform(p, out p); xCoord = p.X; yCoord = p.Y; } int[] newData = null; if (additionalDataCount > 0) { //don't init, we'll do that below newData = new int[additionalDataCount]; } StylusPoint newStylusPoint = new StylusPoint(xCoord, yCoord, pressure, subsetToReformatToWithCurrentMetrics, newData, false, false); //start at 3, skipping x, y, pressure for (int x = StylusPointDescription.RequiredCountOfProperties/*3*/; x < properties.Count; x++) { int value = stylusPoint.GetPropertyValue(properties[x]); newStylusPoint.SetPropertyValue(properties[x], value, false/*copy on write*/); } //bypass validation ((List )newCollection.Items).Add(newStylusPoint); } return newCollection; } /// /// Returns this StylusPointCollection as a flat integer array in the himetric coordiate space /// ///public int[] ToHiMetricArray() { // // X and Y are in Avalon units, we need to convert to HIMETRIC // int lengthPerPoint = this.Description.GetOutputArrayLengthPerPoint(); int[] output = new int[lengthPerPoint * this.Count]; for (int i = 0, x = 0; i < this.Count; i++, x += lengthPerPoint) { StylusPoint stylusPoint = this[i]; output[x] = (int)Math.Round(stylusPoint.X * StrokeCollectionSerializer.AvalonToHimetricMultiplier); output[x + 1] = (int)Math.Round(stylusPoint.Y * StrokeCollectionSerializer.AvalonToHimetricMultiplier); output[x + 2] = stylusPoint.GetPropertyValue(StylusPointProperties.NormalPressure); if (lengthPerPoint > StylusPointDescription.RequiredCountOfProperties/*3*/) { int[] additionalData = stylusPoint.GetAdditionalData(); int countToCopy = lengthPerPoint - StylusPointDescription.RequiredCountOfProperties;/*3*/ Debug.Assert(additionalData.Length == countToCopy); for (int y = 0; y < countToCopy; y++) { output[x + y + 3] = additionalData[y]; } } } return output; } /// /// ToISFReadyArrays - Returns an array of arrays of packet values: /// /// int[] /// - int[x,x,x,x,x,x] /// - int[y,y,y,y,y,y] /// - int[p,p,p,p,p,p] /// /// For ISF serialization /// /// Also returns if any non-default pressures were found or the metric for /// pressure was non-default /// /// internal void ToISFReadyArrays(out int[][]output, out bool shouldPersistPressure) { Debug.Assert(this.Count != 0, "Why are we serializing an empty StylusPointCollection???"); // // X and Y are in Avalon units, we need to convert to HIMETRIC // // // int lengthPerPoint = this.Description.GetOutputArrayLengthPerPoint(); if (this.Description.ButtonCount > 0) { //don't serialize button data. See Windows OS Bugs 1413460 for details lengthPerPoint--; } output = new int[lengthPerPoint][]; for (int x = 0; x < lengthPerPoint; x++) { output[x] = new int[this.Count]; } // // we serialize pressure if // 1) The StylusPointPropertyInfo for pressure is not the default // 2) There is at least one non-default pressure value in this SPC // StylusPointPropertyInfo pressureInfo = this.Description.GetPropertyInfo(StylusPointPropertyIds.NormalPressure); shouldPersistPressure = !StylusPointPropertyInfo.AreCompatible(pressureInfo, StylusPointPropertyInfoDefaults.NormalPressure); for (int b = 0; b < this.Count; b++) { StylusPoint stylusPoint = this[b]; output[0][b] = (int)Math.Round(stylusPoint.X * StrokeCollectionSerializer.AvalonToHimetricMultiplier); output[1][b] = (int)Math.Round(stylusPoint.Y * StrokeCollectionSerializer.AvalonToHimetricMultiplier); output[2][b] = stylusPoint.GetPropertyValue(StylusPointProperties.NormalPressure); // // it's not necessary to check HasDefaultPressure if // allDefaultPressures is already set // if (!shouldPersistPressure && !stylusPoint.HasDefaultPressure) { shouldPersistPressure = true; } if (lengthPerPoint > StylusPointDescription.RequiredCountOfProperties) { int[] additionalData = stylusPoint.GetAdditionalData(); int countToCopy = lengthPerPoint - StylusPointDescription.RequiredCountOfProperties;/*3*/ Debug.Assert( this.Description.ButtonCount > 0 ? additionalData.Length -1 == countToCopy : additionalData.Length == countToCopy); for (int y = 0; y < countToCopy; y++) { output[y + 3][b] = additionalData[y]; } } } } ////// Private helper use to consult with any listening strokes if it is safe to go to zero count /// ///private bool CanGoToZero() { if (null == this.CountGoingToZero) { // // no one is listening // return true; } CancelEventArgs e = new CancelEventArgs(); e.Cancel = false; // // call the listeners // this.CountGoingToZero(this, e); Debug.Assert(e.Cancel, "This event should always be cancelled"); return !e.Cancel; } } } // 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
- XmlSchemaSet.cs
- WeakReadOnlyCollection.cs
- WebHttpBindingElement.cs
- EntityCommandExecutionException.cs
- DataList.cs
- TypeResolver.cs
- MonitorWrapper.cs
- SqlCachedBuffer.cs
- DataServicePagingProviderWrapper.cs
- Rijndael.cs
- Size.cs
- DataTableMapping.cs
- PerfCounterSection.cs
- GridViewCommandEventArgs.cs
- ModuleElement.cs
- DoubleConverter.cs
- safesecurityhelperavalon.cs
- DynamicFilter.cs
- RectAnimation.cs
- mediapermission.cs
- Bidi.cs
- DataKey.cs
- BlurBitmapEffect.cs
- TranslateTransform.cs
- CallId.cs
- ActivityBindForm.cs
- HostProtectionPermission.cs
- DataSetMappper.cs
- PropertyDescriptor.cs
- TraceContextEventArgs.cs
- SqlInternalConnectionTds.cs
- dataprotectionpermission.cs
- WmpBitmapEncoder.cs
- LayoutEditorPart.cs
- AvTraceFormat.cs
- ObjectDataSourceSelectingEventArgs.cs
- SystemIcmpV6Statistics.cs
- ScalarConstant.cs
- GetCardDetailsRequest.cs
- PointHitTestResult.cs
- XmlUTF8TextWriter.cs
- EventMappingSettingsCollection.cs
- FixUpCollection.cs
- InputProcessorProfilesLoader.cs
- AmbientValueAttribute.cs
- ExitEventArgs.cs
- SmiContext.cs
- ResolveCriteriaCD1.cs
- ConfigurationStrings.cs
- WebReferenceOptions.cs
- RuntimeArgumentHandle.cs
- DocumentEventArgs.cs
- BehaviorEditorPart.cs
- TimeoutValidationAttribute.cs
- QilSortKey.cs
- AlignmentXValidation.cs
- AppDomainProtocolHandler.cs
- EncryptedKey.cs
- MemberDescriptor.cs
- DefaultBindingPropertyAttribute.cs
- MaskedTextProvider.cs
- InputProcessorProfilesLoader.cs
- TreeWalker.cs
- ComponentChangedEvent.cs
- ObjectContextServiceProvider.cs
- WebHttpBinding.cs
- SafeRegistryKey.cs
- UIElementParagraph.cs
- DataServiceBuildProvider.cs
- DataGridViewImageCell.cs
- IdentitySection.cs
- MailMessageEventArgs.cs
- PrimitiveXmlSerializers.cs
- FontNamesConverter.cs
- SoapHeaderAttribute.cs
- ClientWindowsAuthenticationMembershipProvider.cs
- ProfilePropertyNameValidator.cs
- OrderedDictionary.cs
- ToolStripButton.cs
- TableCellCollection.cs
- TreeNodeCollectionEditor.cs
- SingleKeyFrameCollection.cs
- XPathDocument.cs
- FontClient.cs
- InvalidCommandTreeException.cs
- LayoutTable.cs
- CreatingCookieEventArgs.cs
- DesignTimeParseData.cs
- GeometryDrawing.cs
- TreeNodeCollection.cs
- DESCryptoServiceProvider.cs
- FieldToken.cs
- FormatException.cs
- XmlNotation.cs
- Brush.cs
- EncryptedType.cs
- Double.cs
- ModuleBuilderData.cs
- URLString.cs
- SafeUserTokenHandle.cs