Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / Media / RealizationDrawingContextWalker.cs / 1 / RealizationDrawingContextWalker.cs
//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: RealizationDrawingContextWalker.cs // // Description: // This file contains the implementation of RealizationDrawingContextWalker. // This DrawingContextWalker is used to perform realization updates on // render data. // //----------------------------------------------------------------------------- namespace System.Windows.Media { using MS.Internal; 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; ////// RealizationDrawingContextWalker - a DrawingContextWalker which will /// update realizations of the contents of the render data. /// internal class RealizationDrawingContextWalker : DrawingContextWalker { //--------------------------------------------------------------------- // // Internal Constructors // //--------------------------------------------------------------------- #region Internal Constructors ////// Constructor for BoundsDrawingContextWalker /// /// The render context. internal RealizationDrawingContextWalker(RealizationContext ctx) { Debug.Assert(ctx != null); _ctx = ctx; _operationTypeStack = new Stack(2); _opacityMaskBoundsStack = new Stack (2); _opacityMaskBrushStack = new Stack (2); _opacityMaskMatrixStack = new MatrixStack(); _opacityMaskRect = Rect.Empty; _opacityMaskAccumulate = 0; } #endregion Internal Constructors //---------------------------------------------------------------------- // // Public Methods // //--------------------------------------------------------------------- #region Public Methods /// /// 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) { // Ignore the clip value. _operationTypeStack.Push(OperationType.Clip); } ////// Push an opacity mask /// /// /// The opacity mask /// public override void PushOpacityMask(Brush brush) { _operationTypeStack.Push(OperationType.OpacityMask); _opacityMaskBoundsStack.Push(_opacityMaskRect); _opacityMaskRect = Rect.Empty; _opacityMaskAccumulate++; _opacityMaskBrushStack.Push(brush); _opacityMaskMatrixStack.Push(Transform.Identity, /* combine */ false); } private void PopOpacityMask() { Debug.Assert(_opacityMaskBoundsStack.Count > 0); Debug.Assert(_opacityMaskBrushStack.Count > 0); Brush brush = _opacityMaskBrushStack.Pop(); if (brush != null) { brush.UpdateRealizations(_opacityMaskRect, _ctx); } _opacityMaskRect = Rect.Union(_opacityMaskRect, _opacityMaskBoundsStack.Pop()); _opacityMaskAccumulate--; } private void TransformAndUnionOpacityMaskBounds(Rect bounds) { Rect r = Rect.Transform(bounds, _opacityMaskMatrixStack.Peek()); _opacityMaskRect.Union(r); return; } ////// 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) { // Ignore the opacity value. _operationTypeStack.Push(OperationType.Opacity); } ////// Push a Transform which will apply to all drawing operations /// until the corresponding Pop. /// /// The Transform to push. public override void PushTransform(Transform transform) { // Retrieve the new transform as a matrix if it exists. if (transform != null && !transform.IsIdentity) { // Push the operation type. _operationTypeStack.Push(OperationType.Transform); // Push the valid transform on the stack. _ctx.TransformStack.Push(transform, /* combine */ true); _opacityMaskMatrixStack.Push(transform, /* combine */ true); } else { // Do not store identity (or null) transforms on the transform stack. _operationTypeStack.Push(OperationType.InvalidOrIrrelevantTransform); } } ////// 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) { _operationTypeStack.Push(OperationType.BitmapEffect); pushedEffects++; } ////// PushGuidelineSet - /// Push a set of guidelines which should be applied /// to all drawing operations until the /// corresponding Pop. /// /// The GuidelineSet to push. public override void PushGuidelineSet( GuidelineSet guidelines) { // Ignore the guidelines value. _operationTypeStack.Push(OperationType.Guidelines); } ////// PushGuidelineY1 - /// Explicitly push one horizontal guideline. /// /// The coordinate of leading guideline. internal override void PushGuidelineY1( Double coordinate) { // Ignore the guidelines values. _operationTypeStack.Push(OperationType.Guidelines); } ////// 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) { // Ignore the guidelines values. _operationTypeStack.Push(OperationType.Guidelines); } ////// Pops a transform/clip/opacity change from the stack. /// public override void Pop() { // We must have a type stack and it must not be empty. Debug.Assert(_operationTypeStack != null); Debug.Assert(_operationTypeStack.Count > 0); // Retrieve the OperationType to figure out what what this Pop is. OperationType operationType = _operationTypeStack.Pop(); switch (operationType) { case OperationType.Transform: // Restore the previous transform _ctx.TransformStack.Pop(); _opacityMaskMatrixStack.Pop(); break; case OperationType.BitmapEffect: pushedEffects--; break; case OperationType.OpacityMask: PopOpacityMask(); break; default: // Do nothing for the 'not stored' operation types Debug.Assert(operationType == OperationType.Clip || operationType == OperationType.Opacity || operationType == OperationType.Guidelines || operationType == OperationType.InvalidOrIrrelevantTransform || operationType == OperationType.BitmapEffect); break; } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (pen != null) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, null); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; if ( requiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect fillBounds = Rect.Empty; // This is the union of the geometry and the stroke. Rect strokeBounds = LineGeometry.GetBoundsHelper( pen, Matrix.Identity, // world transform point0, point1, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(strokeBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (pen != null || brush != null) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, brush); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; if (requiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect fillBounds = Rect.Empty; Rect strokeBounds = Rect.Empty; if (brush != null) { fillBounds = RectangleGeometry.GetBoundsHelper( null, Matrix.Identity, // world transform rectangle, 0, 0, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (pen != null) { // This is the union of the geometry and the stroke. strokeBounds = RectangleGeometry.GetBoundsHelper( pen, Matrix.Identity, // world transform rectangle, 0, 0, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(pen != null ? strokeBounds : fillBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (!rectangle.IsEmpty && (pen != null || brush != null)) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, brush); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; if (requiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect fillBounds = Rect.Empty; Rect strokeBounds = Rect.Empty; if (brush != null) { fillBounds = RectangleGeometry.GetBoundsHelper( null, Matrix.Identity, // world transform rectangle, radiusX, radiusY, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (pen != null) { // This is the union of the geometry and the stroke. strokeBounds = RectangleGeometry.GetBoundsHelper( pen, Matrix.Identity, // world transform rectangle, radiusX, radiusY, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(pen != null ? strokeBounds : fillBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (pen != null || brush != null) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, brush); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; Rect fillBounds = Rect.Empty; Rect strokeBounds = Rect.Empty; if (requiresRealizationUpdates || _opacityMaskAccumulate > 0) { if (brush != null) { fillBounds = EllipseGeometry.GetBoundsHelper( null, Matrix.Identity, // world transform center, radiusX, radiusY, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (pen != null) { // This is the union of the geometry and the stroke. strokeBounds = EllipseGeometry.GetBoundsHelper( pen, Matrix.Identity, // world transform center, radiusX, radiusY, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(pen != null ? strokeBounds : fillBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (geometry != null && (pen != null || brush != null)) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, brush); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; if (requiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect fillBounds = Rect.Empty; Rect strokeBounds = Rect.Empty; if (brush != null) { fillBounds = geometry.GetBoundsInternal(null, Matrix.Identity); } if (pen != null) { // This is the union of the geometry and the stroke. strokeBounds = geometry.GetBoundsInternal(pen, Matrix.Identity); } if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(pen != null ? strokeBounds : fillBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } DrawingImage di = imageSource as DrawingImage; if (di != null && di.Drawing != null) { Drawing drawing = di.Drawing; if (drawing.RequiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect drawingBounds = drawing.Bounds; if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(drawingBounds); } if (drawing.RequiresRealizationUpdates && !DoubleUtil.AreClose(drawingBounds.Width, 0) && !DoubleUtil.AreClose(drawingBounds.Height, 0)) { Matrix scale = Matrix.CreateScaling( rectangle.Width / drawingBounds.Width, rectangle.Height / drawingBounds.Height); _ctx.TransformStack.Push(ref scale, true); // Update realizations inside the drawing graph. drawing.UpdateRealizations(_ctx); _ctx.TransformStack.Pop(); } } } } ////// 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 MediaPlayer will be fit. /// public override void DrawVideo( MediaPlayer video, Rect rectangle) { // Do nothing. } ////// Draw a GlyphRun. /// /// Foreground brush to draw GlyphRun with. /// The GlyphRun to draw. public override void DrawGlyphRun(Brush foregroundBrush, GlyphRun glyphRun) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (glyphRun != null && foregroundBrush != null) { RealizationBrushHelper helper = new RealizationBrushHelper(null, foregroundBrush); if (helper.NeedsRealizationUpdates || _opacityMaskAccumulate > 0) { Rect strokeBounds = Rect.Empty; Rect fillBounds = glyphRun.ComputeInkBoundingBox(); if (!fillBounds.IsEmpty) { Point baselineOrigin = glyphRun.BaselineOrigin; fillBounds.X += baselineOrigin.X; fillBounds.Y += baselineOrigin.Y; if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(fillBounds); } if (helper.NeedsRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } } ////// DrawDrawing is being overriden here to invoke the spezialized realization walk /// on Drawings. /// public override void DrawDrawing(Drawing drawing) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (drawing != null) { drawing.UpdateRealizations(_ctx); } } #endregion Public Methods internal RealizationContext Context { get { return _ctx; } } //---------------------------------------------------------------------- // // Private Fields // //---------------------------------------------------------------------- #region Private Fields // The current realization context. private readonly RealizationContext _ctx; // The Type stack for our Push/Pop calls. This tells whether a given // Pop corresponds to a Transform, Clip, etc. private readonly Stack_operationTypeStack; private Stack _opacityMaskBoundsStack; private int _opacityMaskAccumulate; private Rect _opacityMaskRect; private Stack _opacityMaskBrushStack; private MatrixStack _opacityMaskMatrixStack; int pushedEffects; #endregion Private Fields //--------------------------------------------------------------------- // // Private Types // //---------------------------------------------------------------------- #region Private Types /// /// OperationType enum - this defines the type of Pushes in a context, /// so that our untyped Pops know what to Pop. /// private enum OperationType { Transform, InvalidOrIrrelevantTransform, Clip, Opacity, OpacityMask, Guidelines, BitmapEffect } #endregion Private Types } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: RealizationDrawingContextWalker.cs // // Description: // This file contains the implementation of RealizationDrawingContextWalker. // This DrawingContextWalker is used to perform realization updates on // render data. // //----------------------------------------------------------------------------- namespace System.Windows.Media { using MS.Internal; 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; ////// RealizationDrawingContextWalker - a DrawingContextWalker which will /// update realizations of the contents of the render data. /// internal class RealizationDrawingContextWalker : DrawingContextWalker { //--------------------------------------------------------------------- // // Internal Constructors // //--------------------------------------------------------------------- #region Internal Constructors ////// Constructor for BoundsDrawingContextWalker /// /// The render context. internal RealizationDrawingContextWalker(RealizationContext ctx) { Debug.Assert(ctx != null); _ctx = ctx; _operationTypeStack = new Stack(2); _opacityMaskBoundsStack = new Stack (2); _opacityMaskBrushStack = new Stack (2); _opacityMaskMatrixStack = new MatrixStack(); _opacityMaskRect = Rect.Empty; _opacityMaskAccumulate = 0; } #endregion Internal Constructors //---------------------------------------------------------------------- // // Public Methods // //--------------------------------------------------------------------- #region Public Methods /// /// 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) { // Ignore the clip value. _operationTypeStack.Push(OperationType.Clip); } ////// Push an opacity mask /// /// /// The opacity mask /// public override void PushOpacityMask(Brush brush) { _operationTypeStack.Push(OperationType.OpacityMask); _opacityMaskBoundsStack.Push(_opacityMaskRect); _opacityMaskRect = Rect.Empty; _opacityMaskAccumulate++; _opacityMaskBrushStack.Push(brush); _opacityMaskMatrixStack.Push(Transform.Identity, /* combine */ false); } private void PopOpacityMask() { Debug.Assert(_opacityMaskBoundsStack.Count > 0); Debug.Assert(_opacityMaskBrushStack.Count > 0); Brush brush = _opacityMaskBrushStack.Pop(); if (brush != null) { brush.UpdateRealizations(_opacityMaskRect, _ctx); } _opacityMaskRect = Rect.Union(_opacityMaskRect, _opacityMaskBoundsStack.Pop()); _opacityMaskAccumulate--; } private void TransformAndUnionOpacityMaskBounds(Rect bounds) { Rect r = Rect.Transform(bounds, _opacityMaskMatrixStack.Peek()); _opacityMaskRect.Union(r); return; } ////// 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) { // Ignore the opacity value. _operationTypeStack.Push(OperationType.Opacity); } ////// Push a Transform which will apply to all drawing operations /// until the corresponding Pop. /// /// The Transform to push. public override void PushTransform(Transform transform) { // Retrieve the new transform as a matrix if it exists. if (transform != null && !transform.IsIdentity) { // Push the operation type. _operationTypeStack.Push(OperationType.Transform); // Push the valid transform on the stack. _ctx.TransformStack.Push(transform, /* combine */ true); _opacityMaskMatrixStack.Push(transform, /* combine */ true); } else { // Do not store identity (or null) transforms on the transform stack. _operationTypeStack.Push(OperationType.InvalidOrIrrelevantTransform); } } ////// 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) { _operationTypeStack.Push(OperationType.BitmapEffect); pushedEffects++; } ////// PushGuidelineSet - /// Push a set of guidelines which should be applied /// to all drawing operations until the /// corresponding Pop. /// /// The GuidelineSet to push. public override void PushGuidelineSet( GuidelineSet guidelines) { // Ignore the guidelines value. _operationTypeStack.Push(OperationType.Guidelines); } ////// PushGuidelineY1 - /// Explicitly push one horizontal guideline. /// /// The coordinate of leading guideline. internal override void PushGuidelineY1( Double coordinate) { // Ignore the guidelines values. _operationTypeStack.Push(OperationType.Guidelines); } ////// 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) { // Ignore the guidelines values. _operationTypeStack.Push(OperationType.Guidelines); } ////// Pops a transform/clip/opacity change from the stack. /// public override void Pop() { // We must have a type stack and it must not be empty. Debug.Assert(_operationTypeStack != null); Debug.Assert(_operationTypeStack.Count > 0); // Retrieve the OperationType to figure out what what this Pop is. OperationType operationType = _operationTypeStack.Pop(); switch (operationType) { case OperationType.Transform: // Restore the previous transform _ctx.TransformStack.Pop(); _opacityMaskMatrixStack.Pop(); break; case OperationType.BitmapEffect: pushedEffects--; break; case OperationType.OpacityMask: PopOpacityMask(); break; default: // Do nothing for the 'not stored' operation types Debug.Assert(operationType == OperationType.Clip || operationType == OperationType.Opacity || operationType == OperationType.Guidelines || operationType == OperationType.InvalidOrIrrelevantTransform || operationType == OperationType.BitmapEffect); break; } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (pen != null) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, null); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; if ( requiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect fillBounds = Rect.Empty; // This is the union of the geometry and the stroke. Rect strokeBounds = LineGeometry.GetBoundsHelper( pen, Matrix.Identity, // world transform point0, point1, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(strokeBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (pen != null || brush != null) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, brush); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; if (requiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect fillBounds = Rect.Empty; Rect strokeBounds = Rect.Empty; if (brush != null) { fillBounds = RectangleGeometry.GetBoundsHelper( null, Matrix.Identity, // world transform rectangle, 0, 0, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (pen != null) { // This is the union of the geometry and the stroke. strokeBounds = RectangleGeometry.GetBoundsHelper( pen, Matrix.Identity, // world transform rectangle, 0, 0, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(pen != null ? strokeBounds : fillBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (!rectangle.IsEmpty && (pen != null || brush != null)) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, brush); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; if (requiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect fillBounds = Rect.Empty; Rect strokeBounds = Rect.Empty; if (brush != null) { fillBounds = RectangleGeometry.GetBoundsHelper( null, Matrix.Identity, // world transform rectangle, radiusX, radiusY, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (pen != null) { // This is the union of the geometry and the stroke. strokeBounds = RectangleGeometry.GetBoundsHelper( pen, Matrix.Identity, // world transform rectangle, radiusX, radiusY, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(pen != null ? strokeBounds : fillBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (pen != null || brush != null) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, brush); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; Rect fillBounds = Rect.Empty; Rect strokeBounds = Rect.Empty; if (requiresRealizationUpdates || _opacityMaskAccumulate > 0) { if (brush != null) { fillBounds = EllipseGeometry.GetBoundsHelper( null, Matrix.Identity, // world transform center, radiusX, radiusY, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (pen != null) { // This is the union of the geometry and the stroke. strokeBounds = EllipseGeometry.GetBoundsHelper( pen, Matrix.Identity, // world transform center, radiusX, radiusY, Matrix.Identity, // geometry transform Geometry.StandardFlatteningTolerance, ToleranceType.Absolute ); } if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(pen != null ? strokeBounds : fillBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (geometry != null && (pen != null || brush != null)) { RealizationBrushHelper helper = new RealizationBrushHelper(pen, brush); bool requiresRealizationUpdates = helper.NeedsRealizationUpdates; if (requiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect fillBounds = Rect.Empty; Rect strokeBounds = Rect.Empty; if (brush != null) { fillBounds = geometry.GetBoundsInternal(null, Matrix.Identity); } if (pen != null) { // This is the union of the geometry and the stroke. strokeBounds = geometry.GetBoundsInternal(pen, Matrix.Identity); } if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(pen != null ? strokeBounds : fillBounds); } if (requiresRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } ////// 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) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } DrawingImage di = imageSource as DrawingImage; if (di != null && di.Drawing != null) { Drawing drawing = di.Drawing; if (drawing.RequiresRealizationUpdates || _opacityMaskAccumulate > 0) { Rect drawingBounds = drawing.Bounds; if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(drawingBounds); } if (drawing.RequiresRealizationUpdates && !DoubleUtil.AreClose(drawingBounds.Width, 0) && !DoubleUtil.AreClose(drawingBounds.Height, 0)) { Matrix scale = Matrix.CreateScaling( rectangle.Width / drawingBounds.Width, rectangle.Height / drawingBounds.Height); _ctx.TransformStack.Push(ref scale, true); // Update realizations inside the drawing graph. drawing.UpdateRealizations(_ctx); _ctx.TransformStack.Pop(); } } } } ////// 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 MediaPlayer will be fit. /// public override void DrawVideo( MediaPlayer video, Rect rectangle) { // Do nothing. } ////// Draw a GlyphRun. /// /// Foreground brush to draw GlyphRun with. /// The GlyphRun to draw. public override void DrawGlyphRun(Brush foregroundBrush, GlyphRun glyphRun) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (glyphRun != null && foregroundBrush != null) { RealizationBrushHelper helper = new RealizationBrushHelper(null, foregroundBrush); if (helper.NeedsRealizationUpdates || _opacityMaskAccumulate > 0) { Rect strokeBounds = Rect.Empty; Rect fillBounds = glyphRun.ComputeInkBoundingBox(); if (!fillBounds.IsEmpty) { Point baselineOrigin = glyphRun.BaselineOrigin; fillBounds.X += baselineOrigin.X; fillBounds.Y += baselineOrigin.Y; if (_opacityMaskAccumulate > 0) { TransformAndUnionOpacityMaskBounds(fillBounds); } if (helper.NeedsRealizationUpdates) { helper.UpdateRealizations(strokeBounds, fillBounds, _ctx); } } } } } ////// DrawDrawing is being overriden here to invoke the spezialized realization walk /// on Drawings. /// public override void DrawDrawing(Drawing drawing) { // skip realization updates if there is an effect on the stack // we will do this at a later time if (pushedEffects > 0) { return; } if (drawing != null) { drawing.UpdateRealizations(_ctx); } } #endregion Public Methods internal RealizationContext Context { get { return _ctx; } } //---------------------------------------------------------------------- // // Private Fields // //---------------------------------------------------------------------- #region Private Fields // The current realization context. private readonly RealizationContext _ctx; // The Type stack for our Push/Pop calls. This tells whether a given // Pop corresponds to a Transform, Clip, etc. private readonly Stack_operationTypeStack; private Stack _opacityMaskBoundsStack; private int _opacityMaskAccumulate; private Rect _opacityMaskRect; private Stack _opacityMaskBrushStack; private MatrixStack _opacityMaskMatrixStack; int pushedEffects; #endregion Private Fields //--------------------------------------------------------------------- // // Private Types // //---------------------------------------------------------------------- #region Private Types /// /// OperationType enum - this defines the type of Pushes in a context, /// so that our untyped Pops know what to Pop. /// private enum OperationType { Transform, InvalidOrIrrelevantTransform, Clip, Opacity, OpacityMask, Guidelines, BitmapEffect } #endregion Private Types } } // 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
- TextBreakpoint.cs
- MappingException.cs
- DependencyPropertyHelper.cs
- DetailsViewInsertEventArgs.cs
- MetadataAssemblyHelper.cs
- RequestCacheManager.cs
- AlgoModule.cs
- PerformanceCounters.cs
- HttpRequest.cs
- JumpItem.cs
- FeatureAttribute.cs
- HostExecutionContextManager.cs
- CancellationHandler.cs
- GeometryGroup.cs
- UIElement3D.cs
- WindowsScrollBarBits.cs
- RemotingConfiguration.cs
- ByteStreamGeometryContext.cs
- MessageSecurityTokenVersion.cs
- ObjectDataSourceDisposingEventArgs.cs
- BitHelper.cs
- WebPartMovingEventArgs.cs
- EntityWithKeyStrategy.cs
- TextBox.cs
- SelectorItemAutomationPeer.cs
- RuntimeWrappedException.cs
- TreeNodeSelectionProcessor.cs
- WebPartDescriptionCollection.cs
- PopOutPanel.cs
- indexingfiltermarshaler.cs
- LongPath.cs
- ProtocolViolationException.cs
- Trace.cs
- SplineQuaternionKeyFrame.cs
- _Semaphore.cs
- TextProperties.cs
- EmbeddedObject.cs
- XmlQueryRuntime.cs
- XmlDocumentType.cs
- AddingNewEventArgs.cs
- ComplexBindingPropertiesAttribute.cs
- InvalidateEvent.cs
- CodeSnippetCompileUnit.cs
- NavigationPropertyEmitter.cs
- MouseCaptureWithinProperty.cs
- PageHandlerFactory.cs
- ServicePointManagerElement.cs
- XmlCountingReader.cs
- MailWriter.cs
- Evaluator.cs
- NativeMethods.cs
- CellParagraph.cs
- GraphicsState.cs
- FullTextBreakpoint.cs
- EventLogPermissionEntryCollection.cs
- RectangleHotSpot.cs
- NonParentingControl.cs
- WebPartHelpVerb.cs
- Container.cs
- QuadTree.cs
- RawStylusSystemGestureInputReport.cs
- XsltSettings.cs
- SortableBindingList.cs
- FloatUtil.cs
- JavaScriptSerializer.cs
- NotifyCollectionChangedEventArgs.cs
- FrameworkElement.cs
- keycontainerpermission.cs
- _HTTPDateParse.cs
- ForceCopyBuildProvider.cs
- KernelTypeValidation.cs
- PropertyEntry.cs
- DataGridCellItemAutomationPeer.cs
- ConfigurationSectionGroupCollection.cs
- RectAnimationBase.cs
- WindowsContainer.cs
- ZipFileInfoCollection.cs
- Encoder.cs
- LocatorPart.cs
- RadioButton.cs
- IndicFontClient.cs
- IntellisenseTextBox.cs
- CqlBlock.cs
- SimpleTextLine.cs
- DataGridViewMethods.cs
- CurrencyWrapper.cs
- NavigationEventArgs.cs
- FontSourceCollection.cs
- NonSerializedAttribute.cs
- TimeoutValidationAttribute.cs
- GroupItem.cs
- TextFormatter.cs
- DoubleCollection.cs
- CodeTypeMember.cs
- CommandSet.cs
- AbandonedMutexException.cs
- Funcletizer.cs
- TextBox.cs
- CustomPopupPlacement.cs
- Form.cs