Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / Media / Effects / BitmapEffectDrawingContextWalker.cs / 1 / BitmapEffectDrawingContextWalker.cs
//---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: BitmapEffectDrawingContextWalker.cs // // Description: This file contains the implementation of BitmapEffectDrawingContextWalker. // This DrawingContextWalker is used to render the commands between // PushEffect and Pop // // History: // 07/25/2005 : [....] - Created it. // //--------------------------------------------------------------------------- using MS.Internal; using MS.Utility; using System; using System.ComponentModel; using System.Collections; using System.Collections.Generic; using System.ComponentModel.Design.Serialization; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Composition; using System.Windows.Media.Effects; using System.Windows.Media.Imaging; using System.Windows.Media.Media3D; using System.Security; using System.Security.Permissions; namespace System.Windows.Media.Effects { class BitmapEffectDrawingContextWalker : DrawingContextWalker { ////// PushType enum - this defines the type of Pushes in a context, so that our /// untyped Pops know what to Pop. /// private enum PushType { Transform, Clip, Opacity, OpacityMask, BitmapEffect, GuidelineSet, GuidelineY1, GuidelineY2 } public BitmapEffectDrawingContextWalker() { _transform = Matrix.Identity; _windowClip = Rect.Empty; } public BitmapEffectDrawingContextWalker(Matrix transform, Rect windowClip) { _transform = transform; _windowClip = windowClip; } ////// DrawLine - /// Draws a line with the specified pen. /// Note that this API does not accept a Brush, as there is no area to fill. /// /// The Pen with which to stroke the line. /// The start Point for the line. /// The end Point for the line. public override void DrawLine( Pen pen, Point point0, Point point1) { if (_effectContext != null) { _effectContext.Context.DrawLine( pen, point0, point1); } } ////// DrawLine - /// Draws a line with the specified pen. /// Note that this API does not accept a Brush, as there is no area to fill. /// /// The Pen with which to stroke the line. /// The start Point for the line. /// Optional AnimationClock for point0. /// The end Point for the line. /// Optional AnimationClock for point1. public override void DrawLine( Pen pen, Point point0, AnimationClock point0Animations, Point point1, AnimationClock point1Animations) { if (_effectContext != null) { _effectContext.Context.DrawLine( pen, point0, point0Animations, point1, point1Animations); } } ////// DrawRectangle - /// Draw a rectangle with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the rectangle. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the rectangle. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Rect to fill and/or stroke. public override void DrawRectangle( Brush brush, Pen pen, Rect rectangle) { if (_effectContext != null) { _effectContext.Context.DrawRectangle( brush, pen, rectangle); } } ////// DrawRectangle - /// Draw a rectangle with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the rectangle. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the rectangle. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Rect to fill and/or stroke. /// Optional AnimationClock for rectangle. public override void DrawRectangle( Brush brush, Pen pen, Rect rectangle, AnimationClock rectangleAnimations) { if (_effectContext != null) { _effectContext.Context.DrawRectangle( brush, pen, rectangle); } } ////// DrawRoundedRectangle - /// Draw a rounded rectangle with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the rectangle. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the rectangle. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Rect to fill and/or stroke. /// /// The radius in the X dimension of the rounded corners of this /// rounded Rect. This value will be clamped to the range [0..rectangle.Width/2] /// /// /// The radius in the Y dimension of the rounded corners of this /// rounded Rect. This value will be clamped to the range [0..rectangle.Height/2]. /// public override void DrawRoundedRectangle( Brush brush, Pen pen, Rect rectangle, Double radiusX, Double radiusY) { if (_effectContext != null) { _effectContext.Context.DrawRoundedRectangle( brush, pen, rectangle, radiusX, radiusY); } } ////// DrawRoundedRectangle - /// Draw a rounded rectangle with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the rectangle. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the rectangle. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Rect to fill and/or stroke. /// Optional AnimationClock for rectangle. /// /// The radius in the X dimension of the rounded corners of this /// rounded Rect. This value will be clamped to the range [0..rectangle.Width/2] /// /// Optional AnimationClock for radiusX. /// /// The radius in the Y dimension of the rounded corners of this /// rounded Rect. This value will be clamped to the range [0..rectangle.Height/2]. /// /// Optional AnimationClock for radiusY. public override void DrawRoundedRectangle( Brush brush, Pen pen, Rect rectangle, AnimationClock rectangleAnimations, Double radiusX, AnimationClock radiusXAnimations, Double radiusY, AnimationClock radiusYAnimations) { if (_effectContext != null) { _effectContext.Context.DrawRoundedRectangle( brush, pen, rectangle, rectangleAnimations, radiusX, radiusXAnimations, radiusY, radiusYAnimations); } } ////// DrawEllipse - /// Draw an ellipse with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the ellipse. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the ellipse. /// This is optional, and can be null, in which case no stroke is performed. /// /// /// The center of the ellipse to fill and/or stroke. /// /// /// The radius in the X dimension of the ellipse. /// The absolute value of the radius provided will be used. /// /// /// The radius in the Y dimension of the ellipse. /// The absolute value of the radius provided will be used. /// public override void DrawEllipse( Brush brush, Pen pen, Point center, Double radiusX, Double radiusY) { if (_effectContext != null) { _effectContext.Context.DrawEllipse( brush, pen, center, radiusX, radiusY); } } ////// DrawEllipse - /// Draw an ellipse with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the ellipse. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the ellipse. /// This is optional, and can be null, in which case no stroke is performed. /// /// /// The center of the ellipse to fill and/or stroke. /// /// Optional AnimationClock for center. /// /// The radius in the X dimension of the ellipse. /// The absolute value of the radius provided will be used. /// /// Optional AnimationClock for radiusX. /// /// The radius in the Y dimension of the ellipse. /// The absolute value of the radius provided will be used. /// /// Optional AnimationClock for radiusY. public override void DrawEllipse( Brush brush, Pen pen, Point center, AnimationClock centerAnimations, Double radiusX, AnimationClock radiusXAnimations, Double radiusY, AnimationClock radiusYAnimations) { if (_effectContext != null) { _effectContext.Context.DrawEllipse( brush, pen, center, centerAnimations, radiusX, radiusXAnimations, radiusY, radiusYAnimations); } } ////// DrawGeometry - /// Draw a Geometry with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the Geometry. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the Geometry. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Geometry to fill and/or stroke. public override void DrawGeometry( Brush brush, Pen pen, Geometry geometry) { if (_effectContext != null) { _effectContext.Context.DrawGeometry( brush, pen, geometry); } } ////// DrawImage - /// Draw an Image into the region specified by the Rect. /// The Image will potentially be stretched and distorted to fit the Rect. /// For more fine grained control, consider filling a Rect with an ImageBrush via /// DrawRectangle. /// /// The ImageSource to draw. /// /// The Rect into which the ImageSource will be fit. /// public override void DrawImage( ImageSource imageSource, Rect rectangle) { if (_effectContext != null) { _effectContext.Context.DrawImage( imageSource, rectangle); } } ////// DrawImage - /// Draw an Image into the region specified by the Rect. /// The Image will potentially be stretched and distorted to fit the Rect. /// For more fine grained control, consider filling a Rect with an ImageBrush via /// DrawRectangle. /// /// The ImageSource to draw. /// /// The Rect into which the ImageSource will be fit. /// /// Optional AnimationClock for rectangle. public override void DrawImage( ImageSource imageSource, Rect rectangle, AnimationClock rectangleAnimations) { if (_effectContext != null) { _effectContext.Context.DrawImage( imageSource, rectangle, rectangleAnimations); } } ////// DrawGlyphRun - /// Draw a GlyphRun /// /// /// Foreground brush to draw the GlyphRun with. /// /// The GlyphRun to draw. public override void DrawGlyphRun( Brush foregroundBrush, GlyphRun glyphRun) { if (_effectContext != null) { _effectContext.Context.DrawGlyphRun( foregroundBrush, glyphRun); } } ////// DrawDrawing - /// Draw a Drawing by appending a sub-Drawing to the current Drawing. /// /// The drawing to draw. public override void DrawDrawing( Drawing drawing) { if (_effectContext != null) { _effectContext.Context.DrawDrawing(drawing); } } ////// DrawVideo - /// Draw a Video into the region specified by the Rect. /// The Video will potentially be stretched and distorted to fit the Rect. /// For more fine grained control, consider filling a Rect with an VideoBrush via /// DrawRectangle. /// /// The MediaPlayer to draw. /// /// The Rect into which the MediaClock will be fit. /// public override void DrawVideo( MediaPlayer player, Rect rectangle) { if (_effectContext != null) { _effectContext.Context.DrawVideo( player, rectangle); } } ////// DrawVideo - /// Draw a Video into the region specified by the Rect. /// The Video will potentially be stretched and distorted to fit the Rect. /// For more fine grained control, consider filling a Rect with an VideoBrush via /// DrawRectangle. /// /// The MediaPlayer to draw. /// /// The Rect into which the MediaClock will be fit. /// /// Optional AnimationClock for rectangle. public override void DrawVideo( MediaPlayer player, Rect rectangle, AnimationClock rectangleAnimations) { if (_effectContext != null) { _effectContext.Context.DrawVideo( player, rectangle, rectangleAnimations); } } ////// DrawScene3D - /// Draw a Scene3D (internal object encapsulating a 3D scene) /// /// The Scene3D to draw. internal override void DrawScene3D( Scene3D scene3D) { if (_effectContext != null) { _effectContext.Context.DrawScene3D(scene3D); } } ////// PushGuidelineSet - /// Push a set of guidelines which will apply to all drawing operations until the /// corresponding Pop. /// /// The GuidelineSet to push. public override void PushGuidelineSet( GuidelineSet guidelines) { if (_effectContext != null) { _effectContext.Context.PushGuidelineSet(guidelines); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.GuidelineSet); } /// /// PushGuidelineY1 - /// Explicitly push one horizontal guideline. /// /// The coordinate of leading guideline. internal override void PushGuidelineY1( Double coordinate) { if (_effectContext != null) { _effectContext.Context.PushGuidelineY1(coordinate); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.GuidelineY1); } /// /// PushGuidelineY2 - /// Explicitly push a pair of horizontal guidelines. /// /// /// The coordinate of leading guideline. /// /// /// The offset from leading guideline to driven guideline. /// internal override void PushGuidelineY2( Double leadingCoordinate, Double offsetToDrivenCoordinate) { if (_effectContext != null) { _effectContext.Context.PushGuidelineY2(leadingCoordinate, offsetToDrivenCoordinate); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.GuidelineY2); } /// /// Push an opacity mask /// /// /// The opacity mask /// public override void PushOpacityMask(Brush brush) { if (_effectContext != null) { _effectContext.Context.PushOpacityMask(brush); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.OpacityMask); } /// /// PushClip - /// Push a clip region, which will apply to all drawing primitives until the /// corresponding Pop call. /// /// The Geometry to which we will clip. public override void PushClip( Geometry clipGeometry) { if (_effectContext != null) { _effectContext.Context.PushClip(clipGeometry); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.Clip); } /// /// PushOpacity - /// Push an opacity which will blend the composite of all drawing primitives added /// until the corresponding Pop call. /// /// /// The opacity with which to blend - 0 is transparent, 1 is opaque. /// public override void PushOpacity( Double opacity) { if (_effectContext != null) { _effectContext.Context.PushOpacity(opacity); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.Opacity); } /// /// PushOpacity - /// Push an opacity which will blend the composite of all drawing primitives added /// until the corresponding Pop call. /// /// /// The opacity with which to blend - 0 is transparent, 1 is opaque. /// /// Optional AnimationClock for opacity. public override void PushOpacity( Double opacity, AnimationClock opacityAnimations) { if (_effectContext != null) { _effectContext.Context.PushOpacity( opacity, opacityAnimations); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.Opacity); } /// /// PushTransform - /// Push a Transform which will apply to all drawing operations until the corresponding /// Pop. /// /// The Transform to push. public override void PushTransform( Transform transform) { if (_effectContext != null) { _effectContext.Context.PushTransform(transform); } // Ensure the transform stack if (_transformStack == null) { _transformStack = new Stack(2); } // Push the old transform. _transformStack.Push(_transform); // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack (2); } // Push the transform type _pushTypeStack.Push(PushType.Transform); Matrix newValue = Matrix.Identity; // Retrieve the new transform as a matrix if it exists if ((transform != null) && !transform.IsIdentity) { // If the transform is degeneraate, we can skip all instructions until the // corresponding Pop. newValue = transform.Value; } // Update the current transform _transform = newValue * _transform; } /// /// PushEffect - /// Push a BitmapEffect which will apply to all drawing operations until the /// corresponding Pop. /// /// The BitmapEffect to push. /// The BitmapEffectInput. public override void PushEffect( BitmapEffect effect, BitmapEffectInput effectInput) { // create new context if (_effectContext == null) { _effectContext = new BitmapEffectDrawingContextState(effect, effectInput); } else { _effectContext.Context.PushEffect(effect, effectInput); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.BitmapEffect); _effectStackDepth++; } /// /// Pop /// public override void Pop( ) { // We must have a type stack and it must not be empty. Debug.Assert(_pushTypeStack != null); Debug.Assert(_pushTypeStack.Count > 0); // Retrieve the PushType to figure out what what this Pop is. PushType pushType = _pushTypeStack.Pop(); switch (pushType) { case PushType.Transform: // We must have a Transform stack and it must not be empty. Debug.Assert(_transformStack != null); Debug.Assert(_transformStack.Count > 0); // Restore the transform _transform = _transformStack.Pop(); break; case PushType.BitmapEffect: Debug.Assert(_effectStackDepth > 0, "We should have pushed an effect first"); Debug.Assert(_effectContext != null, "We should have created a context"); _effectStackDepth--; // render only if it is a toplevel effect if (_effectStackDepth == 0) { _effectContext.Context.Close(); Matrix worldTransform = _transform; BitmapSource effectImage = _effectContext.RenderBitmapEffect(ref worldTransform, _windowClip); ImageDrawing drawing = new ImageDrawing(); if (effectImage != null) { drawing.ImageSource = effectImage; drawing.Rect = new Rect(0, 0, effectImage.Width, effectImage.Height); } DrawingGroup group = new DrawingGroup(); group.Children.Add(drawing); group.Transform = new MatrixTransform(worldTransform); BitmapEffectDrawing.Drawings.Add(group); BitmapEffectDrawing.WorldTransforms.Add(new MatrixTransform(_transform)); _effectContext = null; } break; default: // Ignore the rest break; } if (_effectContext != null) { _effectContext.Context.Pop(); } } internal BitmapEffectDrawing BitmapEffectDrawing { get { if (_bitmapEffectDrawing == null) { _bitmapEffectDrawing = new BitmapEffectDrawing(); } return _bitmapEffectDrawing; } } #region Private Fields private BitmapEffectDrawing _bitmapEffectDrawing; // The current local->world Transform as a matrix. private Matrix _transform; private Rect _windowClip = Rect.Empty; // The Type stack for our Push/Pop calls. This tells whether a given Pop corresponds // to a Transform, Clip, etc. private Stack_pushTypeStack; // This stack contains the Matrices encountered during our walk. // The current transform is stored in _transform and not in the Stack. private Stack _transformStack; // this contains the effect drawing context private BitmapEffectDrawingContextState _effectContext; private long _effectStackDepth; #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: BitmapEffectDrawingContextWalker.cs // // Description: This file contains the implementation of BitmapEffectDrawingContextWalker. // This DrawingContextWalker is used to render the commands between // PushEffect and Pop // // History: // 07/25/2005 : [....] - Created it. // //--------------------------------------------------------------------------- using MS.Internal; using MS.Utility; using System; using System.ComponentModel; using System.Collections; using System.Collections.Generic; using System.ComponentModel.Design.Serialization; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Composition; using System.Windows.Media.Effects; using System.Windows.Media.Imaging; using System.Windows.Media.Media3D; using System.Security; using System.Security.Permissions; namespace System.Windows.Media.Effects { class BitmapEffectDrawingContextWalker : DrawingContextWalker { /// /// PushType enum - this defines the type of Pushes in a context, so that our /// untyped Pops know what to Pop. /// private enum PushType { Transform, Clip, Opacity, OpacityMask, BitmapEffect, GuidelineSet, GuidelineY1, GuidelineY2 } public BitmapEffectDrawingContextWalker() { _transform = Matrix.Identity; _windowClip = Rect.Empty; } public BitmapEffectDrawingContextWalker(Matrix transform, Rect windowClip) { _transform = transform; _windowClip = windowClip; } ////// DrawLine - /// Draws a line with the specified pen. /// Note that this API does not accept a Brush, as there is no area to fill. /// /// The Pen with which to stroke the line. /// The start Point for the line. /// The end Point for the line. public override void DrawLine( Pen pen, Point point0, Point point1) { if (_effectContext != null) { _effectContext.Context.DrawLine( pen, point0, point1); } } ////// DrawLine - /// Draws a line with the specified pen. /// Note that this API does not accept a Brush, as there is no area to fill. /// /// The Pen with which to stroke the line. /// The start Point for the line. /// Optional AnimationClock for point0. /// The end Point for the line. /// Optional AnimationClock for point1. public override void DrawLine( Pen pen, Point point0, AnimationClock point0Animations, Point point1, AnimationClock point1Animations) { if (_effectContext != null) { _effectContext.Context.DrawLine( pen, point0, point0Animations, point1, point1Animations); } } ////// DrawRectangle - /// Draw a rectangle with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the rectangle. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the rectangle. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Rect to fill and/or stroke. public override void DrawRectangle( Brush brush, Pen pen, Rect rectangle) { if (_effectContext != null) { _effectContext.Context.DrawRectangle( brush, pen, rectangle); } } ////// DrawRectangle - /// Draw a rectangle with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the rectangle. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the rectangle. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Rect to fill and/or stroke. /// Optional AnimationClock for rectangle. public override void DrawRectangle( Brush brush, Pen pen, Rect rectangle, AnimationClock rectangleAnimations) { if (_effectContext != null) { _effectContext.Context.DrawRectangle( brush, pen, rectangle); } } ////// DrawRoundedRectangle - /// Draw a rounded rectangle with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the rectangle. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the rectangle. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Rect to fill and/or stroke. /// /// The radius in the X dimension of the rounded corners of this /// rounded Rect. This value will be clamped to the range [0..rectangle.Width/2] /// /// /// The radius in the Y dimension of the rounded corners of this /// rounded Rect. This value will be clamped to the range [0..rectangle.Height/2]. /// public override void DrawRoundedRectangle( Brush brush, Pen pen, Rect rectangle, Double radiusX, Double radiusY) { if (_effectContext != null) { _effectContext.Context.DrawRoundedRectangle( brush, pen, rectangle, radiusX, radiusY); } } ////// DrawRoundedRectangle - /// Draw a rounded rectangle with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the rectangle. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the rectangle. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Rect to fill and/or stroke. /// Optional AnimationClock for rectangle. /// /// The radius in the X dimension of the rounded corners of this /// rounded Rect. This value will be clamped to the range [0..rectangle.Width/2] /// /// Optional AnimationClock for radiusX. /// /// The radius in the Y dimension of the rounded corners of this /// rounded Rect. This value will be clamped to the range [0..rectangle.Height/2]. /// /// Optional AnimationClock for radiusY. public override void DrawRoundedRectangle( Brush brush, Pen pen, Rect rectangle, AnimationClock rectangleAnimations, Double radiusX, AnimationClock radiusXAnimations, Double radiusY, AnimationClock radiusYAnimations) { if (_effectContext != null) { _effectContext.Context.DrawRoundedRectangle( brush, pen, rectangle, rectangleAnimations, radiusX, radiusXAnimations, radiusY, radiusYAnimations); } } ////// DrawEllipse - /// Draw an ellipse with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the ellipse. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the ellipse. /// This is optional, and can be null, in which case no stroke is performed. /// /// /// The center of the ellipse to fill and/or stroke. /// /// /// The radius in the X dimension of the ellipse. /// The absolute value of the radius provided will be used. /// /// /// The radius in the Y dimension of the ellipse. /// The absolute value of the radius provided will be used. /// public override void DrawEllipse( Brush brush, Pen pen, Point center, Double radiusX, Double radiusY) { if (_effectContext != null) { _effectContext.Context.DrawEllipse( brush, pen, center, radiusX, radiusY); } } ////// DrawEllipse - /// Draw an ellipse with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the ellipse. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the ellipse. /// This is optional, and can be null, in which case no stroke is performed. /// /// /// The center of the ellipse to fill and/or stroke. /// /// Optional AnimationClock for center. /// /// The radius in the X dimension of the ellipse. /// The absolute value of the radius provided will be used. /// /// Optional AnimationClock for radiusX. /// /// The radius in the Y dimension of the ellipse. /// The absolute value of the radius provided will be used. /// /// Optional AnimationClock for radiusY. public override void DrawEllipse( Brush brush, Pen pen, Point center, AnimationClock centerAnimations, Double radiusX, AnimationClock radiusXAnimations, Double radiusY, AnimationClock radiusYAnimations) { if (_effectContext != null) { _effectContext.Context.DrawEllipse( brush, pen, center, centerAnimations, radiusX, radiusXAnimations, radiusY, radiusYAnimations); } } ////// DrawGeometry - /// Draw a Geometry with the provided Brush and/or Pen. /// If both the Brush and Pen are null this call is a no-op. /// /// /// The Brush with which to fill the Geometry. /// This is optional, and can be null, in which case no fill is performed. /// /// /// The Pen with which to stroke the Geometry. /// This is optional, and can be null, in which case no stroke is performed. /// /// The Geometry to fill and/or stroke. public override void DrawGeometry( Brush brush, Pen pen, Geometry geometry) { if (_effectContext != null) { _effectContext.Context.DrawGeometry( brush, pen, geometry); } } ////// DrawImage - /// Draw an Image into the region specified by the Rect. /// The Image will potentially be stretched and distorted to fit the Rect. /// For more fine grained control, consider filling a Rect with an ImageBrush via /// DrawRectangle. /// /// The ImageSource to draw. /// /// The Rect into which the ImageSource will be fit. /// public override void DrawImage( ImageSource imageSource, Rect rectangle) { if (_effectContext != null) { _effectContext.Context.DrawImage( imageSource, rectangle); } } ////// DrawImage - /// Draw an Image into the region specified by the Rect. /// The Image will potentially be stretched and distorted to fit the Rect. /// For more fine grained control, consider filling a Rect with an ImageBrush via /// DrawRectangle. /// /// The ImageSource to draw. /// /// The Rect into which the ImageSource will be fit. /// /// Optional AnimationClock for rectangle. public override void DrawImage( ImageSource imageSource, Rect rectangle, AnimationClock rectangleAnimations) { if (_effectContext != null) { _effectContext.Context.DrawImage( imageSource, rectangle, rectangleAnimations); } } ////// DrawGlyphRun - /// Draw a GlyphRun /// /// /// Foreground brush to draw the GlyphRun with. /// /// The GlyphRun to draw. public override void DrawGlyphRun( Brush foregroundBrush, GlyphRun glyphRun) { if (_effectContext != null) { _effectContext.Context.DrawGlyphRun( foregroundBrush, glyphRun); } } ////// DrawDrawing - /// Draw a Drawing by appending a sub-Drawing to the current Drawing. /// /// The drawing to draw. public override void DrawDrawing( Drawing drawing) { if (_effectContext != null) { _effectContext.Context.DrawDrawing(drawing); } } ////// DrawVideo - /// Draw a Video into the region specified by the Rect. /// The Video will potentially be stretched and distorted to fit the Rect. /// For more fine grained control, consider filling a Rect with an VideoBrush via /// DrawRectangle. /// /// The MediaPlayer to draw. /// /// The Rect into which the MediaClock will be fit. /// public override void DrawVideo( MediaPlayer player, Rect rectangle) { if (_effectContext != null) { _effectContext.Context.DrawVideo( player, rectangle); } } ////// DrawVideo - /// Draw a Video into the region specified by the Rect. /// The Video will potentially be stretched and distorted to fit the Rect. /// For more fine grained control, consider filling a Rect with an VideoBrush via /// DrawRectangle. /// /// The MediaPlayer to draw. /// /// The Rect into which the MediaClock will be fit. /// /// Optional AnimationClock for rectangle. public override void DrawVideo( MediaPlayer player, Rect rectangle, AnimationClock rectangleAnimations) { if (_effectContext != null) { _effectContext.Context.DrawVideo( player, rectangle, rectangleAnimations); } } ////// DrawScene3D - /// Draw a Scene3D (internal object encapsulating a 3D scene) /// /// The Scene3D to draw. internal override void DrawScene3D( Scene3D scene3D) { if (_effectContext != null) { _effectContext.Context.DrawScene3D(scene3D); } } ////// PushGuidelineSet - /// Push a set of guidelines which will apply to all drawing operations until the /// corresponding Pop. /// /// The GuidelineSet to push. public override void PushGuidelineSet( GuidelineSet guidelines) { if (_effectContext != null) { _effectContext.Context.PushGuidelineSet(guidelines); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.GuidelineSet); } /// /// PushGuidelineY1 - /// Explicitly push one horizontal guideline. /// /// The coordinate of leading guideline. internal override void PushGuidelineY1( Double coordinate) { if (_effectContext != null) { _effectContext.Context.PushGuidelineY1(coordinate); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.GuidelineY1); } /// /// PushGuidelineY2 - /// Explicitly push a pair of horizontal guidelines. /// /// /// The coordinate of leading guideline. /// /// /// The offset from leading guideline to driven guideline. /// internal override void PushGuidelineY2( Double leadingCoordinate, Double offsetToDrivenCoordinate) { if (_effectContext != null) { _effectContext.Context.PushGuidelineY2(leadingCoordinate, offsetToDrivenCoordinate); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.GuidelineY2); } /// /// Push an opacity mask /// /// /// The opacity mask /// public override void PushOpacityMask(Brush brush) { if (_effectContext != null) { _effectContext.Context.PushOpacityMask(brush); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.OpacityMask); } /// /// PushClip - /// Push a clip region, which will apply to all drawing primitives until the /// corresponding Pop call. /// /// The Geometry to which we will clip. public override void PushClip( Geometry clipGeometry) { if (_effectContext != null) { _effectContext.Context.PushClip(clipGeometry); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.Clip); } /// /// PushOpacity - /// Push an opacity which will blend the composite of all drawing primitives added /// until the corresponding Pop call. /// /// /// The opacity with which to blend - 0 is transparent, 1 is opaque. /// public override void PushOpacity( Double opacity) { if (_effectContext != null) { _effectContext.Context.PushOpacity(opacity); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.Opacity); } /// /// PushOpacity - /// Push an opacity which will blend the composite of all drawing primitives added /// until the corresponding Pop call. /// /// /// The opacity with which to blend - 0 is transparent, 1 is opaque. /// /// Optional AnimationClock for opacity. public override void PushOpacity( Double opacity, AnimationClock opacityAnimations) { if (_effectContext != null) { _effectContext.Context.PushOpacity( opacity, opacityAnimations); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.Opacity); } /// /// PushTransform - /// Push a Transform which will apply to all drawing operations until the corresponding /// Pop. /// /// The Transform to push. public override void PushTransform( Transform transform) { if (_effectContext != null) { _effectContext.Context.PushTransform(transform); } // Ensure the transform stack if (_transformStack == null) { _transformStack = new Stack(2); } // Push the old transform. _transformStack.Push(_transform); // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack (2); } // Push the transform type _pushTypeStack.Push(PushType.Transform); Matrix newValue = Matrix.Identity; // Retrieve the new transform as a matrix if it exists if ((transform != null) && !transform.IsIdentity) { // If the transform is degeneraate, we can skip all instructions until the // corresponding Pop. newValue = transform.Value; } // Update the current transform _transform = newValue * _transform; } /// /// PushEffect - /// Push a BitmapEffect which will apply to all drawing operations until the /// corresponding Pop. /// /// The BitmapEffect to push. /// The BitmapEffectInput. public override void PushEffect( BitmapEffect effect, BitmapEffectInput effectInput) { // create new context if (_effectContext == null) { _effectContext = new BitmapEffectDrawingContextState(effect, effectInput); } else { _effectContext.Context.PushEffect(effect, effectInput); } // Ensure the type stack if (_pushTypeStack == null) { _pushTypeStack = new Stack(2); } _pushTypeStack.Push(PushType.BitmapEffect); _effectStackDepth++; } /// /// Pop /// public override void Pop( ) { // We must have a type stack and it must not be empty. Debug.Assert(_pushTypeStack != null); Debug.Assert(_pushTypeStack.Count > 0); // Retrieve the PushType to figure out what what this Pop is. PushType pushType = _pushTypeStack.Pop(); switch (pushType) { case PushType.Transform: // We must have a Transform stack and it must not be empty. Debug.Assert(_transformStack != null); Debug.Assert(_transformStack.Count > 0); // Restore the transform _transform = _transformStack.Pop(); break; case PushType.BitmapEffect: Debug.Assert(_effectStackDepth > 0, "We should have pushed an effect first"); Debug.Assert(_effectContext != null, "We should have created a context"); _effectStackDepth--; // render only if it is a toplevel effect if (_effectStackDepth == 0) { _effectContext.Context.Close(); Matrix worldTransform = _transform; BitmapSource effectImage = _effectContext.RenderBitmapEffect(ref worldTransform, _windowClip); ImageDrawing drawing = new ImageDrawing(); if (effectImage != null) { drawing.ImageSource = effectImage; drawing.Rect = new Rect(0, 0, effectImage.Width, effectImage.Height); } DrawingGroup group = new DrawingGroup(); group.Children.Add(drawing); group.Transform = new MatrixTransform(worldTransform); BitmapEffectDrawing.Drawings.Add(group); BitmapEffectDrawing.WorldTransforms.Add(new MatrixTransform(_transform)); _effectContext = null; } break; default: // Ignore the rest break; } if (_effectContext != null) { _effectContext.Context.Pop(); } } internal BitmapEffectDrawing BitmapEffectDrawing { get { if (_bitmapEffectDrawing == null) { _bitmapEffectDrawing = new BitmapEffectDrawing(); } return _bitmapEffectDrawing; } } #region Private Fields private BitmapEffectDrawing _bitmapEffectDrawing; // The current local->world Transform as a matrix. private Matrix _transform; private Rect _windowClip = Rect.Empty; // The Type stack for our Push/Pop calls. This tells whether a given Pop corresponds // to a Transform, Clip, etc. private Stack_pushTypeStack; // This stack contains the Matrices encountered during our walk. // The current transform is stored in _transform and not in the Stack. private Stack _transformStack; // this contains the effect drawing context private BitmapEffectDrawingContextState _effectContext; private long _effectStackDepth; #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
- CacheOutputQuery.cs
- RemoteDebugger.cs
- ThicknessAnimationUsingKeyFrames.cs
- TransactedBatchContext.cs
- DocumentGrid.cs
- SamlSecurityTokenAuthenticator.cs
- SettingsPropertyIsReadOnlyException.cs
- InertiaRotationBehavior.cs
- XmlSchemaComplexContentExtension.cs
- XmlSerializationReader.cs
- FixedPageAutomationPeer.cs
- IPEndPoint.cs
- ElementHostAutomationPeer.cs
- SecurityContext.cs
- FilePrompt.cs
- TimelineClockCollection.cs
- CorePropertiesFilter.cs
- CodeChecksumPragma.cs
- DecimalAnimation.cs
- ContextMenuAutomationPeer.cs
- SizeF.cs
- XmlSchemaInclude.cs
- ExtractorMetadata.cs
- GridViewAutomationPeer.cs
- CodeExporter.cs
- CqlLexerHelpers.cs
- ListManagerBindingsCollection.cs
- Italic.cs
- ControlBindingsConverter.cs
- TextDecorationLocationValidation.cs
- TabControlCancelEvent.cs
- CodeDirectiveCollection.cs
- QueryExpr.cs
- AnonymousIdentificationSection.cs
- _BaseOverlappedAsyncResult.cs
- ImportStoreException.cs
- CompareInfo.cs
- UrlPath.cs
- SafeLibraryHandle.cs
- ToolStripContainerActionList.cs
- SchemaImporter.cs
- SmtpTransport.cs
- ResourceAssociationTypeEnd.cs
- SqlClientPermission.cs
- Mutex.cs
- ScaleTransform3D.cs
- FixedSOMTableRow.cs
- KnownColorTable.cs
- TargetParameterCountException.cs
- TextEditorDragDrop.cs
- GeneralTransform3DCollection.cs
- TableHeaderCell.cs
- SimpleMailWebEventProvider.cs
- WebPartsPersonalization.cs
- AlphabetConverter.cs
- TextContainer.cs
- InvokeCompletedEventArgs.cs
- FontClient.cs
- CommandLineParser.cs
- Compiler.cs
- NavigationProperty.cs
- PenContext.cs
- ObjectDisposedException.cs
- SpecialNameAttribute.cs
- OdbcParameter.cs
- DocumentGridPage.cs
- PersonalizationState.cs
- OperationResponse.cs
- BufferedWebEventProvider.cs
- RepeaterItemEventArgs.cs
- XmlDesigner.cs
- RegexWorker.cs
- AppLevelCompilationSectionCache.cs
- WindowsRebar.cs
- RegistrySecurity.cs
- XmlIterators.cs
- WSHttpSecurity.cs
- ButtonChrome.cs
- WebConfigurationHost.cs
- ContravarianceAdapter.cs
- updateconfighost.cs
- MILUtilities.cs
- BrowserCapabilitiesFactoryBase.cs
- DllNotFoundException.cs
- RoutedUICommand.cs
- BitSet.cs
- FontUnitConverter.cs
- ToolStripSeparatorRenderEventArgs.cs
- smtppermission.cs
- ProcessThreadCollection.cs
- DataGridViewBand.cs
- FakeModelItemImpl.cs
- SmiGettersStream.cs
- Translator.cs
- LineMetrics.cs
- ToolBarButtonClickEvent.cs
- SimpleHandlerFactory.cs
- ScopedKnownTypes.cs
- Command.cs
- XmlProcessingInstruction.cs