Exemplo n.º 1
0
        private static void CreatePathSegment(char command, SvgPathSegmentList segments, CoordinateParser parser,
            bool isRelative)
        {
            var coords = new float[6];

            switch (command)
            {
                case 'm': // relative moveto
                case 'M': // moveto
                    if (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]))
                    {
                        segments.Add(new SvgMoveToSegment(ToAbsolute(coords[0], coords[1], segments, isRelative)));
                    }

                    while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]))
                    {
                        segments.Add(new SvgLineSegment(segments.Last.End,
                            ToAbsolute(coords[0], coords[1], segments, isRelative)));
                    }
                    break;
                case 'a':
                case 'A':
                    bool size;
                    bool sweep;

                    while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]) &&
                           parser.TryGetFloat(out coords[2]) && parser.TryGetBool(out size) &&
                           parser.TryGetBool(out sweep) && parser.TryGetFloat(out coords[3]) &&
                           parser.TryGetFloat(out coords[4]))
                    {
                        // A|a rx ry x-axis-rotation large-arc-flag sweep-flag x y
                        segments.Add(new SvgArcSegment(segments.Last.End, coords[0], coords[1], coords[2],
                            (size ? SvgArcSize.Large : SvgArcSize.Small),
                            (sweep ? SvgArcSweep.Positive : SvgArcSweep.Negative),
                            ToAbsolute(coords[3], coords[4], segments, isRelative)));
                    }
                    break;
                case 'l': // relative lineto
                case 'L': // lineto
                    while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]))
                    {
                        segments.Add(new SvgLineSegment(segments.Last.End,
                            ToAbsolute(coords[0], coords[1], segments, isRelative)));
                    }
                    break;
                case 'H': // horizontal lineto
                case 'h': // relative horizontal lineto
                    while (parser.TryGetFloat(out coords[0]))
                    {
                        segments.Add(new SvgLineSegment(segments.Last.End,
                            ToAbsolute(coords[0], segments.Last.End.Y, segments, isRelative, false)));
                    }
                    break;
                case 'V': // vertical lineto
                case 'v': // relative vertical lineto
                    while (parser.TryGetFloat(out coords[0]))
                    {
                        segments.Add(new SvgLineSegment(segments.Last.End,
                            ToAbsolute(segments.Last.End.X, coords[0], segments, false, isRelative)));
                    }
                    break;
                case 'Q': // curveto
                case 'q': // relative curveto
                    while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]) &&
                           parser.TryGetFloat(out coords[2]) && parser.TryGetFloat(out coords[3]))
                    {
                        segments.Add(new SvgQuadraticCurveSegment(segments.Last.End,
                            ToAbsolute(coords[0], coords[1], segments, isRelative),
                            ToAbsolute(coords[2], coords[3], segments, isRelative)));
                    }
                    break;
                case 'T': // shorthand/smooth curveto
                case 't': // relative shorthand/smooth curveto
                    while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]))
                    {
                        var lastQuadCurve = segments.Last as SvgQuadraticCurveSegment;

                        var controlPoint = lastQuadCurve != null
                            ? Reflect(lastQuadCurve.ControlPoint, segments.Last.End)
                            : segments.Last.End;

                        segments.Add(new SvgQuadraticCurveSegment(segments.Last.End, controlPoint,
                            ToAbsolute(coords[0], coords[1], segments, isRelative)));
                    }
                    break;
                case 'C': // curveto
                case 'c': // relative curveto
                    while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]) &&
                           parser.TryGetFloat(out coords[2]) && parser.TryGetFloat(out coords[3]) &&
                           parser.TryGetFloat(out coords[4]) && parser.TryGetFloat(out coords[5]))
                    {
                        segments.Add(new SvgCubicCurveSegment(segments.Last.End,
                            ToAbsolute(coords[0], coords[1], segments, isRelative),
                            ToAbsolute(coords[2], coords[3], segments, isRelative),
                            ToAbsolute(coords[4], coords[5], segments, isRelative)));
                    }
                    break;
                case 'S': // shorthand/smooth curveto
                case 's': // relative shorthand/smooth curveto
                    while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]) &&
                           parser.TryGetFloat(out coords[2]) && parser.TryGetFloat(out coords[3]))
                    {
                        var lastCubicCurve = segments.Last as SvgCubicCurveSegment;

                        var controlPoint = lastCubicCurve != null
                            ? Reflect(lastCubicCurve.SecondControlPoint, segments.Last.End)
                            : segments.Last.End;

                        segments.Add(new SvgCubicCurveSegment(segments.Last.End, controlPoint,
                            ToAbsolute(coords[0], coords[1], segments, isRelative),
                            ToAbsolute(coords[2], coords[3], segments, isRelative)));
                    }
                    break;
                case 'Z': // closepath
                case 'z': // relative closepath
                    segments.Add(new SvgClosePathSegment());
                    break;
            }
        }
