/// <summary> /// Parse a PathFigureCollection string /// </summary> 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 this.formatProvider = CultureInfo.InvariantCulture; this.context = context; this.pathString = pathString; this.pathLength = pathString.Length; this.curIndex = startIndex; this.secondLastPoint = new Point(0, 0); this.lastPoint = new Point(0, 0); this.lastStart = new Point(0, 0); this.figureStarted = false; bool first = true; char lastCmd = ' '; while (this.ReadToken()) // Empty path is allowed in XAML { char cmd = this.token; if (first) { if ((cmd != 'M') && (cmd != 'm')) // Path starts with M|m { this.ThrowBadToken(); } first = false; } switch (cmd) { case 'm': case 'M': // XAML allows multiple points after M/m this.lastPoint = this.ReadPoint(cmd, !this.allowComma); context.BeginFigure(this.lastPoint, this.isFilled, !this.isClosed); this.figureStarted = true; this.lastStart = this.lastPoint; lastCmd = 'M'; while (this.IsNumber(this.allowComma)) { this.lastPoint = this.ReadPoint(cmd, !this.allowComma); context.LineTo(this.lastPoint, this.isStroked, !this.isSmoothJoin); lastCmd = 'L'; } break; case 'l': case 'L': case 'h': case 'H': case 'v': case 'V': this.EnsureFigure(); do { switch (cmd) { case 'l': this.lastPoint = this.ReadPoint(cmd, !this.allowComma); break; case 'L': this.lastPoint = this.ReadPoint(cmd, !this.allowComma); break; case 'h': this.lastPoint.X += this.ReadNumber(!this.allowComma); break; case 'H': this.lastPoint.X = this.ReadNumber(!this.allowComma); break; case 'v': this.lastPoint.Y += this.ReadNumber(!this.allowComma); break; case 'V': this.lastPoint.Y = this.ReadNumber(!this.allowComma); break; } context.LineTo(this.lastPoint, this.isStroked, !this.isSmoothJoin); }while (this.IsNumber(this.allowComma)); lastCmd = 'L'; break; case 'c': case 'C': // cubic Bezier case 's': case 'S': // smooth cublic Bezier this.EnsureFigure(); do { Point p; if ((cmd == 's') || (cmd == 'S')) { if (lastCmd == 'C') { p = this.Reflect(); } else { p = this.lastPoint; } this.secondLastPoint = this.ReadPoint(cmd, !this.allowComma); } else { p = this.ReadPoint(cmd, !this.allowComma); this.secondLastPoint = this.ReadPoint(cmd, this.allowComma); } this.lastPoint = this.ReadPoint(cmd, this.allowComma); context.BezierTo(p, this.secondLastPoint, this.lastPoint, this.isStroked, !this.isSmoothJoin); lastCmd = 'C'; }while (this.IsNumber(this.allowComma)); break; case 'q': case 'Q': // quadratic Bezier case 't': case 'T': // smooth quadratic Bezier this.EnsureFigure(); do { if ((cmd == 't') || (cmd == 'T')) { if (lastCmd == 'Q') { this.secondLastPoint = this.Reflect(); } else { this.secondLastPoint = this.lastPoint; } this.lastPoint = this.ReadPoint(cmd, !this.allowComma); } else { this.secondLastPoint = this.ReadPoint(cmd, !this.allowComma); this.lastPoint = this.ReadPoint(cmd, this.allowComma); } context.QuadraticBezierTo(this.secondLastPoint, this.lastPoint, this.isStroked, !this.isSmoothJoin); lastCmd = 'Q'; }while (this.IsNumber(this.allowComma)); break; case 'a': case 'A': this.EnsureFigure(); do { // A 3,4 5, 0, 0, 6,7 double w = this.ReadNumber(!this.allowComma); double h = this.ReadNumber(this.allowComma); double rotation = this.ReadNumber(this.allowComma); bool large = this.ReadBool(); bool sweep = this.ReadBool(); this.lastPoint = this.ReadPoint(cmd, this.allowComma); context.ArcTo( this.lastPoint, new Size(w, h), rotation, large, #if PBTCOMPILER sweep, #else sweep ? SweepDirection.Clockwise : SweepDirection.Counterclockwise, #endif this.isStroked, !this.isSmoothJoin); }while (this.IsNumber(this.allowComma)); lastCmd = 'A'; break; case 'z': case 'Z': this.EnsureFigure(); //context.SetClosedState(isClosed); var mi = context.GetType().GetMethod("SetClosedState", BindingFlags.Instance | BindingFlags.NonPublic); if (mi != null) { var pia = mi.GetParameters(); if (pia != null && pia.Length == 1 && pia[0].ParameterType == typeof(bool)) { mi.Invoke(context, new object[] { this.isClosed }); } } this.figureStarted = false; lastCmd = 'Z'; this.lastPoint = this.lastStart; // Set reference point to be first point of current figure break; default: this.ThrowBadToken(); break; } } }