Example #1
0
        public static IEnumerable <SvgPathSegment> Create(SvgPathSegment lastSegment, string commandString, SvgConverter conv)
        {
            if (!conv.TrySplitValues(commandString.Substring(1), out var values, false))
            {
                yield break;
            }

            int valuePos = 0;

            while (valuePos < values.Length)
            {
                var start = new Pnt2d();
                if (lastSegment != null)
                {
                    start = lastSegment.End;
                }

                double      rx    = values[0] * conv.Scale;
                double      ry    = values[1] * conv.Scale;
                double      angle = values[2];
                SvgArcSize  size  = values[3] == 0 ? SvgArcSize.Small : SvgArcSize.Large;
                SvgArcSweep sweep = values[4] == 0 ? SvgArcSweep.Negative : SvgArcSweep.Positive;
                Pnt2d       end   = new Pnt2d(values[5] * conv.Scale, values[6] * conv.Scale);
                if (char.IsLower(commandString[0]))
                {
                    end += start;
                }
                valuePos += 7;

                lastSegment = new SvgPathSegArc(start, rx, ry, angle, size, sweep, end);
                yield return(lastSegment);
            }
        }
Example #2
0
        public static SvgPathSegClosePath Create(SvgPathSegment firstSegment, SvgPathSegment lastSegment)
        {
            var seg = new SvgPathSegClosePath {
                Start = lastSegment?.Start ?? Pnt2d.Origin,
                End   = firstSegment?.End ?? Pnt2d.Origin
            };

            return(seg);
        }
Example #3
0
        public static IEnumerable <SvgPathSegment> Create(SvgPathSegment lastSegment, string commandString, SvgConverter conv)
        {
            if (!conv.TrySplitValues(commandString.Substring(1), out var values, true))
            {
                yield break;
            }

            int valuePos = 0;

            while (valuePos < values.Length)
            {
                var start = lastSegment?.End ?? Pnt2d.Origin;

                Pnt2d c1;
                Pnt2d c2;
                Pnt2d end;
                if (char.ToLower(commandString[0]) == 'c')
                {
                    c1        = new Pnt2d(values[valuePos], values[valuePos + 1]);
                    c2        = new Pnt2d(values[valuePos + 2], values[valuePos + 3]);
                    end       = new Pnt2d(values[valuePos + 4], values[valuePos + 5]);
                    valuePos += 6;

                    if (char.IsLower(commandString[0]))
                    {
                        c1  += start;
                        c2  += start;
                        end += start;
                    }
                    lastSegment = new SvgPathSegCurvetoCubic(start, c1, c2, end);
                    yield return(lastSegment);
                }
                else if (char.ToLower(commandString[0]) == 's')
                {
                    c2        = new Pnt2d(values[valuePos], values[valuePos + 1]);
                    end       = new Pnt2d(values[valuePos + 2], values[valuePos + 3]);
                    valuePos += 4;

                    if (char.IsLower(commandString[0]))
                    {
                        c2  += start;
                        end += start;
                    }

                    if (lastSegment is SvgPathSegCurvetoCubic lastSeg)
                    {
                        c1 = lastSeg.C2;
                    }
                    else
                    {
                        c1 = c2;
                    }
                    lastSegment = new SvgPathSegCurvetoCubic(start, c1, c2, end);
                    yield return(lastSegment);
                }
            }
        }
Example #4
0
        public static IEnumerable <SvgPathSegment> Create(SvgPathSegment lastSegment, string commandString, SvgConverter conv)
        {
            if (!conv.TrySplitValues(commandString.Substring(1), out var values, true))
            {
                yield break;
            }

            int valuePos = 0;

            while (valuePos < values.Length)
            {
                var start = lastSegment?.End ?? Pnt2d.Origin;

                SvgPathSegLineto segment = null;
                switch (commandString[0])
                {
                case 'L':
                    segment   = new SvgPathSegLineto(start, new Pnt2d(values[valuePos], values[valuePos + 1]));
                    valuePos += 2;
                    break;

                case 'l':
                    segment   = new SvgPathSegLineto(start, start + new Pnt2d(values[valuePos], values[valuePos + 1]));
                    valuePos += 2;
                    break;

                case 'H':
                    segment   = new SvgPathSegLineto(start, new Pnt2d(values[valuePos], start.Y));
                    valuePos += 1;
                    break;

                case 'h':
                    segment   = new SvgPathSegLineto(start, start + new Pnt2d(values[valuePos], 0));
                    valuePos += 1;
                    break;

                case 'V':
                    segment   = new SvgPathSegLineto(start, new Pnt2d(start.X, values[valuePos]));
                    valuePos += 1;
                    break;

                case 'v':
                    segment   = new SvgPathSegLineto(start, start + new Pnt2d(0, values[valuePos]));
                    valuePos += 1;
                    break;
                }
                yield return(segment);

                lastSegment = segment;
            }
        }
