Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / MS / Internal / Ink / PenCursorManager.cs / 1 / PenCursorManager.cs
//---------------------------------------------------------------------------- // // File: PenCursorManager.cs // // Description: // PenCursorManager is helper class which creates Cursor object for InkCanvas' Pen and Eraser // // Authors: waynezen // // Copyright (C) 2003 by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- //#define CURSOR_DEBUG using MS.Win32; using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution; using System.Security; using System.Security.Permissions; using System.Windows; using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; using MS.Internal.AppModel; namespace MS.Internal.Ink { ////// A static class which generates the cursors for InkCanvas /// internal static class PenCursorManager { //------------------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------------------- #region Internal Methods ////// Create a pen cursor from DrawingAttributes object /// ////// Critical: Call a SecurityCritical method - CreateCursorFromDrawing /// TreatAsSafe: The method is safe because only safe arguments are passed to CreateCursorFromDrawing /// Also the size of the cursor will be limited to the half size of the current primary screen. /// [SecurityCritical, SecurityTreatAsSafe] internal static Cursor GetPenCursor(DrawingAttributes drawingAttributes, bool isHollow, bool isRightToLeft) { // Create pen Drawing. Drawing penDrawing = CreatePenDrawing(drawingAttributes, isHollow, isRightToLeft); // Create Cursor from Drawing return CreateCursorFromDrawing(penDrawing, new Point(0, 0)); } ////// Create a point eraser cursor from StylusShape /// /// Eraser Shape /// Transform ///internal static Cursor GetPointEraserCursor(StylusShape stylusShape, Matrix tranform) { Debug.Assert(DoubleUtil.IsZero(tranform.OffsetX) && DoubleUtil.IsZero(tranform.OffsetY), "The EraserShape cannot be translated."); Debug.Assert(tranform.HasInverse, "The transform has to be invertable."); // Create a DA with IsHollow being set. A point eraser will be rendered to a hollow stroke. DrawingAttributes da = new DrawingAttributes(); if (stylusShape.GetType() == typeof(RectangleStylusShape)) { da.StylusTip = StylusTip.Rectangle; } else { da.StylusTip = StylusTip.Ellipse; } da.Height = stylusShape.Height; da.Width = stylusShape.Width; da.Color = Colors.Black; if ( !tranform.IsIdentity ) { // Apply the LayoutTransform and/or RenderTransform da.StylusTipTransform *= tranform; } if ( !DoubleUtil.IsZero(stylusShape.Rotation) ) { // Apply the tip rotation Matrix rotationMatrix = Matrix.Identity; rotationMatrix.Rotate(stylusShape.Rotation); da.StylusTipTransform *= rotationMatrix; } // Forward to GetPenCursor. return GetPenCursor(da, true, false/*isRightToLeft*/); } /// /// Create a stroke eraser cursor /// ////// /// Critical: Call a SecurityCritical method - CreateCursorFromDrawing /// TreatAsSafe: The method is safe because there is no input parameter. /// The erase cursor is created internally which is safe. /// [SecurityCritical, SecurityTreatAsSafe] internal static Cursor GetStrokeEraserCursor() { if ( s_StrokeEraserCursor == null ) { // Get Drawing Drawing drawing = CreateStrokeEraserDrawing(); s_StrokeEraserCursor = CreateCursorFromDrawing(drawing, new Point(5, 5)); } // Return cursor. return s_StrokeEraserCursor; } ////// Retrieve selection cursor /// /// hitResult /// True if InkCanvas.FlowDirection is RightToLeft, false otherwise ///internal static Cursor GetSelectionCursor(InkCanvasSelectionHitResult hitResult, bool isRightToLeft) { Cursor cursor; switch ( hitResult ) { case InkCanvasSelectionHitResult.TopLeft: case InkCanvasSelectionHitResult.BottomRight: { if (isRightToLeft) { cursor = Cursors.SizeNESW; } else { cursor = Cursors.SizeNWSE; } break; } case InkCanvasSelectionHitResult.Bottom: case InkCanvasSelectionHitResult.Top: { cursor = Cursors.SizeNS; break; } case InkCanvasSelectionHitResult.BottomLeft: case InkCanvasSelectionHitResult.TopRight: { if (isRightToLeft) { cursor = Cursors.SizeNWSE; } else { cursor = Cursors.SizeNESW; } break; } case InkCanvasSelectionHitResult.Left: case InkCanvasSelectionHitResult.Right: { cursor = Cursors.SizeWE; break; } case InkCanvasSelectionHitResult.Selection: { cursor = Cursors.SizeAll; break; } default: { // By default, use the Cross cursor. cursor = Cursors.Cross; break; } } return cursor; } #endregion Internal Methods //-------------------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------------------- #region Private Methods /// /// Create a Cursor from a Drawing object /// /// Drawing /// Cursor Hotspot ////// /// Critical: Critical as this code calls IconHelper.CreateIconCursor which is Critical /// [SecurityCritical] private static Cursor CreateCursorFromDrawing(Drawing drawing, Point hotspot) { // A default cursor. Cursor cursor = Cursors.Arrow; Rect drawingBounds = drawing.Bounds; double originalWidth = drawingBounds.Width; double originalHeight = drawingBounds.Height; // Cursors like to be multiples of 8 in dimension. int width = IconHelper.AlignToBytes(drawingBounds.Width, 1); int height = IconHelper.AlignToBytes(drawingBounds.Height, 1); // Now inflate the drawing bounds to the new dimension. drawingBounds.Inflate((width - originalWidth) / 2, (height - originalHeight) / 2); // Translate the hotspot accordingly. int xHotspot = (int)Math.Round(hotspot.X - drawingBounds.Left); int yHotspot = (int)Math.Round(hotspot.Y - drawingBounds.Top); // Create a DrawingVisual which represents the cursor drawing. DrawingVisual cursorDrawingVisual = CreateCursorDrawingVisual(drawing, width, height); // Render the cursor visual to a bitmap RenderTargetBitmap rtb = RenderVisualToBitmap(cursorDrawingVisual, width, height); // Get pixel data in Bgra32 fromat from the bitmap byte[] pixels = GetPixels(rtb, width, height); NativeMethods.IconHandle finalCursor = IconHelper.CreateIconCursor(pixels, width, height, xHotspot, yHotspot, false); if ( finalCursor.IsInvalid ) { // Return the default cursor if above is failed. return Cursors.Arrow; } cursor = CursorInteropHelper.CriticalCreate(finalCursor); return cursor; } ////// Create a DrawingVisual from a Drawing /// /// /// /// ///private static DrawingVisual CreateCursorDrawingVisual(Drawing drawing, int width, int height) { // Create a drawing brush with the drawing as its content. DrawingBrush db = new DrawingBrush(drawing); db.Stretch = Stretch.None; db.AlignmentX = AlignmentX.Center; db.AlignmentY = AlignmentY.Center; // Create a drawing visual with our drawing brush. DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext dc = null; try { dc = drawingVisual.RenderOpen(); dc.DrawRectangle(db, null, new Rect(0, 0, width, height)); } finally { if ( dc != null ) { dc.Close(); } } return drawingVisual; } /// /// Renders a visual into a bitmap /// /// visual /// Bitmap width /// Bitmap height ///A bitmap object ////// Critical - The code supresses the unmanaged code security /// [SecurityCritical] private static RenderTargetBitmap RenderVisualToBitmap(Visual visual, int width, int height) { // Use RenderTargetBitmap and BitmapVisualManager to render drawing visual into // a bitmap RenderTargetBitmap rtb = new RenderTargetBitmap (width, height, 96, 96, PixelFormats.Pbgra32); rtb.Render(visual); return rtb; } ////// Get bitmap pixel data in Bgra32 format from a custom Drawing. /// /// A bitmap /// Bitmap width /// Bitmap height ////// /// Critical - Call the internal BitmapSource.CriticalCopyPixels which skips the MediaPermission Demand. /// [SecurityCritical] private static byte[] GetPixels(RenderTargetBitmap rtb, int width, int height) { int strideColorBitmap = width * 4 /* 32 BitsPerPixel */; // Convert the bitmap from Pbgra32 to Bgra32 FormatConvertedBitmap converter = new FormatConvertedBitmap(); converter.BeginInit(); converter.Source = rtb; converter.DestinationFormat = PixelFormats.Bgra32; converter.EndInit(); byte[] pixels = new byte[strideColorBitmap * height]; // Call the internal method which skips the MediaPermission Demand converter.CriticalCopyPixels(Int32Rect.Empty, pixels, strideColorBitmap, 0); return pixels; } ////// Custom Pen Drawing /// private static Drawing CreatePenDrawing(DrawingAttributes drawingAttributes, bool isHollow, bool isRightToLeft) { // Create a single point stroke. StylusPointCollection stylusPoints = new StylusPointCollection(); stylusPoints.Add(new StylusPoint(0f, 0f)); DrawingAttributes da = new DrawingAttributes(); da.Color = drawingAttributes.Color; da.Width = drawingAttributes.Width; da.Height = drawingAttributes.Height; da.StylusTipTransform = drawingAttributes.StylusTipTransform; da.IsHighlighter = drawingAttributes.IsHighlighter; da.StylusTip = drawingAttributes.StylusTip; Stroke singleStroke = new Stroke(stylusPoints, da); // NTRAID#WINDOWS-1326403-2005/10/03-waynezen, // We should draw our cursor in the device unit since it's device dependent object. singleStroke.DrawingAttributes.Width = ConvertToPixel(singleStroke.DrawingAttributes.Width); singleStroke.DrawingAttributes.Height = ConvertToPixel(singleStroke.DrawingAttributes.Height); double maxLength = Math.Min(SystemParameters.PrimaryScreenWidth / 2, SystemParameters.PrimaryScreenHeight / 2); // // NOTE: there are two ways to set the width / height of a stroke // 1) using .Width and .Height // 2) using StylusTipTransform and specifying a scale // these two can multiply and we need to prevent the size from ever going // over maxLength or under 1.0. The simplest way to check if we're too big // is by checking the bounds of the stroke, which takes both into account // Rect strokeBounds = singleStroke.GetBounds(); bool outOfBounds = false; // Make sure that the cursor won't exceed the minimum or the maximum boundary. if ( DoubleUtil.LessThan(strokeBounds.Width, 1.0) ) { singleStroke.DrawingAttributes.Width = 1.0; outOfBounds = true; } else if ( DoubleUtil.GreaterThan(strokeBounds.Width, maxLength) ) { singleStroke.DrawingAttributes.Width = maxLength; outOfBounds = true; } if ( DoubleUtil.LessThan(strokeBounds.Height, 1.0) ) { singleStroke.DrawingAttributes.Height = 1.0; outOfBounds = true; } else if ( DoubleUtil.GreaterThan(strokeBounds.Height, maxLength) ) { singleStroke.DrawingAttributes.Height = maxLength; outOfBounds = true; } //drop the StylusTipTransform if we're out of bounds. we might //consider trying to preserve any transform but this is such a rare //case (scaling over or under with a STT) that we don't care. if (outOfBounds) { singleStroke.DrawingAttributes.StylusTipTransform = Matrix.Identity; } if (isRightToLeft) { //reverse left to right to right to left Matrix xf = singleStroke.DrawingAttributes.StylusTipTransform; xf.Scale(-1, 1); //only set the xf if it has an inverse or the STT will throw if (xf.HasInverse) { singleStroke.DrawingAttributes.StylusTipTransform = xf; } } DrawingGroup penDrawing = new DrawingGroup(); DrawingContext dc = null; try { dc = penDrawing.Open(); // Call the internal drawing method on Stroke to draw as hollow if isHollow == true if ( isHollow ) { singleStroke.DrawInternal(dc, singleStroke.DrawingAttributes, isHollow); } else { // Invoke the public Draw method which will handle the Highlighter correctly. singleStroke.Draw(dc, singleStroke.DrawingAttributes); } } finally { if ( dc != null ) { dc.Close(); } } return penDrawing; } ////// Custom StrokeEraser Drawing /// ///private static Drawing CreateStrokeEraserDrawing() { DrawingGroup drawingGroup = new DrawingGroup(); DrawingContext dc = null; try { dc = drawingGroup.Open(); LinearGradientBrush brush1 = new LinearGradientBrush( Color.FromRgb(240, 242, 255), // Start Color Color.FromRgb(180, 207, 248), // End Color 45f // Angle ); brush1.Freeze(); SolidColorBrush brush2 = new SolidColorBrush(Color.FromRgb(180, 207, 248)); brush2.Freeze(); Pen pen1 = new Pen(Brushes.Gray, 0.7); pen1.Freeze(); PathGeometry pathGeometry = new PathGeometry(); PathFigure path = new PathFigure(); path.StartPoint = new Point(5, 5); LineSegment segment = new LineSegment(new Point(16, 5), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(26, 15), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(15, 15), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(5, 5), true); segment.Freeze(); path.Segments.Add(segment); path.IsClosed = true; path.Freeze(); pathGeometry.Figures.Add(path); path = new PathFigure(); path.StartPoint = new Point(5, 5); segment = new LineSegment(new Point(5, 10), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(15, 19), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(15, 15), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(5, 5), true); segment.Freeze(); path.Segments.Add(segment); path.IsClosed = true; path.Freeze(); pathGeometry.Figures.Add(path); pathGeometry.Freeze(); PathGeometry pathGeometry1 = new PathGeometry(); path = new PathFigure(); path.StartPoint = new Point(15, 15); segment = new LineSegment(new Point(15, 19), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(26, 19), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(26, 15), true); segment.Freeze(); path.Segments.Add(segment); segment.Freeze(); segment = new LineSegment(new Point(15, 15), true); path.Segments.Add(segment); path.IsClosed = true; path.Freeze(); pathGeometry1.Figures.Add(path); pathGeometry1.Freeze(); dc.DrawGeometry(brush1, pen1, pathGeometry); dc.DrawGeometry(brush2, pen1, pathGeometry1); dc.DrawLine(pen1, new Point(5, 5), new Point(5, 0)); dc.DrawLine(pen1, new Point(5, 5), new Point(0, 5)); dc.DrawLine(pen1, new Point(5, 5), new Point(2, 2)); dc.DrawLine(pen1, new Point(5, 5), new Point(8, 2)); dc.DrawLine(pen1, new Point(5, 5), new Point(2, 8)); } finally { if ( dc != null ) { dc.Close(); } } return drawingGroup; } /// /// Convert values from Avalon unit to the current display unit. /// /// ///private static double ConvertToPixel(double value) { int dpi = SystemParameters.Dpi; if ( dpi != 0 ) { return ( value * dpi ) / 96d ; } return value; } #endregion Private Methods //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ #region Private Fields private static Cursor s_StrokeEraserCursor; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // File: PenCursorManager.cs // // Description: // PenCursorManager is helper class which creates Cursor object for InkCanvas' Pen and Eraser // // Authors: waynezen // // Copyright (C) 2003 by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- //#define CURSOR_DEBUG using MS.Win32; using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution; using System.Security; using System.Security.Permissions; using System.Windows; using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; using MS.Internal.AppModel; namespace MS.Internal.Ink { /// /// A static class which generates the cursors for InkCanvas /// internal static class PenCursorManager { //------------------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------------------- #region Internal Methods ////// Create a pen cursor from DrawingAttributes object /// ////// Critical: Call a SecurityCritical method - CreateCursorFromDrawing /// TreatAsSafe: The method is safe because only safe arguments are passed to CreateCursorFromDrawing /// Also the size of the cursor will be limited to the half size of the current primary screen. /// [SecurityCritical, SecurityTreatAsSafe] internal static Cursor GetPenCursor(DrawingAttributes drawingAttributes, bool isHollow, bool isRightToLeft) { // Create pen Drawing. Drawing penDrawing = CreatePenDrawing(drawingAttributes, isHollow, isRightToLeft); // Create Cursor from Drawing return CreateCursorFromDrawing(penDrawing, new Point(0, 0)); } ////// Create a point eraser cursor from StylusShape /// /// Eraser Shape /// Transform ///internal static Cursor GetPointEraserCursor(StylusShape stylusShape, Matrix tranform) { Debug.Assert(DoubleUtil.IsZero(tranform.OffsetX) && DoubleUtil.IsZero(tranform.OffsetY), "The EraserShape cannot be translated."); Debug.Assert(tranform.HasInverse, "The transform has to be invertable."); // Create a DA with IsHollow being set. A point eraser will be rendered to a hollow stroke. DrawingAttributes da = new DrawingAttributes(); if (stylusShape.GetType() == typeof(RectangleStylusShape)) { da.StylusTip = StylusTip.Rectangle; } else { da.StylusTip = StylusTip.Ellipse; } da.Height = stylusShape.Height; da.Width = stylusShape.Width; da.Color = Colors.Black; if ( !tranform.IsIdentity ) { // Apply the LayoutTransform and/or RenderTransform da.StylusTipTransform *= tranform; } if ( !DoubleUtil.IsZero(stylusShape.Rotation) ) { // Apply the tip rotation Matrix rotationMatrix = Matrix.Identity; rotationMatrix.Rotate(stylusShape.Rotation); da.StylusTipTransform *= rotationMatrix; } // Forward to GetPenCursor. return GetPenCursor(da, true, false/*isRightToLeft*/); } /// /// Create a stroke eraser cursor /// ////// /// Critical: Call a SecurityCritical method - CreateCursorFromDrawing /// TreatAsSafe: The method is safe because there is no input parameter. /// The erase cursor is created internally which is safe. /// [SecurityCritical, SecurityTreatAsSafe] internal static Cursor GetStrokeEraserCursor() { if ( s_StrokeEraserCursor == null ) { // Get Drawing Drawing drawing = CreateStrokeEraserDrawing(); s_StrokeEraserCursor = CreateCursorFromDrawing(drawing, new Point(5, 5)); } // Return cursor. return s_StrokeEraserCursor; } ////// Retrieve selection cursor /// /// hitResult /// True if InkCanvas.FlowDirection is RightToLeft, false otherwise ///internal static Cursor GetSelectionCursor(InkCanvasSelectionHitResult hitResult, bool isRightToLeft) { Cursor cursor; switch ( hitResult ) { case InkCanvasSelectionHitResult.TopLeft: case InkCanvasSelectionHitResult.BottomRight: { if (isRightToLeft) { cursor = Cursors.SizeNESW; } else { cursor = Cursors.SizeNWSE; } break; } case InkCanvasSelectionHitResult.Bottom: case InkCanvasSelectionHitResult.Top: { cursor = Cursors.SizeNS; break; } case InkCanvasSelectionHitResult.BottomLeft: case InkCanvasSelectionHitResult.TopRight: { if (isRightToLeft) { cursor = Cursors.SizeNWSE; } else { cursor = Cursors.SizeNESW; } break; } case InkCanvasSelectionHitResult.Left: case InkCanvasSelectionHitResult.Right: { cursor = Cursors.SizeWE; break; } case InkCanvasSelectionHitResult.Selection: { cursor = Cursors.SizeAll; break; } default: { // By default, use the Cross cursor. cursor = Cursors.Cross; break; } } return cursor; } #endregion Internal Methods //-------------------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------------------- #region Private Methods /// /// Create a Cursor from a Drawing object /// /// Drawing /// Cursor Hotspot ////// /// Critical: Critical as this code calls IconHelper.CreateIconCursor which is Critical /// [SecurityCritical] private static Cursor CreateCursorFromDrawing(Drawing drawing, Point hotspot) { // A default cursor. Cursor cursor = Cursors.Arrow; Rect drawingBounds = drawing.Bounds; double originalWidth = drawingBounds.Width; double originalHeight = drawingBounds.Height; // Cursors like to be multiples of 8 in dimension. int width = IconHelper.AlignToBytes(drawingBounds.Width, 1); int height = IconHelper.AlignToBytes(drawingBounds.Height, 1); // Now inflate the drawing bounds to the new dimension. drawingBounds.Inflate((width - originalWidth) / 2, (height - originalHeight) / 2); // Translate the hotspot accordingly. int xHotspot = (int)Math.Round(hotspot.X - drawingBounds.Left); int yHotspot = (int)Math.Round(hotspot.Y - drawingBounds.Top); // Create a DrawingVisual which represents the cursor drawing. DrawingVisual cursorDrawingVisual = CreateCursorDrawingVisual(drawing, width, height); // Render the cursor visual to a bitmap RenderTargetBitmap rtb = RenderVisualToBitmap(cursorDrawingVisual, width, height); // Get pixel data in Bgra32 fromat from the bitmap byte[] pixels = GetPixels(rtb, width, height); NativeMethods.IconHandle finalCursor = IconHelper.CreateIconCursor(pixels, width, height, xHotspot, yHotspot, false); if ( finalCursor.IsInvalid ) { // Return the default cursor if above is failed. return Cursors.Arrow; } cursor = CursorInteropHelper.CriticalCreate(finalCursor); return cursor; } ////// Create a DrawingVisual from a Drawing /// /// /// /// ///private static DrawingVisual CreateCursorDrawingVisual(Drawing drawing, int width, int height) { // Create a drawing brush with the drawing as its content. DrawingBrush db = new DrawingBrush(drawing); db.Stretch = Stretch.None; db.AlignmentX = AlignmentX.Center; db.AlignmentY = AlignmentY.Center; // Create a drawing visual with our drawing brush. DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext dc = null; try { dc = drawingVisual.RenderOpen(); dc.DrawRectangle(db, null, new Rect(0, 0, width, height)); } finally { if ( dc != null ) { dc.Close(); } } return drawingVisual; } /// /// Renders a visual into a bitmap /// /// visual /// Bitmap width /// Bitmap height ///A bitmap object ////// Critical - The code supresses the unmanaged code security /// [SecurityCritical] private static RenderTargetBitmap RenderVisualToBitmap(Visual visual, int width, int height) { // Use RenderTargetBitmap and BitmapVisualManager to render drawing visual into // a bitmap RenderTargetBitmap rtb = new RenderTargetBitmap (width, height, 96, 96, PixelFormats.Pbgra32); rtb.Render(visual); return rtb; } ////// Get bitmap pixel data in Bgra32 format from a custom Drawing. /// /// A bitmap /// Bitmap width /// Bitmap height ////// /// Critical - Call the internal BitmapSource.CriticalCopyPixels which skips the MediaPermission Demand. /// [SecurityCritical] private static byte[] GetPixels(RenderTargetBitmap rtb, int width, int height) { int strideColorBitmap = width * 4 /* 32 BitsPerPixel */; // Convert the bitmap from Pbgra32 to Bgra32 FormatConvertedBitmap converter = new FormatConvertedBitmap(); converter.BeginInit(); converter.Source = rtb; converter.DestinationFormat = PixelFormats.Bgra32; converter.EndInit(); byte[] pixels = new byte[strideColorBitmap * height]; // Call the internal method which skips the MediaPermission Demand converter.CriticalCopyPixels(Int32Rect.Empty, pixels, strideColorBitmap, 0); return pixels; } ////// Custom Pen Drawing /// private static Drawing CreatePenDrawing(DrawingAttributes drawingAttributes, bool isHollow, bool isRightToLeft) { // Create a single point stroke. StylusPointCollection stylusPoints = new StylusPointCollection(); stylusPoints.Add(new StylusPoint(0f, 0f)); DrawingAttributes da = new DrawingAttributes(); da.Color = drawingAttributes.Color; da.Width = drawingAttributes.Width; da.Height = drawingAttributes.Height; da.StylusTipTransform = drawingAttributes.StylusTipTransform; da.IsHighlighter = drawingAttributes.IsHighlighter; da.StylusTip = drawingAttributes.StylusTip; Stroke singleStroke = new Stroke(stylusPoints, da); // NTRAID#WINDOWS-1326403-2005/10/03-waynezen, // We should draw our cursor in the device unit since it's device dependent object. singleStroke.DrawingAttributes.Width = ConvertToPixel(singleStroke.DrawingAttributes.Width); singleStroke.DrawingAttributes.Height = ConvertToPixel(singleStroke.DrawingAttributes.Height); double maxLength = Math.Min(SystemParameters.PrimaryScreenWidth / 2, SystemParameters.PrimaryScreenHeight / 2); // // NOTE: there are two ways to set the width / height of a stroke // 1) using .Width and .Height // 2) using StylusTipTransform and specifying a scale // these two can multiply and we need to prevent the size from ever going // over maxLength or under 1.0. The simplest way to check if we're too big // is by checking the bounds of the stroke, which takes both into account // Rect strokeBounds = singleStroke.GetBounds(); bool outOfBounds = false; // Make sure that the cursor won't exceed the minimum or the maximum boundary. if ( DoubleUtil.LessThan(strokeBounds.Width, 1.0) ) { singleStroke.DrawingAttributes.Width = 1.0; outOfBounds = true; } else if ( DoubleUtil.GreaterThan(strokeBounds.Width, maxLength) ) { singleStroke.DrawingAttributes.Width = maxLength; outOfBounds = true; } if ( DoubleUtil.LessThan(strokeBounds.Height, 1.0) ) { singleStroke.DrawingAttributes.Height = 1.0; outOfBounds = true; } else if ( DoubleUtil.GreaterThan(strokeBounds.Height, maxLength) ) { singleStroke.DrawingAttributes.Height = maxLength; outOfBounds = true; } //drop the StylusTipTransform if we're out of bounds. we might //consider trying to preserve any transform but this is such a rare //case (scaling over or under with a STT) that we don't care. if (outOfBounds) { singleStroke.DrawingAttributes.StylusTipTransform = Matrix.Identity; } if (isRightToLeft) { //reverse left to right to right to left Matrix xf = singleStroke.DrawingAttributes.StylusTipTransform; xf.Scale(-1, 1); //only set the xf if it has an inverse or the STT will throw if (xf.HasInverse) { singleStroke.DrawingAttributes.StylusTipTransform = xf; } } DrawingGroup penDrawing = new DrawingGroup(); DrawingContext dc = null; try { dc = penDrawing.Open(); // Call the internal drawing method on Stroke to draw as hollow if isHollow == true if ( isHollow ) { singleStroke.DrawInternal(dc, singleStroke.DrawingAttributes, isHollow); } else { // Invoke the public Draw method which will handle the Highlighter correctly. singleStroke.Draw(dc, singleStroke.DrawingAttributes); } } finally { if ( dc != null ) { dc.Close(); } } return penDrawing; } ////// Custom StrokeEraser Drawing /// ///private static Drawing CreateStrokeEraserDrawing() { DrawingGroup drawingGroup = new DrawingGroup(); DrawingContext dc = null; try { dc = drawingGroup.Open(); LinearGradientBrush brush1 = new LinearGradientBrush( Color.FromRgb(240, 242, 255), // Start Color Color.FromRgb(180, 207, 248), // End Color 45f // Angle ); brush1.Freeze(); SolidColorBrush brush2 = new SolidColorBrush(Color.FromRgb(180, 207, 248)); brush2.Freeze(); Pen pen1 = new Pen(Brushes.Gray, 0.7); pen1.Freeze(); PathGeometry pathGeometry = new PathGeometry(); PathFigure path = new PathFigure(); path.StartPoint = new Point(5, 5); LineSegment segment = new LineSegment(new Point(16, 5), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(26, 15), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(15, 15), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(5, 5), true); segment.Freeze(); path.Segments.Add(segment); path.IsClosed = true; path.Freeze(); pathGeometry.Figures.Add(path); path = new PathFigure(); path.StartPoint = new Point(5, 5); segment = new LineSegment(new Point(5, 10), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(15, 19), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(15, 15), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(5, 5), true); segment.Freeze(); path.Segments.Add(segment); path.IsClosed = true; path.Freeze(); pathGeometry.Figures.Add(path); pathGeometry.Freeze(); PathGeometry pathGeometry1 = new PathGeometry(); path = new PathFigure(); path.StartPoint = new Point(15, 15); segment = new LineSegment(new Point(15, 19), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(26, 19), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(26, 15), true); segment.Freeze(); path.Segments.Add(segment); segment.Freeze(); segment = new LineSegment(new Point(15, 15), true); path.Segments.Add(segment); path.IsClosed = true; path.Freeze(); pathGeometry1.Figures.Add(path); pathGeometry1.Freeze(); dc.DrawGeometry(brush1, pen1, pathGeometry); dc.DrawGeometry(brush2, pen1, pathGeometry1); dc.DrawLine(pen1, new Point(5, 5), new Point(5, 0)); dc.DrawLine(pen1, new Point(5, 5), new Point(0, 5)); dc.DrawLine(pen1, new Point(5, 5), new Point(2, 2)); dc.DrawLine(pen1, new Point(5, 5), new Point(8, 2)); dc.DrawLine(pen1, new Point(5, 5), new Point(2, 8)); } finally { if ( dc != null ) { dc.Close(); } } return drawingGroup; } /// /// Convert values from Avalon unit to the current display unit. /// /// ///private static double ConvertToPixel(double value) { int dpi = SystemParameters.Dpi; if ( dpi != 0 ) { return ( value * dpi ) / 96d ; } return value; } #endregion Private Methods //------------------------------------------------------ // // Private Fields // //------------------------------------------------------ #region Private Fields private static Cursor s_StrokeEraserCursor; #endregion Private Fields } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- iisPickupDirectory.cs
- IteratorDescriptor.cs
- MethodSignatureGenerator.cs
- XmlNamespaceDeclarationsAttribute.cs
- UserNamePasswordValidationMode.cs
- ObjectSet.cs
- AnnotationService.cs
- RadioButtonAutomationPeer.cs
- EntityException.cs
- DebugHandleTracker.cs
- DivideByZeroException.cs
- ReferencedCollectionType.cs
- LinkLabel.cs
- TypeBrowser.xaml.cs
- VectorAnimationBase.cs
- TextServicesContext.cs
- AuthenticationConfig.cs
- SearchForVirtualItemEventArgs.cs
- XmlSchemaSimpleType.cs
- MetaModel.cs
- SqlConnectionFactory.cs
- SystemGatewayIPAddressInformation.cs
- Point3DCollection.cs
- CodeMethodInvokeExpression.cs
- DiscreteKeyFrames.cs
- XmlWhitespace.cs
- DrawingAttributeSerializer.cs
- MasterPageBuildProvider.cs
- LogFlushAsyncResult.cs
- InternalConfigEventArgs.cs
- Int32Animation.cs
- WebPartVerbsEventArgs.cs
- FocusWithinProperty.cs
- MasterPageBuildProvider.cs
- DrawingAttributes.cs
- ListViewDeletedEventArgs.cs
- Win32MouseDevice.cs
- SBCSCodePageEncoding.cs
- ThicknessConverter.cs
- XamlParser.cs
- TypeSystem.cs
- NavigatingCancelEventArgs.cs
- EntityDataSourceContainerNameConverter.cs
- DefaultValidator.cs
- BitmapFrame.cs
- Point3DAnimation.cs
- DataGridTable.cs
- SoapMessage.cs
- SqlCacheDependencySection.cs
- TemplateControlBuildProvider.cs
- PriorityRange.cs
- SecurityPermission.cs
- PersonalizablePropertyEntry.cs
- ProgressBarAutomationPeer.cs
- TextBoxBaseDesigner.cs
- DoubleLinkList.cs
- DataKey.cs
- PropertyValue.cs
- ScaleTransform.cs
- DbRetry.cs
- PackWebRequestFactory.cs
- PixelFormats.cs
- ThreadSafeList.cs
- FrameworkPropertyMetadata.cs
- EntityType.cs
- DbCommandTree.cs
- ADMembershipProvider.cs
- DataShape.cs
- AutoScrollExpandMessageFilter.cs
- HttpApplicationFactory.cs
- WebCategoryAttribute.cs
- TableFieldsEditor.cs
- OdbcConnectionHandle.cs
- OleDbPropertySetGuid.cs
- ParseElement.cs
- ArgumentsParser.cs
- DataGridViewRow.cs
- CursorInteropHelper.cs
- BridgeDataReader.cs
- ListViewGroup.cs
- Point3DValueSerializer.cs
- sqlinternaltransaction.cs
- NonNullItemCollection.cs
- ConstrainedDataObject.cs
- ExtensionQuery.cs
- ConditionalDesigner.cs
- DataBindEngine.cs
- ListDesigner.cs
- MenuItemCollection.cs
- FocusManager.cs
- documentsequencetextpointer.cs
- RouteValueExpressionBuilder.cs
- AttachedPropertiesService.cs
- HttpConfigurationSystem.cs
- CriticalFinalizerObject.cs
- InputEventArgs.cs
- Helpers.cs
- Typeface.cs
- RedistVersionInfo.cs
- PropertiesTab.cs