StreamGeometry.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / StreamGeometry.cs / 1305600 / StreamGeometry.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Description: Implementation of the class StreamGeometry 
//
//--------------------------------------------------------------------------- 
 
using System;
using MS.Internal; 
using MS.Internal.PresentationCore;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics; 
using System.Reflection;
using System.Collections; 
using System.Collections.Generic; 
using System.Text;
using System.Globalization; 
using System.Windows.Media;
using System.Windows.Media.Composition;
using System.Windows;
using System.Text.RegularExpressions; 
using System.Windows.Media.Animation;
using System.Windows.Markup; 
using System.Windows.Converters; 
using System.Runtime.InteropServices;
using System.Security; 
using System.Security.Permissions;
using MS.Win32;

using SR=MS.Internal.PresentationCore.SR; 
using SRID=MS.Internal.PresentationCore.SRID;
using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods; 
 
namespace System.Windows.Media
{ 
    #region StreamGeometry
    /// 
    /// StreamGeometry
    ///  
    [TypeConverter(typeof(GeometryConverter))]
    public sealed partial class StreamGeometry : Geometry 
    { 
        #region Constructors
        ///  
        ///
        /// 
        public StreamGeometry()
        { 
        }
        #endregion 
 
        /// 
        /// Opens the StreamGeometry for population. 
        /// 
        public StreamGeometryContext Open()
        {
            WritePreamble(); 

            return new StreamGeometryCallbackContext(this); 
        } 

 
        /// 
        /// Remove all figures
        /// 
        public void Clear() 
        {
            WritePreamble(); 
 
            _data = null;
            SetDirty(); 
            RegisterForAsyncUpdateResource();
        }

        ///  
        /// Returns true if this geometry is empty
        ///  
        /// 
        /// Critical as this has an unsafe block.
        /// PublicOK - This method reads from a buffer. 
        ///
        [SecurityCritical]
        public override bool IsEmpty()
        { 
            ReadPreamble();
 
            if ((_data == null) || (_data.Length <= 0)) 
            {
                return true; 
            }

            unsafe
            { 
                Invariant.Assert((_data != null) && (_data.Length >= sizeof(MIL_PATHGEOMETRY)));
                fixed (byte *pbPathData = _data) 
                { 
                    MIL_PATHGEOMETRY* pPathGeometry = (MIL_PATHGEOMETRY*)pbPathData;
 
                    return pPathGeometry->FigureCount <= 0;
                }
            }
        } 

        ///  
        /// AreBoundsValid Property - returns true if the bounds are valid, false otherwise. 
        /// If true, the bounds are stored in the bounds param.
        ///  
        /// 
        ///     Critical: Manipulates unsafe code
        ///     TreatAsSafe: Access a local byte[] as a pointer.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private bool AreBoundsValid(ref MilRectD bounds) 
        { 
            if (IsEmpty())
            { 
                return false;
            }

            unsafe 
            {
                Debug.Assert((_data != null) && (_data.Length >= sizeof(MIL_PATHGEOMETRY))); 
                fixed (byte* pbPathData = _data) 
                {
                    MIL_PATHGEOMETRY* pGeometry = (MIL_PATHGEOMETRY*)pbPathData; 

                    bool areBoundsValid = (pGeometry->Flags & MilPathGeometryFlags.BoundsValid) != 0;

                    if (areBoundsValid) 
                    {
                        bounds = pGeometry->Bounds; 
                    } 

                    return areBoundsValid; 
                }
            }
        }
 
        /// 
        /// CacheBounds - store the calculated bounds in the data stream. 
        ///  
        /// 
        ///     Critical: Manipulates unsafe code 
        ///     TreatAsSafe: Access a local byte[] as a pointer.
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void CacheBounds(ref MilRectD bounds) 
        {
            unsafe 
            { 
                Debug.Assert((_data != null) && (_data.Length >= sizeof(MIL_PATHGEOMETRY)));
                fixed (byte* pbPathData = _data) 
                {
                    MIL_PATHGEOMETRY* pGeometry = (MIL_PATHGEOMETRY*)pbPathData;

                    pGeometry->Flags |= MilPathGeometryFlags.BoundsValid; 
                    pGeometry->Bounds = bounds;
                } 
            } 
        }
 
