Example #1
0
        /// <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;
        }
Example #2
0
 public static void DrawLine(this ICanvas canvas, Point start, Point end, Color color, double width = 1.0)
 {
     var p = new Path { Pen = new Pen(color, width) };
     p.MoveTo(start, false);
     p.LineTo(end);
     p.Draw(canvas);
 }
Example #3
0
 public static void DrawLine(this ICanvas canvas, double x1, double y1, double x2, double y2, Color color, double width = 1.0)
 {
     var p = new Path { Pen = new Pen(color, width) };
     p.MoveTo(x1, y1,false);
     p.LineTo(x2, y2,false);
     p.Draw(canvas);
 }
Example #4
0
 public static void DrawLine(this ICanvas canvas, Point start, Point end, Pen pen)
 {
     var p = new Path { Pen = pen };
     p.MoveTo(start,false);
     p.LineTo(end);
     p.Draw(canvas);
 }
Example #5
0
 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();
 }
Example #6
0
        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;
            }
        }
Example #7
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);
            }
        }
Example #8
0
 public override void AddToPath(Path graphicsPath)
 {
     graphicsPath.MoveTo(Start, End, false);
 }
Example #9
0
 public abstract void AddToPath(Path graphicsPath);
Example #10
0
 public static void DrawPath(this ICanvas canvas, Action<Path> draw, Pen pen = null, BaseBrush brush = null)
 {
     var p = new Path(pen, brush);
     draw(p);
     p.Draw(canvas);
 }
Example #11
0
 public static void FillPath(this ICanvas canvas, Action<Path> draw, BaseBrush brush)
 {
     var p = new Path(null, brush);
     draw(p);
     p.Draw(canvas);
 }
Example #12
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.Id = ReadString(e.Attribute("id"));
              }

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