public void Offset(float dx, float dy) { Transform(SKMatrix.MakeTranslation(dx, dy)); }
public void Draw (SKCanvas canvas, float x, float y) { var matrix = SKMatrix.MakeTranslation (x, y); Draw (canvas, ref matrix); }
private SKMatrix ReadTransform(string raw) { var t = SKMatrix.MakeIdentity(); if (string.IsNullOrWhiteSpace(raw)) { return(t); } var calls = raw.Trim().Split(new[] { ')' }, StringSplitOptions.RemoveEmptyEntries); foreach (var c in calls) { var args = c.Split(new[] { '(', ',', ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); var nt = SKMatrix.MakeIdentity(); switch (args[0]) { case "matrix": if (args.Length == 7) { nt.Values = new float[] { ReadNumber(args[1]), ReadNumber(args[3]), ReadNumber(args[5]), ReadNumber(args[2]), ReadNumber(args[4]), ReadNumber(args[6]), 0, 0, 1 }; } else { LogOrThrow($"Matrices are expected to have 6 elements, this one has {args.Length - 1}"); } break; case "translate": if (args.Length >= 3) { nt = SKMatrix.MakeTranslation(ReadNumber(args[1]), ReadNumber(args[2])); } else if (args.Length >= 2) { nt = SKMatrix.MakeTranslation(ReadNumber(args[1]), 0); } break; case "scale": if (args.Length >= 3) { nt = SKMatrix.MakeScale(ReadNumber(args[1]), ReadNumber(args[2])); } else if (args.Length >= 2) { var sx = ReadNumber(args[1]); nt = SKMatrix.MakeScale(sx, sx); } break; case "rotate": var a = ReadNumber(args[1]); if (args.Length >= 4) { var x = ReadNumber(args[2]); var y = ReadNumber(args[3]); var t1 = SKMatrix.MakeTranslation(x, y); var t2 = SKMatrix.MakeRotationDegrees(a); var t3 = SKMatrix.MakeTranslation(-x, -y); SKMatrix.Concat(ref nt, ref t1, ref t2); SKMatrix.Concat(ref nt, ref nt, ref t3); } else { nt = SKMatrix.MakeRotationDegrees(a); } break; default: LogOrThrow($"Can't transform {args[0]}"); break; } SKMatrix.Concat(ref t, ref t, ref nt); } return(t); }
public void DrawPicture(SKPicture picture, float x, float y, SKPaint paint = null) { var matrix = SKMatrix.MakeTranslation(x, y); DrawPicture(picture, ref matrix, paint); }
private void ReadElement(XElement e, SKCanvas canvas, SKPaint stroke, SKPaint fill) { ReadPaints(e, ref stroke, ref fill); // transform matrix var transform = ReadTransform(e.Attribute("transform")?.Value ?? string.Empty); canvas.Save(); canvas.Concat(ref transform); // SVG elements var elementName = e.Name.LocalName; switch (elementName) { case "text": if (stroke != null || fill != null) { ReadText(e, canvas, stroke?.Clone(), fill?.Clone()); } break; case "rect": if (stroke != null || fill != null) { 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")); var rect = SKRect.Create(x, y, width, height); if (rx > 0 || ry > 0) { if (fill != null) { canvas.DrawRoundRect(rect, rx, ry, fill); } if (stroke != null) { canvas.DrawRoundRect(rect, rx, ry, stroke); } } else { if (fill != null) { canvas.DrawRect(rect, fill); } if (stroke != null) { canvas.DrawRect(rect, stroke); } } } break; case "ellipse": if (stroke != null || fill != null) { var cx = ReadNumber(e.Attribute("cx")); var cy = ReadNumber(e.Attribute("cy")); var rx = ReadNumber(e.Attribute("rx")); var ry = ReadNumber(e.Attribute("ry")); if (fill != null) { canvas.DrawOval(cx, cy, rx, ry, fill); } if (stroke != null) { canvas.DrawOval(cx, cy, rx, ry, stroke); } } break; case "circle": if (stroke != null || fill != null) { var cx = ReadNumber(e.Attribute("cx")); var cy = ReadNumber(e.Attribute("cy")); var rr = ReadNumber(e.Attribute("r")); if (fill != null) { canvas.DrawCircle(cx, cy, rr, fill); } if (stroke != null) { canvas.DrawCircle(cx, cy, rr, stroke); } } break; case "path": if (stroke != null || fill != null) { var d = e.Attribute("d")?.Value; if (!string.IsNullOrWhiteSpace(d)) { var path = SKPath.ParseSvgPathData(d); if (fill != null) { canvas.DrawPath(path, fill); } if (stroke != null) { canvas.DrawPath(path, stroke); } } } break; case "polygon": case "polyline": if (stroke != null || fill != null) { var close = elementName == "polygon"; var p = e.Attribute("points")?.Value; if (!string.IsNullOrWhiteSpace(p)) { var path = ReadPolyPath(p, close); if (fill != null) { canvas.DrawPath(path, fill); } if (stroke != null) { canvas.DrawPath(path, stroke); } } } break; case "g": if (e.HasElements) { foreach (var gElement in e.Elements()) { ReadElement(gElement, canvas, stroke?.Clone(), fill?.Clone()); } } break; case "use": if (e.HasAttributes) { var href = ReadHref(e); if (href != null) { // TODO: copy/process other attributes var x = ReadNumber(e.Attribute("x")); var y = ReadNumber(e.Attribute("y")); var useTransform = SKMatrix.MakeTranslation(x, y); canvas.Save(); canvas.Concat(ref useTransform); ReadElement(href, canvas, stroke?.Clone(), fill?.Clone()); canvas.Restore(); } } break; case "line": if (stroke != null) { var x1 = ReadNumber(e.Attribute("x1")); var x2 = ReadNumber(e.Attribute("x2")); var y1 = ReadNumber(e.Attribute("y1")); var y2 = ReadNumber(e.Attribute("y2")); canvas.DrawLine(x1, y1, x2, y2, stroke); } break; case "switch": if (e.HasElements) { foreach (var ee in e.Elements()) { var requiredFeatures = ee.Attribute("requiredFeatures"); var requiredExtensions = ee.Attribute("requiredExtensions"); var systemLanguage = ee.Attribute("systemLanguage"); // TODO: evaluate requiredFeatures, requiredExtensions and systemLanguage var isVisible = requiredFeatures == null && requiredExtensions == null && systemLanguage == null; if (isVisible) { ReadElement(ee, canvas, stroke?.Clone(), fill?.Clone()); } } } break; case "defs": case "title": case "desc": case "description": // already read earlier break; default: LogOrThrow($"SVG element '{elementName}' is not supported"); break; } // restore matrix canvas.Restore(); }