        /// 
        /// SetDirty - indicate that the cached bounds on this Geometry are not valid.
        /// 
        ///  
        ///     Critical: Manipulates unsafe code
        ///     TreatAsSafe: Access a local byte[] as a pointer. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal void SetDirty() 
        {
            if (!IsEmpty())
            {
                unsafe 
                {
                    Debug.Assert((_data != null) && (_data.Length >= sizeof(MIL_PATHGEOMETRY))); 
                    fixed (byte* pbPathData = _data) 
                    {
                        MIL_PATHGEOMETRY* pGeometry = (MIL_PATHGEOMETRY*)pbPathData; 

                        pGeometry->Flags &= ~MilPathGeometryFlags.BoundsValid;
                    }
                } 
            }
        } 
 
        /// 
        /// Gets the bounds of this StreamGeometry as an axis-aligned bounding box 
        /// 
        public override Rect Bounds
        {
            get 
            {
                ReadPreamble(); 
 
                if (IsEmpty())
                { 
                    return Rect.Empty;
                }
                else
                { 
                    MilRectD bounds = new MilRectD();
 
                    if (!AreBoundsValid(ref bounds)) 
                    {
                        // Update the cached bounds 
                        bounds = PathGeometry.GetPathBoundsAsRB(
                            GetPathGeometryData(),
                            null,   // pen
                            Matrix.Identity, 
                            StandardFlatteningTolerance,
                            ToleranceType.Absolute, 
                            false);  // Do not skip non-fillable figures 

                        CacheBounds(ref bounds); 
                    }

                    return bounds.AsRect;
                } 
            }
        } 
 
        /// 
        /// Returns true if this geometry may have curved segments 
        /// 
        /// 
        ///     Critical: Manipulates unsafe code
        ///     PublicOK: Access a local byte[] as a pointer. 
        /// 
        [SecurityCritical] 
        public override bool MayHaveCurves() 
        {
            // IsEmpty() calls ReadPreamble() 
            if (IsEmpty())
            {
                return false;
            } 

            unsafe 
            { 
                Invariant.Assert((_data != null) && (_data.Length >= sizeof(MIL_PATHGEOMETRY)));
                fixed (byte* pbPathData = (this._data)) 
                {
                    MIL_PATHGEOMETRY* pPathGeometryData = (MIL_PATHGEOMETRY*)pbPathData;
                    return (pPathGeometryData->Flags & MilPathGeometryFlags.HasCurves) != 0;
                } 
            }
        } 
 
        #region Internal
 
        /// 
        /// Returns true if this geometry may have curved segments
        /// 
        ///  
        ///     Critical: Manipulates unsafe code
        ///     TreatAsSafe: Access a local byte[] as a pointer. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal bool HasHollows() 
        {
            // IsEmpty() calls ReadPreamble()
            if (IsEmpty())
            { 
                return false;
            } 
 
            unsafe
            { 
                Invariant.Assert((_data != null) && (_data.Length >= sizeof(MIL_PATHGEOMETRY)));
                fixed (byte* pbPathData = (this._data))
                {
                    MIL_PATHGEOMETRY* pPathGeometryData = (MIL_PATHGEOMETRY*)pbPathData; 
                    return (pPathGeometryData->Flags & MilPathGeometryFlags.HasHollows) != 0;
                } 
            } 
        }
 
        /// 
        /// Returns true if this geometry may have curved segments
        /// 
        ///  
        ///     Critical: Manipulates unsafe code
        ///     TreatAsSafe: Access a local byte[] as a pointer. 
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal bool HasGaps() 
        {
            // IsEmpty() calls ReadPreamble()
            if (IsEmpty())
            { 
                return false;
            } 
 
            unsafe
            { 
                Invariant.Assert((_data != null) && (_data.Length >= sizeof(MIL_PATHGEOMETRY)));
                fixed (byte* pbPathData = (this._data))
                {
                    MIL_PATHGEOMETRY* pPathGeometryData = (MIL_PATHGEOMETRY*)pbPathData; 
                    return (pPathGeometryData->Flags & MilPathGeometryFlags.HasGaps) != 0;
                } 
            } 
        }
 
        /// 
        /// Called from the StreamGeometryContext when it is closed.
        /// 
        internal void Close(byte[] _buffer) 
        {
            SetDirty(); 
            _data = _buffer; 

            RegisterForAsyncUpdateResource(); 
        }

        /// 
        /// Implementation of Freezable.OnChanged. 
        /// 
        protected override void OnChanged() 
        { 
            SetDirty();
 
            base.OnChanged();
        }

        ///  
        /// GetAsPathGeometry - return a PathGeometry version of this Geometry
        ///  
        internal override PathGeometry GetAsPathGeometry() 
        {
            PathStreamGeometryContext ctx = new PathStreamGeometryContext(FillRule, Transform); 
            PathGeometry.ParsePathGeometryData(GetPathGeometryData(), ctx);

            return ctx.GetPathGeometry();
        } 

