/// <summary>
        ///     Parses the specified string into a collection of path segments.
        /// </summary>
        /// <param name="path">A <see cref="string" /> containing path data.</param>
        public static void Parse(Path path, string pathString)
        {
            if (string.IsNullOrEmpty(pathString))
            {
                throw new ArgumentNullException("pathString");
            }

            var segments = new SvgPathSegmentList();

            try
            {
                char command;
                bool isRelative;

                foreach (var commandSet in SplitCommands(pathString.TrimEnd(null)))
                {
                    command = commandSet[0];
                    isRelative = char.IsLower(command);
                    // http://www.w3.org/TR/SVG11/paths.html#PathDataGeneralInformation

                    CreatePathSegment(command, segments, new CoordinateParser(commandSet.Trim()), isRelative);
                }

                foreach (var segment in segments)
                {
                    segment.AddToPath(path);
                }
            }
            catch (Exception exc)
            {
                throw new Exception(string.Format("Error parsing path \"{0}\": {1}", path, exc.Message));
            }

            //return segments;
        }
 public override void AddToPath(Path graphicsPath)
 {
     //todo May need to fix
     //// Important for custom line caps.  Force the path the close with an explicit line, not just an implicit close of the figure.
     //if (graphicsPath.PointCount > 0 && !graphicsPath.PathPoints[0].Equals(graphicsPath.PathPoints[graphicsPath.PathPoints.Length - 1]))
     //{
     //    int i = graphicsPath.PathTypes.Length - 1;
     //    while (i >= 0 && graphicsPath.PathTypes[i] > 0) i--;
     //    if (i < 0) i = 0;
     //    graphicsPath.AddLine(graphicsPath.PathPoints[graphicsPath.PathPoints.Length - 1], graphicsPath.PathPoints[i]);
     //}
     graphicsPath.Close();
 }
        public override void AddToPath(Path graphicsPath)
        {
            if (Start == End)
            {
                return;
            }

            if (RadiusX == 0.0f && RadiusY == 0.0f)
            {
                graphicsPath.LineTo(Start, End);
                return;
            }

            var sinPhi = Math.Sin(Angle*RadiansPerDegree);
            var cosPhi = Math.Cos(Angle*RadiansPerDegree);

            var x1dash = cosPhi*(Start.X - End.X)/2.0 + sinPhi*(Start.Y - End.Y)/2.0;
            var y1dash = -sinPhi*(Start.X - End.X)/2.0 + cosPhi*(Start.Y - End.Y)/2.0;

            double root;
            var numerator = RadiusX*RadiusX*RadiusY*RadiusY - RadiusX*RadiusX*y1dash*y1dash -
                            RadiusY*RadiusY*x1dash*x1dash;

            var rx = RadiusX;
            var ry = RadiusY;

            if (numerator < 0.0)
            {
                var s = (float) Math.Sqrt(1.0 - numerator/(RadiusX*RadiusX*RadiusY*RadiusY));

                rx *= s;
                ry *= s;
                root = 0.0;
            }
            else
            {
                root = ((Size == SvgArcSize.Large && Sweep == SvgArcSweep.Positive) ||
                        (Size == SvgArcSize.Small && Sweep == SvgArcSweep.Negative)
                    ? -1.0
                    : 1.0)*Math.Sqrt(numerator/(RadiusX*RadiusX*y1dash*y1dash + RadiusY*RadiusY*x1dash*x1dash));
            }

            var cxdash = root*rx*y1dash/ry;
            var cydash = -root*ry*x1dash/rx;

            var cx = cosPhi*cxdash - sinPhi*cydash + (Start.X + End.X)/2.0;
            var cy = sinPhi*cxdash + cosPhi*cydash + (Start.Y + End.Y)/2.0;

            var theta1 = CalculateVectorAngle(1.0, 0.0, (x1dash - cxdash)/rx, (y1dash - cydash)/ry);
            var dtheta = CalculateVectorAngle((x1dash - cxdash)/rx, (y1dash - cydash)/ry, (-x1dash - cxdash)/rx,
                (-y1dash - cydash)/ry);

            if (Sweep == SvgArcSweep.Negative && dtheta > 0)
            {
                dtheta -= 2.0*Math.PI;
            }
            else if (Sweep == SvgArcSweep.Positive && dtheta < 0)
            {
                dtheta += 2.0*Math.PI;
            }

            var segments = (int) Math.Ceiling(Math.Abs(dtheta/(Math.PI/2.0)));
            var delta = dtheta/segments;
            var t = 8.0/3.0*Math.Sin(delta/4.0)*Math.Sin(delta/4.0)/Math.Sin(delta/2.0);

            var startX = Start.X;
            var startY = Start.Y;

            for (var i = 0; i < segments; ++i)
            {
                var cosTheta1 = Math.Cos(theta1);
                var sinTheta1 = Math.Sin(theta1);
                var theta2 = theta1 + delta;
                var cosTheta2 = Math.Cos(theta2);
                var sinTheta2 = Math.Sin(theta2);

                var endpointX = cosPhi*rx*cosTheta2 - sinPhi*ry*sinTheta2 + cx;
                var endpointY = sinPhi*rx*cosTheta2 + cosPhi*ry*sinTheta2 + cy;

                var dx1 = t*(-cosPhi*rx*sinTheta1 - sinPhi*ry*cosTheta1);
                var dy1 = t*(-sinPhi*rx*sinTheta1 + cosPhi*ry*cosTheta1);

                var dxe = t*(cosPhi*rx*sinTheta2 + sinPhi*ry*cosTheta2);
                var dye = t*(sinPhi*rx*sinTheta2 - cosPhi*ry*cosTheta2);

                graphicsPath.CurveTo(new Point(startX, startY), new Point((startX + dx1), (startY + dy1)),
                    new Point((endpointX + dxe), (endpointY + dye)), new Point(endpointX, endpointY));

                theta1 = theta2;
                startX = (float) endpointX;
                startY = (float) endpointY;
            }
        }
 public override void AddToPath(Path graphicsPath)
 {
     graphicsPath.MoveTo(Start, End, false);
 }
