Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / 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
- DataGridCaption.cs
- AtlasWeb.Designer.cs
- HttpPostedFile.cs
- DataList.cs
- RelatedImageListAttribute.cs
- xamlnodes.cs
- ArrayElementGridEntry.cs
- RawStylusInputReport.cs
- HttpWrapper.cs
- ColumnPropertiesGroup.cs
- CryptographicAttribute.cs
- ScriptRegistrationManager.cs
- PropertyRecord.cs
- ToggleButtonAutomationPeer.cs
- DbConnectionPoolIdentity.cs
- XmlAutoDetectWriter.cs
- DifferencingCollection.cs
- SaveFileDialogDesigner.cs
- BrowserTree.cs
- NamespaceQuery.cs
- SecurityRuntime.cs
- TileModeValidation.cs
- SHA1CryptoServiceProvider.cs
- ArcSegment.cs
- ColorConvertedBitmap.cs
- DataRowView.cs
- ListViewDeletedEventArgs.cs
- PartManifestEntry.cs
- MaterialCollection.cs
- TextRangeEditTables.cs
- ExpressionConverter.cs
- KeyEvent.cs
- PreloadedPackages.cs
- SemaphoreSlim.cs
- MarkupObject.cs
- M3DUtil.cs
- StrokeDescriptor.cs
- DispatcherExceptionFilterEventArgs.cs
- Calendar.cs
- SimpleFieldTemplateFactory.cs
- XmlSchemaInclude.cs
- SignatureDescription.cs
- UniqueEventHelper.cs
- Classification.cs
- InvalidContentTypeException.cs
- FamilyMap.cs
- DocumentXPathNavigator.cs
- TextDocumentView.cs
- TemplateXamlParser.cs
- CurrentTimeZone.cs
- CalendarKeyboardHelper.cs
- StringBuilder.cs
- AsyncOperation.cs
- DetailsViewUpdatedEventArgs.cs
- DataGridTableCollection.cs
- WebPartConnectionsCloseVerb.cs
- LambdaCompiler.cs
- OleDbConnection.cs
- OuterGlowBitmapEffect.cs
- FamilyMapCollection.cs
- Base64Decoder.cs
- WindowsListViewItemStartMenu.cs
- InvokeMemberBinder.cs
- XmlILIndex.cs
- documentsequencetextview.cs
- PluralizationServiceUtil.cs
- GridViewColumn.cs
- TabControlEvent.cs
- SQLString.cs
- FileDialogCustomPlace.cs
- GlyphTypeface.cs
- TypeConverterHelper.cs
- TypeSystemHelpers.cs
- GetLedgerRequest.cs
- LocalizableResourceBuilder.cs
- DataGridRow.cs
- Button.cs
- EventLogEntryCollection.cs
- MaskedTextBoxTextEditorDropDown.cs
- Byte.cs
- WrapPanel.cs
- ContentDefinition.cs
- RegexFCD.cs
- ContractListAdapter.cs
- DataGridView.cs
- SystemUnicastIPAddressInformation.cs
- WmiPutTraceRecord.cs
- WebControlsSection.cs
- TypeSemantics.cs
- EndpointAddressAugust2004.cs
- MimeMapping.cs
- Utils.cs
- ADMembershipUser.cs
- SecurityVerifiedMessage.cs
- InstanceDataCollection.cs
- EditorPartCollection.cs
- XsltArgumentList.cs
- PriorityQueue.cs
- ICspAsymmetricAlgorithm.cs
- PeerCustomResolverElement.cs