/// <summary> /// Parses the specified markup string. /// </summary> /// <param name="s">The markup string.</param> public void Parse(string s) { bool openFigure = false; using (StringReader reader = new StringReader(s)) { Command command = Command.None; Point point = new Point(); bool relative = false; Point? previousControlPoint = null; while (ReadCommand(reader, ref command, ref relative)) { switch (command) { case Command.FillRule: _context.SetFillRule(ReadFillRule(reader)); previousControlPoint = null; break; case Command.Move: if (openFigure) { _context.EndFigure(false); } point = ReadPoint(reader, point, relative); _context.BeginFigure(point, true); openFigure = true; previousControlPoint = null; break; case Command.Line: point = ReadPoint(reader, point, relative); _context.LineTo(point); previousControlPoint = null; break; case Command.HorizontalLine: if (!relative) { point = point.WithX(ReadDouble(reader)); } else { point = new Point(point.X + ReadDouble(reader), point.Y); } _context.LineTo(point); previousControlPoint = null; break; case Command.VerticalLine: if (!relative) { point = point.WithY(ReadDouble(reader)); } else { point = new Point(point.X, point.Y + ReadDouble(reader)); } _context.LineTo(point); previousControlPoint = null; break; case Command.QuadraticBezierCurve: { Point handle = ReadPoint(reader, point, relative); previousControlPoint = handle; ReadSeparator(reader); point = ReadPoint(reader, point, relative); _context.QuadraticBezierTo(handle, point); break; } case Command.SmoothQuadraticBezierCurve: { Point end = ReadPoint(reader, point, relative); if (previousControlPoint != null) { previousControlPoint = MirrorControlPoint((Point)previousControlPoint, point); } _context.QuadraticBezierTo(previousControlPoint ?? point, end); point = end; break; } case Command.CubicBezierCurve: { Point point1 = ReadPoint(reader, point, relative); ReadSeparator(reader); Point point2 = ReadPoint(reader, point, relative); previousControlPoint = point2; ReadSeparator(reader); point = ReadPoint(reader, point, relative); _context.CubicBezierTo(point1, point2, point); break; } case Command.SmoothCubicBezierCurve: { Point point2 = ReadPoint(reader, point, relative); ReadSeparator(reader); Point end = ReadPoint(reader, point, relative); if (previousControlPoint != null) { previousControlPoint = MirrorControlPoint((Point)previousControlPoint, point); } _context.CubicBezierTo(previousControlPoint ?? point, point2, end); previousControlPoint = point2; point = end; break; } case Command.Arc: { Size size = ReadSize(reader); ReadSeparator(reader); double rotationAngle = ReadDouble(reader); ReadSeparator(reader); bool isLargeArc = ReadBool(reader); ReadSeparator(reader); SweepDirection sweepDirection = ReadBool(reader) ? SweepDirection.Clockwise : SweepDirection.CounterClockwise; ReadSeparator(reader); point = ReadPoint(reader, point, relative); _context.ArcTo(point, size, rotationAngle, isLargeArc, sweepDirection); previousControlPoint = null; break; } case Command.Close: _context.EndFigure(true); openFigure = false; previousControlPoint = null; break; default: throw new NotSupportedException("Unsupported command"); } } if (openFigure) { _context.EndFigure(false); } } }
/// <summary> /// Parses the specified markup string. /// </summary> /// <param name="s">The markup string.</param> public void Parse(string s) { bool openFigure = false; using (StringReader reader = new StringReader(s)) { Command lastCommand = Command.None; Command command; Point point = new Point(); while ((command = ReadCommand(reader, lastCommand)) != Command.Eof) { switch (command) { case Command.FillRule: _context.SetFillRule(ReadFillRule(reader)); break; case Command.Move: case Command.MoveRelative: if (openFigure) { _context.EndFigure(false); } point = command == Command.Move ? ReadPoint(reader) : ReadRelativePoint(reader, point); _context.BeginFigure(point, true); openFigure = true; break; case Command.Line: point = ReadPoint(reader); _context.LineTo(point); break; case Command.LineRelative: point = ReadRelativePoint(reader, point); _context.LineTo(point); break; case Command.HorizontalLine: point = point.WithX(ReadDouble(reader)); _context.LineTo(point); break; case Command.HorizontalLineRelative: point = new Point(point.X + ReadDouble(reader), point.Y); _context.LineTo(point); break; case Command.VerticalLine: point = point.WithY(ReadDouble(reader)); _context.LineTo(point); break; case Command.VerticalLineRelative: point = new Point(point.X, point.Y + ReadDouble(reader)); _context.LineTo(point); break; case Command.CubicBezierCurve: { Point point1 = ReadPoint(reader); Point point2 = ReadPoint(reader); point = ReadPoint(reader); _context.CubicBezierTo(point1, point2, point); break; } case Command.CubicBezierCurveRelative: { Point point1 = ReadRelativePoint(reader, point); Point point2 = ReadRelativePoint(reader, point); _context.CubicBezierTo(point, point1, point2); point = point2; break; } case Command.Arc: { //example: A10,10 0 0,0 10,20 //format - size rotationAngle isLargeArcFlag sweepDirectionFlag endPoint Size size = ReadSize(reader); ReadSeparator(reader); double rotationAngle = ReadDouble(reader); ReadSeparator(reader); bool isLargeArc = ReadBool(reader); ReadSeparator(reader); SweepDirection sweepDirection = ReadBool(reader) ? SweepDirection.Clockwise : SweepDirection.CounterClockwise; point = ReadPoint(reader); _context.ArcTo(point, size, rotationAngle, isLargeArc, sweepDirection); break; } case Command.Close: _context.EndFigure(true); openFigure = false; break; default: throw new NotSupportedException("Unsupported command"); } lastCommand = command; } if (openFigure) { _context.EndFigure(false); } } }