Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / Media / ParserStreamGeometryContext.cs / 1305600 / ParserStreamGeometryContext.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// This class is used to compress a Path to BAML.
//
// At compile-time this api is called into to "flatten" graphics calls to a BinaryWriter
// At run-time this api is called into to rehydrate the flattened graphics calls
// via invoking methods on a supplied StreamGeometryContext.
//
// Via this compression - we reduce the time spent parsing at startup, we create smaller baml,
// and we reduce creation of temporary strings.
//
//---------------------------------------------------------------------------
using MS.Internal;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security;
using System.Security.Permissions;
using System.IO;
using MS.Utility;
#if PBTCOMPILER
using MS.Internal.Markup;
namespace MS.Internal.Markup
#else
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using MS.Internal.PresentationCore;
namespace MS.Internal.Media
#endif
{
///
/// ParserStreamGeometryContext
///
internal class ParserStreamGeometryContext : StreamGeometryContext
{
enum ParserGeometryContextOpCodes : byte
{
BeginFigure = 0,
LineTo = 1,
QuadraticBezierTo = 2,
BezierTo = 3,
PolyLineTo = 4,
PolyQuadraticBezierTo = 5,
PolyBezierTo = 6,
ArcTo = 7,
Closed = 8,
FillRule = 9,
}
private const byte HighNibble = 0xF0;
private const byte LowNibble = 0x0F;
private const byte SetBool1 = 0x10; // 00010000
private const byte SetBool2 = 0x20; // 00100000
private const byte SetBool3 = 0x40; // 01000000
private const byte SetBool4 = 0x80; // 10000000
#region Constructors
///
/// This constructor exists to prevent external derivation
///
internal ParserStreamGeometryContext(BinaryWriter bw)
{
_bw = bw;
}
#endregion Constructors
#region internal Methods
#if PRESENTATION_CORE
internal void SetFillRule(FillRule fillRule)
#else
internal void SetFillRule(bool boolFillRule)
#endif
{
#if PRESENTATION_CORE
bool boolFillRule = FillRuleToBool(fillRule);
#endif
byte packedByte = PackByte(ParserGeometryContextOpCodes.FillRule, boolFillRule, false);
_bw.Write(packedByte);
}
///
/// BeginFigure - Start a new figure.
///
///
/// Stored as [PointAndTwoBools] (see SerializepointAndTwoBools method).
///
public override void BeginFigure(Point startPoint, bool isFilled, bool isClosed)
{
//
// We need to update the BeginFigure block of the last figure (if
// there was one).
//
FinishFigure();
_startPoint = startPoint;
_isFilled = isFilled;
_isClosed = isClosed;
_figureStreamPosition = CurrentStreamPosition;
//
// This will be overwritten later when we start the next figure (i.e. when we're sure isClosed isn't
// going to change). We write it out now to ensure that we reserve exactly the right amount of space.
// Note that the number of bytes written is dependant on the particular value of startPoint, since
// we can compress doubles when they are in fact integral.
//
SerializePointAndTwoBools(ParserGeometryContextOpCodes.BeginFigure, startPoint, isFilled, isClosed);
}
///
/// LineTo - append a LineTo to the current figure.
///
///
/// Stored as [PointAndTwoBools] (see SerializepointAndTwoBools method).
///
public override void LineTo(Point point, bool isStroked, bool isSmoothJoin)
{
SerializePointAndTwoBools(ParserGeometryContextOpCodes.LineTo, point, isStroked, isSmoothJoin);
}
///
/// QuadraticBezierTo - append a QuadraticBezierTo to the current figure.
///
///
/// Stored as [PointAndTwoBools] [Number] [Number]
///
public override void QuadraticBezierTo(Point point1, Point point2, bool isStroked, bool isSmoothJoin)
{
SerializePointAndTwoBools(ParserGeometryContextOpCodes.QuadraticBezierTo, point1, isStroked, isSmoothJoin);
XamlSerializationHelper.WriteDouble(_bw, point2.X);
XamlSerializationHelper.WriteDouble(_bw, point2.Y);
}
///
/// BezierTo - apply a BezierTo to the current figure.
///
///
/// Stored as [PointAndTwoBools] [Number] [Number] [Number] [Number]
///
public override void BezierTo(Point point1, Point point2, Point point3, bool isStroked, bool isSmoothJoin)
{
SerializePointAndTwoBools(ParserGeometryContextOpCodes.BezierTo, point1, isStroked, isSmoothJoin);
XamlSerializationHelper.WriteDouble(_bw, point2.X);
XamlSerializationHelper.WriteDouble(_bw, point2.Y);
XamlSerializationHelper.WriteDouble(_bw, point3.X);
XamlSerializationHelper.WriteDouble(_bw, point3.Y);
}
///
/// PolyLineTo - append a PolyLineTo to the current figure.
///
///
/// Stored as [ListOfPointAndTwoBools] (see SerializeListOfPointsAndTwoBools method).
///
public override void PolyLineTo(IList points, bool isStroked, bool isSmoothJoin)
{
SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes.PolyLineTo, points, isStroked, isSmoothJoin);
}
///
/// PolyQuadraticBezierTo - append a PolyQuadraticBezierTo to the current figure.
///
///
/// Stored as [ListOfPointAndTwoBools] (see SerializeListOfPointsAndTwoBools method).
///
public override void PolyQuadraticBezierTo(IList points, bool isStroked, bool isSmoothJoin)
{
SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes.PolyQuadraticBezierTo, points, isStroked, isSmoothJoin);
}
///
/// PolyBezierTo - append a PolyBezierTo to the current figure.
///
///
/// Stored as [ListOfPointAndTwoBools] (see SerializeListOfPointsAndTwoBools method).
///
public override void PolyBezierTo(IList points, bool isStroked, bool isSmoothJoin)
{
SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes.PolyBezierTo, points, isStroked, isSmoothJoin);
}
///
/// ArcTo - append an ArcTo to the current figure.
///
///
/// Stored as [PointAndTwoBools] [Packed byte for isLargeArc and sweepDirection] [Pair of Numbers for Size] [Pair of Numbers for rotation Angle]
///
/// Also note that we've special cased this method signature to avoid moving the enum for SweepDirection into PBT (will require codegen changes).
///
#if PBTCOMPILER
public override void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, bool sweepDirection, bool isStroked, bool isSmoothJoin)
#else
public override void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin)
#endif
{
SerializePointAndTwoBools(ParserGeometryContextOpCodes.ArcTo, point, isStroked, isSmoothJoin);
//
// Pack isLargeArc & sweepDirection into a single byte.
//
byte packMe = 0;
if (isLargeArc)
{
packMe = LowNibble;
}
#if PBTCOMPILER
if (sweepDirection)
#else
if (SweepToBool(sweepDirection))
#endif
{
packMe |= HighNibble;
}
_bw.Write(packMe);
//
// Write out Size & Rotation Angle.
//
XamlSerializationHelper.WriteDouble(_bw, size.Width);
XamlSerializationHelper.WriteDouble(_bw, size.Height);
XamlSerializationHelper.WriteDouble(_bw, rotationAngle);
}
internal bool FigurePending
{
get
{
return (_figureStreamPosition > -1);
}
}
internal int CurrentStreamPosition
{
get
{
return checked((int)_bw.Seek(0, SeekOrigin.Current));
}
}
internal void FinishFigure()
{
if (FigurePending)
{
int currentOffset = CurrentStreamPosition;
//
// Go back and overwrite our existing begin figure block. See comment in BeginFigure.
//
_bw.Seek(_figureStreamPosition, SeekOrigin.Begin);
SerializePointAndTwoBools(ParserGeometryContextOpCodes.BeginFigure, _startPoint, _isFilled, _isClosed);
_bw.Seek(currentOffset, SeekOrigin.Begin);
}
}
///
/// This is the same as the Close call:
/// Closes the Context and flushes the content.
/// Afterwards the Context can not be used anymore.
/// This call does not require all Push calls to have been Popped.
///
internal override void DisposeCore()
{
}
///
/// SetClosedState - Sets the current closed state of the figure.
///
internal override void SetClosedState(bool closed)
{
_isClosed = closed;
}
///
/// Mark that the stream is Done.
///
internal void MarkEOF()
{
//
// We need to update the BeginFigure block of the last figure (if
// there was one).
//
FinishFigure();
_bw.Write((byte) ParserGeometryContextOpCodes.Closed);
}
#if PRESENTATION_CORE
internal static void Deserialize(BinaryReader br, StreamGeometryContext sc, StreamGeometry geometry)
{
bool closed = false;
Byte currentByte;
while (!closed)
{
currentByte = br.ReadByte();
ParserGeometryContextOpCodes opCode = UnPackOpCode(currentByte);
switch(opCode)
{
case ParserGeometryContextOpCodes.FillRule :
DeserializeFillRule(br, currentByte, geometry);
break;
case ParserGeometryContextOpCodes.BeginFigure :
DeserializeBeginFigure(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.LineTo :
DeserializeLineTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.QuadraticBezierTo :
DeserializeQuadraticBezierTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.BezierTo :
DeserializeBezierTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.PolyLineTo :
DeserializePolyLineTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.PolyQuadraticBezierTo :
DeserializePolyQuadraticBezierTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.PolyBezierTo :
DeserializePolyBezierTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.ArcTo :
DeserializeArcTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.Closed :
closed = true;
break;
}
}
}
#endif
#endregion internal Methods
#region private Methods
//
// Deserialization Methods.
//
// These are only required at "runtime" - therefore only in PRESENTATION_CORE
//
#if PRESENTATION_CORE
private static void DeserializeFillRule(BinaryReader br, Byte firstByte, StreamGeometry geometry)
{
bool boolFillRule;
bool unused;
FillRule fillRule;
UnPackBools(firstByte, out boolFillRule, out unused);
fillRule = BoolToFillRule(boolFillRule);
geometry.FillRule = fillRule;
}
private static void DeserializeBeginFigure(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
Point point;
bool isFilled;
bool isClosed;
DeserializePointAndTwoBools(br, firstByte, out point, out isFilled, out isClosed);
sc.BeginFigure(point, isFilled, isClosed);
}
private static void DeserializeLineTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
Point point;
bool isStroked;
bool isSmoothJoin;
DeserializePointAndTwoBools(br, firstByte, out point, out isStroked, out isSmoothJoin);
sc.LineTo(point, isStroked, isSmoothJoin);
}
private static void DeserializeQuadraticBezierTo(BinaryReader br, byte firstByte, StreamGeometryContext sc)
{
Point point1;
Point point2 = new Point();
bool isStroked;
bool isSmoothJoin;
DeserializePointAndTwoBools(br, firstByte, out point1, out isStroked, out isSmoothJoin);
point2.X = XamlSerializationHelper.ReadDouble(br);
point2.Y = XamlSerializationHelper.ReadDouble(br);
sc.QuadraticBezierTo(point1, point2, isStroked, isSmoothJoin);
}
private static void DeserializeBezierTo(BinaryReader br, byte firstByte, StreamGeometryContext sc)
{
Point point1;
Point point2 = new Point();
Point point3 = new Point();
bool isStroked;
bool isSmoothJoin;
DeserializePointAndTwoBools(br, firstByte, out point1, out isStroked, out isSmoothJoin);
point2.X = XamlSerializationHelper.ReadDouble(br);
point2.Y = XamlSerializationHelper.ReadDouble(br);
point3.X = XamlSerializationHelper.ReadDouble(br);
point3.Y = XamlSerializationHelper.ReadDouble(br);
sc.BezierTo(point1, point2, point3, isStroked, isSmoothJoin);
}
private static void DeserializePolyLineTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
bool isStroked;
bool isSmoothJoin;
IList points;
points = DeserializeListOfPointsAndTwoBools(br, firstByte, out isStroked, out isSmoothJoin);
sc.PolyLineTo(points, isStroked, isSmoothJoin);
}
private static void DeserializePolyQuadraticBezierTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
bool isStroked;
bool isSmoothJoin;
IList points;
points = DeserializeListOfPointsAndTwoBools(br, firstByte, out isStroked, out isSmoothJoin);
sc.PolyQuadraticBezierTo(points, isStroked, isSmoothJoin);
}
private static void DeserializePolyBezierTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
bool isStroked;
bool isSmoothJoin;
IList points;
points = DeserializeListOfPointsAndTwoBools(br, firstByte, out isStroked, out isSmoothJoin);
sc.PolyBezierTo(points, isStroked, isSmoothJoin);
}
private static void DeserializeArcTo(BinaryReader br, byte firstByte, StreamGeometryContext sc)
{
Point point;
Size size = new Size();
double rotationAngle;
bool isStroked;
bool isSmoothJoin;
bool isLargeArc;
SweepDirection sweepDirection;
DeserializePointAndTwoBools(br, firstByte, out point, out isStroked, out isSmoothJoin);
// Read the packed byte for isLargeArd & sweepDirection.
//
// Pack isLargeArc & sweepDirection into a signle byte.
//
byte packedByte = br.ReadByte();
isLargeArc = ((packedByte & LowNibble) != 0);
sweepDirection = BoolToSweep(((packedByte & HighNibble) != 0));
size.Width = XamlSerializationHelper.ReadDouble(br);
size.Height = XamlSerializationHelper.ReadDouble(br);
rotationAngle = XamlSerializationHelper.ReadDouble(br);
sc.ArcTo(point, size, rotationAngle, isLargeArc, sweepDirection, isStroked, isSmoothJoin);
}
//
// Private Deserialization helpers.
//
private static void UnPackBools(byte packedByte, out bool bool1, out bool bool2)
{
bool1 = (packedByte & SetBool1) != 0;
bool2 = (packedByte & SetBool2) != 0;
}
private static void UnPackBools(byte packedByte, out bool bool1, out bool bool2, out bool bool3, out bool bool4)
{
bool1 = (packedByte & SetBool1) != 0;
bool2 = (packedByte & SetBool2) != 0;
bool3 = (packedByte & SetBool3) != 0;
bool4 = (packedByte & SetBool4) != 0;
}
private static ParserGeometryContextOpCodes UnPackOpCode(byte packedByte)
{
return ((ParserGeometryContextOpCodes) (packedByte & 0x0F));
}
private static IList DeserializeListOfPointsAndTwoBools(BinaryReader br, Byte firstByte, out bool bool1, out bool bool2)
{
int count;
IList points;
Point point;
// Pack the two bools into one byte
UnPackBools(firstByte, out bool1, out bool2);
count = br.ReadInt32();
points = new List(count);
for(int i = 0; i < count; i++)
{
point = new Point(XamlSerializationHelper.ReadDouble(br),
XamlSerializationHelper.ReadDouble(br));
points.Add(point);
}
return points;
}
private static void DeserializePointAndTwoBools(BinaryReader br, Byte firstByte, out Point point, out bool bool1, out bool bool2)
{
bool isScaledIntegerX = false;
bool isScaledIntegerY = false;
UnPackBools(firstByte, out bool1, out bool2, out isScaledIntegerX, out isScaledIntegerY);
point = new Point(DeserializeDouble(br, isScaledIntegerX),
DeserializeDouble(br, isScaledIntegerY));
}
private static Double DeserializeDouble(BinaryReader br, bool isScaledInt)
{
if (isScaledInt)
{
return XamlSerializationHelper.ReadScaledInteger(br);
}
else
{
return XamlSerializationHelper.ReadDouble(br);
}
}
//
// Private serialization helpers
//
private static SweepDirection BoolToSweep(bool value)
{
if(!value)
return SweepDirection.Counterclockwise;
else
return SweepDirection.Clockwise;
}
private static bool SweepToBool(SweepDirection sweep)
{
if (sweep == SweepDirection.Counterclockwise)
return false;
else
return true;
}
private static FillRule BoolToFillRule(bool value)
{
if(!value)
return FillRule.EvenOdd;
else
return FillRule.Nonzero;
}
private static bool FillRuleToBool(FillRule fill)
{
if (fill == FillRule.EvenOdd)
return false;
else
return true;
}
#endif
//
// SerializePointAndTwoBools
//
// Binary format is :
//
//
//
// Where :
// := OpCode + bool1 + bool2 + isScaledIntegerX + isScaledIntegerY
// := | |
// := | |
// :=
//
// By packing the flags for isScaledInteger into the first byte - we save 2 extra bytes per number for the common case.
//
// As a result - most LineTo's (and other operations) will be stored in 9 bytes.
// Some LineTo's will be 6 (or even sometimes 3)
// Max LineTo will be 19 (two doubles).
private void SerializePointAndTwoBools(ParserGeometryContextOpCodes opCode,
Point point,
bool bool1,
bool bool2)
{
int intValueX = 0;
int intValueY = 0;
bool isScaledIntegerX, isScaledIntegerY;
isScaledIntegerX = XamlSerializationHelper.CanConvertToInteger(point.X, ref intValueX);
isScaledIntegerY = XamlSerializationHelper.CanConvertToInteger(point.Y, ref intValueY);
_bw.Write(PackByte(opCode, bool1, bool2, isScaledIntegerX, isScaledIntegerY));
SerializeDouble(point.X, isScaledIntegerX, intValueX);
SerializeDouble(point.Y, isScaledIntegerY, intValueY);
}
// SerializeListOfPointsAndTwoBools
//
// Binary format is :
//
// ...
//
// := OpCode + bool1 + bool2
// := int32
// := | |
private void SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes opCode, IList points, bool bool1, bool bool2)
{
// Pack the two bools into one byte
Byte packedByte = PackByte(opCode, bool1, bool2);
_bw.Write(packedByte);
// Write the count.
_bw.Write(points.Count);
// Write out all the Points
for(int i = 0; i < points.Count; i++)
{
XamlSerializationHelper.WriteDouble(_bw, points[i].X);
XamlSerializationHelper.WriteDouble(_bw, points[i].Y);
}
}
private void SerializeDouble(double value, bool isScaledInt, int scaledIntValue)
{
if (isScaledInt)
{
_bw.Write(scaledIntValue);
}
else
{
XamlSerializationHelper.WriteDouble(_bw, value);
}
}
private static byte PackByte(ParserGeometryContextOpCodes opCode, bool bool1, bool bool2)
{
return PackByte(opCode, bool1, bool2, false, false);
}
// PackByte
// Packs an op-code, and up to 4 booleans into a single byte.
//
// Binary format is :
// First 4 bits map directly to the op-code.
// Next 4 bits map to booleans 1 - 4.
//
// Like this:
//
// 7| 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// |||<- Op Code ->
//
private static byte PackByte(ParserGeometryContextOpCodes opCode, bool bool1, bool bool2, bool bool3, bool bool4)
{
byte packedByte = (byte) opCode;
if (packedByte >= 16)
{
throw new ArgumentException(SR.Get(SRID.UnknownPathOperationType));
}
if (bool1)
{
packedByte |= SetBool1;
}
if (bool2)
{
packedByte |= SetBool2;
}
if (bool3)
{
packedByte |= SetBool3;
}
if (bool4)
{
packedByte |= SetBool4;
}
return packedByte;
}
#endregion private Methods
private BinaryWriter _bw;
Point _startPoint;
bool _isClosed;
bool _isFilled;
int _figureStreamPosition = -1;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// This class is used to compress a Path to BAML.
//
// At compile-time this api is called into to "flatten" graphics calls to a BinaryWriter
// At run-time this api is called into to rehydrate the flattened graphics calls
// via invoking methods on a supplied StreamGeometryContext.
//
// Via this compression - we reduce the time spent parsing at startup, we create smaller baml,
// and we reduce creation of temporary strings.
//
//---------------------------------------------------------------------------
using MS.Internal;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security;
using System.Security.Permissions;
using System.IO;
using MS.Utility;
#if PBTCOMPILER
using MS.Internal.Markup;
namespace MS.Internal.Markup
#else
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using MS.Internal.PresentationCore;
namespace MS.Internal.Media
#endif
{
///
/// ParserStreamGeometryContext
///
internal class ParserStreamGeometryContext : StreamGeometryContext
{
enum ParserGeometryContextOpCodes : byte
{
BeginFigure = 0,
LineTo = 1,
QuadraticBezierTo = 2,
BezierTo = 3,
PolyLineTo = 4,
PolyQuadraticBezierTo = 5,
PolyBezierTo = 6,
ArcTo = 7,
Closed = 8,
FillRule = 9,
}
private const byte HighNibble = 0xF0;
private const byte LowNibble = 0x0F;
private const byte SetBool1 = 0x10; // 00010000
private const byte SetBool2 = 0x20; // 00100000
private const byte SetBool3 = 0x40; // 01000000
private const byte SetBool4 = 0x80; // 10000000
#region Constructors
///
/// This constructor exists to prevent external derivation
///
internal ParserStreamGeometryContext(BinaryWriter bw)
{
_bw = bw;
}
#endregion Constructors
#region internal Methods
#if PRESENTATION_CORE
internal void SetFillRule(FillRule fillRule)
#else
internal void SetFillRule(bool boolFillRule)
#endif
{
#if PRESENTATION_CORE
bool boolFillRule = FillRuleToBool(fillRule);
#endif
byte packedByte = PackByte(ParserGeometryContextOpCodes.FillRule, boolFillRule, false);
_bw.Write(packedByte);
}
///
/// BeginFigure - Start a new figure.
///
///
/// Stored as [PointAndTwoBools] (see SerializepointAndTwoBools method).
///
public override void BeginFigure(Point startPoint, bool isFilled, bool isClosed)
{
//
// We need to update the BeginFigure block of the last figure (if
// there was one).
//
FinishFigure();
_startPoint = startPoint;
_isFilled = isFilled;
_isClosed = isClosed;
_figureStreamPosition = CurrentStreamPosition;
//
// This will be overwritten later when we start the next figure (i.e. when we're sure isClosed isn't
// going to change). We write it out now to ensure that we reserve exactly the right amount of space.
// Note that the number of bytes written is dependant on the particular value of startPoint, since
// we can compress doubles when they are in fact integral.
//
SerializePointAndTwoBools(ParserGeometryContextOpCodes.BeginFigure, startPoint, isFilled, isClosed);
}
///
/// LineTo - append a LineTo to the current figure.
///
///
/// Stored as [PointAndTwoBools] (see SerializepointAndTwoBools method).
///
public override void LineTo(Point point, bool isStroked, bool isSmoothJoin)
{
SerializePointAndTwoBools(ParserGeometryContextOpCodes.LineTo, point, isStroked, isSmoothJoin);
}
///
/// QuadraticBezierTo - append a QuadraticBezierTo to the current figure.
///
///
/// Stored as [PointAndTwoBools] [Number] [Number]
///
public override void QuadraticBezierTo(Point point1, Point point2, bool isStroked, bool isSmoothJoin)
{
SerializePointAndTwoBools(ParserGeometryContextOpCodes.QuadraticBezierTo, point1, isStroked, isSmoothJoin);
XamlSerializationHelper.WriteDouble(_bw, point2.X);
XamlSerializationHelper.WriteDouble(_bw, point2.Y);
}
///
/// BezierTo - apply a BezierTo to the current figure.
///
///
/// Stored as [PointAndTwoBools] [Number] [Number] [Number] [Number]
///
public override void BezierTo(Point point1, Point point2, Point point3, bool isStroked, bool isSmoothJoin)
{
SerializePointAndTwoBools(ParserGeometryContextOpCodes.BezierTo, point1, isStroked, isSmoothJoin);
XamlSerializationHelper.WriteDouble(_bw, point2.X);
XamlSerializationHelper.WriteDouble(_bw, point2.Y);
XamlSerializationHelper.WriteDouble(_bw, point3.X);
XamlSerializationHelper.WriteDouble(_bw, point3.Y);
}
///
/// PolyLineTo - append a PolyLineTo to the current figure.
///
///
/// Stored as [ListOfPointAndTwoBools] (see SerializeListOfPointsAndTwoBools method).
///
public override void PolyLineTo(IList points, bool isStroked, bool isSmoothJoin)
{
SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes.PolyLineTo, points, isStroked, isSmoothJoin);
}
///
/// PolyQuadraticBezierTo - append a PolyQuadraticBezierTo to the current figure.
///
///
/// Stored as [ListOfPointAndTwoBools] (see SerializeListOfPointsAndTwoBools method).
///
public override void PolyQuadraticBezierTo(IList points, bool isStroked, bool isSmoothJoin)
{
SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes.PolyQuadraticBezierTo, points, isStroked, isSmoothJoin);
}
///
/// PolyBezierTo - append a PolyBezierTo to the current figure.
///
///
/// Stored as [ListOfPointAndTwoBools] (see SerializeListOfPointsAndTwoBools method).
///
public override void PolyBezierTo(IList points, bool isStroked, bool isSmoothJoin)
{
SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes.PolyBezierTo, points, isStroked, isSmoothJoin);
}
///
/// ArcTo - append an ArcTo to the current figure.
///
///
/// Stored as [PointAndTwoBools] [Packed byte for isLargeArc and sweepDirection] [Pair of Numbers for Size] [Pair of Numbers for rotation Angle]
///
/// Also note that we've special cased this method signature to avoid moving the enum for SweepDirection into PBT (will require codegen changes).
///
#if PBTCOMPILER
public override void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, bool sweepDirection, bool isStroked, bool isSmoothJoin)
#else
public override void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin)
#endif
{
SerializePointAndTwoBools(ParserGeometryContextOpCodes.ArcTo, point, isStroked, isSmoothJoin);
//
// Pack isLargeArc & sweepDirection into a single byte.
//
byte packMe = 0;
if (isLargeArc)
{
packMe = LowNibble;
}
#if PBTCOMPILER
if (sweepDirection)
#else
if (SweepToBool(sweepDirection))
#endif
{
packMe |= HighNibble;
}
_bw.Write(packMe);
//
// Write out Size & Rotation Angle.
//
XamlSerializationHelper.WriteDouble(_bw, size.Width);
XamlSerializationHelper.WriteDouble(_bw, size.Height);
XamlSerializationHelper.WriteDouble(_bw, rotationAngle);
}
internal bool FigurePending
{
get
{
return (_figureStreamPosition > -1);
}
}
internal int CurrentStreamPosition
{
get
{
return checked((int)_bw.Seek(0, SeekOrigin.Current));
}
}
internal void FinishFigure()
{
if (FigurePending)
{
int currentOffset = CurrentStreamPosition;
//
// Go back and overwrite our existing begin figure block. See comment in BeginFigure.
//
_bw.Seek(_figureStreamPosition, SeekOrigin.Begin);
SerializePointAndTwoBools(ParserGeometryContextOpCodes.BeginFigure, _startPoint, _isFilled, _isClosed);
_bw.Seek(currentOffset, SeekOrigin.Begin);
}
}
///
/// This is the same as the Close call:
/// Closes the Context and flushes the content.
/// Afterwards the Context can not be used anymore.
/// This call does not require all Push calls to have been Popped.
///
internal override void DisposeCore()
{
}
///
/// SetClosedState - Sets the current closed state of the figure.
///
internal override void SetClosedState(bool closed)
{
_isClosed = closed;
}
///
/// Mark that the stream is Done.
///
internal void MarkEOF()
{
//
// We need to update the BeginFigure block of the last figure (if
// there was one).
//
FinishFigure();
_bw.Write((byte) ParserGeometryContextOpCodes.Closed);
}
#if PRESENTATION_CORE
internal static void Deserialize(BinaryReader br, StreamGeometryContext sc, StreamGeometry geometry)
{
bool closed = false;
Byte currentByte;
while (!closed)
{
currentByte = br.ReadByte();
ParserGeometryContextOpCodes opCode = UnPackOpCode(currentByte);
switch(opCode)
{
case ParserGeometryContextOpCodes.FillRule :
DeserializeFillRule(br, currentByte, geometry);
break;
case ParserGeometryContextOpCodes.BeginFigure :
DeserializeBeginFigure(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.LineTo :
DeserializeLineTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.QuadraticBezierTo :
DeserializeQuadraticBezierTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.BezierTo :
DeserializeBezierTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.PolyLineTo :
DeserializePolyLineTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.PolyQuadraticBezierTo :
DeserializePolyQuadraticBezierTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.PolyBezierTo :
DeserializePolyBezierTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.ArcTo :
DeserializeArcTo(br, currentByte, sc);
break;
case ParserGeometryContextOpCodes.Closed :
closed = true;
break;
}
}
}
#endif
#endregion internal Methods
#region private Methods
//
// Deserialization Methods.
//
// These are only required at "runtime" - therefore only in PRESENTATION_CORE
//
#if PRESENTATION_CORE
private static void DeserializeFillRule(BinaryReader br, Byte firstByte, StreamGeometry geometry)
{
bool boolFillRule;
bool unused;
FillRule fillRule;
UnPackBools(firstByte, out boolFillRule, out unused);
fillRule = BoolToFillRule(boolFillRule);
geometry.FillRule = fillRule;
}
private static void DeserializeBeginFigure(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
Point point;
bool isFilled;
bool isClosed;
DeserializePointAndTwoBools(br, firstByte, out point, out isFilled, out isClosed);
sc.BeginFigure(point, isFilled, isClosed);
}
private static void DeserializeLineTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
Point point;
bool isStroked;
bool isSmoothJoin;
DeserializePointAndTwoBools(br, firstByte, out point, out isStroked, out isSmoothJoin);
sc.LineTo(point, isStroked, isSmoothJoin);
}
private static void DeserializeQuadraticBezierTo(BinaryReader br, byte firstByte, StreamGeometryContext sc)
{
Point point1;
Point point2 = new Point();
bool isStroked;
bool isSmoothJoin;
DeserializePointAndTwoBools(br, firstByte, out point1, out isStroked, out isSmoothJoin);
point2.X = XamlSerializationHelper.ReadDouble(br);
point2.Y = XamlSerializationHelper.ReadDouble(br);
sc.QuadraticBezierTo(point1, point2, isStroked, isSmoothJoin);
}
private static void DeserializeBezierTo(BinaryReader br, byte firstByte, StreamGeometryContext sc)
{
Point point1;
Point point2 = new Point();
Point point3 = new Point();
bool isStroked;
bool isSmoothJoin;
DeserializePointAndTwoBools(br, firstByte, out point1, out isStroked, out isSmoothJoin);
point2.X = XamlSerializationHelper.ReadDouble(br);
point2.Y = XamlSerializationHelper.ReadDouble(br);
point3.X = XamlSerializationHelper.ReadDouble(br);
point3.Y = XamlSerializationHelper.ReadDouble(br);
sc.BezierTo(point1, point2, point3, isStroked, isSmoothJoin);
}
private static void DeserializePolyLineTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
bool isStroked;
bool isSmoothJoin;
IList points;
points = DeserializeListOfPointsAndTwoBools(br, firstByte, out isStroked, out isSmoothJoin);
sc.PolyLineTo(points, isStroked, isSmoothJoin);
}
private static void DeserializePolyQuadraticBezierTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
bool isStroked;
bool isSmoothJoin;
IList points;
points = DeserializeListOfPointsAndTwoBools(br, firstByte, out isStroked, out isSmoothJoin);
sc.PolyQuadraticBezierTo(points, isStroked, isSmoothJoin);
}
private static void DeserializePolyBezierTo(BinaryReader br, Byte firstByte, StreamGeometryContext sc)
{
bool isStroked;
bool isSmoothJoin;
IList points;
points = DeserializeListOfPointsAndTwoBools(br, firstByte, out isStroked, out isSmoothJoin);
sc.PolyBezierTo(points, isStroked, isSmoothJoin);
}
private static void DeserializeArcTo(BinaryReader br, byte firstByte, StreamGeometryContext sc)
{
Point point;
Size size = new Size();
double rotationAngle;
bool isStroked;
bool isSmoothJoin;
bool isLargeArc;
SweepDirection sweepDirection;
DeserializePointAndTwoBools(br, firstByte, out point, out isStroked, out isSmoothJoin);
// Read the packed byte for isLargeArd & sweepDirection.
//
// Pack isLargeArc & sweepDirection into a signle byte.
//
byte packedByte = br.ReadByte();
isLargeArc = ((packedByte & LowNibble) != 0);
sweepDirection = BoolToSweep(((packedByte & HighNibble) != 0));
size.Width = XamlSerializationHelper.ReadDouble(br);
size.Height = XamlSerializationHelper.ReadDouble(br);
rotationAngle = XamlSerializationHelper.ReadDouble(br);
sc.ArcTo(point, size, rotationAngle, isLargeArc, sweepDirection, isStroked, isSmoothJoin);
}
//
// Private Deserialization helpers.
//
private static void UnPackBools(byte packedByte, out bool bool1, out bool bool2)
{
bool1 = (packedByte & SetBool1) != 0;
bool2 = (packedByte & SetBool2) != 0;
}
private static void UnPackBools(byte packedByte, out bool bool1, out bool bool2, out bool bool3, out bool bool4)
{
bool1 = (packedByte & SetBool1) != 0;
bool2 = (packedByte & SetBool2) != 0;
bool3 = (packedByte & SetBool3) != 0;
bool4 = (packedByte & SetBool4) != 0;
}
private static ParserGeometryContextOpCodes UnPackOpCode(byte packedByte)
{
return ((ParserGeometryContextOpCodes) (packedByte & 0x0F));
}
private static IList DeserializeListOfPointsAndTwoBools(BinaryReader br, Byte firstByte, out bool bool1, out bool bool2)
{
int count;
IList points;
Point point;
// Pack the two bools into one byte
UnPackBools(firstByte, out bool1, out bool2);
count = br.ReadInt32();
points = new List(count);
for(int i = 0; i < count; i++)
{
point = new Point(XamlSerializationHelper.ReadDouble(br),
XamlSerializationHelper.ReadDouble(br));
points.Add(point);
}
return points;
}
private static void DeserializePointAndTwoBools(BinaryReader br, Byte firstByte, out Point point, out bool bool1, out bool bool2)
{
bool isScaledIntegerX = false;
bool isScaledIntegerY = false;
UnPackBools(firstByte, out bool1, out bool2, out isScaledIntegerX, out isScaledIntegerY);
point = new Point(DeserializeDouble(br, isScaledIntegerX),
DeserializeDouble(br, isScaledIntegerY));
}
private static Double DeserializeDouble(BinaryReader br, bool isScaledInt)
{
if (isScaledInt)
{
return XamlSerializationHelper.ReadScaledInteger(br);
}
else
{
return XamlSerializationHelper.ReadDouble(br);
}
}
//
// Private serialization helpers
//
private static SweepDirection BoolToSweep(bool value)
{
if(!value)
return SweepDirection.Counterclockwise;
else
return SweepDirection.Clockwise;
}
private static bool SweepToBool(SweepDirection sweep)
{
if (sweep == SweepDirection.Counterclockwise)
return false;
else
return true;
}
private static FillRule BoolToFillRule(bool value)
{
if(!value)
return FillRule.EvenOdd;
else
return FillRule.Nonzero;
}
private static bool FillRuleToBool(FillRule fill)
{
if (fill == FillRule.EvenOdd)
return false;
else
return true;
}
#endif
//
// SerializePointAndTwoBools
//
// Binary format is :
//
//
//
// Where :
// := OpCode + bool1 + bool2 + isScaledIntegerX + isScaledIntegerY
// := | |
// := | |
// :=
//
// By packing the flags for isScaledInteger into the first byte - we save 2 extra bytes per number for the common case.
//
// As a result - most LineTo's (and other operations) will be stored in 9 bytes.
// Some LineTo's will be 6 (or even sometimes 3)
// Max LineTo will be 19 (two doubles).
private void SerializePointAndTwoBools(ParserGeometryContextOpCodes opCode,
Point point,
bool bool1,
bool bool2)
{
int intValueX = 0;
int intValueY = 0;
bool isScaledIntegerX, isScaledIntegerY;
isScaledIntegerX = XamlSerializationHelper.CanConvertToInteger(point.X, ref intValueX);
isScaledIntegerY = XamlSerializationHelper.CanConvertToInteger(point.Y, ref intValueY);
_bw.Write(PackByte(opCode, bool1, bool2, isScaledIntegerX, isScaledIntegerY));
SerializeDouble(point.X, isScaledIntegerX, intValueX);
SerializeDouble(point.Y, isScaledIntegerY, intValueY);
}
// SerializeListOfPointsAndTwoBools
//
// Binary format is :
//
// ...
//
// := OpCode + bool1 + bool2
// := int32
// := | |
private void SerializeListOfPointsAndTwoBools(ParserGeometryContextOpCodes opCode, IList points, bool bool1, bool bool2)
{
// Pack the two bools into one byte
Byte packedByte = PackByte(opCode, bool1, bool2);
_bw.Write(packedByte);
// Write the count.
_bw.Write(points.Count);
// Write out all the Points
for(int i = 0; i < points.Count; i++)
{
XamlSerializationHelper.WriteDouble(_bw, points[i].X);
XamlSerializationHelper.WriteDouble(_bw, points[i].Y);
}
}
private void SerializeDouble(double value, bool isScaledInt, int scaledIntValue)
{
if (isScaledInt)
{
_bw.Write(scaledIntValue);
}
else
{
XamlSerializationHelper.WriteDouble(_bw, value);
}
}
private static byte PackByte(ParserGeometryContextOpCodes opCode, bool bool1, bool bool2)
{
return PackByte(opCode, bool1, bool2, false, false);
}
// PackByte
// Packs an op-code, and up to 4 booleans into a single byte.
//
// Binary format is :
// First 4 bits map directly to the op-code.
// Next 4 bits map to booleans 1 - 4.
//
// Like this:
//
// 7| 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// |||<- Op Code ->
//
private static byte PackByte(ParserGeometryContextOpCodes opCode, bool bool1, bool bool2, bool bool3, bool bool4)
{
byte packedByte = (byte) opCode;
if (packedByte >= 16)
{
throw new ArgumentException(SR.Get(SRID.UnknownPathOperationType));
}
if (bool1)
{
packedByte |= SetBool1;
}
if (bool2)
{
packedByte |= SetBool2;
}
if (bool3)
{
packedByte |= SetBool3;
}
if (bool4)
{
packedByte |= SetBool4;
}
return packedByte;
}
#endregion private Methods
private BinaryWriter _bw;
Point _startPoint;
bool _isClosed;
bool _isFilled;
int _figureStreamPosition = -1;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WithStatement.cs
- ValueType.cs
- VariableExpressionConverter.cs
- _SSPIWrapper.cs
- MetabaseSettingsIis7.cs
- CustomAttributeBuilder.cs
- _Rfc2616CacheValidators.cs
- ComboBox.cs
- CompilerError.cs
- TextBoxRenderer.cs
- DifferencingCollection.cs
- SHA1Managed.cs
- DataException.cs
- ApplyImportsAction.cs
- ReferencedCollectionType.cs
- TextEffectCollection.cs
- FocusWithinProperty.cs
- Label.cs
- ImageConverter.cs
- CodeAttributeArgument.cs
- ErrorHandler.cs
- EncryptedXml.cs
- AsynchronousChannelMergeEnumerator.cs
- TaskHelper.cs
- KeyedCollection.cs
- BufferedStream.cs
- RunClient.cs
- SchemaEntity.cs
- RelatedPropertyManager.cs
- XPathDescendantIterator.cs
- DependencyObjectType.cs
- SchemaRegistration.cs
- Block.cs
- RootProfilePropertySettingsCollection.cs
- Events.cs
- LinkConverter.cs
- Input.cs
- Timer.cs
- ListViewCommandEventArgs.cs
- InvokeBase.cs
- PageMediaSize.cs
- EntryWrittenEventArgs.cs
- CodeStatement.cs
- ToolStripComboBox.cs
- StreamReader.cs
- AccessDataSourceDesigner.cs
- SQLInt64Storage.cs
- ScriptResourceInfo.cs
- ListBoxChrome.cs
- EndEvent.cs
- CustomWebEventKey.cs
- TextHidden.cs
- QueryOutputWriter.cs
- WhereQueryOperator.cs
- TextSerializer.cs
- EncodingTable.cs
- StatusStrip.cs
- SoapObjectWriter.cs
- EndPoint.cs
- CredentialCache.cs
- SecurityState.cs
- SimpleParser.cs
- DependencySource.cs
- TextBoxLine.cs
- SqlProviderManifest.cs
- TrackPointCollection.cs
- SchemaMerger.cs
- CategoryList.cs
- WindowsHyperlink.cs
- ProviderCollection.cs
- DatatypeImplementation.cs
- DataServiceEntityAttribute.cs
- SecurityPolicyVersion.cs
- _Semaphore.cs
- Int64Animation.cs
- DropTarget.cs
- ColumnPropertiesGroup.cs
- ChtmlFormAdapter.cs
- ClientConfigurationHost.cs
- ListViewItemSelectionChangedEvent.cs
- CodeGroup.cs
- MetadataSerializer.cs
- OrderedDictionaryStateHelper.cs
- RolePrincipal.cs
- ObjectListFieldsPage.cs
- EntityDataSourceDataSelectionPanel.cs
- FontStyleConverter.cs
- BitmapEffectRenderDataResource.cs
- ErrorWebPart.cs
- DataSourceCache.cs
- ChtmlTextWriter.cs
- TextLineBreak.cs
- TypefaceMetricsCache.cs
- Int32Animation.cs
- BitmapEffectDrawing.cs
- NotEqual.cs
- SettingsBase.cs
- NumericExpr.cs
- Expression.cs
- LabelLiteral.cs