Beispiel #5
0
        private void AddElement(IList<IDrawable> list, XElement e, Pen inheritPen, BaseBrush inheritBaseBrush)
        {
            Element element = null;

              var styleAttributedDictionary = e.Attributes().ToDictionary(k => k.Name.LocalName, v => v.Value);

              var pen = _stylesParser.GetPen(styleAttributedDictionary);
              var baseBrush = _stylesParser.GetBrush(styleAttributedDictionary,defs, pen);

              var style = ReadString(e.Attribute("style"));

              if (!string.IsNullOrWhiteSpace(style))
              {
            ApplyStyle(style, ref pen, ref baseBrush);
              }

              pen = pen ?? inheritPen;
              baseBrush = baseBrush ?? inheritBaseBrush;

              //var id = ReadString (e.Attribute ("id"));

              //
              // Elements
              //
              switch (e.Name.LocalName)
              {
            case "text":
            {
              var x = _valuesParser.ReadNumber(e.Attribute("x"));
              var y = _valuesParser.ReadNumber(e.Attribute("y"));
              var text = e.Value.Trim();
              var font = new Font();
              element = new Text(text, new Rect(new Point(x, y), new Size(double.MaxValue, double.MaxValue)), font,
            TextAlignment.Left, pen, baseBrush);
            }
              break;
            case "rect":
            {
              var x = _valuesParser.ReadNumber(e.Attribute("x"));
              var y = _valuesParser.ReadNumber(e.Attribute("y"));
              var width = _valuesParser.ReadNumber(e.Attribute("width"));
              var height = _valuesParser.ReadNumber(e.Attribute("height"));
              element = new Rectangle(new Point(x, y), new Size(width, height), pen, baseBrush);
            }
              break;
            case "ellipse":
            {
              var cx = _valuesParser.ReadNumber(e.Attribute("cx"));
              var cy = _valuesParser.ReadNumber(e.Attribute("cy"));
              var rx = _valuesParser.ReadNumber(e.Attribute("rx"));
              var ry = _valuesParser.ReadNumber(e.Attribute("ry"));
              element = new Ellipse(new Point(cx - rx, cy - ry), new Size(2*rx, 2*ry), pen, baseBrush);
            }
              break;
            case "circle":
            {
              var cx = _valuesParser.ReadNumber(e.Attribute("cx"));
              var cy = _valuesParser.ReadNumber(e.Attribute("cy"));
              var rr = _valuesParser.ReadNumber(e.Attribute("r"));
              element = new Ellipse(new Point(cx - rr, cy - rr), new Size(2*rr, 2*rr), pen, baseBrush);
            }
              break;
            case "path":
            {
              var dA = e.Attribute("d");
              if (dA != null && !string.IsNullOrWhiteSpace(dA.Value))
              {
            var p = new Path(pen, baseBrush);
            SvgPathParser.Parse(p, dA.Value);
            element = p;
              }
            }
              break;
            case "g":
            {
              var g = new Group();
              AddElements(g.Children, e.Elements(), pen, baseBrush);
              element = g;
            }
              break;
            case "use":
            {
              var href = ReadString(e.Attributes().FirstOrDefault(x => x.Name.LocalName == "href"));
              if (!string.IsNullOrWhiteSpace(href))
              {
            XElement useE;
            if (defs.TryGetValue(href.Trim().Replace("#", ""), out useE))
            {
              var useList = new List<IDrawable>();
              AddElement(useList, useE, pen, baseBrush);
              element = useList.OfType<Element>().FirstOrDefault();
            }
              }
            }
              break;
            case "title":
              Graphic.Title = ReadString(e);
              break;
            case "description":
              Graphic.Description = ReadString(e);
              break;
            case "defs":
              // Already read in earlier pass
              break;
            case "namedview":
            case "metadata":
            case "SVGTestCase":
            case "switch":
            break;
            default:
              throw new NotSupportedException("SVG element \"" + e.Name.LocalName + "\" is not supported");
              }

              if (element != null)
              {
            element.Transform = ReadTransform(ReadString(e.Attribute("transform")));
            list.Add(element);
              }
        }
 public override void AddToPath(Path graphicsPath)
 {
     graphicsPath.LineTo(Start, End);
 }
 public abstract void AddToPath(Path graphicsPath);
 public override void AddToPath(Path graphicsPath)
 {
     graphicsPath.CurveTo(Start, FirstControlPoint, SecondControlPoint, End);
 }