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); p.LineTo (x2, y2); p.Draw (canvas); }
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); p.LineTo (end); p.Draw (canvas); }
public static void DrawLine(this ICanvas canvas, Point start, Point end, Pen pen) { var p = new Path { Pen = pen }; p.MoveTo (start); p.LineTo (end); p.Draw (canvas); }
public override Element TransformGeometry (Transform transform) { var p = new Path (); base.SetCloneData (p); p.Transform = Transform.Identity; p.MoveTo (frame.TopLeft); p.LineTo (frame.BottomLeft); p.LineTo (frame.BottomRight); p.LineTo (frame.TopRight); p.Close (); var tp = p.TransformGeometry (transform * Transform); return tp; }
void AddElement (IList<Element> list, XElement e, Pen inheritPen, Brush inheritBrush) { // // Style // Element r = null; Style eStyle = new Style(); ApplyStyle (e.Attributes ().ToDictionary (k => k.Name.LocalName, v => v.Value), eStyle); var style = ReadString (e.Attribute ("style")); if (!string.IsNullOrWhiteSpace (style)) { ApplyStyle (style, eStyle); } if (!eStyle.hasPen) eStyle.pen = inheritPen; if (!eStyle.hasBrush) eStyle.brush = inheritBrush; //var id = ReadString (e.Attribute ("id")); // // Elements // switch (e.Name.LocalName) { case "text": { var x = ReadNumber (e.Attribute ("x")); var y = ReadNumber (e.Attribute ("y")); var font = new Font (); var fontFamily = ReadTextFontFamily(e); if (!string.IsNullOrEmpty(fontFamily)) font.Family = fontFamily; var fontSize = ReadTextFontSize(e); if (fontSize >= 0) font.Size = fontSize; TextAlignment textAlignment = ReadTextAlignment(e); var txt = new Text (new Rect (new Point (x, y), new Size (double.MaxValue, double.MaxValue)), font, textAlignment, eStyle.pen, eStyle.brush); ReadTextSpans (txt, e); r = txt; } break; case "rect": { var x = ReadNumber (e.Attribute ("x")); var y = ReadNumber (e.Attribute ("y")); var width = ReadNumber (e.Attribute ("width")); var height = ReadNumber (e.Attribute ("height")); var rx = ReadNumber (e.Attribute ("rx")); var ry = ReadNumber (e.Attribute ("ry")); if (ry == 0) { ry = rx; } r = new Rectangle (new Rect (new Point (x, y), new Size (width, height)), new Size (rx, ry), eStyle.pen, eStyle.brush); } break; case "ellipse": { var cx = ReadNumber (e.Attribute ("cx")); var cy = ReadNumber (e.Attribute ("cy")); var rx = ReadNumber (e.Attribute ("rx")); var ry = ReadNumber (e.Attribute ("ry")); r = new Ellipse (new Point (cx - rx, cy - ry), new Size (2 * rx, 2 * ry), eStyle.pen, eStyle.brush); } break; case "circle": { var cx = ReadNumber (e.Attribute ("cx")); var cy = ReadNumber (e.Attribute ("cy")); var rr = ReadNumber (e.Attribute ("r")); r = new Ellipse (new Point (cx - rr, cy - rr), new Size (2 * rr, 2 * rr), eStyle.pen, eStyle.brush); } break; case "path": { var dA = e.Attribute ("d"); if (dA != null && !string.IsNullOrWhiteSpace (dA.Value)) { var p = new Path (eStyle.pen, eStyle.brush); ReadPath (p, dA.Value); r = p; } } break; case "polygon": { var pA = e.Attribute ("points"); if (pA != null && !string.IsNullOrWhiteSpace (pA.Value)) { var path = new Path (eStyle.pen, eStyle.brush); ReadPoints (path, pA.Value, true); r = path; } } break; case "polyline": { var pA = e.Attribute ("points"); if (pA != null && !string.IsNullOrWhiteSpace (pA.Value)) { var path = new Path (eStyle.pen, eStyle.brush); ReadPoints (path, pA.Value, false); r = path; } } break; case "g": { var g = new Group (); var groupId = e.Attribute("id"); if (groupId != null && !string.IsNullOrEmpty(groupId.Value)) g.Id = groupId.Value; AddElements (g.Children, e.Elements (), eStyle.pen, eStyle.brush); r = 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<Element> (); AddElement (useList, useE, eStyle.pen, eStyle.brush); r = useList.FirstOrDefault (); } } } break; case "title": Graphic.Title = ReadString (e); break; case "desc": case "description": Graphic.Description = ReadString (e); break; case "defs": // Already read in earlier pass break; case "namedview": case "metadata": case "image": // Ignore break; case "line": { var x1 = ReadNumber ( e.Attribute("x1") ); var x2 = ReadNumber ( e.Attribute("x2") ); var y1 = ReadNumber ( e.Attribute("y1") ); var y2 = ReadNumber ( e.Attribute("y2") ); var p = new Path (eStyle.pen, null); p.MoveTo (x1, y1); p.LineTo (x2, y2); r = p; } break; case "foreignObject": { var x = ReadNumber ( e.Attribute("x") ); var y = ReadNumber ( e.Attribute("y") ); var width = ReadNumber ( e.Attribute("width") ); var height = ReadNumber ( e.Attribute("height") ); r = new ForeignObject(new Point(x, y), new Size(width, height)); } break; case "pgf": { var id = e.Attribute("id"); System.Diagnostics.Debug.WriteLine("Ignoring pgf element" + (id != null ? ": '" + id.Value + "'" : "")); } break; case "switch": { // Evaluate requiredFeatures, requiredExtensions and systemLanguage foreach (var ee in e.Elements()) { var requiredFeatures = ee.Attribute("requiredFeatures"); var requiredExtensions = ee.Attribute("requiredExtensions"); var systemLanguage = ee.Attribute("systemLanguage"); // currently no support for any of these restrictions if (requiredFeatures == null && requiredExtensions == null && systemLanguage == null) AddElement (list, ee, eStyle.pen, eStyle.brush); } } break; // color definition that can be referred to by other elements case "linearGradient": break; default: throw new NotSupportedException ("SVG element \"" + e.Name.LocalName + "\" is not supported"); } if (r != null) { eStyle.Apply(r); r.Transform = ReadTransform (ReadString (e.Attribute ("transform"))); var ida = e.Attribute("id"); if (ida != null && !string.IsNullOrEmpty (ida.Value)) { r.Id = ida.Value.Trim (); } list.Add (r); } }
void ReadPoints (Path p, string pathDescriptor, bool closePath) { var args = pathDescriptor.Split (new[]{' '}, StringSplitOptions.RemoveEmptyEntries); var i = 0; var n = args.Length; if (n == 0) throw new Exception ("No points specified"); while (i < n) { var xy = args[i].Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries); var x = 0.0; var y = 0.0; var di = 1; if (xy.Length == 1) { x = ReadNumber (args [i]); y = ReadNumber (args [i + 1]); di = 2; } else { x = ReadNumber (xy[0]); y = ReadNumber (xy[1]); } if (i == 0) { p.MoveTo (x, y); } else { p.LineTo (x, y); } i += di; } if (closePath) p.Close (); }
void ReadPath (Path p, string pathDescriptor) { Match m = pathRegex.Match(pathDescriptor); while(m.Success) { var match = m.Value.TrimStart (); var op = match[0]; if (op == 'z' || op == 'Z') { p.Close (); } else { // make sure negative numbers are split properly match = negativeNumberRe.Replace(match.Substring(1), " -"); var args = match.Split(WSC, StringSplitOptions.RemoveEmptyEntries); Point previousPoint = new Point (); int index = 0; while(index < args.Length) { if (p.Operations.Count > 0 && !(p.Operations.Last() is ClosePath)) previousPoint = p.Operations.Last().EndPoint; if ((op == 'M' || op == 'm') && args.Length >= index+2) { var point = new Point (ReadNumber (args [index]), ReadNumber (args [index+1])); if (op == 'm') point += previousPoint; p.MoveTo (point); index += 2; } else if ((op == 'L' || op == 'l') && args.Length >= index+2) { var point = new Point (ReadNumber (args [index]), ReadNumber (args [index+1])); if (op == 'l') point += previousPoint; p.LineTo (point); index += 2; } else if ((op == 'C' || op == 'c') && args.Length >= index+6) { var c1 = new Point (ReadNumber (args [index]), ReadNumber (args [index+1])); var c2 = new Point (ReadNumber (args [index+2]), ReadNumber (args [index+3])); var pt = new Point (ReadNumber (args [index+4]), ReadNumber (args [index+5])); if (op == 'c') { c1 += previousPoint; c2 += previousPoint; pt += previousPoint; } p.CurveTo (c1, c2, pt); index += 6; } else if ((op == 'S' || op == 's') && args.Length >= index+4) { var c = new Point (ReadNumber (args [index]), ReadNumber (args [index+1])); var pt = new Point (ReadNumber (args [index+2]), ReadNumber (args [index+3])); if (op == 's') { c += previousPoint; pt += previousPoint; } p.ContinueCurveTo (c, pt); index += 4; } else if ((op == 'A' || op == 'a') && args.Length >= index+7) { var r = new Size (ReadNumber (args [index]), ReadNumber (args [index+1])); // var xr = ReadNumber (args [i + 2]); var laf = ReadNumber (args [index+3]) != 0; var swf = ReadNumber (args [index+4]) != 0; var pt = new Point (ReadNumber (args [index+5]), ReadNumber (args [index+6])); if (op == 'a') pt += previousPoint; p.ArcTo (r, laf, swf, pt); index += 7; } else if ((op == 'V' || op == 'v') && args.Length >= index+1 && p.Operations.Count > 0) { var previousX = previousPoint.X; var y = ReadNumber(args[index]); if (op == 'v') y += previousPoint.Y; var point = new Point(previousX, y); p.LineTo(point); index += 1; } else if ((op == 'H' || op == 'h') && args.Length >= index+1 && p.Operations.Count > 0) { var previousY = previousPoint.Y; var x = ReadNumber(args[index]); if (op == 'h') x += previousPoint.X; var point = new Point(x, previousY); p.LineTo(point); index += 1; } else { throw new NotSupportedException ("Path Operation " + op); } } } m = m.NextMatch(); } }
void ReadPoints(Path p, string pathDescriptor, bool closePath) { var args = pathDescriptor.Split (new[]{' '}, StringSplitOptions.RemoveEmptyEntries); var i = 0; var n = args.Length; if (n == 0) throw new Exception ("Not supported point"); while (i < n) { var xy = args[i].Split(new[]{','}, StringSplitOptions.RemoveEmptyEntries); var x = ReadNumber (xy[0]); var y = ReadNumber (xy[1]); if (i == 0) { p.MoveTo (x, y); } else p.LineTo (x, y); i++; } if (closePath) p.Close (); }
void ReadPath(Path p, string pathDescriptor) { Match m = pathRegex.Match(pathDescriptor); while(m.Success) { var match = m.Value.Trim(); var op = match.Substring(0, 1); // make sure negative numbers are split properly match = match.Replace("-", " -"); var args = match.Substring(1).Split(WSC, StringSplitOptions.RemoveEmptyEntries); Point previousPoint = new Point (); if (p.Operations.Count > 0 && !(p.Operations.Last() is ClosePath)) previousPoint = p.Operations.Last().EndPoint; if ((op == "M" || op == "m") && args.Length >= 2) { var point = new Point (ReadNumber (args [0]), ReadNumber (args [1])); if (op == "m") point += previousPoint; p.MoveTo (point); } else if ((op == "L" || op == "l") && args.Length >= 2) { var point = new Point (ReadNumber (args [0]), ReadNumber (args [1])); if (op == "l") point += previousPoint; p.LineTo (point); } else if ((op == "C" || op == "c") && args.Length >= 6) { var c1 = new Point (ReadNumber (args [0]), ReadNumber (args [1])); var c2 = new Point (ReadNumber (args [2]), ReadNumber (args [3])); var pt = new Point (ReadNumber (args [4]), ReadNumber (args [5])); if (op == "c") { c1 += previousPoint; c2 += previousPoint; pt += previousPoint; } p.CurveTo (c1, c2, pt); } else if ((op == "S" || op == "s") && args.Length >= 4) { var c = new Point (ReadNumber (args [0]), ReadNumber (args [1])); var pt = new Point (ReadNumber (args [2]), ReadNumber (args [3])); if (op == "s") { c += previousPoint; pt += previousPoint; } p.ContinueCurveTo (c, pt); } else if ((op == "A" || op == "a") && args.Length >= 7) { var r = new Size (ReadNumber (args [0]), ReadNumber (args [1])); // var xr = ReadNumber (args [i + 2]); var laf = ReadNumber (args [3]) != 0; var swf = ReadNumber (args [4]) != 0; var pt = new Point (ReadNumber (args [5]), ReadNumber (args [6])); if (op == "a") pt += previousPoint; p.ArcTo (r, laf, swf, pt); } else if ((op == "V" || op == "v") && args.Length >= 1 && p.Operations.Count > 0) { var previousX = previousPoint.X; var y = ReadNumber(args[0]); if (op == "v") y += previousPoint.Y; var point = new Point(previousX, y); p.LineTo(point); } else if ((op == "H" || op == "h") && args.Length >= 1 && p.Operations.Count > 0) { var previousY = previousPoint.Y; var x = ReadNumber(args[0]); if (op == "h") x += previousPoint.X; var point = new Point(x, previousY); p.LineTo(point); } else if (op == "z" || op == "Z") { p.Close (); } else { throw new NotSupportedException ("Path Operation " + op); } m = m.NextMatch(); } }
void ReadPolygon(Path p, string pathDescriptor) { var args = pathDescriptor.Split (new[]{' '}, StringSplitOptions.RemoveEmptyEntries); var i = 0; var n = args.Length; if (n == 0) throw new Exception ("Not supported polygon"); while (i < n) { var x = ReadNumber (args [i]); var y = ReadNumber (args [i + 1]); if (i == 0) { p.MoveTo (x, y); } else p.LineTo (x, y); i += 2; } p.Close (); }
void AddElement(IList<IDrawable> list, XElement e, Pen inheritPen, Brush inheritBrush) { // // Style // Element r = null; Pen pen = null; Brush brush = null; bool hasPen, hasBrush; ApplyStyle (e.Attributes ().ToDictionary (k => k.Name.LocalName, v => v.Value), ref pen, out hasPen, ref brush, out hasBrush); var style = ReadString (e.Attribute ("style")); if (!string.IsNullOrWhiteSpace (style)) { ApplyStyle (style, ref pen, out hasPen, ref brush, out hasBrush); } pen = hasPen ? pen : inheritPen; brush = hasBrush ? brush : inheritBrush; //var id = ReadString (e.Attribute ("id")); // // Elements // switch (e.Name.LocalName) { case "text": { var x = ReadNumber (e.Attribute ("x")); var y = ReadNumber (e.Attribute ("y")); var text = e.Value.Trim (); var fontFamilyAttribute = e.Attribute("font-family"); var font = new Font (); //if (fontFamilyAttribute != null) // font.Family = fontFamilyAttribute.Value.Trim('\''); var fontSizeAttribute = e.Attribute("font-size"); if (fontSizeAttribute != null) font.Size = ReadNumber(fontSizeAttribute.Value); r = new Text (text, new Rect (new Point (x, y), new Size (double.MaxValue, double.MaxValue)), font, TextAlignment.Left, pen, brush); } break; case "rect": { var x = ReadNumber (e.Attribute ("x")); var y = ReadNumber (e.Attribute ("y")); var width = ReadNumber (e.Attribute ("width")); var height = ReadNumber (e.Attribute ("height")); r = new Rectangle (new Point (x, y), new Size (width, height), pen, brush); } break; case "ellipse": { var cx = ReadNumber (e.Attribute ("cx")); var cy = ReadNumber (e.Attribute ("cy")); var rx = ReadNumber (e.Attribute ("rx")); var ry = ReadNumber (e.Attribute ("ry")); r = new Ellipse (new Point (cx - rx, cy - ry), new Size (2 * rx, 2 * ry), pen, brush); } break; case "circle": { var cx = ReadNumber (e.Attribute ("cx")); var cy = ReadNumber (e.Attribute ("cy")); var rr = ReadNumber (e.Attribute ("r")); r = new Ellipse (new Point (cx - rr, cy - rr), new Size (2 * rr, 2 * rr), pen, brush); } break; case "path": { var dA = e.Attribute ("d"); if (dA != null && !string.IsNullOrWhiteSpace (dA.Value)) { var p = new Path (pen, brush); ReadPath (p, dA.Value); r = p; } } break; case "polygon": { var pA = e.Attribute ("points"); if (pA != null && !string.IsNullOrWhiteSpace (pA.Value)) { var path = new Path (pen, brush); ReadPolygon (path, pA.Value); r = path; } } break; case "g": { var g = new Group (); AddElements (g.Children, e.Elements (), pen, brush); r = 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, brush); r = useList.OfType<Element> ().FirstOrDefault (); } } } break; case "title": Graphic.Title = ReadString (e); break; case "desc": case "description": Graphic.Description = ReadString (e); break; case "defs": // Already read in earlier pass break; case "namedview": case "metadata": case "image": // Ignore break; case "line": { var x1 = ReadNumber ( e.Attribute("x1") ); var x2 = ReadNumber ( e.Attribute("x2") ); var y1 = ReadNumber ( e.Attribute("y1") ); var y2 = ReadNumber ( e.Attribute("y2") ); r = new Line(new Point(x1, y1), new Point(x2, y2), pen); } break; // color definition that can be referred to by other elements case "linearGradient": break; default: throw new NotSupportedException ("SVG element \"" + e.Name.LocalName + "\" is not supported"); } if (r != null) { r.Transform = ReadTransform (ReadString (e.Attribute ("transform"))); list.Add (r); } }
void ReadPath(Path p, string pathDescriptor) { var args = pathDescriptor.Split (WSC, StringSplitOptions.RemoveEmptyEntries); var i = 0; var n = args.Length; while (i < n) { var a = args[i]; // // Get the operation // var op = ""; if (a.Length == 1) { op = a; i++; } else { op = a.Substring (0, 1); args [i] = a.Substring (1); } // // Execute // if (op == "M" && i + 1 < n) { p.MoveTo (new Point (ReadNumber (args [i]), ReadNumber (args [i + 1]))); i += 2; } else if (op == "L" && i + 1 < n) { p.LineTo (new Point (ReadNumber (args [i]), ReadNumber (args [i + 1]))); i += 2; } else if (op == "C" && i + 5 < n) { var c1 = new Point (ReadNumber (args [i]), ReadNumber (args [i + 1])); var c2 = new Point (ReadNumber (args [i + 2]), ReadNumber (args [i + 3])); var pt = new Point (ReadNumber (args [i + 4]), ReadNumber (args [i + 5])); p.CurveTo (c1, c2, pt); i += 6; } else if (op == "S" && i + 3 < n) { var c = new Point (ReadNumber (args [i]), ReadNumber (args [i + 1])); var pt = new Point (ReadNumber (args [i + 2]), ReadNumber (args [i + 3])); p.ContinueCurveTo (c, pt); i += 4; } else if (op == "A" && i + 6 < n) { var r = new Size (ReadNumber (args [i]), ReadNumber (args [i + 1])); // var xr = ReadNumber (args [i + 2]); var laf = ReadNumber (args [i + 3]) != 0; var swf = ReadNumber (args [i + 4]) != 0; var pt = new Point (ReadNumber (args [i + 5]), ReadNumber (args [i + 6])); p.ArcTo (r, laf, swf, pt); i += 7; } else if (op == "z" || op == "Z") { p.Close (); } else { throw new NotSupportedException ("Path Operation " + op); } } }
public static void DrawPath(this ICanvas canvas, Action<Path> draw, Pen pen = null, Brush brush = null) { var p = new Path (pen, brush); draw (p); p.Draw (canvas); }
public static void FillPath(this ICanvas canvas, Action<Path> draw, Brush brush) { var p = new Path (null, brush); draw (p); p.Draw (canvas); }
public virtual void EndVisit (Path path) { EndVisitElement (path); }