예제 #1
0
            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);
            }
예제 #2
0
        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());
            }
        }