DrawingVisual.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Media / DrawingVisual.cs / 1 / DrawingVisual.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2001
//
//  File:       DrawingVisual.cs 
//-----------------------------------------------------------------------------
 
using System; 
using System.Windows.Threading;
 
using System.Windows.Media;
using System.Windows.Media.Composition;
using System.Diagnostics;
using System.Collections.Generic; 
using MS.Internal;
using MS.Win32; 
using System.Resources; 
using System.Runtime.InteropServices;
 
namespace System.Windows.Media
{
    /// 
    /// A DrawingVisual is a Visual that can be used to render Vector graphics on the screen. 
    /// The content is persistet by the System.
    ///  
    public class DrawingVisual : ContainerVisual 
    {
        // bbox in inner coordinate space. Note that this bbox does not 
        // contain the childrens extent.
        IDrawingContent _content;

        ///  
        /// HitTestCore implements precise hit testing against render contents
        ///  
        protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) 
        {
            if (hitTestParameters == null) 
            {
                throw new ArgumentNullException("hitTestParameters");
            }
 
            if (_content != null)
            { 
                if (_content.HitTestPoint(hitTestParameters.HitPoint)) 
                {
                    return new PointHitTestResult(this, hitTestParameters.HitPoint); 
                }
            }

            return null; 
        }
 
