diff --git a/src/ACadSharp.Tests/IO/SvgWriterTests.cs b/src/ACadSharp.Tests/IO/SvgWriterTests.cs new file mode 100644 index 00000000..de79bc4d --- /dev/null +++ b/src/ACadSharp.Tests/IO/SvgWriterTests.cs @@ -0,0 +1,67 @@ +using ACadSharp.Entities; +using ACadSharp.IO; +using ACadSharp.Tests.Common; +using CSMath; +using System; +using System.IO; +using Xunit; + +namespace ACadSharp.Tests.IO +{ + public class SvgWriterTests + { + public static readonly TheoryData EntityTypes = new TheoryData(); + + static SvgWriterTests() + { + foreach (var item in DataFactory.GetTypes()) + { + if (item == typeof(UnknownEntity)) + { + continue; + } + + EntityTypes.Add(item); + } + + if (!Directory.Exists(TestVariables.OutputSvgFolder)) + { + Directory.CreateDirectory(TestVariables.OutputSvgFolder); + } + } + + [Theory] + [MemberData(nameof(EntityTypes))] + public void WriteEntitiesNoDocument(Type t) + { + Entity e = (Entity)Factory.CreateObject(t); + string filename = Path.Combine(TestVariables.OutputSvgFolder, $"{e.SubclassMarker}.svg"); + + using (SvgWriter writer = new SvgWriter(filename)) + { + writer.WriteEntity(e); + } + } + + [Fact] + public void WriteLineNoDocument() + { + Entity e = new Line(new XYZ(0, 0, 0), new XYZ(10, 10, 0)); + + string filename = Path.Combine(TestVariables.OutputSvgFolder, $"{e.ObjectType}.svg"); + + using (SvgWriter writer = new SvgWriter(filename)) + { + writer.WriteEntity(e); + } + } + + private void writeSvg(string filename, string svg) + { + using (StreamWriter sw = new StreamWriter(filename)) + { + sw.Write(svg); + } + } + } +} diff --git a/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs b/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs index 722321ac..5775f7ef 100644 --- a/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs +++ b/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs @@ -162,6 +162,15 @@ public void SingleMText() this.Document.Entities.Add(mtext); } + public void MTextChineseCharacters() + { + MText mtext = new MText(); + + mtext.Value = "这是一个多行文本"; + + this.Document.Entities.Add(mtext); + } + public void SingleMTextSpecialCharacter() { MText mtext = new MText(); @@ -483,6 +492,7 @@ static WriterSingleObjectTests() Data.Add(new(nameof(SingleCaseGenerator.SingleMText))); Data.Add(new(nameof(SingleCaseGenerator.SingleMTextSpecialCharacter))); Data.Add(new(nameof(SingleCaseGenerator.SingleMTextMultiline))); + Data.Add(new(nameof(SingleCaseGenerator.MTextChineseCharacters))); Data.Add(new(nameof(SingleCaseGenerator.SinglePoint))); Data.Add(new(nameof(SingleCaseGenerator.ClosedLwPolyline))); Data.Add(new(nameof(SingleCaseGenerator.ClosedPolyline2DTest))); diff --git a/src/ACadSharp.Tests/TestVariables.cs b/src/ACadSharp.Tests/TestVariables.cs index f9675524..400470a9 100644 --- a/src/ACadSharp.Tests/TestVariables.cs +++ b/src/ACadSharp.Tests/TestVariables.cs @@ -9,11 +9,13 @@ public static class TestVariables public static string DesktopFolder { get { return Environment.GetFolderPath(Environment.SpecialFolder.Desktop); } } public static string SamplesFolder { get { return EnvironmentVars.Get("SAMPLES_FOLDER"); } } - + public static string OutputSamplesFolder { get { return EnvironmentVars.Get("OUTPUT_SAMPLES_FOLDER"); } } public static string OutputSingleCasesFolder { get { return EnvironmentVars.Get("OUTPUT_SINGLE_CASES_FOLDER"); } } + public static string OutputSvgFolder { get { return EnvironmentVars.Get("OUTPUT_SVG"); } } + public static bool LocalEnv { get { return EnvironmentVars.Get("LOCAL_ENV"); } } public static double Delta { get { return EnvironmentVars.Get("DELTA"); } } @@ -27,6 +29,7 @@ static TestVariables() EnvironmentVars.SetIfNull("SAMPLES_FOLDER", "../../../../../samples/"); EnvironmentVars.SetIfNull("OUTPUT_SAMPLES_FOLDER", "../../../../../samples/out"); EnvironmentVars.SetIfNull("OUTPUT_SINGLE_CASES_FOLDER", "../../../../../samples/out/single_cases"); + EnvironmentVars.SetIfNull("OUTPUT_SVG", "../../../../../samples/out/svg"); EnvironmentVars.SetIfNull("LOCAL_ENV", "true"); EnvironmentVars.SetIfNull("DELTA", "0.00001"); EnvironmentVars.SetIfNull("DECIMAL_PRECISION", "5"); @@ -35,14 +38,16 @@ static TestVariables() public static void CreateOutputFolders() { - if (!Directory.Exists(OutputSamplesFolder)) - { - Directory.CreateDirectory(OutputSamplesFolder); - } + craateFolderIfDoesNotExist(OutputSamplesFolder); + craateFolderIfDoesNotExist(OutputSingleCasesFolder); + craateFolderIfDoesNotExist(OutputSvgFolder); + } - if (!Directory.Exists(OutputSingleCasesFolder)) + private static void craateFolderIfDoesNotExist(string path) + { + if (!Directory.Exists(path)) { - Directory.CreateDirectory(OutputSingleCasesFolder); + Directory.CreateDirectory(path); } } } diff --git a/src/ACadSharp/Entities/Line.cs b/src/ACadSharp/Entities/Line.cs index 959732ca..234e2e0b 100644 --- a/src/ACadSharp/Entities/Line.cs +++ b/src/ACadSharp/Entities/Line.cs @@ -48,12 +48,12 @@ public class Line : Entity public XYZ EndPoint { get; set; } = XYZ.Zero; /// - /// Default constructor + /// Default constructor. /// public Line() : base() { } /// - /// Constructor with the start and end + /// Constructor with the start and end. /// /// /// @@ -72,4 +72,4 @@ public override BoundingBox GetBoundingBox() return new BoundingBox(min, max); } } -} +} \ No newline at end of file diff --git a/src/ACadSharp/IO/CadWriterBase.cs b/src/ACadSharp/IO/CadWriterBase.cs index d0042595..f54eb9e6 100644 --- a/src/ACadSharp/IO/CadWriterBase.cs +++ b/src/ACadSharp/IO/CadWriterBase.cs @@ -3,12 +3,6 @@ using System; using System.IO; using ACadSharp.Classes; -using ACadSharp.IO; -using ACadSharp.Exceptions; -using ACadSharp.IO.DWG; -using ACadSharp.IO.DWG.DwgStreamWriters; -using CSUtilities.IO; -using System.Collections.Generic; namespace ACadSharp.IO { @@ -18,12 +12,7 @@ namespace ACadSharp.IO public abstract class CadWriterBase : ICadWriter where T : CadWriterConfiguration, new() { - /// - /// Notification event to get information about the writing process. - /// - /// - /// The notification system informs about any issue or non critical errors during the writing. - /// + /// public event NotificationEventHandler OnNotification; /// diff --git a/src/ACadSharp/IO/ICadWriter.cs b/src/ACadSharp/IO/ICadWriter.cs index 413d5bce..e80f2c56 100644 --- a/src/ACadSharp/IO/ICadWriter.cs +++ b/src/ACadSharp/IO/ICadWriter.cs @@ -5,7 +5,15 @@ namespace ACadSharp.IO public interface ICadWriter : IDisposable { /// - /// Write the + /// Notification event to get information about the writing process. + /// + /// + /// The notification system informs about any issue or non critical errors during the writing. + /// + event NotificationEventHandler OnNotification; + + /// + /// Write the into the stream. /// void Write(); } diff --git a/src/ACadSharp/IO/SvgWriter.cs b/src/ACadSharp/IO/SvgWriter.cs new file mode 100644 index 00000000..c0764bfc --- /dev/null +++ b/src/ACadSharp/IO/SvgWriter.cs @@ -0,0 +1,183 @@ +using ACadSharp.Entities; +using CSMath; +using System; +using System.Globalization; +using System.IO; +using System.Text; +using System.Xml; + +namespace ACadSharp.IO +{ + public class SvgWriter : CadWriterBase + { + private SvgXmlWriter _writer; + + public SvgWriter(Stream stream) : base(stream, null) + { + StreamWriter textWriter = new StreamWriter(stream); + this._writer = new SvgXmlWriter(textWriter); + } + + public SvgWriter(string filename) + : this(File.Create(filename), null) + { + } + + public SvgWriter(string filename, CadDocument document) + : this(File.Create(filename), document) + { + } + + public SvgWriter(Stream stream, CadDocument document) : base(stream, document) + { + StreamWriter textWriter = new StreamWriter(this._stream); + this._writer = new SvgXmlWriter(this._stream, Encoding.Default); + + this._writer.Formatting = Formatting.Indented; + } + + /// + /// + /// will draw all the content in the model space.
+ /// The writer must be initialized with a none null . + ///
+ public override void Write() + { + this.Write(this._document); + + throw new NotImplementedException(); + } + + public void Write(CadDocument document) + { + if (this._document is null) + { + throw new ArgumentNullException("CadDocument cannot be null in the SvgWriter.", "CadDocument"); + } + + this._encoding = this.getListedEncoding(document.Header.CodePage); + + throw new NotImplementedException(); + } + + public void WriteEntity(Entity entity) + { + this._writer.WriteStartDocument(); + + this._writer.WriteStartElement("svg"); + + BoundingBox box = entity.GetBoundingBox(); + this._writer.WriteAttributeString("width", box.Max.X); + this._writer.WriteAttributeString("height", box.Max.Y); + + switch (entity) + { + case Line line: + this.writeLine(line); + break; + default: + throw new NotImplementedException($"Entity {entity.SubclassMarker} is not implemented."); + } + + this._writer.WriteEndElement(); + + this._writer.WriteEndDocument(); + + this._writer.Close(); + } + + private void writeEntityStyle(Entity entity) + { + this._writer.WriteAttributeString("style", $"stroke:rgb({entity.Color.R},{entity.Color.G},{entity.Color.B})"); + } + + private void writeLine(Line line) + { + this._writer.WriteStartElement("line"); + + this.writeEntityStyle(line); + + this._writer.WriteAttributeString("x1", line.StartPoint.X); + this._writer.WriteAttributeString("y1", line.StartPoint.Y); + this._writer.WriteAttributeString("x2", line.EndPoint.X); + this._writer.WriteAttributeString("y2", line.EndPoint.Y); + } + + public string Convert(Entity entity) + { + StringBuilder sb = new StringBuilder(); + + BoundingBox box = entity.GetBoundingBox(); + + + + sb.AppendLine($""); + + switch (entity) + { + case Line line: + sb.AppendLine(convertLine(line)); + break; + default: + throw new NotImplementedException($"Svg convertion not implemented for {entity.SubclassMarker}"); + } + + sb.AppendLine($""); + + return sb.ToString(); + } + + /// + public override void Dispose() + { + this._stream.Dispose(); + } + + private string convertLine(Line line) + { + StringBuilder sb = new StringBuilder(); + + sb.Append($"\t"); + sb.Append($""); + + return sb.ToString(); + } + + private string entityStyle(Entity entity) + { + StringBuilder style = new StringBuilder(); + + style.Append($"style="); + + style.Append($"\"stroke:rgb({entity.Color.R},{entity.Color.G},{entity.Color.B})\""); + + return style.ToString(); + } + } + + public class SvgXmlWriter : XmlTextWriter + { + public SvgXmlWriter(TextWriter w) : base(w) + { + } + + public SvgXmlWriter(Stream w, Encoding encoding) : base(w, encoding) + { + } + + public SvgXmlWriter(string filename, Encoding encoding) : base(filename, encoding) + { + } + + public void WriteAttributeString(string localName, double value) + { + this.WriteAttributeString(localName, value.ToString(CultureInfo.InvariantCulture)); + } + } +} diff --git a/src/CSUtilities b/src/CSUtilities index 041deaf6..8e90ba97 160000 --- a/src/CSUtilities +++ b/src/CSUtilities @@ -1 +1 @@ -Subproject commit 041deaf69322f64fe27b42fa6f482f14991dc82e +Subproject commit 8e90ba97610979043414306d57016d9a25db0251