Exemplo n.º 2
0
        private static void CreatePathSegment(char command, SvgPathSegmentList segments, CoordinateParser parser,
                                              bool isRelative)
        {
            var coords = new float[6];

            switch (command)
            {
            case 'm':     // relative moveto
            case 'M':     // moveto
                if (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]))
                {
                    segments.Add(new SvgMoveToSegment(ToAbsolute(coords[0], coords[1], segments, isRelative)));
                }

                while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]))
                {
                    segments.Add(new SvgLineSegment(segments.Last.End,
                                                    ToAbsolute(coords[0], coords[1], segments, isRelative)));
                }
                break;

            case 'a':
            case 'A':
                bool size;
                bool sweep;

                while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]) &&
                       parser.TryGetFloat(out coords[2]) && parser.TryGetBool(out size) &&
                       parser.TryGetBool(out sweep) && parser.TryGetFloat(out coords[3]) &&
                       parser.TryGetFloat(out coords[4]))
                {
                    // A|a rx ry x-axis-rotation large-arc-flag sweep-flag x y
                    segments.Add(new SvgArcSegment(segments.Last.End, coords[0], coords[1], coords[2],
                                                   (size ? SvgArcSize.Large : SvgArcSize.Small),
                                                   (sweep ? SvgArcSweep.Positive : SvgArcSweep.Negative),
                                                   ToAbsolute(coords[3], coords[4], segments, isRelative)));
                }
                break;

            case 'l':     // relative lineto
            case 'L':     // lineto
                while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]))
                {
                    segments.Add(new SvgLineSegment(segments.Last.End,
                                                    ToAbsolute(coords[0], coords[1], segments, isRelative)));
                }
                break;

            case 'H':     // horizontal lineto
            case 'h':     // relative horizontal lineto
                while (parser.TryGetFloat(out coords[0]))
                {
                    segments.Add(new SvgLineSegment(segments.Last.End,
                                                    ToAbsolute(coords[0], segments.Last.End.Y, segments, isRelative, false)));
                }
                break;

            case 'V':     // vertical lineto
            case 'v':     // relative vertical lineto
                while (parser.TryGetFloat(out coords[0]))
                {
                    segments.Add(new SvgLineSegment(segments.Last.End,
                                                    ToAbsolute(segments.Last.End.X, coords[0], segments, false, isRelative)));
                }
                break;

            case 'Q':     // curveto
            case 'q':     // relative curveto
                while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]) &&
                       parser.TryGetFloat(out coords[2]) && parser.TryGetFloat(out coords[3]))
                {
                    segments.Add(new SvgQuadraticCurveSegment(segments.Last.End,
                                                              ToAbsolute(coords[0], coords[1], segments, isRelative),
                                                              ToAbsolute(coords[2], coords[3], segments, isRelative)));
                }
                break;

            case 'T':     // shorthand/smooth curveto
            case 't':     // relative shorthand/smooth curveto
                while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]))
                {
                    var lastQuadCurve = segments.Last as SvgQuadraticCurveSegment;

                    var controlPoint = lastQuadCurve != null
                            ? Reflect(lastQuadCurve.ControlPoint, segments.Last.End)
                            : segments.Last.End;

                    segments.Add(new SvgQuadraticCurveSegment(segments.Last.End, controlPoint,
                                                              ToAbsolute(coords[0], coords[1], segments, isRelative)));
                }
                break;

            case 'C':     // curveto
            case 'c':     // relative curveto
                while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]) &&
                       parser.TryGetFloat(out coords[2]) && parser.TryGetFloat(out coords[3]) &&
                       parser.TryGetFloat(out coords[4]) && parser.TryGetFloat(out coords[5]))
                {
                    segments.Add(new SvgCubicCurveSegment(segments.Last.End,
                                                          ToAbsolute(coords[0], coords[1], segments, isRelative),
                                                          ToAbsolute(coords[2], coords[3], segments, isRelative),
                                                          ToAbsolute(coords[4], coords[5], segments, isRelative)));
                }
                break;

            case 'S':     // shorthand/smooth curveto
            case 's':     // relative shorthand/smooth curveto
                while (parser.TryGetFloat(out coords[0]) && parser.TryGetFloat(out coords[1]) &&
                       parser.TryGetFloat(out coords[2]) && parser.TryGetFloat(out coords[3]))
                {
                    var lastCubicCurve = segments.Last as SvgCubicCurveSegment;

                    var controlPoint = lastCubicCurve != null
                            ? Reflect(lastCubicCurve.SecondControlPoint, segments.Last.End)
                            : segments.Last.End;

                    segments.Add(new SvgCubicCurveSegment(segments.Last.End, controlPoint,
                                                          ToAbsolute(coords[0], coords[1], segments, isRelative),
                                                          ToAbsolute(coords[2], coords[3], segments, isRelative)));
                }
                break;

            case 'Z':     // closepath
            case 'z':     // relative closepath
                segments.Add(new SvgClosePathSegment());
                break;
            }
        }