//--------------------------------------------------------------------------------------------------

        bool _AddEllipicalArcSegment(SketchSegmentEllipticalArc arcSegment, Pnt2d start, Pnt2d end)
        {
            var parameters = new double[2];
            var ellipse    = arcSegment.GetEllipse(_Sketch.Points, parameters);

            if (ellipse == null)
            {
                return(false);
            }
            double rotAngle = ellipse.XAxis().Angle(new Ax2d(ellipse.Location(), Dir2d.DX));
            double length   = parameters[1] - parameters[0];
            var    size     = length < Math.PI ? SvgArcSize.Small : SvgArcSize.Large;
            var    sense    = ellipse.Axis().Sense() > 0;

            if (start == _Sketch.Points[arcSegment.EndPoint])
            {
                sense = !sense; // Sense was inverted by interchanged start/end point
            }
            var sweep = sense ? SvgArcSweep.Positive : SvgArcSweep.Negative;

            var svgSegment = new SvgPathSegArc(start, ellipse.MajorRadius(), ellipse.MinorRadius(), rotAngle.ToDeg(), size, sweep, end);

            _CurrentPath.Segments.Add(svgSegment);
            return(true);
        }
        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);
            }
        }
        //--------------------------------------------------------------------------------------------------

        void _ImportArcSegment(SvgPathSegArc svgSegment, ref int startPoint)
        {
            var radiusX     = svgSegment.RadiusX;
            var radiusY     = svgSegment.RadiusY;
            var rotation    = -svgSegment.Angle.ToRad();
            var startPnt2d  = svgSegment.Start;
            var endPnt2d    = svgSegment.End;
            var centerPnt2d = Geom2dUtils.FindEllipseCenterFromEndpoints(
                startPnt2d, endPnt2d,
                radiusX, radiusY, rotation,
                (int)svgSegment.Size != (int)svgSegment.Sweep);

            // Do we have a circle arc?
            if (Math.Abs(radiusX - radiusY) < 0.0001)
            {
                var axis = Ax2d.OX.Rotated(Pnt2d.Origin, rotation).Translated(centerPnt2d.ToVec());
                var circ = new gp_Circ2d(axis, radiusX, svgSegment.Sweep != SvgArcSweep.Positive);

                //Debug.WriteLine("StartParam: {0}  -  EndParam: {1}", ElCLib.Parameter(circ, startPnt2d), ElCLib.Parameter(circ, endPnt2d));
                var startParam = ElCLib.Parameter(circ, startPnt2d);
                var endParam   = ElCLib.Parameter(circ, endPnt2d);
                if (endParam < startParam)
                {
                    endParam += 2 * Math.PI;
                }
                var rimPnt2d = ElCLib.Value(startParam + (endParam - startParam) / 2, circ);

                var endPoint = _AddPoint(endPnt2d);
                _Segments.Add(new SketchSegmentArc(startPoint, endPoint, _AddPoint(rimPnt2d)));
                startPoint = endPoint;
            }
            else
            {
                // No, we have a elliptical arc
                // Construct ellipse, convert to bezier
                var axis       = Ax2d.OX.Rotated(Pnt2d.Origin, rotation).Translated(centerPnt2d.ToVec());
                var ellipse    = new gp_Elips2d(axis, radiusX, radiusY, svgSegment.Sweep != SvgArcSweep.Positive);
                var startParam = ElCLib.Parameter(ellipse, startPnt2d);
                var endParam   = ElCLib.Parameter(ellipse, endPnt2d);
                if (double.IsNaN(startParam) || double.IsNaN(endParam))
                {
                    Messages.Warning("Invalid elliptical arc found in SVG file.");
                    return;
                }

                var bezierPointArray = Geom2dUtils.EllipticalArcToBezier(ellipse, startParam, endParam);
                foreach (var bezierPoints in bezierPointArray)
                {
                    var endPoint = _AddPoint(bezierPoints.p2);
                    _Segments.Add(new SketchSegmentBezier(startPoint, _AddPoint(bezierPoints.c1), _AddPoint(bezierPoints.c2), endPoint));
                    startPoint = endPoint;
                }
            }
        }
        //--------------------------------------------------------------------------------------------------

        bool _AddArcSegment(SketchSegmentArc arcSegment, Pnt2d start, Pnt2d end)
        {
            var parameters = new double[2];
            var circle     = arcSegment.GetCircle(_Sketch.Points, parameters);

            if (circle == null)
            {
                return(false);
            }
            double length = parameters[1] - parameters[0];
            var    size   = length < Math.PI ? SvgArcSize.Small : SvgArcSize.Large;
            var    sweep  = circle.Position().Sense() > 0 ? SvgArcSweep.Positive : SvgArcSweep.Negative;

            var svgSegment = new SvgPathSegArc(start, circle.Radius(), circle.Radius(), 0, size, sweep, end);

            _CurrentPath.Segments.Add(svgSegment);
            return(true);
        }
        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);
                }
            }
        }