        ///  
        /// HitTestCore implements precise hit testing against render contents
        ///  
        protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters)
        {
            if (hitTestParameters == null)
            { 
                throw new ArgumentNullException("hitTestParameters");
            } 
 
            if ((_content != null) && GetHitTestBounds().IntersectsWith(hitTestParameters.Bounds))
            { 
                IntersectionDetail intersectionDetail;

                intersectionDetail = _content.HitTestGeometry(hitTestParameters.InternalHitGeometry);
                Debug.Assert(intersectionDetail != IntersectionDetail.NotCalculated); 

                if (intersectionDetail != IntersectionDetail.Empty) 
                { 
                    return new GeometryHitTestResult(this, intersectionDetail);
                } 

            }

            return null; 
        }
 
 
        /// 
        /// Opens the DrawingVisual for rendering. The returned DrawingContext can be used to 
        /// render into the DrawingVisual.
        /// 
        public DrawingContext RenderOpen()
        { 
            VerifyAPIReadWrite();
 
            return new VisualDrawingContext(this); 
        }
 
        /// 
        /// Called from the DrawingContext when the DrawingContext is closed.
        /// 
        internal override void RenderClose(IDrawingContent newContent) 
        {
            IDrawingContent oldContent; 
            VisualFlags mask = VisualFlags.IsSubtreeDirtyForPrecompute | VisualFlags.NodeNeedsBitmapEffectUpdate; 

            // 
            // First cleanup the old content and the state associate with this node
            // related to it's content.
            //
 
            oldContent = _content;
            _content = null; 
 
            if (oldContent != null)
            { 
                //
                // Remove the notification handlers.
                //
 
                oldContent.PropagateChangedHandler(ContentsChangedHandler, false /* remove */);
 
 
                //
                // Disconnect the old content from this visual. 
                //

                DisconnectAttachedResource(
                    VisualProxyFlags.IsContentConnected, 
                    ((DUCE.IResource)oldContent));
            } 
 

            // 
            // Prepare the new content.
            //

            if (newContent != null) 
            {
                // Propagate notification handlers. 
                newContent.PropagateChangedHandler(ContentsChangedHandler, true /* adding */); 

                // Might need a new realization if this content contains text. 
                SetFlags(true, VisualFlags.NodeRequiresNewRealization);
                mask |= VisualFlags.NodeInSubtreeRequiresNewRealization;

            } 

            _content = newContent; 
 

            // 
            // Mark the visual dirty on all channels and propagate
            // the flags up the parent chain.
            //
 
            SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty);
 
            PropagateFlags( 
                this,
                mask, 
                VisualProxyFlags.IsSubtreeDirtyForRender);

        }
 
        /// 
        /// Precomputes the render data content. 
        ///  
        internal override void PrecomputeContent()
        { 
            base.PrecomputeContent();

            if (_content != null)
            { 
                _content.PrecomputeContent();
                bool requiresRealizations = _content.ContentRequiresRealizationUpdates; 
                // Set the NodeUsesRealizationCaches flag for this content. 
                SetFlags(requiresRealizations, VisualFlags.NodeUsesRealizationCaches);
 
                SetFlags(_content.ContentIntroducesGraphness, VisualFlags.NodeOrDescendantIntroducesGraphness);
            }
        }
 

        ///  
        /// Overriding this function to release DUCE resources during Dispose and during removal of a subtree. 
        /// 
        internal override void FreeContent(DUCE.Channel channel) 
        {
            Debug.Assert(_proxy.IsOnChannel(channel));

            if (_content != null) 
            {
                if (CheckFlagsAnd(channel, VisualProxyFlags.IsContentConnected)) 
                { 
                    DUCE.CompositionNode.SetContent(
                        _proxy.GetHandle(channel), 
                        DUCE.ResourceHandle.Null,
                        channel);

                    SetFlags( 
                        channel,
                        false, 
                        VisualProxyFlags.IsContentConnected); 

                    ((DUCE.IResource)_content).ReleaseOnChannel(channel); 
                }
            }

            // Call the base method too 
            base.FreeContent(channel);
        } 
 
        /// 
        /// Returns the bounding box of the content. 
        /// 
        internal override Rect GetContentBounds()
        {
            if (_content != null) 
            {
                Rect resultRect = Rect.Empty; 
                MediaContext mediaContext = MediaContext.From(Dispatcher); 
                BoundsDrawingContextWalker ctx = mediaContext.AcquireBoundsDrawingContextWalker();
 
                resultRect = _content.GetContentBounds(ctx);
                mediaContext.ReleaseBoundsDrawingContextWalker(ctx);

                return resultRect; 
            }
            else 
            { 
                return Rect.Empty;
            } 
        }

        /// 
        /// WalkContent - method which walks the content (if present) and calls out to the 
        /// supplied DrawingContextWalker.
        ///  
        ///  
        ///   DrawingContextWalker - the target of the calls which occur during
        ///   the content walk. 
        /// 
        internal void WalkContent(DrawingContextWalker walker)
        {
            VerifyAPIReadOnly(); 

            if (_content != null) 
            { 
                _content.WalkContent(walker);
            } 
        }

        /// 
        /// RenderContent is implemented by derived classes to hook up their 
        /// content. The implementer of this function can assert that the _hCompNode
        /// is valid on a channel when the function is executed. 
        ///  
        internal override void RenderContent(RenderContext ctx, bool isOnChannel)
        { 
            DUCE.Channel channel = ctx.Channel;

            Debug.Assert(!CheckFlagsAnd(channel, VisualProxyFlags.IsContentConnected));
            Debug.Assert(_proxy.IsOnChannel(channel)); 

 
            // 
            // Create the content on the channel.
            // 

            if (_content != null)
            {
                DUCE.CompositionNode.SetContent( 
                    _proxy.GetHandle(channel),
                    ((DUCE.IResource)_content).AddRefOnChannel(channel), 
                    channel); 

                SetFlags( 
                    channel,
                    true,
                    VisualProxyFlags.IsContentConnected);
            } 
            else if (isOnChannel) /*_content == null*/
            { 
                DUCE.CompositionNode.SetContent( 
                    _proxy.GetHandle(channel),
                    DUCE.ResourceHandle.Null, 
                    channel);
            }
        }
 
        /// 
        /// Called by the base class to update realization caches. 
        /// Updates the realization cache on the content. 
        /// 
        internal override void UpdateRealizations(RealizationContext ctx) 
        {
            if (_content != null)
            {
                _content.UpdateRealizations(ctx); 
            }
        } 
 
        /// 
        /// GetDrawing - Returns the drawing content of this Visual. 
        /// 
        /// 
        /// Changes to this DrawingGroup will not be propagated to the Visual's content.
        /// This method is called by both the Drawing property, and VisualTreeHelper.GetDrawing() 
        /// 
        internal override DrawingGroup GetDrawing() 
        { 
            //
 

            VerifyAPIReadOnly();

            DrawingGroup drawingGroupContent = null; 

            // Convert our content to a DrawingGroup, if content exists 
            if (_content != null) 
            {
                drawingGroupContent = DrawingServices.DrawingGroupFromRenderData((RenderData) _content); 
            }

            return drawingGroupContent;
        } 

        ///  
        /// Drawing - Returns the drawing content of this Visual. 
        /// 
        ///  
        /// Changes to this DrawingGroup will not propagated to the Visual's content.
        /// 
        public DrawingGroup Drawing
        { 
            get
            { 
                return GetDrawing(); 
            }
        } 
    }
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2001
//
//  File:       DrawingVisual.cs 
//-----------------------------------------------------------------------------
 
