diff --git a/CSharp/Utils/SVG/Clipper.SVG.Utils.cs b/CSharp/Utils/SVG/Clipper.SVG.Utils.cs index e6ab09a2..b1f24dbd 100644 --- a/CSharp/Utils/SVG/Clipper.SVG.Utils.cs +++ b/CSharp/Utils/SVG/Clipper.SVG.Utils.cs @@ -17,10 +17,9 @@ namespace Clipper2Lib { public static class SvgUtils { - static Random rc = new Random(); - public static uint RandomColor() { + Random rc = new Random(); return (uint) (rc.Next() | 0xBF000000); } diff --git a/CSharp/Utils/SVG/Clipper.SVG.cs b/CSharp/Utils/SVG/Clipper.SVG.cs index 79083ccf..ab9422a0 100644 --- a/CSharp/Utils/SVG/Clipper.SVG.cs +++ b/CSharp/Utils/SVG/Clipper.SVG.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Threading.Tasks; #if USINGZ namespace Clipper2ZLib @@ -161,7 +162,7 @@ public void AddClosedPaths(PathsD paths, uint brushColor, brushColor, penColor, penWidth, showCoords, false)); } - public void AddOpenPath(Path64 path, uint penColor, + public void AddOpenPath(Path64 path, uint penColor, double penWidth, bool showCoords = false) { Paths64 tmp = new Paths64(); @@ -169,7 +170,7 @@ public void AddOpenPath(Path64 path, uint penColor, AddOpenPaths(tmp, penColor, penWidth, showCoords); } - public void AddOpenPath(PathD path, uint penColor, + public void AddOpenPath(PathD path, uint penColor, double penWidth, bool showCoords = false) { PathsD tmp = new PathsD(); @@ -185,7 +186,7 @@ public void AddOpenPaths(Paths64 paths, 0x0, penColor, penWidth, showCoords, true)); } - public void AddOpenPaths(PathsD paths, uint penColor, + public void AddOpenPaths(PathsD paths, uint penColor, double penWidth, bool showCoords = false) { if (paths.Count == 0) return; @@ -224,11 +225,26 @@ private static float GetAlpha(uint clr) return ((float) (clr >> 24) / 255); } - public bool SaveToFile(string filename, int maxWidth = 0, int maxHeight = 0, int margin = -1) + /// + /// Save SVG to file. + /// + /// The path of file. + /// MaxWidth. + /// MaxHeight. + /// Margin. + /// + /// + public void SaveToFile( + string filename, + int maxWidth = 0, + int maxHeight = 0, + int margin = 20) { - if (margin < 0) margin = 20; + if (string.IsNullOrEmpty(filename)) + throw new ArgumentNullException(nameof(filename), "Filename can't be null or empty"); + if (margin < 0) throw new ArgumentOutOfRangeException(nameof(margin), "Margin should larger than zero"); RectD bounds = GetBounds(); - if (bounds.IsEmpty()) return false; + if (bounds.IsEmpty()) throw new Exception("UnBound"); double scale = 1.0; if (maxWidth > 0 && maxHeight > 0) @@ -239,15 +255,7 @@ public bool SaveToFile(string filename, int maxWidth = 0, int maxHeight = 0, int long offsetX = margin - (long) (bounds.left * scale); long offsetY = margin - (long) (bounds.top * scale); - StreamWriter writer; - try - { - writer = new StreamWriter(filename); - } - catch - { - return false; - } + using StreamWriter writer = new StreamWriter(filename); if (maxWidth <= 0 || maxHeight <= 0) writer.Write(svg_header, (bounds.right - bounds.left) + margin * 2, @@ -285,7 +293,7 @@ public bool SaveToFile(string filename, int maxWidth = 0, int maxHeight = 0, int if (!pi.ShowCoords) continue; { - writer.Write("\n", + writer.Write("\n", coordStyle.FontName, coordStyle.FontSize, ColorToHtml(coordStyle.FontColor)); foreach (PathD path in pi.paths) { @@ -295,7 +303,7 @@ public bool SaveToFile(string filename, int maxWidth = 0, int maxHeight = 0, int writer.Write("{2:f2},{3:f2},{4}\n", (pt.x * scale + offsetX), (pt.y * scale + offsetY), pt.x, pt.y, pt.z); #else - writer.Write("{2:f2},{3:f2}\n", + writer.Write("{2:f2},{3:f2}\n", (pt.x * scale + offsetX), (pt.y * scale + offsetY), pt.x, pt.y); #endif } @@ -307,15 +315,136 @@ public bool SaveToFile(string filename, int maxWidth = 0, int maxHeight = 0, int foreach (TextInfo captionInfo in textInfos) { writer.Write("\n", + "font-weight=\"normal\" font-size=\"{0}\" fill=\"{1}\">\n", captionInfo.fontSize, ColorToHtml(captionInfo.fontColor)); - writer.Write("{2}\n\n", + writer.Write("{2}\n\n", captionInfo.posX * scale + offsetX, captionInfo.posY * scale + offsetY, captionInfo.text); } writer.Write("\n"); - writer.Close(); - return true; + } + + /// + /// Save SVG to file asynchronously. + /// + /// The path of file. + /// MaxWidth. + /// MaxHeight. + /// Margin. + /// + /// + public async Task SaveToFileAsync( + string filename, + int maxWidth = 0, + int maxHeight = 0, + int margin = 20) + { + if (string.IsNullOrEmpty(filename)) + throw new ArgumentNullException(nameof(filename), "Filename can't be null or empty"); + if (margin < 0) throw new ArgumentOutOfRangeException(nameof(margin), "Margin should larger than zero"); + RectD bounds = GetBounds(); + if (bounds.IsEmpty()) throw new Exception("UnBound"); + + double scale = 1.0; + if (maxWidth > 0 && maxHeight > 0) + scale = Math.Min( + (maxWidth - margin * 2) / bounds.Width, + (maxHeight - margin * 2) / bounds.Height); + + long offsetX = margin - (long) (bounds.left * scale); + long offsetY = margin - (long) (bounds.top * scale); + + using StreamWriter writer = new StreamWriter(filename); + + if (maxWidth <= 0 || maxHeight <= 0) + await writer.WriteAsync(string.Format( + NumberFormatInfo.InvariantInfo, + svg_header, + (bounds.right - bounds.left) + margin * 2, + (bounds.bottom - bounds.top) + margin * 2)); + else + await writer.WriteAsync(string.Format(svg_header, maxWidth, maxHeight)); + + foreach (PolyInfo pi in PolyInfoList) + { + await writer.WriteAsync(" \n", + coordStyle.FontName, + coordStyle.FontSize, + ColorToHtml(coordStyle.FontColor))); + foreach (PathD path in pi.paths) + { + foreach (PointD pt in path) + { +#if USINGZ + await writer.WriteAsync(string.Format( + "{2:f2},{3:f2},{4}\n", + (pt.x * scale + offsetX), + (pt.y * scale + offsetY), + pt.x, + pt.y, + pt.z)); +#else + await writer.WriteAsync(string.Format( + NumberFormatInfo.InvariantInfo, + "{2:f2},{3:f2}\n", + (pt.x * scale + offsetX), + (pt.y * scale + offsetY), + pt.x, + pt.y)); +#endif + } + } + await writer.WriteAsync("\n\n"); + } + } + + foreach (TextInfo captionInfo in textInfos) + { + await writer.WriteAsync(string.Format( + NumberFormatInfo.InvariantInfo, + "\n", + captionInfo.fontSize, + ColorToHtml(captionInfo.fontColor))); + await writer.WriteAsync(string.Format( + NumberFormatInfo.InvariantInfo, + "{2}\n\n", + captionInfo.posX * scale + offsetX, + captionInfo.posY * scale + offsetY, + captionInfo.text)); + } + + await writer.WriteAsync("\n"); } }