        ///  
        /// GetTransformedFigureCollection - inherited from Geometry. 
        /// Basically, this is used to collapse this Geometry into an existing PathGeometry.
        ///  
        internal override PathFigureCollection GetTransformedFigureCollection(Transform transform)
        {
            PathGeometry thisAsPathGeometry = GetAsPathGeometry();
 
            if (null != thisAsPathGeometry)
            { 
                return thisAsPathGeometry.GetTransformedFigureCollection(transform); 
            }
            else 
            {
                return null;
            }
        } 

        ///  
        /// Can serialize "this" to a string 
        /// 
        internal override bool CanSerializeToString() 
        {
            Transform transform = Transform;

            return (((transform == null) || transform.IsIdentity) && 
                    !HasHollows() && !HasGaps());
        } 
 
        /// 
        /// Creates a string representation of this object based on the format string 
        /// and IFormatProvider passed in.
        /// If the provider is null, the CurrentCulture is used.
        /// See the documentation for IFormattable for more information.
        ///  
        /// 
        /// A string representation of this object. 
        ///  
        internal override string ConvertToString(string format, IFormatProvider provider)
        { 
            //

            return GetAsPathGeometry().ConvertToString(format, provider);
        } 

        private void InvalidateResourceFigures(object sender, EventArgs args) 
        { 
            // This is necessary to invalidate the cached bounds.
            SetDirty(); 
            RegisterForAsyncUpdateResource();
        }

        ///  
        /// GetPathGeometryData - returns a struct which contains this Geometry represented
        /// as a path geometry's serialized format. 
        ///  
        internal override PathGeometryData GetPathGeometryData()
        { 
            if (IsEmpty())
            {
                return Geometry.GetEmptyPathGeometryData();
            } 

            PathGeometryData data = new PathGeometryData(); 
            data.FillRule = FillRule; 
            data.Matrix = CompositionResourceManager.TransformToMilMatrix3x2D(Transform);
            data.SerializedData = _data; 

            return data;
        }
 
        internal override void TransformPropertyChangedHook(DependencyPropertyChangedEventArgs e)
        { 
            SetDirty(); 
        }
 
        #endregion

        #region DUCE
 
        /// 
        ///     Critical: Manipulates unsafe code 
        ///  
        [SecurityCritical]
        private unsafe int GetFigureSize(byte* pbPathData) 
        {
            MIL_PATHGEOMETRY* pPathGeometryData = (MIL_PATHGEOMETRY*)pbPathData;
            return pPathGeometryData == null ? 0 : (int)pPathGeometryData->Size;
        } 

        ///  
        ///     Critical: This code calls into an unsafe code block 
        ///     TreatAsSafe: This code does not return any critical data.It is ok to expose
        ///     Channels are safe to call into and do not go cross domain and cross process 
        /// 
        [SecurityCritical,SecurityTreatAsSafe]
        internal override void UpdateResource(DUCE.Channel channel, bool skipOnChannelCheck)
        { 
            // If we're told we can skip the channel check, then we must be on channel
            Debug.Assert(!skipOnChannelCheck || _duceResource.IsOnChannel(channel)); 
 
            if (skipOnChannelCheck || _duceResource.IsOnChannel(channel))
            { 
                checked
                {
                    Transform vTransform = Transform;
 
                    // Obtain handles for properties that implement DUCE.IResource
                    DUCE.ResourceHandle hTransform; 
                    if (vTransform == null || 
                        Object.ReferenceEquals(vTransform, Transform.Identity)
                       ) 
                    {
                        hTransform = DUCE.ResourceHandle.Null;
                    }
                    else 
                    {
                        hTransform = ((DUCE.IResource)vTransform).GetHandle(channel); 
                    } 

                    DUCE.MILCMD_PATHGEOMETRY data; 
                    data.Type = MILCMD.MilCmdPathGeometry;
                    data.Handle = _duceResource.GetHandle(channel);
                    data.hTransform = hTransform;
                    data.FillRule = FillRule; 

                    byte[] pathDataToMarshal = _data == null ? 
                        Geometry.GetEmptyPathGeometryData().SerializedData : 
                        _data;
 
                    unsafe
                    {
                        fixed (byte* pbPathData = pathDataToMarshal)
                        { 
                            data.FiguresSize = (uint)GetFigureSize(pbPathData);
 
                            channel.BeginCommand( 
                                (byte*)&data,
                                sizeof(DUCE.MILCMD_PATHGEOMETRY), 
                                (int)data.FiguresSize
                                );

                            channel.AppendCommandData(pbPathData, (int)data.FiguresSize); 
                        }
 
                        channel.EndCommand(); 
                    }
                } 
            }

            base.UpdateResource(channel, skipOnChannelCheck);
        } 

