Пример #1
0
        /// <summary>
        /// Converts the given object to the type of this converter, using the specified context and culture information.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
        /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture.</param>
        /// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
        /// <returns>
        /// An <see cref="T:System.Object"/> that represents the converted value.
        /// </returns>
        /// <exception cref="T:System.NotSupportedException">The conversion cannot be performed. </exception>
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                var parser     = new CoordinateParser(((string)value).Trim());
                var pointValue = 0.0f;
                var result     = new SvgPointCollection();
                while (parser.TryGetFloat(out pointValue))
                {
                    result.Add(new SvgUnit(SvgUnitType.User, pointValue));
                }

                return(result);
            }

            return(base.ConvertFrom(context, culture, value));
        }
Пример #2
0
        /// <summary>
        /// Converts the given object to the type of this converter, using the specified context and culture information.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
        /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture.</param>
        /// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
        /// <returns>
        /// An <see cref="T:System.Object"/> that represents the converted value.
        /// </returns>
        /// <exception cref="T:System.NotSupportedException">The conversion cannot be performed. </exception>
        public override SvgPointCollection Convert(string value)
        {
            var strValue = ((string)value).Trim();

            if (string.Compare(strValue, "none", StringComparison.OrdinalIgnoreCase) == 0)
            {
                return(null);
            }

            var parser     = new CoordinateParser(strValue);
            var pointValue = 0.0f;
            var result     = new SvgPointCollection();

            while (parser.TryGetFloat(out pointValue))
            {
                result.Add(new SvgUnit(SvgUnitType.User, pointValue));
            }

            return(result);
        }
Пример #3
0
        //private static readonly SvgUnitConverter _unitConverter = new SvgUnitConverter();


        /// <summary>
        /// Converts the given object to the type of this converter, using the specified context and culture information.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
        /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture.</param>
        /// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
        /// <returns>
        /// An <see cref="T:System.Object"/> that represents the converted value.
        /// </returns>
        /// <exception cref="T:System.NotSupportedException">The conversion cannot be performed. </exception>
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                var strValue = ((string)value).Trim();
                if (string.Compare(strValue, "none", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    return(null);
                }

                var parser     = new CoordinateParser(strValue);
                var pointValue = 0.0f;
                var result     = new SvgPointCollection();
                while (parser.TryGetFloat(out pointValue))
                {
                    result.Add(new SvgUnit(SvgUnitType.User, pointValue));
                }

                return(result);
            }

            return(base.ConvertFrom(context, culture, value));
        }
Пример #4
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;
            }
        }
Пример #5
0
        private static void CreatePathSegment(char command, SvgPathSegmentList segments, ref CoordinateParserState state, ref ReadOnlySpan <char> chars)
        {
            var isRelative = char.IsLower(command);

            // http://www.w3.org/TR/SVG11/paths.html#PathDataGeneralInformation

            switch (command)
            {
            case 'M':     // moveto
            case 'm':     // relative moveto
            {
                if (CoordinateParser.TryGetFloat(out var coords0, ref chars, ref state) &&
                    CoordinateParser.TryGetFloat(out var coords1, ref chars, ref state))
                {
                    segments.Add(
                        new SvgMoveToSegment(
                            isRelative, new PointF(coords0, coords1)));
                }
                while (CoordinateParser.TryGetFloat(out coords0, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out coords1, ref chars, ref state))
                {
                    segments.Add(
                        new SvgLineSegment(
                            isRelative, new PointF(coords0, coords1)));
                }
            }
            break;

            case 'A':     // elliptical arc
            case 'a':     // relative elliptical arc
            {
                while (CoordinateParser.TryGetFloat(out var coords0, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords1, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords2, ref chars, ref state) &&
                       CoordinateParser.TryGetBool(out var size, ref chars, ref state) &&
                       CoordinateParser.TryGetBool(out var sweep, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords3, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords4, ref chars, ref state))
                {
                    // A|a rx ry x-axis-rotation large-arc-flag sweep-flag x y
                    segments.Add(
                        new SvgArcSegment(
                            coords0,
                            coords1,
                            coords2,
                            size ? SvgArcSize.Large : SvgArcSize.Small,
                            sweep ? SvgArcSweep.Positive : SvgArcSweep.Negative,
                            isRelative, new PointF(coords3, coords4)));
                }
            }
            break;

            case 'L':     // lineto
            case 'l':     // relative lineto
            {
                while (CoordinateParser.TryGetFloat(out var coords0, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords1, ref chars, ref state))
                {
                    segments.Add(
                        new SvgLineSegment(
                            isRelative, new PointF(coords0, coords1)));
                }
            }
            break;

            case 'H':     // horizontal lineto
            case 'h':     // relative horizontal lineto
            {
                while (CoordinateParser.TryGetFloat(out var coords0, ref chars, ref state))
                {
                    segments.Add(
                        new SvgLineSegment(
                            isRelative, new PointF(coords0, float.NaN)));
                }
            }
            break;

            case 'V':     // vertical lineto
            case 'v':     // relative vertical lineto
            {
                while (CoordinateParser.TryGetFloat(out var coords0, ref chars, ref state))
                {
                    segments.Add(
                        new SvgLineSegment(
                            isRelative, new PointF(float.NaN, coords0)));
                }
            }
            break;

            case 'Q':     // quadratic bézier curveto
            case 'q':     // relative quadratic bézier curveto
            {
                while (CoordinateParser.TryGetFloat(out var coords0, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords1, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords2, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords3, ref chars, ref state))
                {
                    segments.Add(
                        new SvgQuadraticCurveSegment(
                            isRelative,
                            new PointF(coords0, coords1),
                            new PointF(coords2, coords3)));
                }
            }
            break;

            case 'T':     // shorthand/smooth quadratic bézier curveto
            case 't':     // relative shorthand/smooth quadratic bézier curveto
            {
                while (CoordinateParser.TryGetFloat(out var coords0, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords1, ref chars, ref state))
                {
                    segments.Add(
                        new SvgQuadraticCurveSegment(
                            isRelative, new PointF(coords0, coords1)));
                }
            }
            break;

            case 'C':     // curveto
            case 'c':     // relative curveto
            {
                while (CoordinateParser.TryGetFloat(out var coords0, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords1, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords2, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords3, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords4, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords5, ref chars, ref state))
                {
                    segments.Add(
                        new SvgCubicCurveSegment(
                            isRelative,
                            new PointF(coords0, coords1),
                            new PointF(coords2, coords3),
                            new PointF(coords4, coords5)));
                }
            }
            break;

            case 'S':     // shorthand/smooth curveto
            case 's':     // relative shorthand/smooth curveto
            {
                while (CoordinateParser.TryGetFloat(out var coords0, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords1, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords2, ref chars, ref state) &&
                       CoordinateParser.TryGetFloat(out var coords3, ref chars, ref state))
                {
                    segments.Add(
                        new SvgCubicCurveSegment(
                            isRelative,
                            new PointF(coords0, coords1),
                            new PointF(coords2, coords3)));
                }
            }
            break;

            case 'Z':     // closepath
            case 'z':     // relative closepath
            {
                segments.Add(new SvgClosePathSegment(isRelative));
            }
            break;
            }
        }
Пример #6
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;
            }
        }