Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / MS / Internal / Ink / LassoHelper.cs / 1 / LassoHelper.cs
//------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------- using System; using System.Windows; using System.Windows.Media; using System.Windows.Ink; using System.Collections; using System.Collections.Generic; using System.Windows.Documents; namespace MS.Internal.Ink { #region LassoHelper ////// An internal helper class to draw lasso as a sequence of dots /// closed with a rubber line. LassoSelectionBehavior creates an object of /// this class to render a single lasso, so, for simplicity, /// LassoHelper objects are indended for one-time use only. /// internal class LassoHelper { #region Fields // Visuals, geometry builders and drawing stuff DrawingVisual _containerVisual = null; Brush _brush = null; Pen _pen = null; //Pen _linePen = null; // bool _isActivated = false; Point _firstLassoPoint; Point _lastLassoPoint; int _count = 0; // Entire lasso. Collected to hit test InkCanvas' subelements after stylus up. List_lasso = null; Rect _boundingBox; // NTRAID#T2-00000-2003/07/14-vsmirnov - some of these are probably not in [....] // with the spec (which is not available at this moment), and also might // need to be different for the high contrast mode. public const double MinDistanceSquared = 49.0; const double DotRadius = 2.5; const double DotCircumferenceThickness = 0.5; const double ConnectLineThickness = 0.75; const double ConnectLineOpacity = 0.75; static readonly Color DotColor = Colors.Orange; //FromArgb(1, 0.89f, 0.3607f, 0.1843f); static readonly Color DotCircumferenceColor = Colors.White; #endregion #region Public API /// /// Read-only access to the container visual for dynamic drawing a lasso /// public Visual Visual { get { EnsureVisual(); return _containerVisual; } } ///TBS public Point[] AddPoints(Listpoints) { if (null == points) throw new ArgumentNullException("points"); // Lazy initialization. EnsureReady(); List justAdded = new List (); int count = points.Count; for ( int i = 0; i < count ; i++ ) { Point point = points[i]; if (0 == _count) { AddLassoPoint(point); justAdded.Add(point); _lasso.Add(point); _boundingBox.Union(point); _firstLassoPoint = point; _lastLassoPoint = point; _count++; } else { Vector last2next = point - _lastLassoPoint; double distanceSquared = last2next.LengthSquared; // Avoid using Sqrt when the distance is equal to the step. if (DoubleUtil.AreClose(MinDistanceSquared, distanceSquared)) { AddLassoPoint(point); justAdded.Add(point); _lasso.Add(point); _boundingBox.Union(point); _lastLassoPoint = point; _count++; } else if (MinDistanceSquared < distanceSquared) { double step = Math.Sqrt(MinDistanceSquared / distanceSquared); Point last = _lastLassoPoint; for (double findex = step; findex < 1.0f; findex += step) { Point lassoPoint = last + (last2next * findex); AddLassoPoint(lassoPoint); justAdded.Add(lassoPoint); _lasso.Add(lassoPoint); _boundingBox.Union(lassoPoint); _lastLassoPoint = lassoPoint; _count++; } } } } // still working on perf here. // Draw a line between the last point and the first one. //if (_count > 1) //{ // DrawingContext dc = _containerVisual.RenderOpen(); // dc.DrawLine(_linePen, _firstLassoPoint, _lastLassoPoint); // dc.Close(); //} return justAdded.ToArray(); } ///// ///// Draws a single lasso dot with the center at the given point. ///// private void AddLassoPoint(Point lassoPoint) { DrawingVisual dv = new DrawingVisual(); DrawingContext dc = null; try { dc = dv.RenderOpen(); dc.DrawEllipse(_brush, _pen, lassoPoint, DotRadius, DotRadius); } finally { if (dc != null) { dc.Close(); } } // Add the new visual to the container. _containerVisual.Children.Add(dv); } #endregion #region ArePointsInLasso ///Copy-pasted Platform's Lasso.Contains(...) public bool ArePointsInLasso(Point[] points, int percentIntersect) { System.Diagnostics.Debug.Assert(null != points); System.Diagnostics.Debug.Assert((0 <= percentIntersect) && (100 >= percentIntersect)); // Find out how many of the points need to be inside the lasso to satisfy the percentIntersect. int marginCount = (points.Length * percentIntersect) / 100; if ((0 == marginCount) || (50 <= ((points.Length * percentIntersect) % 100))) { marginCount++; } // Check if any point on the stroke is within the lasso or not. // This is done by checking all segments on the left side of the point. // If the no of such segments is odd then the point is within the lasso otherwise not. int countPointsInLasso = 0; foreach (Point point in points) { if (true == Contains(point)) { countPointsInLasso++; if (countPointsInLasso == marginCount) break; } } return (countPointsInLasso == marginCount); } ///TBS private bool Contains(Point point) { if (false == _boundingBox.Contains(point)) { return false; } bool isHigher = false; int last = _lasso.Count; while (--last >= 0) { if (false == DoubleUtil.AreClose(_lasso[last].Y, point.Y)) { isHigher = point.Y < _lasso[last].Y; break; } } bool isInside = false, isOnClosingSegment = false; Point prevLassoPoint = _lasso[_lasso.Count - 1]; for (int i = 0; i < _lasso.Count; i++) { Point lassoPoint = _lasso[i]; if (DoubleUtil.AreClose(lassoPoint.Y, point.Y)) { if (DoubleUtil.AreClose(lassoPoint.X, point.X)) { isInside = true; break; } if ((0 != i) && DoubleUtil.AreClose(prevLassoPoint.Y, point.Y) && DoubleUtil.GreaterThanOrClose(point.X, Math.Min(prevLassoPoint.X, lassoPoint.X)) && DoubleUtil.LessThanOrClose(point.X, Math.Max(prevLassoPoint.X, lassoPoint.X))) { isInside = true; break; } } else if (isHigher != (point.Y < lassoPoint.Y)) { isHigher = !isHigher; if (DoubleUtil.GreaterThanOrClose(point.X, Math.Max(prevLassoPoint.X, lassoPoint.X))) { // there certainly is an intersection on the left isInside = !isInside; // The closing segment is the only exclusive one. Special case it. if ((0 == i) && DoubleUtil.AreClose(point.X, Math.Max(prevLassoPoint.X, lassoPoint.X))) { isOnClosingSegment = true; } } else if (DoubleUtil.GreaterThanOrClose(point.X, Math.Min(prevLassoPoint.X, lassoPoint.X))) { // The X of the point lies within the x ranges for the segment. // Calculate the x value of the point where the segment intersects with the line. Vector lassoSegment = lassoPoint - prevLassoPoint; double x = prevLassoPoint.X + (lassoSegment.X / lassoSegment.Y) * (point.Y - prevLassoPoint.Y); if (DoubleUtil.GreaterThanOrClose(point.X, x)) { isInside = !isInside; if ((0 == i) && DoubleUtil.AreClose(point.X, x)) { isOnClosingSegment = true; } } } } prevLassoPoint = lassoPoint; } return isInside ? !isOnClosingSegment : false; } #endregion #region Implementation helpers ///Creates the container visual when needed. private void EnsureVisual() { if (null == _containerVisual) { _containerVisual = new DrawingVisual(); } } ////// Creates and initializes objects required for drawing /// private void EnsureReady() { if (false == _isActivated) { _isActivated = true; EnsureVisual(); _brush = new SolidColorBrush(DotColor); _brush.Freeze(); //_linePen = new Pen(new SolidColorBrush(Colors.DarkGray), ConnectLineThickness); //_linePen.Brush.Opacity = ConnectLineOpacity; //_linePen.LineJoin = PenLineJoin.Round; _pen = new Pen(new SolidColorBrush(DotCircumferenceColor), DotCircumferenceThickness); _pen.LineJoin = PenLineJoin.Round; _pen.Freeze(); _lasso = new List(100); _boundingBox = Rect.Empty; _count = 0; } } #endregion } #endregion } // 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.Windows.Media; using System.Windows.Ink; using System.Collections; using System.Collections.Generic; using System.Windows.Documents; namespace MS.Internal.Ink { #region LassoHelper ////// An internal helper class to draw lasso as a sequence of dots /// closed with a rubber line. LassoSelectionBehavior creates an object of /// this class to render a single lasso, so, for simplicity, /// LassoHelper objects are indended for one-time use only. /// internal class LassoHelper { #region Fields // Visuals, geometry builders and drawing stuff DrawingVisual _containerVisual = null; Brush _brush = null; Pen _pen = null; //Pen _linePen = null; // bool _isActivated = false; Point _firstLassoPoint; Point _lastLassoPoint; int _count = 0; // Entire lasso. Collected to hit test InkCanvas' subelements after stylus up. List_lasso = null; Rect _boundingBox; // NTRAID#T2-00000-2003/07/14-vsmirnov - some of these are probably not in [....] // with the spec (which is not available at this moment), and also might // need to be different for the high contrast mode. public const double MinDistanceSquared = 49.0; const double DotRadius = 2.5; const double DotCircumferenceThickness = 0.5; const double ConnectLineThickness = 0.75; const double ConnectLineOpacity = 0.75; static readonly Color DotColor = Colors.Orange; //FromArgb(1, 0.89f, 0.3607f, 0.1843f); static readonly Color DotCircumferenceColor = Colors.White; #endregion #region Public API /// /// Read-only access to the container visual for dynamic drawing a lasso /// public Visual Visual { get { EnsureVisual(); return _containerVisual; } } ///TBS public Point[] AddPoints(Listpoints) { if (null == points) throw new ArgumentNullException("points"); // Lazy initialization. EnsureReady(); List justAdded = new List (); int count = points.Count; for ( int i = 0; i < count ; i++ ) { Point point = points[i]; if (0 == _count) { AddLassoPoint(point); justAdded.Add(point); _lasso.Add(point); _boundingBox.Union(point); _firstLassoPoint = point; _lastLassoPoint = point; _count++; } else { Vector last2next = point - _lastLassoPoint; double distanceSquared = last2next.LengthSquared; // Avoid using Sqrt when the distance is equal to the step. if (DoubleUtil.AreClose(MinDistanceSquared, distanceSquared)) { AddLassoPoint(point); justAdded.Add(point); _lasso.Add(point); _boundingBox.Union(point); _lastLassoPoint = point; _count++; } else if (MinDistanceSquared < distanceSquared) { double step = Math.Sqrt(MinDistanceSquared / distanceSquared); Point last = _lastLassoPoint; for (double findex = step; findex < 1.0f; findex += step) { Point lassoPoint = last + (last2next * findex); AddLassoPoint(lassoPoint); justAdded.Add(lassoPoint); _lasso.Add(lassoPoint); _boundingBox.Union(lassoPoint); _lastLassoPoint = lassoPoint; _count++; } } } } // still working on perf here. // Draw a line between the last point and the first one. //if (_count > 1) //{ // DrawingContext dc = _containerVisual.RenderOpen(); // dc.DrawLine(_linePen, _firstLassoPoint, _lastLassoPoint); // dc.Close(); //} return justAdded.ToArray(); } ///// ///// Draws a single lasso dot with the center at the given point. ///// private void AddLassoPoint(Point lassoPoint) { DrawingVisual dv = new DrawingVisual(); DrawingContext dc = null; try { dc = dv.RenderOpen(); dc.DrawEllipse(_brush, _pen, lassoPoint, DotRadius, DotRadius); } finally { if (dc != null) { dc.Close(); } } // Add the new visual to the container. _containerVisual.Children.Add(dv); } #endregion #region ArePointsInLasso ///Copy-pasted Platform's Lasso.Contains(...) public bool ArePointsInLasso(Point[] points, int percentIntersect) { System.Diagnostics.Debug.Assert(null != points); System.Diagnostics.Debug.Assert((0 <= percentIntersect) && (100 >= percentIntersect)); // Find out how many of the points need to be inside the lasso to satisfy the percentIntersect. int marginCount = (points.Length * percentIntersect) / 100; if ((0 == marginCount) || (50 <= ((points.Length * percentIntersect) % 100))) { marginCount++; } // Check if any point on the stroke is within the lasso or not. // This is done by checking all segments on the left side of the point. // If the no of such segments is odd then the point is within the lasso otherwise not. int countPointsInLasso = 0; foreach (Point point in points) { if (true == Contains(point)) { countPointsInLasso++; if (countPointsInLasso == marginCount) break; } } return (countPointsInLasso == marginCount); } ///TBS private bool Contains(Point point) { if (false == _boundingBox.Contains(point)) { return false; } bool isHigher = false; int last = _lasso.Count; while (--last >= 0) { if (false == DoubleUtil.AreClose(_lasso[last].Y, point.Y)) { isHigher = point.Y < _lasso[last].Y; break; } } bool isInside = false, isOnClosingSegment = false; Point prevLassoPoint = _lasso[_lasso.Count - 1]; for (int i = 0; i < _lasso.Count; i++) { Point lassoPoint = _lasso[i]; if (DoubleUtil.AreClose(lassoPoint.Y, point.Y)) { if (DoubleUtil.AreClose(lassoPoint.X, point.X)) { isInside = true; break; } if ((0 != i) && DoubleUtil.AreClose(prevLassoPoint.Y, point.Y) && DoubleUtil.GreaterThanOrClose(point.X, Math.Min(prevLassoPoint.X, lassoPoint.X)) && DoubleUtil.LessThanOrClose(point.X, Math.Max(prevLassoPoint.X, lassoPoint.X))) { isInside = true; break; } } else if (isHigher != (point.Y < lassoPoint.Y)) { isHigher = !isHigher; if (DoubleUtil.GreaterThanOrClose(point.X, Math.Max(prevLassoPoint.X, lassoPoint.X))) { // there certainly is an intersection on the left isInside = !isInside; // The closing segment is the only exclusive one. Special case it. if ((0 == i) && DoubleUtil.AreClose(point.X, Math.Max(prevLassoPoint.X, lassoPoint.X))) { isOnClosingSegment = true; } } else if (DoubleUtil.GreaterThanOrClose(point.X, Math.Min(prevLassoPoint.X, lassoPoint.X))) { // The X of the point lies within the x ranges for the segment. // Calculate the x value of the point where the segment intersects with the line. Vector lassoSegment = lassoPoint - prevLassoPoint; double x = prevLassoPoint.X + (lassoSegment.X / lassoSegment.Y) * (point.Y - prevLassoPoint.Y); if (DoubleUtil.GreaterThanOrClose(point.X, x)) { isInside = !isInside; if ((0 == i) && DoubleUtil.AreClose(point.X, x)) { isOnClosingSegment = true; } } } } prevLassoPoint = lassoPoint; } return isInside ? !isOnClosingSegment : false; } #endregion #region Implementation helpers ///Creates the container visual when needed. private void EnsureVisual() { if (null == _containerVisual) { _containerVisual = new DrawingVisual(); } } ////// Creates and initializes objects required for drawing /// private void EnsureReady() { if (false == _isActivated) { _isActivated = true; EnsureVisual(); _brush = new SolidColorBrush(DotColor); _brush.Freeze(); //_linePen = new Pen(new SolidColorBrush(Colors.DarkGray), ConnectLineThickness); //_linePen.Brush.Opacity = ConnectLineOpacity; //_linePen.LineJoin = PenLineJoin.Round; _pen = new Pen(new SolidColorBrush(DotCircumferenceColor), DotCircumferenceThickness); _pen.LineJoin = PenLineJoin.Round; _pen.Freeze(); _lasso = new List(100); _boundingBox = Rect.Empty; _count = 0; } } #endregion } #endregion } // 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
- ProviderException.cs
- ProjectionPathBuilder.cs
- RotationValidation.cs
- NativeMethods.cs
- ParsedAttributeCollection.cs
- StringUtil.cs
- TriggerBase.cs
- ComEventsMethod.cs
- DataBoundControlAdapter.cs
- EventProvider.cs
- FlatButtonAppearance.cs
- NamespaceInfo.cs
- TabControlCancelEvent.cs
- DataSysAttribute.cs
- ListSourceHelper.cs
- EncryptedData.cs
- HealthMonitoringSection.cs
- DockEditor.cs
- EtwTrace.cs
- ToolStripItemTextRenderEventArgs.cs
- Size3DConverter.cs
- ExpressionBinding.cs
- StringUtil.cs
- UnaryOperationBinder.cs
- _BasicClient.cs
- LateBoundBitmapDecoder.cs
- EnumerableCollectionView.cs
- DecoderBestFitFallback.cs
- HashSetDebugView.cs
- XmlSchemaSet.cs
- QilChoice.cs
- Figure.cs
- SessionSwitchEventArgs.cs
- ModelVisual3D.cs
- XamlPathDataSerializer.cs
- IOException.cs
- Vector3DConverter.cs
- EdmConstants.cs
- ButtonChrome.cs
- StringHelper.cs
- TraceContextEventArgs.cs
- Triplet.cs
- TextBoxBaseDesigner.cs
- KeyEventArgs.cs
- BaseCollection.cs
- LoginName.cs
- WSTrustDec2005.cs
- ParagraphVisual.cs
- Type.cs
- CodeDomSerializerException.cs
- TreeNodeBindingDepthConverter.cs
- dbenumerator.cs
- WSFederationHttpSecurity.cs
- ArraySegment.cs
- TransformerTypeCollection.cs
- PeerPresenceInfo.cs
- DbException.cs
- dtdvalidator.cs
- TagPrefixAttribute.cs
- Utils.cs
- SqlTypesSchemaImporter.cs
- GifBitmapEncoder.cs
- DataGridViewCell.cs
- EmptyReadOnlyDictionaryInternal.cs
- RepeaterDataBoundAdapter.cs
- CompareValidator.cs
- RequestBringIntoViewEventArgs.cs
- TaskScheduler.cs
- SessionMode.cs
- AxHost.cs
- OdbcDataReader.cs
- EnvironmentPermission.cs
- AutoScrollExpandMessageFilter.cs
- GZipDecoder.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- Matrix3DValueSerializer.cs
- StringComparer.cs
- SqlRecordBuffer.cs
- FontUnit.cs
- LightweightCodeGenerator.cs
- CellTreeNode.cs
- LeaseManager.cs
- ClientScriptManagerWrapper.cs
- OpenFileDialog.cs
- IPGlobalProperties.cs
- ProtocolsConfiguration.cs
- WindowsContainer.cs
- filewebresponse.cs
- XmlIlTypeHelper.cs
- XNameConverter.cs
- ForEachAction.cs
- FileStream.cs
- HttpAsyncResult.cs
- SlotInfo.cs
- Deflater.cs
- TargetPerspective.cs
- TypefaceMap.cs
- WhitespaceRuleReader.cs
- Formatter.cs
- XPathDocumentNavigator.cs