Example #5
0
        //--------------------------------------------------------------------------------------------------

        internal override bool Read(XmlReader reader, SvgConverter conv)
        {
            var data = reader.GetAttribute("d");

            if (!base.Read(reader, conv))
            {
                return(false);
            }

            if (!data.IsNullOrEmpty())
            {
                Segments.AddRange(SvgPathSegment.Create(data, conv));
            }

            Segments.ForEach(seg => seg.Transform(conv));

            conv.PopTransform();
            return(Segments.Count > 0);
        }
Example #6
0
        //--------------------------------------------------------------------------------------------------

        protected void AddToPath(SvgPathSegment segment)
        {
            if (CurrentPath == null)
            {
                InitPathExport();
                _PathStart = segment.Start;
                CurrentPath.Segments.Add(new SvgPathSegMoveto(segment.Start));
            }
            else
            {
                // If Segment-Start does not match current subpath end...
                if (!_AreEqual(_PathPosition, segment.Start))
                {
                    if (_AreEqual(_PathStart, segment.End))
                    {
                        // Segment-End matches path start, but Segment-Start
                        // not to current subpath end, so insert on top
                        CurrentPath.Segments.Insert(_SubPathStartIndex + 1, segment);
                        CurrentPath.Segments[_SubPathStartIndex] = new SvgPathSegMoveto(segment.Start);
                        _PathStart = segment.Start;
                        return;
                    }
                    else
                    {
                        // Both Segment-Points do not match to any side of the path
                        // Start new subpath
                        ClosePath();
                        _SubPathStartIndex = CurrentPath.Segments.Count;
                        CurrentPath.Segments.Add(new SvgPathSegMoveto(segment.Start));
                        _PathStart = segment.Start;
                    }
                }
            }

            // Append to current / just created subpath
            _PathPosition = segment.End;
            CurrentPath.Segments.Add(segment);
        }
Example #7
0
        public static IEnumerable <SvgPathSegment> Create(SvgPathSegment lastSegment, string commandString, SvgConverter conv)
        {
            if (!conv.TrySplitValues(commandString.Substring(1), out var values, true))
            {
                yield break;
            }

            bool  isRelative = commandString[0] == 'm';
            int   valuePos   = 0;
            Pnt2d endPoint   = new Pnt2d();

            if (valuePos < values.Length)
            {
                endPoint = new Pnt2d(values[valuePos], values[valuePos + 1]);
                if (isRelative && lastSegment != null)
                {
                    endPoint += lastSegment.End;
                }
                yield return(new SvgPathSegMoveto(endPoint));

                valuePos += 2;
            }

            // subsequent value pairs are implicit lineto's
            while (valuePos < values.Length)
            {
                var startPoint = endPoint;
                endPoint = new Pnt2d(values[valuePos], values[valuePos + 1]);
                if (isRelative)
                {
                    endPoint += startPoint;
                }
                yield return(new SvgPathSegLineto(startPoint, endPoint));

                valuePos += 2;
            }
        }
Example #8
0
        //--------------------------------------------------------------------------------------------------

        internal static IEnumerable <SvgPathSegment> Create(string pathString, SvgConverter conv)
        {
            SvgPathSegment lastSegment  = null;
            SvgPathSegment firstSegment = null;
            int            next         = 0;

            while (next < pathString.Length)
            {
                int start = next;
                next = pathString.IndexOfAny(_PathCommands, start + 1);
                if (next == -1)
                {
                    next = pathString.Length;
                }

                IEnumerable <SvgPathSegment> newSegments = null;
                var commandString = pathString.Substring(start, next - start);
                switch (char.ToLower(commandString[0]))
                {
                case 'm':
                    newSegments = SvgPathSegMoveto.Create(lastSegment, commandString, conv);
                    break;

                case 'l':
                case 'h':
                case 'v':
                    newSegments = SvgPathSegLineto.Create(lastSegment, commandString, conv);
                    break;

                case 'c':
                case 's':
                    newSegments = SvgPathSegCurvetoCubic.Create(lastSegment, commandString, conv);
                    break;

                case 'q':
                case 't':
                    newSegments = SvgPathSegCurvetoQuadratic.Create(lastSegment, commandString, conv);
                    break;

                case 'a':
                    newSegments = SvgPathSegArc.Create(lastSegment, commandString, conv);
                    break;

                case 'z':
                    lastSegment = SvgPathSegClosePath.Create(firstSegment, lastSegment);
                    yield return(lastSegment);

                    firstSegment = null;
                    continue;
                }

                if (newSegments == null)
                {
                    continue;
                }

                foreach (var segment in newSegments)
                {
                    if (firstSegment == null)
                    {
                        firstSegment = segment;
                    }
                    lastSegment = segment;
                    yield return(segment);
                }
            }
        }