Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Ink / StrokeCollection2.cs / 1305600 / StrokeCollection2.cs
//------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------
using MS.Utility;
using System;
using System.ComponentModel;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Media;
using System.Windows.Input;
using MS.Internal;
using MS.Internal.Ink;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
namespace System.Windows.Ink
{
///
/// The hit-testing API of StrokeCollection.
///
public partial class StrokeCollection : Collection, INotifyPropertyChanged, INotifyCollectionChanged
{
#region Public APIs
///
/// Calculates the combined bounds of all strokes in the collection
///
///
public Rect GetBounds()
{
Rect bounds = Rect.Empty;
foreach (Stroke stroke in this)
{
// samgeo - Presharp issue
// Presharp gives a warning when get methods might deref a null. It's complaining
// here that 'stroke'' could be null, but StrokeCollection never allows nulls to be added
// so this is not possible
#pragma warning disable 1634, 1691
#pragma warning suppress 6506
bounds.Union(stroke.GetBounds());
#pragma warning restore 1634, 1691
}
return bounds;
}
// ISSUE-2004/12/13-XIAOTU: In M8.2, the following two tap-hit APIs return the top-hit stroke,
// giving preference to non-highlighter strokes. We have decided not to treat highlighter and
// non-highlighter differently and only return the top-hit stroke. But there are two remaining
// open-issues on this:
// 1. Do we need to make these two APIs virtual, so user can treat highlighter differently if they
// want to?
// 2. Since we are only returning the top-hit stroke, should we use Stroke as the return type?
//
///
/// Tap-hit. Hit tests all strokes within a point, and returns a StrokeCollection for these strokes.Internally does Stroke.HitTest(Point, 1pxlRectShape).
///
/// A StrokeCollection that either empty or contains the top hit stroke
public StrokeCollection HitTest(Point point)
{
return PointHitTest(point, new RectangleStylusShape(1f, 1f));
}
///
/// Tap-hit
///
/// The central point
/// The diameter value of the circle
/// A StrokeCollection that either empty or contains the top hit stroke
public StrokeCollection HitTest(Point point, double diameter)
{
if (Double.IsNaN(diameter) || diameter < DrawingAttributes.MinWidth || diameter > DrawingAttributes.MaxWidth)
{
throw new ArgumentOutOfRangeException("diameter", SR.Get(SRID.InvalidDiameter));
}
return PointHitTest(point, new EllipseStylusShape(diameter, diameter));
}
///
/// Hit-testing with lasso
///
/// points making the lasso
/// the margin value to tell whether a stroke
/// is in or outside of the rect
/// collection of strokes found inside the rectangle
public StrokeCollection HitTest(IEnumerable lassoPoints, int percentageWithinLasso)
{
// Check the input parameters
if (lassoPoints == null)
{
throw new System.ArgumentNullException("lassoPoints");
}
if ((percentageWithinLasso < 0) || (percentageWithinLasso > 100))
{
throw new System.ArgumentOutOfRangeException("percentageWithinLasso");
}
if (IEnumerablePointHelper.GetCount(lassoPoints) < 3)
{
return new StrokeCollection();
}
Lasso lasso = new SingleLoopLasso();
lasso.AddPoints(lassoPoints);
// Enumerate through the strokes and collect those captured by the lasso.
StrokeCollection lassoedStrokes = new StrokeCollection();
foreach (Stroke stroke in this)
{
if (percentageWithinLasso == 0)
{
lassoedStrokes.Add(stroke);
}
else
{
StrokeInfo strokeInfo = null;
try
{
strokeInfo = new StrokeInfo(stroke);
StylusPointCollection stylusPoints = strokeInfo.StylusPoints;
double target = strokeInfo.TotalWeight * percentageWithinLasso / 100.0f - Stroke.PercentageTolerance;
for (int i = 0; i < stylusPoints.Count; i++)
{
if (true == lasso.Contains((Point)stylusPoints[i]))
{
target -= strokeInfo.GetPointWeight(i);
if (DoubleUtil.LessThanOrClose(target, 0f))
{
lassoedStrokes.Add(stroke);
break;
}
}
}
}
finally
{
if (strokeInfo != null)
{
//detach from event handlers, or else we leak.
strokeInfo.Detach();
}
}
}
}
// Return the resulting collection
return lassoedStrokes;
}
///
/// Hit-testing with rectangle
///
/// hitting rectangle
/// the percentage of the stroke that must be within
/// the bounds to be considered hit
/// collection of strokes found inside the rectangle
public StrokeCollection HitTest(Rect bounds, int percentageWithinBounds)
{
// Check the input parameters
if ((percentageWithinBounds < 0) || (percentageWithinBounds > 100))
{
throw new System.ArgumentOutOfRangeException("percentageWithinBounds");
}
if (bounds.IsEmpty)
{
return new StrokeCollection();
}
// Enumerate thru the strokes collect those found within the rectangle.
StrokeCollection hits = new StrokeCollection();
foreach (Stroke stroke in this)
{
// samgeo - Presharp issue
// Presharp gives a warning when get methods might deref a null. It's complaining
// here that 'stroke'' could be null, but StrokeCollection never allows nulls to be added
// so this is not possible
#pragma warning disable 1634, 1691
#pragma warning suppress 6506
if (true == stroke.HitTest(bounds, percentageWithinBounds))
{
hits.Add(stroke);
}
#pragma warning restore 1634, 1691
}
return hits;
}
///
/// Issue: what's the return value
///
///
///
///
public StrokeCollection HitTest(IEnumerable path, StylusShape stylusShape)
{
// Check the input parameters
if (stylusShape == null)
{
throw new System.ArgumentNullException("stylusShape");
}
if (path == null)
{
throw new System.ArgumentNullException("path");
}
if (IEnumerablePointHelper.GetCount(path) == 0)
{
return new StrokeCollection();
}
// validate input
ErasingStroke erasingStroke = new ErasingStroke(stylusShape, path);
Rect erasingBounds = erasingStroke.Bounds;
if (erasingBounds.IsEmpty)
{
return new StrokeCollection();
}
StrokeCollection hits = new StrokeCollection();
foreach (Stroke stroke in this)
{
// samgeo - Presharp issue
// Presharp gives a warning when get methods might deref a null. It's complaining
// here that 'stroke'' could be null, but StrokeCollection never allows nulls to be added
// so this is not possible
#pragma warning disable 1634, 1691
#pragma warning suppress 6506
if (erasingBounds.IntersectsWith(stroke.GetBounds()) &&
erasingStroke.HitTest(StrokeNodeIterator.GetIterator(stroke, stroke.DrawingAttributes)))
{
hits.Add(stroke);
}
#pragma warning restore 1634, 1691
}
return hits;
}
///
/// Clips out all ink outside a given lasso
///
/// lasso
public void Clip(IEnumerable lassoPoints)
{
// Check the input parameters
if (lassoPoints == null)
{
throw new System.ArgumentNullException("lassoPoints");
}
int length = IEnumerablePointHelper.GetCount(lassoPoints);
if (length == 0)
{
throw new ArgumentException(SR.Get(SRID.EmptyArray));
}
if (length < 3)
{
//
// if you're clipping with a point or a line with
// two points, it doesn't matter where the line is or if it
// intersects any of the strokes, the point or line has no region
// so technically everything in the strokecollection
// should be removed
//
this.Clear(); //raises the appropriate events
return;
}
Lasso lasso = new SingleLoopLasso();
lasso.AddPoints(lassoPoints);
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
StrokeCollection clipResult = stroke.Clip(stroke.HitTest(lasso));
UpdateStrokeCollection(stroke, clipResult, ref i);
}
}
///
/// Clips out all ink outside a given rectangle.
///
/// rectangle to clip with
public void Clip(Rect bounds)
{
if (bounds.IsEmpty == false)
{
Clip(new Point[4] { bounds.TopLeft, bounds.TopRight, bounds.BottomRight, bounds.BottomLeft });
}
}
///
/// Erases all ink inside a lasso
///
/// lasso to erase within
public void Erase(IEnumerable lassoPoints)
{
// Check the input parameters
if (lassoPoints == null)
{
throw new System.ArgumentNullException("lassoPoints");
}
int length = IEnumerablePointHelper.GetCount(lassoPoints);
if (length == 0)
{
throw new ArgumentException(SR.Get(SRID.EmptyArray));
}
if (length < 3)
{
return;
}
Lasso lasso = new SingleLoopLasso();
lasso.AddPoints(lassoPoints);
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
StrokeCollection eraseResult = stroke.Erase(stroke.HitTest(lasso));
UpdateStrokeCollection(stroke, eraseResult, ref i);
}
}
///
/// Erases all ink inside a given rectangle
///
/// rectangle to erase within
public void Erase(Rect bounds)
{
if (bounds.IsEmpty == false)
{
Erase(new Point[4] { bounds.TopLeft, bounds.TopRight, bounds.BottomRight, bounds.BottomLeft });
}
}
///
/// Erases all ink hit by the contour of an erasing stroke
///
/// Shape of the eraser
/// a path making the spine of the erasing stroke
public void Erase(IEnumerable eraserPath, StylusShape eraserShape)
{
// Check the input parameters
if (eraserShape == null)
{
throw new System.ArgumentNullException(SR.Get(SRID.SCEraseShape));
}
if (eraserPath == null)
{
throw new System.ArgumentNullException(SR.Get(SRID.SCErasePath));
}
if (IEnumerablePointHelper.GetCount(eraserPath) == 0)
{
return;
}
ErasingStroke erasingStroke = new ErasingStroke(eraserShape, eraserPath);
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
List intersections = new List();
erasingStroke.EraseTest(StrokeNodeIterator.GetIterator(stroke, stroke.DrawingAttributes), intersections);
StrokeCollection eraseResult = stroke.Erase(intersections.ToArray());
UpdateStrokeCollection(stroke, eraseResult, ref i);
}
}
///
/// Render the StrokeCollection under the specified DrawingContext.
///
///
public void Draw(DrawingContext context)
{
if (null == context)
{
throw new System.ArgumentNullException("context");
}
//The verification of UI context affinity is done in Stroke.Draw()
List solidStrokes = new List();
Dictionary> highLighters = new Dictionary>();
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
List strokes;
if (stroke.DrawingAttributes.IsHighlighter)
{
// It's very important to override the Alpha value so that Colors of the same RGB vale
// but different Alpha would be in the same list.
Color color = StrokeRenderer.GetHighlighterColor(stroke.DrawingAttributes.Color);
if (highLighters.TryGetValue(color, out strokes) == false)
{
strokes = new List();
highLighters.Add(color, strokes);
}
strokes.Add(stroke);
}
else
{
solidStrokes.Add(stroke);
}
}
foreach (List strokes in highLighters.Values)
{
context.PushOpacity(StrokeRenderer.HighlighterOpacity);
try
{
foreach (Stroke stroke in strokes)
{
stroke.DrawInternal(context, StrokeRenderer.GetHighlighterAttributes(stroke, stroke.DrawingAttributes),
false /*Don't draw selected stroke as hollow*/);
}
}
finally
{
context.Pop();
}
}
foreach(Stroke stroke in solidStrokes)
{
stroke.DrawInternal(context, stroke.DrawingAttributes, false/*Don't draw selected stroke as hollow*/);
}
}
#endregion
#region Incremental hit-testing
///
/// Creates an incremental hit-tester for hit-testing with a shape.
/// Scenarios: stroke-erasing and point-erasing
///
/// shape of the eraser
/// an instance of IncrementalStrokeHitTester
public IncrementalStrokeHitTester GetIncrementalStrokeHitTester(StylusShape eraserShape)
{
if (eraserShape == null)
{
throw new System.ArgumentNullException("eraserShape");
}
return new IncrementalStrokeHitTester(this, eraserShape);
}
///
/// Creates an incremental hit-tester for selecting with lasso.
///
/// The percentage of the stroke that must be within the lasso to be considered hit
/// an instance of incremental hit-tester
public IncrementalLassoHitTester GetIncrementalLassoHitTester(int percentageWithinLasso)
{
if ((percentageWithinLasso < 0) || (percentageWithinLasso > 100))
{
throw new System.ArgumentOutOfRangeException("percentageWithinLasso");
}
return new IncrementalLassoHitTester(this, percentageWithinLasso);
}
#endregion
///
/// Return all hit strokes that the StylusShape intersects and returns them in a StrokeCollection
///
private StrokeCollection PointHitTest(Point point, StylusShape shape)
{
// Create the collection to return
StrokeCollection hits = new StrokeCollection();
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
if (stroke.HitTest(new Point[] { point }, shape))
{
hits.Add(stroke);
}
}
return hits;
}
private void UpdateStrokeCollection(Stroke original, StrokeCollection toReplace, ref int index)
{
System.Diagnostics.Debug.Assert(original != null && toReplace != null);
System.Diagnostics.Debug.Assert(index >= 0 && index < this.Count);
if (toReplace.Count == 0)
{
Remove(original);
index--;
}
else if (!(toReplace.Count == 1 && toReplace[0] == original))
{
Replace(original, toReplace);
// Update the current index
index += toReplace.Count - 1;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------
using MS.Utility;
using System;
using System.ComponentModel;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Media;
using System.Windows.Input;
using MS.Internal;
using MS.Internal.Ink;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
namespace System.Windows.Ink
{
///
/// The hit-testing API of StrokeCollection.
///
public partial class StrokeCollection : Collection, INotifyPropertyChanged, INotifyCollectionChanged
{
#region Public APIs
///
/// Calculates the combined bounds of all strokes in the collection
///
///
public Rect GetBounds()
{
Rect bounds = Rect.Empty;
foreach (Stroke stroke in this)
{
// samgeo - Presharp issue
// Presharp gives a warning when get methods might deref a null. It's complaining
// here that 'stroke'' could be null, but StrokeCollection never allows nulls to be added
// so this is not possible
#pragma warning disable 1634, 1691
#pragma warning suppress 6506
bounds.Union(stroke.GetBounds());
#pragma warning restore 1634, 1691
}
return bounds;
}
// ISSUE-2004/12/13-XIAOTU: In M8.2, the following two tap-hit APIs return the top-hit stroke,
// giving preference to non-highlighter strokes. We have decided not to treat highlighter and
// non-highlighter differently and only return the top-hit stroke. But there are two remaining
// open-issues on this:
// 1. Do we need to make these two APIs virtual, so user can treat highlighter differently if they
// want to?
// 2. Since we are only returning the top-hit stroke, should we use Stroke as the return type?
//
///
/// Tap-hit. Hit tests all strokes within a point, and returns a StrokeCollection for these strokes.Internally does Stroke.HitTest(Point, 1pxlRectShape).
///
/// A StrokeCollection that either empty or contains the top hit stroke
public StrokeCollection HitTest(Point point)
{
return PointHitTest(point, new RectangleStylusShape(1f, 1f));
}
///
/// Tap-hit
///
/// The central point
/// The diameter value of the circle
/// A StrokeCollection that either empty or contains the top hit stroke
public StrokeCollection HitTest(Point point, double diameter)
{
if (Double.IsNaN(diameter) || diameter < DrawingAttributes.MinWidth || diameter > DrawingAttributes.MaxWidth)
{
throw new ArgumentOutOfRangeException("diameter", SR.Get(SRID.InvalidDiameter));
}
return PointHitTest(point, new EllipseStylusShape(diameter, diameter));
}
///
/// Hit-testing with lasso
///
/// points making the lasso
/// the margin value to tell whether a stroke
/// is in or outside of the rect
/// collection of strokes found inside the rectangle
public StrokeCollection HitTest(IEnumerable lassoPoints, int percentageWithinLasso)
{
// Check the input parameters
if (lassoPoints == null)
{
throw new System.ArgumentNullException("lassoPoints");
}
if ((percentageWithinLasso < 0) || (percentageWithinLasso > 100))
{
throw new System.ArgumentOutOfRangeException("percentageWithinLasso");
}
if (IEnumerablePointHelper.GetCount(lassoPoints) < 3)
{
return new StrokeCollection();
}
Lasso lasso = new SingleLoopLasso();
lasso.AddPoints(lassoPoints);
// Enumerate through the strokes and collect those captured by the lasso.
StrokeCollection lassoedStrokes = new StrokeCollection();
foreach (Stroke stroke in this)
{
if (percentageWithinLasso == 0)
{
lassoedStrokes.Add(stroke);
}
else
{
StrokeInfo strokeInfo = null;
try
{
strokeInfo = new StrokeInfo(stroke);
StylusPointCollection stylusPoints = strokeInfo.StylusPoints;
double target = strokeInfo.TotalWeight * percentageWithinLasso / 100.0f - Stroke.PercentageTolerance;
for (int i = 0; i < stylusPoints.Count; i++)
{
if (true == lasso.Contains((Point)stylusPoints[i]))
{
target -= strokeInfo.GetPointWeight(i);
if (DoubleUtil.LessThanOrClose(target, 0f))
{
lassoedStrokes.Add(stroke);
break;
}
}
}
}
finally
{
if (strokeInfo != null)
{
//detach from event handlers, or else we leak.
strokeInfo.Detach();
}
}
}
}
// Return the resulting collection
return lassoedStrokes;
}
///
/// Hit-testing with rectangle
///
/// hitting rectangle
/// the percentage of the stroke that must be within
/// the bounds to be considered hit
/// collection of strokes found inside the rectangle
public StrokeCollection HitTest(Rect bounds, int percentageWithinBounds)
{
// Check the input parameters
if ((percentageWithinBounds < 0) || (percentageWithinBounds > 100))
{
throw new System.ArgumentOutOfRangeException("percentageWithinBounds");
}
if (bounds.IsEmpty)
{
return new StrokeCollection();
}
// Enumerate thru the strokes collect those found within the rectangle.
StrokeCollection hits = new StrokeCollection();
foreach (Stroke stroke in this)
{
// samgeo - Presharp issue
// Presharp gives a warning when get methods might deref a null. It's complaining
// here that 'stroke'' could be null, but StrokeCollection never allows nulls to be added
// so this is not possible
#pragma warning disable 1634, 1691
#pragma warning suppress 6506
if (true == stroke.HitTest(bounds, percentageWithinBounds))
{
hits.Add(stroke);
}
#pragma warning restore 1634, 1691
}
return hits;
}
///
/// Issue: what's the return value
///
///
///
///
public StrokeCollection HitTest(IEnumerable path, StylusShape stylusShape)
{
// Check the input parameters
if (stylusShape == null)
{
throw new System.ArgumentNullException("stylusShape");
}
if (path == null)
{
throw new System.ArgumentNullException("path");
}
if (IEnumerablePointHelper.GetCount(path) == 0)
{
return new StrokeCollection();
}
// validate input
ErasingStroke erasingStroke = new ErasingStroke(stylusShape, path);
Rect erasingBounds = erasingStroke.Bounds;
if (erasingBounds.IsEmpty)
{
return new StrokeCollection();
}
StrokeCollection hits = new StrokeCollection();
foreach (Stroke stroke in this)
{
// samgeo - Presharp issue
// Presharp gives a warning when get methods might deref a null. It's complaining
// here that 'stroke'' could be null, but StrokeCollection never allows nulls to be added
// so this is not possible
#pragma warning disable 1634, 1691
#pragma warning suppress 6506
if (erasingBounds.IntersectsWith(stroke.GetBounds()) &&
erasingStroke.HitTest(StrokeNodeIterator.GetIterator(stroke, stroke.DrawingAttributes)))
{
hits.Add(stroke);
}
#pragma warning restore 1634, 1691
}
return hits;
}
///
/// Clips out all ink outside a given lasso
///
/// lasso
public void Clip(IEnumerable lassoPoints)
{
// Check the input parameters
if (lassoPoints == null)
{
throw new System.ArgumentNullException("lassoPoints");
}
int length = IEnumerablePointHelper.GetCount(lassoPoints);
if (length == 0)
{
throw new ArgumentException(SR.Get(SRID.EmptyArray));
}
if (length < 3)
{
//
// if you're clipping with a point or a line with
// two points, it doesn't matter where the line is or if it
// intersects any of the strokes, the point or line has no region
// so technically everything in the strokecollection
// should be removed
//
this.Clear(); //raises the appropriate events
return;
}
Lasso lasso = new SingleLoopLasso();
lasso.AddPoints(lassoPoints);
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
StrokeCollection clipResult = stroke.Clip(stroke.HitTest(lasso));
UpdateStrokeCollection(stroke, clipResult, ref i);
}
}
///
/// Clips out all ink outside a given rectangle.
///
/// rectangle to clip with
public void Clip(Rect bounds)
{
if (bounds.IsEmpty == false)
{
Clip(new Point[4] { bounds.TopLeft, bounds.TopRight, bounds.BottomRight, bounds.BottomLeft });
}
}
///
/// Erases all ink inside a lasso
///
/// lasso to erase within
public void Erase(IEnumerable lassoPoints)
{
// Check the input parameters
if (lassoPoints == null)
{
throw new System.ArgumentNullException("lassoPoints");
}
int length = IEnumerablePointHelper.GetCount(lassoPoints);
if (length == 0)
{
throw new ArgumentException(SR.Get(SRID.EmptyArray));
}
if (length < 3)
{
return;
}
Lasso lasso = new SingleLoopLasso();
lasso.AddPoints(lassoPoints);
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
StrokeCollection eraseResult = stroke.Erase(stroke.HitTest(lasso));
UpdateStrokeCollection(stroke, eraseResult, ref i);
}
}
///
/// Erases all ink inside a given rectangle
///
/// rectangle to erase within
public void Erase(Rect bounds)
{
if (bounds.IsEmpty == false)
{
Erase(new Point[4] { bounds.TopLeft, bounds.TopRight, bounds.BottomRight, bounds.BottomLeft });
}
}
///
/// Erases all ink hit by the contour of an erasing stroke
///
/// Shape of the eraser
/// a path making the spine of the erasing stroke
public void Erase(IEnumerable eraserPath, StylusShape eraserShape)
{
// Check the input parameters
if (eraserShape == null)
{
throw new System.ArgumentNullException(SR.Get(SRID.SCEraseShape));
}
if (eraserPath == null)
{
throw new System.ArgumentNullException(SR.Get(SRID.SCErasePath));
}
if (IEnumerablePointHelper.GetCount(eraserPath) == 0)
{
return;
}
ErasingStroke erasingStroke = new ErasingStroke(eraserShape, eraserPath);
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
List intersections = new List();
erasingStroke.EraseTest(StrokeNodeIterator.GetIterator(stroke, stroke.DrawingAttributes), intersections);
StrokeCollection eraseResult = stroke.Erase(intersections.ToArray());
UpdateStrokeCollection(stroke, eraseResult, ref i);
}
}
///
/// Render the StrokeCollection under the specified DrawingContext.
///
///
public void Draw(DrawingContext context)
{
if (null == context)
{
throw new System.ArgumentNullException("context");
}
//The verification of UI context affinity is done in Stroke.Draw()
List solidStrokes = new List();
Dictionary> highLighters = new Dictionary>();
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
List strokes;
if (stroke.DrawingAttributes.IsHighlighter)
{
// It's very important to override the Alpha value so that Colors of the same RGB vale
// but different Alpha would be in the same list.
Color color = StrokeRenderer.GetHighlighterColor(stroke.DrawingAttributes.Color);
if (highLighters.TryGetValue(color, out strokes) == false)
{
strokes = new List();
highLighters.Add(color, strokes);
}
strokes.Add(stroke);
}
else
{
solidStrokes.Add(stroke);
}
}
foreach (List strokes in highLighters.Values)
{
context.PushOpacity(StrokeRenderer.HighlighterOpacity);
try
{
foreach (Stroke stroke in strokes)
{
stroke.DrawInternal(context, StrokeRenderer.GetHighlighterAttributes(stroke, stroke.DrawingAttributes),
false /*Don't draw selected stroke as hollow*/);
}
}
finally
{
context.Pop();
}
}
foreach(Stroke stroke in solidStrokes)
{
stroke.DrawInternal(context, stroke.DrawingAttributes, false/*Don't draw selected stroke as hollow*/);
}
}
#endregion
#region Incremental hit-testing
///
/// Creates an incremental hit-tester for hit-testing with a shape.
/// Scenarios: stroke-erasing and point-erasing
///
/// shape of the eraser
/// an instance of IncrementalStrokeHitTester
public IncrementalStrokeHitTester GetIncrementalStrokeHitTester(StylusShape eraserShape)
{
if (eraserShape == null)
{
throw new System.ArgumentNullException("eraserShape");
}
return new IncrementalStrokeHitTester(this, eraserShape);
}
///
/// Creates an incremental hit-tester for selecting with lasso.
///
/// The percentage of the stroke that must be within the lasso to be considered hit
/// an instance of incremental hit-tester
public IncrementalLassoHitTester GetIncrementalLassoHitTester(int percentageWithinLasso)
{
if ((percentageWithinLasso < 0) || (percentageWithinLasso > 100))
{
throw new System.ArgumentOutOfRangeException("percentageWithinLasso");
}
return new IncrementalLassoHitTester(this, percentageWithinLasso);
}
#endregion
///
/// Return all hit strokes that the StylusShape intersects and returns them in a StrokeCollection
///
private StrokeCollection PointHitTest(Point point, StylusShape shape)
{
// Create the collection to return
StrokeCollection hits = new StrokeCollection();
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
if (stroke.HitTest(new Point[] { point }, shape))
{
hits.Add(stroke);
}
}
return hits;
}
private void UpdateStrokeCollection(Stroke original, StrokeCollection toReplace, ref int index)
{
System.Diagnostics.Debug.Assert(original != null && toReplace != null);
System.Diagnostics.Debug.Assert(index >= 0 && index < this.Count);
if (toReplace.Count == 0)
{
Remove(original);
index--;
}
else if (!(toReplace.Count == 1 && toReplace[0] == original))
{
Replace(original, toReplace);
// Update the current index
index += toReplace.Count - 1;
}
}
}
}
// 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
- CompilerParameters.cs
- TextBox.cs
- TableLayoutPanelCellPosition.cs
- DoubleStorage.cs
- JsonSerializer.cs
- HttpHeaderCollection.cs
- ExpressionVisitorHelpers.cs
- AutomationEventArgs.cs
- SelectorItemAutomationPeer.cs
- TransactionFilter.cs
- SamlAction.cs
- XamlFilter.cs
- RefType.cs
- TextDecorationUnitValidation.cs
- TitleStyle.cs
- UIPropertyMetadata.cs
- RegistryKey.cs
- InputMethod.cs
- PrimitiveType.cs
- UrlAuthFailedErrorFormatter.cs
- PackagePart.cs
- HtmlInputImage.cs
- CqlBlock.cs
- SessionEndingEventArgs.cs
- WebPageTraceListener.cs
- EmulateRecognizeCompletedEventArgs.cs
- Manipulation.cs
- RegexTypeEditor.cs
- StateMachine.cs
- HttpRuntimeSection.cs
- ToolStripItemBehavior.cs
- COM2Properties.cs
- CustomCredentialPolicy.cs
- CellQuery.cs
- FileChangesMonitor.cs
- NativeMethods.cs
- HWStack.cs
- RequestQueryParser.cs
- AppearanceEditorPart.cs
- JumpPath.cs
- HostingEnvironmentException.cs
- PopupControlService.cs
- ActivitiesCollection.cs
- MemberRestriction.cs
- PermissionToken.cs
- MatcherBuilder.cs
- xmlglyphRunInfo.cs
- RtfToXamlLexer.cs
- XmlDomTextWriter.cs
- MailDefinition.cs
- UpdateRecord.cs
- MsmqOutputSessionChannel.cs
- GeneratedContractType.cs
- GridViewHeaderRowPresenterAutomationPeer.cs
- SafeProcessHandle.cs
- PasswordBox.cs
- DesignerCapabilities.cs
- DataObjectCopyingEventArgs.cs
- Timeline.cs
- Base64Decoder.cs
- Point4D.cs
- FragmentQueryKB.cs
- CryptoKeySecurity.cs
- Pen.cs
- BaseCodeDomTreeGenerator.cs
- CodeAttributeDeclaration.cs
- RegionIterator.cs
- ListDictionaryInternal.cs
- ActivityExecutorSurrogate.cs
- COM2PictureConverter.cs
- StreamWriter.cs
- serverconfig.cs
- DesignTimeTemplateParser.cs
- WebBrowserContainer.cs
- EntityDataSourceChangingEventArgs.cs
- ObjectSecurity.cs
- EntityDataSourceDataSelectionPanel.designer.cs
- SolidColorBrush.cs
- DeferredRunTextReference.cs
- TextDecorationLocationValidation.cs
- VariableQuery.cs
- PriorityBinding.cs
- CultureInfo.cs
- SendMailErrorEventArgs.cs
- ActivitiesCollection.cs
- OdbcConnectionFactory.cs
- BaseUriHelper.cs
- Filter.cs
- AttributeProviderAttribute.cs
- CorrelationTokenInvalidatedHandler.cs
- FrameworkReadOnlyPropertyMetadata.cs
- CommandTreeTypeHelper.cs
- TimeoutException.cs
- InternalPermissions.cs
- _ProxyChain.cs
- DataGrid.cs
- Part.cs
- DispatcherExceptionEventArgs.cs
- RootNamespaceAttribute.cs
- ValidationErrorEventArgs.cs