• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DomCR / ACadSharp / 14083457468

26 Mar 2025 12:37PM UTC coverage: 76.338% (+0.2%) from 76.127%
14083457468

Pull #211

github

web-flow
Merge 48899a8f3 into c902191a1
Pull Request #211: Cad to svg

5534 of 7958 branches covered (69.54%)

Branch coverage included in aggregate %.

247 of 293 new or added lines in 7 files covered. (84.3%)

22 existing lines in 2 files now uncovered.

21914 of 27998 relevant lines covered (78.27%)

74980.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.98
/src/ACadSharp/IO/SVG/SvgXmlWriter.cs
1
using ACadSharp.Entities;
2
using ACadSharp.Tables;
3
using CSMath;
4
using System;
5
using System.Collections.Generic;
6
using System.Globalization;
7
using System.IO;
8
using System.Linq;
9
using System.Text;
10
using System.Xml;
11

12
namespace ACadSharp.IO.SVG
13
{
14
        internal class SvgXmlWriter : XmlTextWriter
15
        {
16
                public event NotificationEventHandler OnNotification;
17

18
                public SvgConfiguration Configuration { get; } = new();
18✔
19

20
                public SvgXmlWriter(Stream w, Encoding encoding, SvgConfiguration configuration) : base(w, encoding)
1✔
21
                {
1✔
22
                        this.Configuration = configuration;
1✔
23
                }
1✔
24

25
                public void WriteAttributeString(string localName, double value)
26
                {
52✔
27
                        this.WriteAttributeString(localName, value.ToString(CultureInfo.InvariantCulture));
52✔
28
                }
52✔
29

30
                public void WriteBlock(BlockRecord record)
31
                {
1✔
32
                        BoundingBox box = record.GetBoundingBox();
1✔
33
                        this.startDocument(box);
1✔
34

35
                        Transform transform = new Transform(-box.Min, new XYZ(1), XYZ.Zero);
1✔
36
                        foreach (var e in record.Entities)
47✔
37
                        {
22✔
38
                                this.writeEntity(e);
22✔
39
                        }
22✔
40

41
                        this.endDocument();
1✔
42
                }
1✔
43

44
                private string colorSvg(Color color)
45
                {
19✔
46
                        return $"rgb({color.R},{color.G},{color.B})";
19✔
47
                }
19✔
48

49
                private void endDocument()
50
                {
1✔
51
                        this.WriteEndElement();
1✔
52
                        this.WriteEndDocument();
1✔
53
                        this.Close();
1✔
54
                }
1✔
55

56
                private void notify(string message, NotificationType type, Exception ex = null)
57
                {
4✔
58
                        this.OnNotification?.Invoke(this, new NotificationEventArgs(message, type, ex));
4!
59
                }
4✔
60

61
                private void startDocument(BoundingBox box)
62
                {
1✔
63
                        this.WriteStartDocument();
1✔
64

65
                        this.WriteStartElement("svg");
1✔
66
                        this.WriteAttributeString("xmlns", "http://www.w3.org/2000/svg");
1✔
67

68
                        this.WriteAttributeString("width", box.Max.X - box.Min.X);
1✔
69
                        this.WriteAttributeString("height", box.Max.Y - box.Min.Y);
1✔
70

71
                        this.WriteStartAttribute("viewBox");
1✔
72
                        this.WriteValue(box.Min.X);
1✔
73
                        this.WriteValue(" ");
1✔
74
                        this.WriteValue(box.Min.Y);
1✔
75
                        this.WriteValue(" ");
1✔
76
                        this.WriteValue(box.Max.X - box.Min.X);
1✔
77
                        this.WriteValue(" ");
1✔
78
                        this.WriteValue(box.Max.Y - box.Min.Y);
1✔
79
                        this.WriteEndAttribute();
1✔
80

81
                        this.WriteAttributeString("transform", $"scale(1,-1)");
1✔
82
                }
1✔
83

84
                private string svgPoints(IEnumerable<IVector> points, Transform transform)
85
                {
7✔
86
                        if (!points.Any())
7!
NEW
87
                        {
×
NEW
88
                                return string.Empty;
×
89
                        }
90

91
                        StringBuilder sb = new StringBuilder();
7✔
92
                        sb.Append(transform.ApplyTransform(points.First().Convert<XYZ>()).SvgPoint());
7✔
93
                        foreach (IVector point in points.Skip(1))
2,079✔
94
                        {
1,029✔
95
                                sb.Append(' ');
1,029✔
96
                                sb.Append(transform.ApplyTransform(point.Convert<XYZ>()).SvgPoint());
1,029✔
97
                        }
1,029✔
98

99
                        return sb.ToString();
7✔
100
                }
7✔
101

102
                private void writeArc(Arc arc, Transform transform)
103
                {
3✔
104
                        //A rx ry rotation large-arc-flag sweep-flag x y
105

106
                        this.WriteStartElement("polyline");
3✔
107

108
                        this.writeEntityStyle(arc);
3✔
109

110
                        IEnumerable<IVector> vertices = arc.PolygonalVertexes(256).OfType<IVector>();
3✔
111
                        string pts = this.svgPoints(vertices, transform);
3✔
112
                        this.WriteAttributeString("points", pts);
3✔
113
                        this.WriteAttributeString("fill", "none");
3✔
114

115
                        this.WriteEndElement();
3✔
116
                }
3✔
117

118
                private void writeCircle(Circle circle, Transform transform)
119
                {
1✔
120
                        var loc = transform.ApplyTransform(circle.Center);
1✔
121

122
                        this.WriteStartElement("circle");
1✔
123

124
                        this.writeEntityStyle(circle);
1✔
125

126
                        this.WriteAttributeString("r", circle.Radius);
1✔
127
                        this.WriteAttributeString("cx", loc.X);
1✔
128
                        this.WriteAttributeString("cy", loc.Y);
1✔
129

130
                        this.WriteAttributeString("fill", "none");
1✔
131

132
                        this.WriteEndElement();
1✔
133
                }
1✔
134

135
                private void writeEllipse(Ellipse ellipse, Transform transform)
136
                {
1✔
137
                        this.WriteStartElement("polygon");
1✔
138

139
                        this.writeEntityStyle(ellipse);
1✔
140

141
                        IEnumerable<IVector> vertices = ellipse.PolygonalVertexes(256).OfType<IVector>();
1✔
142
                        string pts = this.svgPoints(vertices, transform);
1✔
143
                        this.WriteAttributeString("points", pts);
1✔
144
                        this.WriteAttributeString("fill", "none");
1✔
145

146
                        this.WriteEndElement();
1✔
147
                }
1✔
148

149
                private void writeEntity(Entity entity)
150
                {
22✔
151
                        this.writeEntity(entity, new Transform());
22✔
152
                }
22✔
153

154
                private void writeEntity(Entity entity, Transform transform)
155
                {
22✔
156
                        switch (entity)
22✔
157
                        {
158
                                case Arc arc:
159
                                        this.writeArc(arc, transform);
3✔
160
                                        break;
3✔
161
                                case Line line:
162
                                        this.writeLine(line, transform);
7✔
163
                                        break;
7✔
164
                                case Point point:
165
                                        this.writePoint(point, transform);
1✔
166
                                        break;
1✔
167
                                case Circle circle:
168
                                        this.writeCircle(circle, transform);
1✔
169
                                        break;
1✔
170
                                case Ellipse ellipse:
171
                                        this.writeEllipse(ellipse, transform);
1✔
172
                                        break;
1✔
173
                                case IPolyline polyline:
174
                                        this.writePolyline(polyline, transform);
3✔
175
                                        break;
3✔
176
                                case TextEntity text:
177
                                        this.writeText(text, transform);
2✔
178
                                        break;
2✔
179
                                default:
180
                                        this.notify($"[{entity.ObjectName}] Entity not implemented.", NotificationType.NotImplemented);
4✔
181
                                        break;
4✔
182
                        }
183
                }
22✔
184

185
                private void writeEntityStyle(IEntity entity)
186
                {
16✔
187
                        Color color = entity.GetActiveColor();
16✔
188

189
                        this.WriteAttributeString("stroke", this.colorSvg(color));
16✔
190

191
                        var lineWeight = entity.LineWeight;
16✔
192
                        switch (lineWeight)
16✔
193
                        {
194
                                case LineweightType.ByLayer:
195
                                        lineWeight = entity.Layer.LineWeight;
16✔
196
                                        break;
16✔
197
                        }
198

199
                        this.WriteAttributeString("stroke-width", Configuration.GetLineWeightValue(lineWeight));
16✔
200
                }
16✔
201

202
                private void writeLine(Line line, Transform transform)
203
                {
7✔
204
                        var start = transform.ApplyTransform(line.StartPoint);
7✔
205
                        var end = transform.ApplyTransform(line.EndPoint);
7✔
206

207
                        this.WriteStartElement("line");
7✔
208

209
                        this.writeEntityStyle(line);
7✔
210

211
                        this.WriteAttributeString("x1", start.X);
7✔
212
                        this.WriteAttributeString("y1", start.Y);
7✔
213
                        this.WriteAttributeString("x2", end.X);
7✔
214
                        this.WriteAttributeString("y2", end.Y);
7✔
215

216
                        this.WriteEndElement();
7✔
217
                }
7✔
218

219
                private void writePoint(Point point, Transform transform)
220
                {
1✔
221
                        var loc = transform.ApplyTransform(point.Location);
1✔
222

223
                        this.WriteStartElement("circle");
1✔
224

225
                        this.writeEntityStyle(point);
1✔
226

227
                        this.WriteAttributeString("r", this.Configuration.PointRadius);
1✔
228
                        this.WriteAttributeString("cx", loc.X);
1✔
229
                        this.WriteAttributeString("cy", loc.Y);
1✔
230

231
                        this.WriteAttributeString("fill", this.colorSvg(point.GetActiveColor()));
1✔
232

233
                        this.WriteEndElement();
1✔
234
                }
1✔
235

236
                private void writeText(TextEntity text, Transform transform)
237
                {
2✔
238
                        var insert = transform.ApplyTransform(text.InsertPoint);
2✔
239

240
                        this.WriteStartElement("g");
2✔
241
                        this.WriteAttributeString("transform", $"translate({insert.X.ToString(CultureInfo.InvariantCulture)},{insert.Y.ToString(CultureInfo.InvariantCulture)})");
2✔
242

243
                        this.WriteStartElement("text");
2✔
244
                        this.WriteAttributeString("transform", "scale(1,-1)");
2✔
245

246
                        this.WriteAttributeString("fill", this.colorSvg(text.GetActiveColor()));
2✔
247

248
                        //<text x="20" y="35" class="small">My</text>
249
                        this.WriteStartAttribute("style");
2✔
250
                        this.WriteValue("font:");
2✔
251
                        this.WriteValue(text.Height);
2✔
252
                        this.WriteValue("px");
2✔
253
                        this.WriteValue(" ");
2✔
254
                        this.WriteValue(Path.GetFileNameWithoutExtension(text.Style.Filename));
2✔
255
                        this.WriteEndAttribute();
2✔
256

257
                        this.WriteRaw(text.Value);
2✔
258

259
                        this.WriteEndElement();
2✔
260
                        this.WriteEndElement();
2✔
261
                }
2✔
262

263
                private void writePolyline(IPolyline polyline, Transform transform)
264
                {
3✔
265
                        if (polyline.IsClosed)
3✔
266
                        {
2✔
267
                                this.WriteStartElement("polygon");
2✔
268
                        }
2✔
269
                        else
270
                        {
1✔
271
                                this.WriteStartElement("polyline");
1✔
272
                        }
1✔
273

274
                        this.writeEntityStyle(polyline);
3✔
275

276
                        var vertices = polyline.Vertices.Select(v => v.Location).ToList();
15✔
277

278
                        string pts = this.svgPoints(polyline.Vertices.Select(v => v.Location), transform);
21✔
279
                        this.WriteAttributeString("points", pts);
3✔
280
                        this.WriteAttributeString("fill", "none");
3✔
281

282
                        this.WriteEndElement();
3✔
283
                }
3✔
284
        }
285
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc