Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Media / StreamGeometry.cs / 1 / 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 protected override void OnChanged() { SetDirty(); base.OnChanged(); } ///Freezable.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(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. //---------------------------------------------------------------------------- // // 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 protected override void OnChanged() { SetDirty(); base.OnChanged(); } ///Freezable.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(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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SelfIssuedAuthAsymmetricKey.cs
- InputLangChangeEvent.cs
- HtmlShimManager.cs
- MinimizableAttributeTypeConverter.cs
- ResourceSet.cs
- ReadOnlyCollection.cs
- GraphicsContext.cs
- EntityCommandExecutionException.cs
- RadioButtonRenderer.cs
- OracleConnectionStringBuilder.cs
- LineProperties.cs
- CollectionEditVerbManager.cs
- ToolStripDropDownItem.cs
- StringUtil.cs
- KerberosSecurityTokenProvider.cs
- ConfigXmlWhitespace.cs
- MemberRelationshipService.cs
- NameValueConfigurationElement.cs
- ListSortDescription.cs
- DataGridViewColumnHeaderCell.cs
- ObjectListShowCommandsEventArgs.cs
- QueueSurrogate.cs
- InertiaTranslationBehavior.cs
- SystemDropShadowChrome.cs
- MonikerBuilder.cs
- DeriveBytes.cs
- Annotation.cs
- ConnectionPointGlyph.cs
- MachineSettingsSection.cs
- EllipseGeometry.cs
- SqlDataSourceSummaryPanel.cs
- SubMenuStyle.cs
- RangeContentEnumerator.cs
- NumberAction.cs
- HttpException.cs
- PropertyValue.cs
- HttpListenerRequest.cs
- BitmapEffectDrawing.cs
- CommonObjectSecurity.cs
- Expr.cs
- FieldCollectionEditor.cs
- BaseConfigurationRecord.cs
- ControlBuilderAttribute.cs
- TextSimpleMarkerProperties.cs
- ExplicitDiscriminatorMap.cs
- bindurihelper.cs
- InternalPermissions.cs
- ConnectionInterfaceCollection.cs
- WebPartCancelEventArgs.cs
- StoreAnnotationsMap.cs
- _ProxyRegBlob.cs
- FrameworkTextComposition.cs
- SingleStorage.cs
- HttpCacheVaryByContentEncodings.cs
- ByteStorage.cs
- UInt64Storage.cs
- TemplateInstanceAttribute.cs
- GenericQueueSurrogate.cs
- ListViewItem.cs
- ProxyHelper.cs
- SizeAnimation.cs
- _NetworkingPerfCounters.cs
- ToolStripCodeDomSerializer.cs
- FrameSecurityDescriptor.cs
- Menu.cs
- ExtendedPropertyCollection.cs
- Thickness.cs
- ServiceDescriptionReflector.cs
- DataSysAttribute.cs
- OpenCollectionAsyncResult.cs
- OracleCommandBuilder.cs
- BinarySerializer.cs
- MultiTrigger.cs
- Selection.cs
- LayoutSettings.cs
- CatalogZoneBase.cs
- CompositeCollection.cs
- HttpHandlerActionCollection.cs
- WhitespaceRule.cs
- WCFModelStrings.Designer.cs
- Exception.cs
- ValueProviderWrapper.cs
- UnknownBitmapDecoder.cs
- HijriCalendar.cs
- SecurityElement.cs
- _AutoWebProxyScriptEngine.cs
- UpdateEventArgs.cs
- TimersDescriptionAttribute.cs
- SecurityTokenReferenceStyle.cs
- TaiwanCalendar.cs
- Enum.cs
- XmlDataCollection.cs
- SigningCredentials.cs
- RemoteWebConfigurationHostServer.cs
- ObfuscateAssemblyAttribute.cs
- FontCollection.cs
- CurrentChangingEventArgs.cs
- WinInet.cs
- ContainerAction.cs
- HostVisual.cs