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

DomCR / ACadSharp / 14084601072

26 Mar 2025 01:32PM UTC coverage: 76.345% (-3.4%) from 79.72%
14084601072

Pull #211

github

web-flow
Merge 070f025e9 into c902191a1
Pull Request #211: Cad to svg

5536 of 7962 branches covered (69.53%)

Branch coverage included in aggregate %.

259 of 305 new or added lines in 8 files covered. (84.92%)

5 existing lines in 2 files now uncovered.

21926 of 28009 relevant lines covered (78.28%)

74951.67 hits per line

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

98.12
/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
                {
60✔
27
                        this.WriteAttributeString(localName, value.ToString(CultureInfo.InvariantCulture));
60✔
28
                }
60✔
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
                {
21✔
46
                        return $"rgb({color.R},{color.G},{color.B})";
21✔
47
                }
21✔
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
                {
2✔
58
                        this.OnNotification?.Invoke(this, new NotificationEventArgs(message, type, ex));
2!
59
                }
2✔
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 IText text:
177
                                        this.writeText(text, transform);
4✔
178
                                        break;
4✔
179
                                default:
180
                                        this.notify($"[{entity.ObjectName}] Entity not implemented.", NotificationType.NotImplemented);
2✔
181
                                        break;
2✔
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 writePolyline(IPolyline polyline, Transform transform)
237
                {
3✔
238
                        if (polyline.IsClosed)
3✔
239
                        {
2✔
240
                                this.WriteStartElement("polygon");
2✔
241
                        }
2✔
242
                        else
243
                        {
1✔
244
                                this.WriteStartElement("polyline");
1✔
245
                        }
1✔
246

247
                        this.writeEntityStyle(polyline);
3✔
248

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

251
                        string pts = this.svgPoints(polyline.Vertices.Select(v => v.Location), transform);
21✔
252
                        this.WriteAttributeString("points", pts);
3✔
253
                        this.WriteAttributeString("fill", "none");
3✔
254

255
                        this.WriteEndElement();
3✔
256
                }
3✔
257

258
                private void writeText(IText text, Transform transform)
259
                {
4✔
260
                        var insert = transform.ApplyTransform(text.InsertPoint);
4✔
261

262
                        this.WriteStartElement("g");
4✔
263
                        this.WriteAttributeString("transform", $"translate({insert.X.ToString(CultureInfo.InvariantCulture)},{insert.Y.ToString(CultureInfo.InvariantCulture)})");
4✔
264

265
                        this.WriteStartElement("text");
4✔
266
                        this.WriteAttributeString("transform", "scale(1,-1)");
4✔
267

268
                        this.WriteAttributeString("fill", this.colorSvg(text.GetActiveColor()));
4✔
269

270
                        //<text x="20" y="35" class="small">My</text>
271
                        this.WriteStartAttribute("style");
4✔
272
                        this.WriteValue("font:");
4✔
273
                        this.WriteValue(text.Height);
4✔
274
                        this.WriteValue("px");
4✔
275
                        this.WriteValue(" ");
4✔
276
                        this.WriteValue(Path.GetFileNameWithoutExtension(text.Style.Filename));
4✔
277
                        this.WriteEndAttribute();
4✔
278

279
                        switch (text)
4✔
280
                        {
281
                                case MText mtext:
282
                                        foreach (var item in mtext.GetTextLines())
22✔
283
                                        {
8✔
284
                                                this.WriteStartElement("tspan");
8✔
285
                                                this.WriteAttributeString("x", 0);
8✔
286
                                                this.WriteAttributeString("dy", "1em");
8✔
287
                                                this.WriteRaw(item);
8✔
288
                                                this.WriteEndElement();
8✔
289
                                        }
8✔
290
                                        break;
2✔
291
                                default:
292
                                        this.WriteRaw(text.Value);
2✔
293
                                        break;
2✔
294
                        }
295

296
                        this.WriteEndElement();
4✔
297
                        this.WriteEndElement();
4✔
298
                }
4✔
299
        }
300
}
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