Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / 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 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(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 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(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
- XmlIlGenerator.cs
- BitmapEffectDrawingContextState.cs
- bindurihelper.cs
- TargetException.cs
- PointLightBase.cs
- ManifestResourceInfo.cs
- XmlWriterTraceListener.cs
- SmtpDigestAuthenticationModule.cs
- RepeatInfo.cs
- Relationship.cs
- DbConnectionPoolIdentity.cs
- DataGrid.cs
- WorkflowWebService.cs
- _IPv6Address.cs
- PathStreamGeometryContext.cs
- TypeElementCollection.cs
- AnonymousIdentificationModule.cs
- SatelliteContractVersionAttribute.cs
- FrameworkTextComposition.cs
- NonBatchDirectoryCompiler.cs
- DataGridViewUtilities.cs
- StatusStrip.cs
- GeometryModel3D.cs
- WizardStepBase.cs
- ReceiveSecurityHeaderEntry.cs
- PresentationSource.cs
- UnaryExpressionHelper.cs
- SkinBuilder.cs
- Restrictions.cs
- XsdDuration.cs
- HwndStylusInputProvider.cs
- XmlReaderSettings.cs
- ApplicationSettingsBase.cs
- JoinSymbol.cs
- HostingEnvironmentSection.cs
- DataListGeneralPage.cs
- PropertyDescriptorComparer.cs
- LocatorGroup.cs
- nulltextnavigator.cs
- XappLauncher.cs
- RuntimeWrappedException.cs
- ControlBuilderAttribute.cs
- ServiceObjectContainer.cs
- MDIClient.cs
- CodeMemberMethod.cs
- SqlProvider.cs
- Compress.cs
- ErrorsHelper.cs
- HttpListenerPrefixCollection.cs
- RequestSecurityTokenResponse.cs
- NetSectionGroup.cs
- PersonalizationAdministration.cs
- SystemFonts.cs
- FormattedText.cs
- HtmlInputControl.cs
- ContextStack.cs
- SystemTcpConnection.cs
- PrivilegedConfigurationManager.cs
- EnumerableCollectionView.cs
- SelectionChangedEventArgs.cs
- NetCodeGroup.cs
- WorkItem.cs
- ProfessionalColorTable.cs
- ReliableChannelFactory.cs
- ColumnMapVisitor.cs
- ImageFormat.cs
- COSERVERINFO.cs
- BindableAttribute.cs
- CustomAttributeBuilder.cs
- FileSecurity.cs
- WebBrowserEvent.cs
- ExceptQueryOperator.cs
- Input.cs
- Visitors.cs
- EncryptedKey.cs
- Path.cs
- ModelUIElement3D.cs
- DbParameterCollection.cs
- GenericsNotImplementedException.cs
- ContextConfiguration.cs
- PeerToPeerException.cs
- XmlTextEncoder.cs
- CodeTypeMemberCollection.cs
- MSHTMLHost.cs
- Timer.cs
- TextSchema.cs
- CqlGenerator.cs
- ImageButton.cs
- UIElement.cs
- ArglessEventHandlerProxy.cs
- COM2PictureConverter.cs
- Double.cs
- SspiSafeHandles.cs
- DataGridViewBindingCompleteEventArgs.cs
- HostProtectionPermission.cs
- EventSetter.cs
- SessionState.cs
- DecimalConstantAttribute.cs
- TemplateBaseAction.cs
- GeometryDrawing.cs