diff --git a/MapToolkit.Drawing/IDrawSurface.cs b/MapToolkit.Drawing/IDrawSurface.cs index 04ae3a5..bb0f16f 100644 --- a/MapToolkit.Drawing/IDrawSurface.cs +++ b/MapToolkit.Drawing/IDrawSurface.cs @@ -39,5 +39,7 @@ IDrawTextStyle AllocateTextStyle( void DrawText(Vector point, string text, IDrawTextStyle style); void DrawIcon(Vector center, IDrawIcon icon); + + void DrawRoundedRectangle(Vector topLeft, Vector bottomRight, IDrawStyle style, float radius); } } diff --git a/MapToolkit.Drawing/ImageRender/ImageSurface.cs b/MapToolkit.Drawing/ImageRender/ImageSurface.cs index ca88a42..52f9a99 100644 --- a/MapToolkit.Drawing/ImageRender/ImageSurface.cs +++ b/MapToolkit.Drawing/ImageRender/ImageSurface.cs @@ -156,5 +156,27 @@ public void DrawIcon(Vector center, IDrawIcon icon) var iicon = (ImageIcon)icon; target.DrawImage(iicon.Image, new Point( (int)(center.X - (iicon.Image.Width / 2)), (int)(center.Y - (iicon.Image.Height / 2))), 1); } + + public void DrawRoundedRectangle(Vector topLeft, Vector bottomRight, IDrawStyle style, float radius) + { + var istyle = (ImageStyle)style; + + var path = new PathBuilder() + .AddArc((float)topLeft.X + radius, (float)topLeft.Y + radius, radius, radius, 0, -90, -90) + .AddArc((float)topLeft.X + radius, (float)bottomRight.Y - radius, radius, radius, 180, 0, -90) + .AddArc((float)bottomRight.X - radius, (float)bottomRight.Y - radius, radius, radius, 0, 90, -90) + .AddArc((float)bottomRight.X - radius, (float)topLeft.Y + radius, radius, radius, 180, 180, -90) + .CloseFigure() + .Build(); + + if (istyle.Brush != null) + { + target.Fill(istyle.Brush, path); + } + if (istyle.Pen != null) + { + target.Draw(istyle.Pen, path); + } + } } } diff --git a/MapToolkit.Drawing/MemoryRender/DrawRoundedRectangle.cs b/MapToolkit.Drawing/MemoryRender/DrawRoundedRectangle.cs new file mode 100644 index 0000000..fdc69ce --- /dev/null +++ b/MapToolkit.Drawing/MemoryRender/DrawRoundedRectangle.cs @@ -0,0 +1,48 @@ + + + +namespace MapToolkit.Drawing.MemoryRender +{ + internal class DrawRoundedRectangle : IDrawOperation + { + public DrawRoundedRectangle(Vector topLeft, Vector bottomRight, MemDrawStyle style, float radius) + { + TopLeft = topLeft; + BottomRight = bottomRight; + Style = style; + Radius = radius; + } + + public Vector TopLeft { get; } + + public Vector BottomRight { get; } + + public MemDrawStyle Style { get; } + + public float Radius { get; } + + public Vector Min => TopLeft; + + public Vector Max => BottomRight; + + public void Draw(MemDrawContext context) + { + context.Target.DrawRoundedRectangle(TopLeft, BottomRight, context.MapStyle(Style), Radius); + } + + public void DrawClipped(MemDrawClipped context) + { + context.Target.DrawRoundedRectangle(TopLeft, BottomRight, context.MapStyle(Style), Radius); + } + + public IDrawOperation Scale(MemDrawScale context) + { + return new DrawRoundedRectangle(TopLeft * context.Scale, BottomRight * context.Scale, context.MapStyle(Style), (float)(Radius * context.Scale)); + } + + public IEnumerable Simplify(double lengthSquared) + { + yield return this; + } + } +} \ No newline at end of file diff --git a/MapToolkit.Drawing/MemoryRender/MemorySurface.cs b/MapToolkit.Drawing/MemoryRender/MemorySurface.cs index f9b94cb..fb3d499 100644 --- a/MapToolkit.Drawing/MemoryRender/MemorySurface.cs +++ b/MapToolkit.Drawing/MemoryRender/MemorySurface.cs @@ -127,5 +127,10 @@ public void DrawIcon(Vector center, IDrawIcon icon) { Operations.Add(new DrawIcon(center, (MemDrawIcon)icon)); } + + public void DrawRoundedRectangle(Vector topLeft, Vector bottomRight, IDrawStyle style, float radius) + { + Operations.Add(new DrawRoundedRectangle(topLeft, bottomRight, (MemDrawStyle)style, radius)); + } } } diff --git a/MapToolkit.Drawing/MemoryRender/TranslateStylesSurface.cs b/MapToolkit.Drawing/MemoryRender/TranslateStylesSurface.cs index 1941ed8..8efc20c 100644 --- a/MapToolkit.Drawing/MemoryRender/TranslateStylesSurface.cs +++ b/MapToolkit.Drawing/MemoryRender/TranslateStylesSurface.cs @@ -66,6 +66,11 @@ public void DrawPolyline(IEnumerable points, IDrawStyle style) throw new System.NotImplementedException(); } + public void DrawRoundedRectangle(Vector topLeft, Vector bottomRight, IDrawStyle style, float radius) + { + s.DrawRoundedRectangle(topLeft, bottomRight, memDrawContext.MapStyle((MemDrawStyle)style), radius); + } + public void DrawText(Vector point, string text, IDrawTextStyle style) { throw new System.NotImplementedException(); diff --git a/MapToolkit.Drawing/PdfRender/PdfSurface.cs b/MapToolkit.Drawing/PdfRender/PdfSurface.cs index d83314a..1f3ac5d 100644 --- a/MapToolkit.Drawing/PdfRender/PdfSurface.cs +++ b/MapToolkit.Drawing/PdfRender/PdfSurface.cs @@ -231,5 +231,19 @@ public void DrawIcon(Vector center, IDrawIcon icon) var top = center - (picon.Size / 2); picon.Draw(new TranslateDraw(this, top.X, top.Y)); } + + public void DrawRoundedRectangle(Vector topLeft, Vector bottomRight, IDrawStyle style, float radius) + { + var pstyle = (PdfStyle)style; + + graphics.DrawRoundedRectangle(pstyle.Pen, + pstyle.Brush, + topLeft.X * pixelSize, + topLeft.Y * pixelSize, + (bottomRight.X - topLeft.X) * pixelSize, + (bottomRight.Y - topLeft.Y) * pixelSize, + radius * pixelSize, + radius * pixelSize); + } } } diff --git a/MapToolkit.Drawing/Render.cs b/MapToolkit.Drawing/Render.cs index a059b33..a3676d7 100644 --- a/MapToolkit.Drawing/Render.cs +++ b/MapToolkit.Drawing/Render.cs @@ -17,9 +17,9 @@ namespace MapToolkit.Drawing { public static class Render { - public static void ToSvg(string file, Vector size, Action draw) + public static void ToSvg(string file, Vector size, Action draw, string stylePrefix = "") { - using (var surface = new SvgRender.SvgSurface(XmlWriter.Create(File.CreateText(file)), size, file)) + using (var surface = new SvgRender.SvgSurface(XmlWriter.Create(File.CreateText(file), new XmlWriterSettings() { CloseOutput = true }), size, file, stylePrefix)) { draw(surface); } diff --git a/MapToolkit.Drawing/SvgRender/SvgSurface.cs b/MapToolkit.Drawing/SvgRender/SvgSurface.cs index 67e5314..bc52473 100644 --- a/MapToolkit.Drawing/SvgRender/SvgSurface.cs +++ b/MapToolkit.Drawing/SvgRender/SvgSurface.cs @@ -25,11 +25,13 @@ internal sealed class SvgSurface : IDrawSurface, IDisposable private readonly int rounding = 1; private bool isWrittingStyle = false; private readonly StringBuilder styles = new StringBuilder(); + private readonly string stylePrefix; - public SvgSurface(XmlWriter writer, Vector size, string? path = null) + public SvgSurface(XmlWriter writer, Vector size, string? path = null, string stylePrefix = "") { this.writer = writer; this.path = path; + this.stylePrefix = stylePrefix; StartSvg(size); } @@ -56,7 +58,7 @@ public IDrawStyle AllocateStyle(IBrush? fill, Pen? pen) private string TakeStyleId() { - return "s" + (nextStyleId++).ToString("x"); + return stylePrefix + "s" + (nextStyleId++).ToString("x"); } private void EndClass() @@ -428,5 +430,18 @@ public void DrawIcon(Vector center, IDrawIcon icon) var top = center - (sicon.Size / 2); sicon.Draw(new TranslateDraw(this, top.X, top.Y)); } + + public void DrawRoundedRectangle(Vector topLeft, Vector bottomRight, IDrawStyle style, float radius) + { + FlushStyles(); + writer.WriteStartElement("rect", SvgXmlns); + writer.WriteAttributeString("x", ToString(topLeft.X)); + writer.WriteAttributeString("y", ToString(topLeft.Y)); + writer.WriteAttributeString("width", ToString(bottomRight.X - topLeft.X)); + writer.WriteAttributeString("height", ToString(bottomRight.Y - topLeft.Y)); + writer.WriteAttributeString("rx", ToString(radius)); + writer.WriteAttributeString("class", ((SvgStyle)style).Name); + writer.WriteEndElement(); + } } } diff --git a/MapToolkit.Drawing/TranslateDraw.cs b/MapToolkit.Drawing/TranslateDraw.cs index a0b388d..9b92945 100644 --- a/MapToolkit.Drawing/TranslateDraw.cs +++ b/MapToolkit.Drawing/TranslateDraw.cs @@ -83,5 +83,10 @@ public void DrawIcon(Vector center, IDrawIcon icon) { drawSurface.DrawIcon(Translate(center), icon); } + + public void DrawRoundedRectangle(Vector topLeft, Vector bottomRight, IDrawStyle style, float radius) + { + drawSurface.DrawRoundedRectangle(Translate(topLeft), Translate(bottomRight), style, radius); + } } }