Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / parserscommon.cs / 1305600 / parserscommon.cs
//------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2006 // // File: ParsersCommon.cs // Synopsis: Implements class Parsers for internal use of type converters // // This file contains all the code that is shared between PresentationBuildTasks and PresentationCore // // Changes to this file will likely result in a compiler update. // // Created: 02/23/2006 // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Specialized; using System.Diagnostics; using MS.Internal; using System.ComponentModel; using System.Globalization; using System.IO; #if PRESENTATION_CORE using System.Windows.Media; using System.Windows.Media.Media3D; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; using MS.Internal.Media; using TypeConverterHelper = System.Windows.Markup.TypeConverterHelper; namespace MS.Internal #elif PBTCOMPILER using MS.Utility ; using MS.Internal.Markup; using TypeConverterHelper = MS.Internal.Markup.TypeConverterHelper; namespace MS.Internal.Markup #endif { internal static partial class Parsers { #if !PBTCOMPILER internal static object DeserializeStreamGeometry( BinaryReader reader ) { StreamGeometry geometry = new StreamGeometry(); using (StreamGeometryContext context = geometry.Open()) { ParserStreamGeometryContext.Deserialize( reader, context, geometry ); } geometry.Freeze(); return geometry; } #endif internal static void PathMinilanguageToBinary( BinaryWriter bw, string stringValue ) { ParserStreamGeometryContext context = new ParserStreamGeometryContext( bw ); #if PRESENTATION_CORE FillRule fillRule = FillRule.EvenOdd ; #else bool fillRule = false ; #endif ParseStringToStreamGeometryContext(context, stringValue, TypeConverterHelper.InvariantEnglishUS, ref fillRule); context.SetFillRule( fillRule ); context.MarkEOF(); } ////// Parse a PathGeometry string. /// The PathGeometry syntax is the same as the PathFigureCollection syntax except that it /// may start with a "wsp*Fwsp*(0|1)" which indicate the winding mode (F0 is EvenOdd while /// F1 is NonZero). /// #if !PBTCOMPILER internal static Geometry ParseGeometry( string pathString, IFormatProvider formatProvider) { FillRule fillRule = FillRule.EvenOdd ; StreamGeometry geometry = new StreamGeometry(); StreamGeometryContext context = geometry.Open(); ParseStringToStreamGeometryContext( context, pathString, formatProvider , ref fillRule ) ; geometry.FillRule = fillRule ; geometry.Freeze(); return geometry; } #endif // // Given a mini-language representation of a Geometry - write it to the // supplied streamgeometrycontext // private static void ParseStringToStreamGeometryContext ( StreamGeometryContext context, string pathString, IFormatProvider formatProvider, #if PRESENTATION_CORE ref FillRule fillRule #else ref bool fillRule #endif ) { using ( context ) { // Check to ensure that there's something to parse if (pathString != null) { int curIndex = 0; // skip any leading space while ((curIndex < pathString.Length) && Char.IsWhiteSpace(pathString, curIndex)) { curIndex++; } // Is there anything to look at? if (curIndex < pathString.Length) { // If so, we only care if the first non-WhiteSpace char encountered is 'F' if (pathString[curIndex] == 'F') { curIndex++; // Since we found 'F' the next non-WhiteSpace char must be 0 or 1 - look for it. while ((curIndex < pathString.Length) && Char.IsWhiteSpace(pathString, curIndex)) { curIndex++; } // If we ran out of text, this is an error, because 'F' cannot be specified without 0 or 1 // Also, if the next token isn't 0 or 1, this too is illegal if ((curIndex == pathString.Length) || ((pathString[curIndex] != '0') && (pathString[curIndex] != '1'))) { throw new FormatException(SR.Get(SRID.Parsers_IllegalToken)); } #if PRESENTATION_CORE fillRule = pathString[curIndex] == '0' ? FillRule.EvenOdd : FillRule.Nonzero; #else fillRule = pathString[curIndex] != '0' ; #endif // Increment curIndex to point to the next char curIndex++; } } AbbreviatedGeometryParser parser = new AbbreviatedGeometryParser(); parser.ParseToGeometryContext(context, pathString, curIndex); } } } } ////// Parser for XAML abbreviated geometry. /// SVG path spec is closely followed http://www.w3.org/TR/SVG11/paths.html /// 3/23/2006, new parser for performance (fyuan) /// sealed internal class AbbreviatedGeometryParser { const bool AllowSign = true; const bool AllowComma = true; const bool IsFilled = true; const bool IsClosed = true; const bool IsStroked = true; const bool IsSmoothJoin = true; IFormatProvider _formatProvider; string _pathString; // Input string to be parsed int _pathLength; int _curIndex; // Location to read next character from bool _figureStarted; // StartFigure is effective Point _lastStart; // Last figure starting point Point _lastPoint; // Last point Point _secondLastPoint; // The point before last point char _token; // Non whitespace character returned by ReadToken StreamGeometryContext _context; ////// Throw unexpected token exception /// private void ThrowBadToken() { throw new System.FormatException(SR.Get(SRID.Parser_UnexpectedToken, _pathString, _curIndex - 1)); } bool More() { return _curIndex < _pathLength; } // Skip white space, one comma if allowed private bool SkipWhiteSpace(bool allowComma) { bool commaMet = false; while (More()) { char ch = _pathString[_curIndex]; switch (ch) { case ' ' : case '\n': case '\r': case '\t': // SVG whitespace break; case ',': if (allowComma) { commaMet = true; allowComma = false; // one comma only } else { ThrowBadToken(); } break; default: // Avoid calling IsWhiteSpace for ch in (' ' .. 'z'] if (((ch >' ') && (ch <= 'z')) || ! Char.IsWhiteSpace(ch)) { return commaMet; } break; } _curIndex ++; } return commaMet; } ////// Read the next non whitespace character /// ///True if not end of string private bool ReadToken() { SkipWhiteSpace(!AllowComma); // Check for end of string if (More()) { _token = _pathString[_curIndex ++]; return true; } else { return false; } } private bool IsNumber(bool allowComma) { bool commaMet = SkipWhiteSpace(allowComma); if (More()) { _token = _pathString[_curIndex]; // Valid start of a number if ((_token == '.') || (_token == '-') || (_token == '+') || ((_token >= '0') && (_token <= '9')) || (_token == 'I') // Infinity || (_token == 'N')) // NaN { return true; } } if (commaMet) // Only allowed between numbers { ThrowBadToken(); } return false; } void SkipDigits(bool signAllowed) { // Allow for a sign if (signAllowed && More() && ((_pathString[_curIndex] == '-') || _pathString[_curIndex] == '+')) { _curIndex++; } while (More() && (_pathString[_curIndex] >= '0') && (_pathString[_curIndex] <= '9')) { _curIndex ++; } } // // ///// /// See if the current token matches the string s. If so, advance and // /// return true. Else, return false. // /// // bool TryAdvance(string s) // { // Debug.Assert(s.Length != 0); // // bool match = false; // if (More() && _pathString[_currentIndex] == s[0]) // { // // // // Don't bother reading subsequent characters, as the CLR parser will // // do this for us later. // // // _currentIndex = Math.Min(_currentIndex + s.Length, _pathLength); // // match = true; // } // // return match; // } // ////// Read a floating point number /// ///double ReadNumber(bool allowComma) { if (!IsNumber(allowComma)) { ThrowBadToken(); } bool simple = true; int start = _curIndex; // // Allow for a sign // // There are numbers that cannot be preceded with a sign, for instance, -NaN, but it's // fine to ignore that at this point, since the CLR parser will catch this later. // if (More() && ((_pathString[_curIndex] == '-') || _pathString[_curIndex] == '+')) { _curIndex ++; } // Check for Infinity (or -Infinity). if (More() && (_pathString[_curIndex] == 'I')) { // // Don't bother reading the characters, as the CLR parser will // do this for us later. // _curIndex = Math.Min(_curIndex+8, _pathLength); // "Infinity" has 8 characters simple = false; } // Check for NaN else if (More() && (_pathString[_curIndex] == 'N')) { // // Don't bother reading the characters, as the CLR parser will // do this for us later. // _curIndex = Math.Min(_curIndex+3, _pathLength); // "NaN" has 3 characters simple = false; } else { SkipDigits(! AllowSign); // Optional period, followed by more digits if (More() && (_pathString[_curIndex] == '.')) { simple = false; _curIndex ++; SkipDigits(! AllowSign); } // Exponent if (More() && ((_pathString[_curIndex] == 'E') || (_pathString[_curIndex] == 'e'))) { simple = false; _curIndex ++; SkipDigits(AllowSign); } } if (simple && (_curIndex <= (start + 8))) // 32-bit integer { int sign = 1; if (_pathString[start] == '+') { start ++; } else if (_pathString[start] == '-') { start ++; sign = -1; } int value = 0; while (start < _curIndex) { value = value * 10 + (_pathString[start] - '0'); start ++; } return value * sign; } else { string subString = _pathString.Substring(start, _curIndex - start); try { return System.Convert.ToDouble(subString, _formatProvider); } catch (FormatException except) { throw new System.FormatException(SR.Get(SRID.Parser_UnexpectedToken, _pathString, start), except); } } } /// /// Read a bool: 1 or 0 /// ///bool ReadBool() { SkipWhiteSpace(AllowComma); if (More()) { _token = _pathString[_curIndex ++]; if (_token == '0') { return false; } else if (_token == '1') { return true; } } ThrowBadToken(); return false; } /// /// Read a relative point /// ///private Point ReadPoint(char cmd, bool allowcomma) { double x = ReadNumber(allowcomma); double y = ReadNumber(AllowComma); if (cmd >= 'a') // 'A' < 'a'. lower case for relative { x += _lastPoint.X; y += _lastPoint.Y; } return new Point(x, y); } /// /// Reflect _secondLastPoint over _lastPoint to get a new point for smooth curve /// ///private Point Reflect() { return new Point(2 * _lastPoint.X - _secondLastPoint.X, 2 * _lastPoint.Y - _secondLastPoint.Y); } private void EnsureFigure() { if (!_figureStarted) { _context.BeginFigure(_lastStart, IsFilled, ! IsClosed); _figureStarted = true; } } /// /// Parse a PathFigureCollection string /// internal void ParseToGeometryContext( StreamGeometryContext context, string pathString, int startIndex) { // [BreakingChange] Dev10 Bug #453199 // We really should throw an ArgumentNullException here for context and pathString. // From original code // This is only used in call to Double.Parse _formatProvider = System.Globalization.CultureInfo.InvariantCulture; _context = context; _pathString = pathString; _pathLength = pathString.Length; _curIndex = startIndex; _secondLastPoint = new Point(0, 0); _lastPoint = new Point(0, 0); _lastStart = new Point(0, 0); _figureStarted = false; bool first = true; char last_cmd = ' '; while (ReadToken()) // Empty path is allowed in XAML { char cmd = _token; if (first) { if ((cmd != 'M') && (cmd != 'm')) // Path starts with M|m { ThrowBadToken(); } first = false; } switch (cmd) { case 'm': case 'M': // XAML allows multiple points after M/m _lastPoint = ReadPoint(cmd, ! AllowComma); context.BeginFigure(_lastPoint, IsFilled, ! IsClosed); _figureStarted = true; _lastStart = _lastPoint; last_cmd = 'M'; while (IsNumber(AllowComma)) { _lastPoint = ReadPoint(cmd, ! AllowComma); context.LineTo(_lastPoint, IsStroked, ! IsSmoothJoin); last_cmd = 'L'; } break; case 'l': case 'L': case 'h': case 'H': case 'v': case 'V': EnsureFigure(); do { switch (cmd) { case 'l': _lastPoint = ReadPoint(cmd, ! AllowComma); break; case 'L': _lastPoint = ReadPoint(cmd, ! AllowComma); break; case 'h': _lastPoint.X += ReadNumber(! AllowComma); break; case 'H': _lastPoint.X = ReadNumber(! AllowComma); break; case 'v': _lastPoint.Y += ReadNumber(! AllowComma); break; case 'V': _lastPoint.Y = ReadNumber(! AllowComma); break; } context.LineTo(_lastPoint, IsStroked, ! IsSmoothJoin); } while (IsNumber(AllowComma)); last_cmd = 'L'; break; case 'c': case 'C': // cubic Bezier case 's': case 'S': // smooth cublic Bezier EnsureFigure(); do { Point p; if ((cmd == 's') || (cmd == 'S')) { if (last_cmd == 'C') { p = Reflect(); } else { p = _lastPoint; } _secondLastPoint = ReadPoint(cmd, ! AllowComma); } else { p = ReadPoint(cmd, ! AllowComma); _secondLastPoint = ReadPoint(cmd, AllowComma); } _lastPoint = ReadPoint(cmd, AllowComma); context.BezierTo(p, _secondLastPoint, _lastPoint, IsStroked, ! IsSmoothJoin); last_cmd = 'C'; } while (IsNumber(AllowComma)); break; case 'q': case 'Q': // quadratic Bezier case 't': case 'T': // smooth quadratic Bezier EnsureFigure(); do { if ((cmd == 't') || (cmd == 'T')) { if (last_cmd == 'Q') { _secondLastPoint = Reflect(); } else { _secondLastPoint = _lastPoint; } _lastPoint = ReadPoint(cmd, ! AllowComma); } else { _secondLastPoint = ReadPoint(cmd, ! AllowComma); _lastPoint = ReadPoint(cmd, AllowComma); } context.QuadraticBezierTo(_secondLastPoint, _lastPoint, IsStroked, ! IsSmoothJoin); last_cmd = 'Q'; } while (IsNumber(AllowComma)); break; case 'a': case 'A': EnsureFigure(); do { // A 3,4 5, 0, 0, 6,7 double w = ReadNumber(! AllowComma); double h = ReadNumber(AllowComma); double rotation = ReadNumber(AllowComma); bool large = ReadBool(); bool sweep = ReadBool(); _lastPoint = ReadPoint(cmd, AllowComma); context.ArcTo( _lastPoint, new Size(w, h), rotation, large, #if PBTCOMPILER sweep, #else sweep ? SweepDirection.Clockwise : SweepDirection.Counterclockwise, #endif IsStroked, ! IsSmoothJoin ); } while (IsNumber(AllowComma)); last_cmd = 'A'; break; case 'z': case 'Z': EnsureFigure(); context.SetClosedState(IsClosed); _figureStarted = false; last_cmd = 'Z'; _lastPoint = _lastStart; // Set reference point to be first point of current figure break; default: ThrowBadToken(); break; } } } } } // 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
- WaitHandleCannotBeOpenedException.cs
- CompositionTarget.cs
- CheckBox.cs
- AppModelKnownContentFactory.cs
- WebEncodingValidatorAttribute.cs
- KeyConstraint.cs
- RijndaelManagedTransform.cs
- ObjectMemberMapping.cs
- ADMembershipUser.cs
- GridViewHeaderRowPresenterAutomationPeer.cs
- QueryResultOp.cs
- DataGridViewRow.cs
- SqlReferenceCollection.cs
- SafeLocalAllocation.cs
- ButtonField.cs
- ContainerActivationHelper.cs
- RunWorkerCompletedEventArgs.cs
- DoubleLinkListEnumerator.cs
- SmtpAuthenticationManager.cs
- TextTreeObjectNode.cs
- WebPartsPersonalization.cs
- ToReply.cs
- XslAstAnalyzer.cs
- ColorContext.cs
- Regex.cs
- TypeElement.cs
- WorkflowOwnerAsyncResult.cs
- BooleanToVisibilityConverter.cs
- Underline.cs
- ToolStripDropDownClosedEventArgs.cs
- ContentPresenter.cs
- SqlDataSourceFilteringEventArgs.cs
- Function.cs
- WebPartUtil.cs
- EpmTargetPathSegment.cs
- DrawingGroup.cs
- IResourceProvider.cs
- GcHandle.cs
- BuildResult.cs
- LayoutSettings.cs
- WindowsFormsHost.cs
- PolyQuadraticBezierSegment.cs
- RSAOAEPKeyExchangeDeformatter.cs
- CodePageUtils.cs
- HttpClientChannel.cs
- MethodCallConverter.cs
- ResourceContainer.cs
- SelfIssuedAuthRSACryptoProvider.cs
- DataGridTableCollection.cs
- GridViewRowCollection.cs
- UmAlQuraCalendar.cs
- ReadOnlyPropertyMetadata.cs
- Membership.cs
- ToggleButtonAutomationPeer.cs
- BaseParagraph.cs
- parserscommon.cs
- NameTable.cs
- DateTimeConverter2.cs
- ClientFormsAuthenticationMembershipProvider.cs
- AssemblyBuilder.cs
- DecoderExceptionFallback.cs
- PenLineJoinValidation.cs
- IntSumAggregationOperator.cs
- SendSecurityHeaderElement.cs
- SafeProcessHandle.cs
- GeneratedCodeAttribute.cs
- RequestQueue.cs
- HierarchicalDataBoundControlAdapter.cs
- HelpInfo.cs
- HandleCollector.cs
- SoapSchemaExporter.cs
- WizardStepBase.cs
- SpoolingTaskBase.cs
- ControlIdConverter.cs
- EdmPropertyAttribute.cs
- RepeatBehaviorConverter.cs
- TypeDefinition.cs
- WebPartVerb.cs
- SafeEventLogWriteHandle.cs
- TimeSpanConverter.cs
- AtomServiceDocumentSerializer.cs
- WebInvokeAttribute.cs
- FontDriver.cs
- SqlWebEventProvider.cs
- URLAttribute.cs
- CodeTryCatchFinallyStatement.cs
- MissingFieldException.cs
- CompiledXpathExpr.cs
- DataExpression.cs
- ClientScriptManager.cs
- XamlReaderHelper.cs
- PropertyFilterAttribute.cs
- SHA512Managed.cs
- Accessors.cs
- AppSettingsExpressionBuilder.cs
- MatrixCamera.cs
- ItemCollection.cs
- UIElement.cs
- WindowsSpinner.cs
- ParameterBuilder.cs