using System; 
using System.Windows.Threading;
 
using System.Windows.Media;
using System.Windows.Media.Composition;
using System.Diagnostics;
using System.Collections.Generic; 
using MS.Internal;
using MS.Win32; 
using System.Resources; 
using System.Runtime.InteropServices;
 
namespace System.Windows.Media
{
    /// 
    /// A DrawingVisual is a Visual that can be used to render Vector graphics on the screen. 
    /// The content is persistet by the System.
    ///  
    public class DrawingVisual : ContainerVisual 
    {
        // bbox in inner coordinate space. Note that this bbox does not 
        // contain the childrens extent.
        IDrawingContent _content;

        ///  
        /// HitTestCore implements precise hit testing against render contents
        ///  
        protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) 
        {
            if (hitTestParameters == null) 
            {
                throw new ArgumentNullException("hitTestParameters");
            }
 
            if (_content != null)
            { 
                if (_content.HitTestPoint(hitTestParameters.HitPoint)) 
                {
                    return new PointHitTestResult(this, hitTestParameters.HitPoint); 
                }
            }

            return null; 
        }
 
        ///  
        /// HitTestCore implements precise hit testing against render contents
        ///  
        protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters)
        {
            if (hitTestParameters == null)
            { 
                throw new ArgumentNullException("hitTestParameters");
            } 
 
            if ((_content != null) && GetHitTestBounds().IntersectsWith(hitTestParameters.Bounds))
            { 
                IntersectionDetail intersectionDetail;

                intersectionDetail = _content.HitTestGeometry(hitTestParameters.InternalHitGeometry);
                Debug.Assert(intersectionDetail != IntersectionDetail.NotCalculated); 

                if (intersectionDetail != IntersectionDetail.Empty) 
                { 
                    return new GeometryHitTestResult(this, intersectionDetail);
                } 

            }

            return null; 
        }
 
 
        /// 
        /// Opens the DrawingVisual for rendering. The returned DrawingContext can be used to 
        /// render into the DrawingVisual.
        /// 
        public DrawingContext RenderOpen()
        { 
            VerifyAPIReadWrite();
 
            return new VisualDrawingContext(this); 
        }
 
        /// 
        /// Called from the DrawingContext when the DrawingContext is closed.
        /// 
        internal override void RenderClose(IDrawingContent newContent) 
        {
            IDrawingContent oldContent; 
            VisualFlags mask = VisualFlags.IsSubtreeDirtyForPrecompute | VisualFlags.NodeNeedsBitmapEffectUpdate; 

            // 
            // First cleanup the old content and the state associate with this node
            // related to it's content.
            //
 
            oldContent = _content;
            _content = null; 
 
            if (oldContent != null)
            { 
                //
                // Remove the notification handlers.
                //
 
                oldContent.PropagateChangedHandler(ContentsChangedHandler, false /* remove */);
 
 
                //
                // Disconnect the old content from this visual. 
                //

                DisconnectAttachedResource(
                    VisualProxyFlags.IsContentConnected, 
                    ((DUCE.IResource)oldContent));
            } 
 

            // 
            // Prepare the new content.
            //

            if (newContent != null) 
            {
                // Propagate notification handlers. 
                newContent.PropagateChangedHandler(ContentsChangedHandler, true /* adding */); 

                // Might need a new realization if this content contains text. 
                SetFlags(true, VisualFlags.NodeRequiresNewRealization);
                mask |= VisualFlags.NodeInSubtreeRequiresNewRealization;

            } 

            _content = newContent; 
 

            // 
            // Mark the visual dirty on all channels and propagate
            // the flags up the parent chain.
            //
 
            SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty);
 
            PropagateFlags( 
                this,
                mask, 
                VisualProxyFlags.IsSubtreeDirtyForRender);

        }
 
        /// 
        /// Precomputes the render data content. 
        ///  
        internal override void PrecomputeContent()
        { 
            base.PrecomputeContent();

            if (_content != null)
            { 
                _content.PrecomputeContent();
                bool requiresRealizations = _content.ContentRequiresRealizationUpdates; 
                // Set the NodeUsesRealizationCaches flag for this content. 
                SetFlags(requiresRealizations, VisualFlags.NodeUsesRealizationCaches);
 
                SetFlags(_content.ContentIntroducesGraphness, VisualFlags.NodeOrDescendantIntroducesGraphness);
            }
        }
 

        ///  
        /// Overriding this function to release DUCE resources during Dispose and during removal of a subtree. 
        /// 
        internal override void FreeContent(DUCE.Channel channel) 
        {
            Debug.Assert(_proxy.IsOnChannel(channel));

            if (_content != null) 
            {
                if (CheckFlagsAnd(channel, VisualProxyFlags.IsContentConnected)) 
                { 
                    DUCE.CompositionNode.SetContent(
                        _proxy.GetHandle(channel), 
                        DUCE.ResourceHandle.Null,
                        channel);

                    SetFlags( 
                        channel,
                        false, 
                        VisualProxyFlags.IsContentConnected); 

                    ((DUCE.IResource)_content).ReleaseOnChannel(channel); 
                }
            }

            // Call the base method too 
            base.FreeContent(channel);
        } 
 
        /// 
        /// Returns the bounding box of the content. 
        /// 
        internal override Rect GetContentBounds()
        {
            if (_content != null) 
            {
                Rect resultRect = Rect.Empty; 
                MediaContext mediaContext = MediaContext.From(Dispatcher); 
                BoundsDrawingContextWalker ctx = mediaContext.AcquireBoundsDrawingContextWalker();
 
                resultRect = _content.GetContentBounds(ctx);
                mediaContext.ReleaseBoundsDrawingContextWalker(ctx);

                return resultRect; 
            }
            else 
            { 
                return Rect.Empty;
            } 
        }

        /// 
        /// WalkContent - method which walks the content (if present) and calls out to the 
        /// supplied DrawingContextWalker.
        ///  
        ///  
        ///   DrawingContextWalker - the target of the calls which occur during
        ///   the content walk. 
        /// 
        internal void WalkContent(DrawingContextWalker walker)
        {
            VerifyAPIReadOnly(); 

            if (_content != null) 
            { 
                _content.WalkContent(walker);
            } 
        }

        /// 
        /// RenderContent is implemented by derived classes to hook up their 
        /// content. The implementer of this function can assert that the _hCompNode
        /// is valid on a channel when the function is executed. 
        ///  
        internal override void RenderContent(RenderContext ctx, bool isOnChannel)
        { 
            DUCE.Channel channel = ctx.Channel;

            Debug.Assert(!CheckFlagsAnd(channel, VisualProxyFlags.IsContentConnected));
            Debug.Assert(_proxy.IsOnChannel(channel)); 

 
            // 
            // Create the content on the channel.
            // 

            if (_content != null)
            {
                DUCE.CompositionNode.SetContent( 
                    _proxy.GetHandle(channel),
                    ((DUCE.IResource)_content).AddRefOnChannel(channel), 
                    channel); 

                SetFlags( 
                    channel,
                    true,
                    VisualProxyFlags.IsContentConnected);
            } 
            else if (isOnChannel) /*_content == null*/
            { 
                DUCE.CompositionNode.SetContent( 
                    _proxy.GetHandle(channel),
                    DUCE.ResourceHandle.Null, 
                    channel);
            }
        }
 
        /// 
        /// Called by the base class to update realization caches. 
        /// Updates the realization cache on the content. 
        /// 
        internal override void UpdateRealizations(RealizationContext ctx) 
        {
            if (_content != null)
            {
                _content.UpdateRealizations(ctx); 
            }
        } 
 
        /// 
        /// GetDrawing - Returns the drawing content of this Visual. 
        /// 
        /// 
        /// Changes to this DrawingGroup will not be propagated to the Visual's content.
        /// This method is called by both the Drawing property, and VisualTreeHelper.GetDrawing() 
        /// 
        internal override DrawingGroup GetDrawing() 
        { 
            //
 

            VerifyAPIReadOnly();

            DrawingGroup drawingGroupContent = null; 

            // Convert our content to a DrawingGroup, if content exists 
            if (_content != null) 
            {
                drawingGroupContent = DrawingServices.DrawingGroupFromRenderData((RenderData) _content); 
            }

            return drawingGroupContent;
        } 

        ///  
        /// Drawing - Returns the drawing content of this Visual. 
        /// 
        ///  
        /// Changes to this DrawingGroup will not propagated to the Visual's content.
        /// 
        public DrawingGroup Drawing
        { 
            get
            { 
                return GetDrawing(); 
            }
        } 
    }
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK