public static bool TryParse(string src, int head, out PathSlice slice, out int next) { head = src.IndexOfAny(_Commands, head); if (head < 0) { slice = default; next = -1; return(false); } var tail = src.IndexOfAny(_Commands, head + 1); if (tail < 0) { tail = src.Length; } else { tail -= 1; } if (tail == head) { slice = default; next = -1; return(false); } slice = new PathSlice(src, head, tail - head); next = tail; return(true); }
public static IEnumerable <Point2[]> ParseShapes(string path) { var commands = PathSlice.Parse(path); var values = new List <float>(); var sequence = new List <Point2>(); var head = Point2.Zero; // beginning of the shape, used to close with Z. var tcpt = Point2.Zero; // 2nd control point, used for smooth curves. var tail = Point2.Zero; // current point. foreach (var cmd in commands) { values.Clear(); cmd.CopyTo(values); switch (cmd.Command) { case CommandType.ClosePath: { if (sequence.Count > 0) { sequence.Add(head); yield return(sequence.ToArray()); } sequence.Clear(); tail = head; break; } case CommandType.MoveTo: { if (sequence.Count > 0) { yield return(sequence.ToArray()); } sequence.Clear(); tcpt = tail = _ApplyLineTo(sequence, tail, values, cmd.IsRelative); head = sequence[0]; break; } case CommandType.LineHorizontalTo: { tcpt = tail = _ApplyLineTo(sequence, tail, values, cmd.IsRelative, true, false); break; } case CommandType.LineVerticalTo: { tcpt = tail = _ApplyLineTo(sequence, tail, values, cmd.IsRelative, false, true); break; } case CommandType.LineTo: { tcpt = tail = _ApplyLineTo(sequence, tail, values, cmd.IsRelative, true, true); break; } case CommandType.Arc: { tcpt = tail = _ApplyArcTo(sequence, tail, values, cmd.IsRelative); break; } case CommandType.CubicCurveTo: { sequence.Add(tail); (tcpt, tail) = _ApplyCurveTo(sequence, tail, values, cmd.IsRelative); break; } case CommandType.SmoothCubicCurveTo: { sequence.Add(tail); (tcpt, tail) = _ApplySmoothCurveTo(sequence, tcpt.XY, tail, values, cmd.IsRelative); break; } default: throw new NotImplementedException(); } } if (sequence.Count > 0) { yield return(sequence.ToArray()); } }