        internal override DUCE.ResourceHandle AddRefOnChannelCore(DUCE.Channel channel) 
        { 
            if (_duceResource.CreateOrAddRefOnChannel(this, channel, System.Windows.Media.Composition.DUCE.ResourceType.TYPE_PATHGEOMETRY))
            { 
                Transform vTransform = Transform;

                if (vTransform != null) ((DUCE.IResource)vTransform).AddRefOnChannel(channel);
 
                UpdateResource(channel, true /* skip "on channel" check - we already know that we're on channel */ );
            } 
 
            return _duceResource.GetHandle(channel);
        } 

        internal override void ReleaseOnChannelCore(DUCE.Channel channel)
        {
            Debug.Assert(_duceResource.IsOnChannel(channel)); 

            if (_duceResource.ReleaseOnChannel(channel)) 
            { 
                Transform vTransform = Transform;
                if (vTransform != null) ((DUCE.IResource)vTransform).ReleaseOnChannel(channel); 
            }
        }

        internal override DUCE.ResourceHandle GetHandleCore(DUCE.Channel channel) 
        {
            // Note that we are in a lock here already. 
            return _duceResource.GetHandle(channel); 
        }
 
        internal override int GetChannelCountCore()
        {
            return _duceResource.GetChannelCount();
        } 

        internal override DUCE.Channel GetChannelCore(int index) 
        { 
            return _duceResource.GetChannel(index);
        } 

        /// 
        /// Implementation of Freezable.CloneCore()
        ///  
        protected override void CloneCore(Freezable source)
        { 
            base.CloneCore(source); 

            StreamGeometry sourceStream = (StreamGeometry) source; 

            if ((sourceStream._data != null) && (sourceStream._data.Length > 0))
            {
                _data = new byte[sourceStream._data.Length]; 
                sourceStream._data.CopyTo(_data, 0);
            } 
        } 
        /// 
        /// Implementation of Freezable.CloneCurrentValueCore() 
        /// 
        protected override void CloneCurrentValueCore(Freezable source)
        {
            base.CloneCurrentValueCore(source); 

            StreamGeometry sourceStream = (StreamGeometry) source; 
 
            if ((sourceStream._data != null) && (sourceStream._data.Length > 0))
            { 
                _data = new byte[sourceStream._data.Length];
                sourceStream._data.CopyTo(_data, 0);
            }
        } 

        ///  
        /// Implementation of Freezable.GetAsFrozenCore() 
        /// 
        protected override void GetAsFrozenCore(Freezable source) 
        {
            base.GetAsFrozenCore(source);

            StreamGeometry sourceStream = (StreamGeometry) source; 

            if ((sourceStream._data != null) && (sourceStream._data.Length > 0)) 
            { 
                _data = new byte[sourceStream._data.Length];
                sourceStream._data.CopyTo(_data, 0); 
            }
        }

        ///  
        /// Implementation of Freezable.GetCurrentValueAsFrozenCore()
        ///  
        protected override void GetCurrentValueAsFrozenCore(Freezable source) 
        {
            base.GetCurrentValueAsFrozenCore(source); 

            StreamGeometry sourceStream = (StreamGeometry) source;

            if ((sourceStream._data != null) && (sourceStream._data.Length > 0)) 
            {
                _data = new byte[sourceStream._data.Length]; 
                sourceStream._data.CopyTo(_data, 0); 
            }
        } 

        #endregion DUCE

        #region Data 

        private byte[] _data; 
        internal System.Windows.Media.Composition.DUCE.MultiChannelResource _duceResource = new System.Windows.Media.Composition.DUCE.MultiChannelResource(); 

        #endregion 
    }
    #endregion

    #region StreamGeometryCallbackContext 
    internal class StreamGeometryCallbackContext: ByteStreamGeometryContext
    { 
        ///  
        /// Creates a geometry stream context which is associated with a given owner
        ///  
        internal StreamGeometryCallbackContext(StreamGeometry owner)
        {
            _owner = owner;
        } 

        ///  
        /// CloseCore - This method is implemented by derived classes to hand off the content 
        /// to its eventual destination.
        ///  
        protected override void CloseCore(byte[] data)
        {
            _owner.Close(data);
        } 

        private StreamGeometry _owner; 
    } 
    #endregion StreamGeometryCallbackContext
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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