Code:
/ 4.0 / 4.0 / 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.
//----------------------------------------------------------------------------
//
// 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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RectangleGeometry.cs
- ObjectParameter.cs
- URIFormatException.cs
- GenerateScriptTypeAttribute.cs
- DesignerDataTable.cs
- WebContext.cs
- Renderer.cs
- DataSourceSelectArguments.cs
- EarlyBoundInfo.cs
- UnsafeNetInfoNativeMethods.cs
- FunctionDefinition.cs
- XPathArrayIterator.cs
- fixedPageContentExtractor.cs
- PartitionedStream.cs
- WindowProviderWrapper.cs
- WarningException.cs
- ResourceType.cs
- HashJoinQueryOperatorEnumerator.cs
- XmlHierarchicalDataSourceView.cs
- GridViewColumn.cs
- FileNotFoundException.cs
- CatalogPartChrome.cs
- ToolStripProgressBar.cs
- NativeMethodsOther.cs
- WebResourceAttribute.cs
- SolidBrush.cs
- CustomErrorCollection.cs
- SubMenuStyle.cs
- PropertyInformationCollection.cs
- LocalIdCollection.cs
- CqlErrorHelper.cs
- QueryResponse.cs
- HttpPostedFile.cs
- ZipIOLocalFileHeader.cs
- Attributes.cs
- HierarchicalDataSourceIDConverter.cs
- DataBoundLiteralControl.cs
- Configuration.cs
- ListSortDescription.cs
- ImportException.cs
- FontFamily.cs
- InputBindingCollection.cs
- DataGridSortingEventArgs.cs
- NumberFormatter.cs
- CompilerParameters.cs
- DataObject.cs
- IndicCharClassifier.cs
- EdmItemCollection.cs
- TraceSwitch.cs
- precedingquery.cs
- LocalValueEnumerator.cs
- EdmToObjectNamespaceMap.cs
- CapabilitiesPattern.cs
- ColorDialog.cs
- DropSource.cs
- PropertiesTab.cs
- BitmapEffectCollection.cs
- Constants.cs
- EnvelopedPkcs7.cs
- CompilerLocalReference.cs
- HtmlLabelAdapter.cs
- RowToFieldTransformer.cs
- log.cs
- WebBrowserSiteBase.cs
- DocumentViewerAutomationPeer.cs
- ReceiveActivity.cs
- InkPresenterAutomationPeer.cs
- GetWinFXPath.cs
- X509UI.cs
- TreeNodeEventArgs.cs
- RightsController.cs
- ContextInformation.cs
- WindowsRichEdit.cs
- HtmlControlPersistable.cs
- InputQueueChannel.cs
- SqlInternalConnectionTds.cs
- RenderingBiasValidation.cs
- ValueTable.cs
- XmlCodeExporter.cs
- DataSourceSerializationException.cs
- Point4D.cs
- SafeNativeMethods.cs
- GAC.cs
- PenContext.cs
- SelectionEditingBehavior.cs
- ReverseInheritProperty.cs
- ClonableStack.cs
- Stack.cs
- PackagePart.cs
- _UncName.cs
- ZoneMembershipCondition.cs
- TextReader.cs
- ArgumentNullException.cs
- SystemIPv4InterfaceProperties.cs
- storepermissionattribute.cs
- TripleDESCryptoServiceProvider.cs
- SettingsAttributes.cs
- SqlRemoveConstantOrderBy.cs
- HopperCache.cs
- XmlnsDictionary.cs