private void EnsureFigure() { if (!_figureStarted) { _context.BeginFigure(_lastStart.AsPointShape(), _isFilled, !_isClosed); _figureStarted = true; } }
/// <summary> /// Parse a SVG path geometry string. /// </summary> /// <param name="context">The geometry context.</param> /// <param name="pathString">The path geometry string</param> /// <param name="startIndex">The string start index.</param> public void Parse(GeometryContext context, string pathString, int startIndex) { _context = context; _pathString = pathString; _pathLength = pathString.Length; _curIndex = startIndex; _secondLastPoint = Point2.FromXY(0, 0); _lastPoint = Point2.FromXY(0, 0); _lastStart = Point2.FromXY(0, 0); _figureStarted = false; bool first = true; char last_cmd = ' '; while (ReadToken()) { char cmd = _token; if (first) { if ((cmd != 'M') && (cmd != 'm')) { InvalidToken(); } first = false; } switch (cmd) { case 'm': case 'M': _lastPoint = ReadPoint(cmd, !_allowComma); _context.BeginFigure(_lastPoint.AsPointShape(), _isFilled, !_isClosed); _figureStarted = true; _lastStart = _lastPoint; last_cmd = 'M'; while (IsNumber(_allowComma)) { _lastPoint = ReadPoint(cmd, !_allowComma); _context.LineTo(_lastPoint.AsPointShape(), _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 = Point2.FromXY(_lastPoint.X + ReadNumber(!_allowComma), _lastPoint.Y); break; case 'H': _lastPoint = Point2.FromXY(_lastPoint.X + ReadNumber(!_allowComma), _lastPoint.Y); break; case 'v': _lastPoint = Point2.FromXY(_lastPoint.X, _lastPoint.Y + ReadNumber(!_allowComma)); break; case 'V': _lastPoint = Point2.FromXY(_lastPoint.X, _lastPoint.Y + ReadNumber(!_allowComma)); break; } _context.LineTo(_lastPoint.AsPointShape(), _isStroked, !_isSmoothJoin); }while (IsNumber(_allowComma)); last_cmd = 'L'; break; case 'c': case 'C': case 's': case 'S': EnsureFigure(); do { Point2 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.CubicBezierTo( p.AsPointShape(), _secondLastPoint.AsPointShape(), _lastPoint.AsPointShape(), _isStroked, !_isSmoothJoin); last_cmd = 'C'; }while (IsNumber(_allowComma)); break; case 'q': case 'Q': case 't': case 'T': 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.AsPointShape(), _lastPoint.AsPointShape(), _isStroked, !_isSmoothJoin); last_cmd = 'Q'; }while (IsNumber(_allowComma)); break; case 'a': case 'A': EnsureFigure(); do { 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.AsPointShape(), PathSize.Create(w, h), rotation, large, sweep ? SweepDirection.Clockwise : SweepDirection.Counterclockwise, _isStroked, !_isSmoothJoin); }while (IsNumber(_allowComma)); last_cmd = 'A'; break; case 'z': case 'Z': EnsureFigure(); _context.SetClosedState(_isClosed); _figureStarted = false; last_cmd = 'Z'; _lastPoint = _lastStart; break; default: InvalidToken(); break; } } }