private void AddArc(ref ReadOnlySpan <char> span, bool relative) { var size = ReadSize(ref span); span = ReadSeparator(span); var rotationAngle = ReadDouble(ref span); span = ReadSeparator(span); var isLargeArc = ReadBool(ref span); span = ReadSeparator(span); // Uno specific: CounterClockwise → Counterclockwise var sweepDirection = ReadBool(ref span) ? SweepDirection.Clockwise : SweepDirection.Counterclockwise; span = ReadSeparator(span); var end = relative ? ReadRelativePoint(ref span, _currentPoint) : ReadPoint(ref span); if (!_isOpen) { CreateFigure(); } _geometryContext.ArcTo(end, size, rotationAngle, isLargeArc, sweepDirection, true, false); // Uno specific: Extra arguments. _currentPoint = end; _previousControlPoint = null; }
/// <summary> /// Parses the specified markup string. /// </summary> /// <param name="s">The markup string.</param> public void Parse(string s, ref FillRule fillRule) { 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: fillRule = ReadFillRule(reader); //_context.SetFillRule(ReadFillRule(reader)); previousControlPoint = null; break; case Command.Move: if (openFigure) { _context.SetClosedState(false); } point = ReadPoint(reader, point, relative); _context.BeginFigure(point, true, false); openFigure = true; previousControlPoint = null; break; case Command.Line: point = ReadPoint(reader, point, relative); _context.LineTo(point, true, false); previousControlPoint = null; break; case Command.HorizontalLine: if (!relative) { point = new Point(ReadDouble(reader), point.Y); } else { point = new Point(point.X + ReadDouble(reader), point.Y); } _context.LineTo(point, true, false); previousControlPoint = null; break; case Command.VerticalLine: if (!relative) { point = new Point(point.X, ReadDouble(reader)); } else { point = new Point(point.X, point.Y + ReadDouble(reader)); } _context.LineTo(point, true, false); 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, true, false); break; } case Command.SmoothQuadraticBezierCurve: { Point end = ReadPoint(reader, point, relative); if (previousControlPoint != null) { previousControlPoint = MirrorControlPoint((Point)previousControlPoint, point); } _context.QuadraticBezierTo(previousControlPoint ?? point, end, true, false); 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.BezierTo(point1, point2, point, true, false); 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.BezierTo(previousControlPoint ?? point, point2, end, true, false); 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, true, false); previousControlPoint = null; break; } case Command.Close: _context.SetClosedState(true); openFigure = false; previousControlPoint = null; break; default: throw new NotSupportedException("Unsupported command"); } } if (openFigure) { _context.SetClosedState(false); } } }