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

DomCR / ACadSharp / 26295452051

22 May 2026 03:03PM UTC coverage: 76.952% (+0.08%) from 76.868%
26295452051

Pull #1085

github

web-flow
Merge ca9169167 into e21f7f3f6
Pull Request #1085: Add TableEntity DXF round-trip (cells, alignment, merges, flow direction)

8721 of 12274 branches covered (71.05%)

Branch coverage included in aggregate %.

221 of 244 new or added lines in 4 files covered. (90.57%)

1 existing line in 1 file now uncovered.

31121 of 39501 relevant lines covered (78.79%)

156739.76 hits per line

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

80.42
/src/ACadSharp/IO/DXF/DxfStreamReader/DxfSectionReaderBase.cs
1
using ACadSharp.Entities;
2
using ACadSharp.IO.Templates;
3
using ACadSharp.Objects;
4
using ACadSharp.Tables;
5
using ACadSharp.XData;
6
using CSMath;
7
using System;
8
using System.Collections.Generic;
9
using System.Diagnostics;
10
using System.Linq;
11
using static ACadSharp.IO.Templates.CadMLeaderAnnotContextTemplate;
12
using static ACadSharp.IO.Templates.CadTableEntityTemplate;
13

14
namespace ACadSharp.IO.DXF
15
{
16
        internal abstract class DxfSectionReaderBase
17
        {
18
                public delegate bool ReadEntityDelegate<T>(CadEntityTemplate template, DxfMap map, string subclass = null) where T : Entity;
19

20
                protected readonly IDxfStreamReader _reader;
21
                protected readonly DxfDocumentBuilder _builder;
22

23
                //Avoid to move the reader to the next line
24
                protected bool lockPointer = false;
1,014✔
25
                protected string currentSubclass = null;
1,014✔
26

27
                public DxfSectionReaderBase(IDxfStreamReader reader, DxfDocumentBuilder builder)
1,014✔
28
                {
1,014✔
29
                        this._reader = reader;
1,014✔
30
                        this._builder = builder;
1,014✔
31
                }
1,014✔
32

33
                public abstract void Read();
34

35
                protected void readCommonObjectData(out string name, out ulong handle, out ulong? ownerHandle, out ulong? xdictHandle, out HashSet<ulong> reactors)
36
                {
2,385✔
37
                        name = null;
2,385✔
38
                        handle = 0;
2,385✔
39
                        ownerHandle = null;
2,385✔
40
                        xdictHandle = null;
2,385✔
41
                        reactors = new HashSet<ulong>();
2,385✔
42

43
                        if (this._reader.DxfCode == DxfCode.Start
2,385!
44
                                        || this._reader.DxfCode == DxfCode.Subclass)
2,385✔
45
                                this._reader.ReadNext();
×
46

47
                        //Loop until the common data end
48
                        while (this._reader.DxfCode != DxfCode.Start
9,473✔
49
                                        && this._reader.DxfCode != DxfCode.Subclass)
9,473✔
50
                        {
7,088✔
51
                                switch (this._reader.Code)
7,088!
52
                                {
53
                                        //Table name
54
                                        case 2:
55
                                                name = this._reader.ValueAsString;
2,385✔
56
                                                break;
2,385✔
57
                                        //Handle
58
                                        case 5:
59
                                        case 105:
60
                                                handle = this._reader.ValueAsHandle;
2,097✔
61
                                                break;
2,097✔
62
                                        //Start of application - defined group
63
                                        case 102:
64
                                                this.readDefinedGroups(out xdictHandle, out reactors);
221✔
65
                                                break;
221✔
66
                                        //Soft - pointer ID / handle to owner BLOCK_RECORD object
67
                                        case 330:
68
                                                ownerHandle = this._reader.ValueAsHandle;
2,097✔
69
                                                break;
2,097✔
70
                                        case 71:
71
                                        //Number of entries for dimension style table
72
                                        case 340:
73
                                        //Dimension table has the handles of the styles at the begining
74
                                        default:
75
                                                this._builder.Notify($"Unhandled dxf code {this._reader.Code} at line {this._reader.Position}.");
288✔
76
                                                break;
288✔
77
                                }
78

79
                                this._reader.ReadNext();
7,088✔
80
                        }
7,088✔
81
                }
2,385✔
82

83
                [Obsolete("Only needed for SortEntitiesTable but it should be removed")]
84
                protected void readCommonObjectData(CadTemplate template)
85
                {
612✔
86
                        while (this._reader.DxfCode != DxfCode.Subclass)
2,448✔
87
                        {
1,836✔
88
                                switch (this._reader.Code)
1,836!
89
                                {
90
                                        //object name
91
                                        case 0:
92
                                                Debug.Assert(template.CadObject.ObjectName == this._reader.ValueAsString);
×
93
                                                break;
×
94
                                        //Handle
95
                                        case 5:
96
                                                template.CadObject.Handle = this._reader.ValueAsHandle;
612✔
97
                                                break;
612✔
98
                                        //Start of application - defined group
99
                                        case 102:
100
                                                this.readDefinedGroups(template);
612✔
101
                                                break;
612✔
102
                                        //Soft - pointer ID / handle to owner BLOCK_RECORD object
103
                                        case 330:
104
                                                template.OwnerHandle = this._reader.ValueAsHandle;
612✔
105
                                                break;
612✔
106
                                        default:
107
                                                this._builder.Notify($"Unhandled dxf code {this._reader.Code} at line {this._reader.Position}.", NotificationType.None);
×
108
                                                break;
×
109
                                }
110

111
                                this._reader.ReadNext();
1,836✔
112
                        }
1,836✔
113
                }
612✔
114

115
                protected void readCommonCodes(CadTemplate template, out bool isExtendedData, DxfMap map = null)
116
                {
837,558✔
117
                        isExtendedData = false;
837,558✔
118

119
                        switch (this._reader.Code)
837,558✔
120
                        {
121
                                //Handle
122
                                case 5:
123
                                        template.CadObject.Handle = this._reader.ValueAsHandle;
315,646✔
124
                                        break;
315,646✔
125
                                //Check with mapper
126
                                case 100:
127
                                        this.currentSubclass = this._reader.ValueAsString;
219,195✔
128
                                        if (map != null && !map.SubClasses.ContainsKey(this._reader.ValueAsString))
219,195!
129
                                        {
1,068✔
130
                                                this._builder.Notify($"[{template.CadObject.ObjectName}] Unidentified subclass {this._reader.ValueAsString}", NotificationType.Warning);
1,068✔
131
                                        }
1,068✔
132
                                        break;
219,195✔
133
                                //Start of application - defined group
134
                                case 102:
135
                                        this.readDefinedGroups(template);
71,780✔
136
                                        break;
71,780✔
137
                                //Soft - pointer ID / handle to owner BLOCK_RECORD object
138
                                case 330:
139
                                        template.OwnerHandle = this._reader.ValueAsHandle;
178,356✔
140
                                        break;
178,356✔
141
                                case 1001:
142
                                        isExtendedData = true;
24,551✔
143
                                        this.readExtendedData(template.EDataTemplateByAppName);
24,551✔
144
                                        break;
24,551✔
145
                                default:
146
                                        this._builder.Notify($"[{this.currentSubclass}] Unhandled dxf code {this._reader.Code} with value {this._reader.ValueAsString}", NotificationType.None);
28,030✔
147
                                        break;
28,030✔
148
                        }
149
                }
837,558✔
150

151
                protected CadEntityTemplate readEntity()
152
                {
154,947✔
153
                        this.currentSubclass = string.Empty;
154,947✔
154
                        switch (this._reader.ValueAsString)
154,947!
155
                        {
156
                                case DxfFileToken.EntityAttribute:
157
                                        return this.readEntityCodes<AttributeEntity>(new CadAttributeTemplate(new AttributeEntity()), this.readAttributeDefinition);
1,008✔
158
                                case DxfFileToken.EntityAttributeDefinition:
159
                                        return this.readEntityCodes<AttributeDefinition>(new CadAttributeTemplate(new AttributeDefinition()), this.readAttributeDefinition);
1,190✔
160
                                case DxfFileToken.EntityArc:
161
                                        return this.readEntityCodes<Arc>(new CadEntityTemplate<Arc>(), this.readArc);
728✔
162
                                case DxfFileToken.EntityBody:
163
                                        return this.readEntityCodes<CadBody>(new CadEntityTemplate<CadBody>(), this.readEntitySubclassMap);
×
164
                                case DxfFileToken.EntityCircle:
165
                                        return this.readEntityCodes<Circle>(new CadEntityTemplate<Circle>(), this.readCircle);
3,226✔
166
                                case DxfFileToken.EntityDimension:
167
                                        var dimTemplate = this.readEntityCodes<Dimension>(new CadDimensionTemplate(), this.readDimension);
2,772✔
168
                                        if (dimTemplate.CadObject is CadDimensionTemplate.DimensionPlaceholder)
2,772✔
169
                                        {
36✔
170
                                                this._builder.Notify($"[{DxfFileToken.EntityDimension}] No subtype found, object discarded.", NotificationType.Warning);
36✔
171
                                                return null;
36✔
172
                                        }
173
                                        return dimTemplate;
2,736✔
174
                                case DxfFileToken.Entity3DFace:
175
                                        return this.readEntityCodes<Face3D>(new CadEntityTemplate<Face3D>(), this.readEntitySubclassMap);
252✔
176
                                case DxfFileToken.EntityEllipse:
177
                                        return this.readEntityCodes<Ellipse>(new CadEntityTemplate<Ellipse>(), this.readEntitySubclassMap);
216✔
178
                                case DxfFileToken.EntityLeader:
179
                                        return this.readEntityCodes<Leader>(new CadLeaderTemplate(), this.readLeader);
216✔
180
                                case DxfFileToken.EntityLine:
181
                                        return this.readEntityCodes<Line>(new CadEntityTemplate<Line>(), this.readEntitySubclassMap);
65,420✔
182
                                case DxfFileToken.EntityLwPolyline:
183
                                        return this.readEntityCodes<LwPolyline>(new CadEntityTemplate<LwPolyline>(), this.readLwPolyline);
4,966✔
184
                                case DxfFileToken.EntityMesh:
185
                                        return this.readEntityCodes<Mesh>(new CadMeshTemplate(), this.readMesh);
432✔
186
                                case DxfFileToken.EntityHatch:
187
                                        return this.readEntityCodes<Hatch>(new CadHatchTemplate(), this.readHatch);
1,728✔
188
                                case DxfFileToken.EntityInsert:
189
                                        return this.readEntityCodes<Insert>(new CadInsertTemplate(), this.readInsert);
5,851✔
190
                                case DxfFileToken.EntityMText:
191
                                        return this.readEntityCodes<MText>(new CadTextEntityTemplate(new MText()), this.readTextEntity);
7,404✔
192
                                case DxfFileToken.EntityMLine:
193
                                        return this.readEntityCodes<MLine>(new CadMLineTemplate(), this.readMLine);
648✔
194
                                case DxfFileToken.EntityMultiLeader:
195
                                        return this.readEntityCodes<MultiLeader>(new CadMLeaderTemplate(), this.readMLeader);
3,240✔
196
                                case DxfFileToken.EntityPdfUnderlay:
197
                                        return this.readEntityCodes<PdfUnderlay>(new CadUnderlayTemplate<PdfUnderlayDefinition>(new PdfUnderlay()), this.readUnderlayEntity<PdfUnderlayDefinition>);
216✔
198
                                case DxfFileToken.EntityPoint:
199
                                        return this.readEntityCodes<Point>(new CadEntityTemplate<Point>(), this.readEntitySubclassMap);
9,604✔
200
                                case DxfFileToken.EntityPolyline:
201
                                        return this.readPolyline();
11,092✔
202
                                case DxfFileToken.EntityOle2Frame:
203
                                        return this.readEntityCodes<Ole2Frame>(new CadOle2FrameTemplate(), this.readOle2Frame);
×
204
                                case DxfFileToken.EntityRay:
205
                                        return this.readEntityCodes<Ray>(new CadEntityTemplate<Ray>(), this.readEntitySubclassMap);
216✔
206
                                case DxfFileToken.EndSequence:
207
                                        return this.readEntityCodes<Seqend>(new CadEntityTemplate<Seqend>(), this.readEntitySubclassMap);
504✔
208
                                case DxfFileToken.EntityTrace:
209
                                case DxfFileToken.EntitySolid:
210
                                        return this.readEntityCodes<Solid>(new CadEntityTemplate<Solid>(), this.readModelerGeometry);
14,600✔
211
                                case DxfFileToken.EntityTable:
212
                                        return this.readEntityCodes<TableEntity>(new CadTableEntityTemplate(), this.readTableEntity);
432✔
213
                                case DxfFileToken.EntityText:
214
                                        return this.readEntityCodes<TextEntity>(new CadTextEntityTemplate(new TextEntity()), this.readTextEntity);
15,026✔
215
                                case DxfFileToken.EntityTolerance:
216
                                        return this.readEntityCodes<Tolerance>(new CadToleranceTemplate(new Tolerance()), this.readTolerance);
648✔
217
                                case DxfFileToken.EntityVertex:
218
                                        return this.readEntityCodes<Entity>(new CadVertexTemplate(), this.readVertex);
×
219
                                case DxfFileToken.EntityViewport:
220
                                        return this.readEntityCodes<Viewport>(new CadViewportTemplate(), this.readViewport);
1,332✔
221
                                case DxfFileToken.EntityShape:
222
                                        return this.readEntityCodes<Shape>(new CadShapeTemplate(new Shape()), this.readShape);
252✔
223
                                case DxfFileToken.EntitySpline:
224
                                        return this.readEntityCodes<Spline>(new CadSplineTemplate(), this.readSpline);
432✔
225
                                case DxfFileToken.Entity3DSolid:
226
                                        return this.readEntityCodes<Solid3D>(new CadSolid3DTemplate(), this.readSolid3d);
432✔
227
                                case DxfFileToken.EntityRegion:
228
                                        return this.readEntityCodes<Region>(new CadEntityTemplate<Region>(), this.readModelerGeometry);
216✔
229
                                case DxfFileToken.EntityImage:
230
                                        return this.readEntityCodes<RasterImage>(new CadWipeoutBaseTemplate(new RasterImage()), this.readWipeoutBase);
216✔
231
                                case DxfFileToken.EntityWipeout:
232
                                        return this.readEntityCodes<Wipeout>(new CadWipeoutBaseTemplate(new Wipeout()), this.readWipeoutBase);
216✔
233
                                case DxfFileToken.EntityXline:
234
                                        return this.readEntityCodes<XLine>(new CadEntityTemplate<XLine>(), this.readEntitySubclassMap);
216✔
235
                                default:
236
                                        DxfMap map = DxfMap.Create<Entity>();
×
237
                                        CadUnknownEntityTemplate unknownEntityTemplate = null;
×
238
                                        if (this._builder.DocumentToBuild.Classes.TryGetByName(this._reader.ValueAsString, out Classes.DxfClass dxfClass))
×
239
                                        {
×
240
                                                this._builder.Notify($"Entity not supported read as an UnknownEntity: {this._reader.ValueAsString}", NotificationType.NotImplemented);
×
241
                                                unknownEntityTemplate = new CadUnknownEntityTemplate(new UnknownEntity(dxfClass));
×
242
                                        }
×
243
                                        else
244
                                        {
×
245
                                                this._builder.Notify($"Entity not supported: {this._reader.ValueAsString}", NotificationType.NotImplemented);
×
246
                                        }
×
247

248
                                        this._reader.ReadNext();
×
249

250
                                        do
251
                                        {
×
252
                                                if (unknownEntityTemplate != null && this._builder.KeepUnknownEntities)
×
253
                                                {
×
254
                                                        this.readCommonEntityCodes(unknownEntityTemplate, out bool isExtendedData, map);
×
255
                                                        if (isExtendedData)
×
256
                                                                continue;
×
257
                                                }
×
258

259
                                                this._reader.ReadNext();
×
260
                                        }
×
261
                                        while (this._reader.DxfCode != DxfCode.Start);
×
262

263
                                        return unknownEntityTemplate;
×
264
                        }
265
                }
154,947✔
266

267
                protected CadEntityTemplate readEntityCodes<T>(CadEntityTemplate template, ReadEntityDelegate<T> readEntity)
268
                        where T : Entity
269
                {
206,741✔
270
                        this._reader.ReadNext();
206,741✔
271

272
                        DxfMap map = DxfMap.Create<T>();
206,741✔
273

274
                        while (this._reader.DxfCode != DxfCode.Start)
2,799,473✔
275
                        {
2,592,732✔
276
                                if (!readEntity(template, map))
2,592,732✔
277
                                {
907,630✔
278
                                        this.readCommonEntityCodes(template, out bool isExtendedData, map);
907,630✔
279
                                        if (isExtendedData)
907,630✔
280
                                                continue;
14,476✔
281
                                }
893,154✔
282

283
                                if (this.lockPointer)
2,578,256✔
284
                                {
3,168✔
285
                                        this.lockPointer = false;
3,168✔
286
                                        continue;
3,168✔
287
                                }
288

289
                                if (this._reader.DxfCode != DxfCode.Start)
2,575,088✔
290
                                        this._reader.ReadNext();
2,574,586✔
291
                        }
2,575,088✔
292

293
                        return template;
206,741✔
294
                }
206,741✔
295

296
                protected void readCommonEntityCodes(CadEntityTemplate template, out bool isExtendedData, DxfMap map = null)
297
                {
979,357✔
298
                        isExtendedData = false;
979,357✔
299
                        switch (this._reader.Code)
979,357✔
300
                        {
301
                                case 6:
302
                                        template.LineTypeName = this._reader.ValueAsString;
27,278✔
303
                                        break;
27,278✔
304
                                case 8:
305
                                        template.LayerName = this._reader.ValueAsString;
224,265✔
306
                                        break;
224,265✔
307
                                //Absent or zero indicates entity is in model space. 1 indicates entity is in paper space (optional).
308
                                case 67:
309
                                        break;
1,336✔
310
                                //Number of bytes Proxy entity graphics data
311
                                case 92:
312
                                case 160:
313
                                //Proxy entity graphics data
314
                                case 310:
315
                                        break;
81,072✔
316
                                case 347:
317
                                        template.MaterialHandle = this._reader.ValueAsHandle;
720✔
318
                                        break;
720✔
319
                                case 430:
320
                                        template.BookColorName = this._reader.ValueAsString;
180✔
321
                                        break;
180✔
322
                                default:
323
                                        if (!this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Entity]))
644,506✔
324
                                        {
501,916✔
325
                                                this.readCommonCodes(template, out isExtendedData, map);
501,916✔
326
                                        }
501,916✔
327
                                        break;
644,506✔
328
                        }
329
                }
979,357✔
330

331
                [Obsolete("use lockpointer instead")]
332
                protected bool checkObjectEnd(CadTemplate template, DxfMap map, Func<CadTemplate, DxfMap, bool> func)
333
                {
3,080✔
334
                        if (this._reader.DxfCode == DxfCode.Start)
3,080!
335
                        {
×
336
                                return true;
×
337
                        }
338
                        else
339
                        {
3,080✔
340
                                return func.Invoke(template, map);
3,080✔
341
                        }
342
                }
3,080✔
343

344
                protected bool checkEntityEnd(CadEntityTemplate template, DxfMap map, string subclass, Func<CadEntityTemplate, DxfMap, string, bool> func)
345
                {
432✔
346
                        if (this._reader.DxfCode == DxfCode.Start)
432!
347
                        {
432✔
348
                                return true;
432✔
349
                        }
350
                        else
351
                        {
×
352
                                return func.Invoke(template, map, subclass);
×
353
                        }
354
                }
432✔
355

356
                private bool readCircle(CadEntityTemplate template, DxfMap map, string subclass = null)
357
                {
38,105✔
358
                        Circle circle = template.CadObject as Circle;
38,105✔
359

360
                        switch (this._reader.Code)
38,105✔
361
                        {
362
                                case 40:
363
                                        double radius = this._reader.ValueAsDouble;
3,954✔
364
                                        if (radius <= 0)
3,954!
365
                                        {
×
366
                                                circle.Radius = MathHelper.Epsilon;
×
367
                                        }
×
368
                                        else
369
                                        {
3,954✔
370
                                                circle.Radius = radius;
3,954✔
371
                                        }
3,954✔
372
                                        return true;
3,954✔
373
                                default:
374
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Circle]);
34,151✔
375
                        }
376
                }
38,105✔
377

378
                private bool readArc(CadEntityTemplate template, DxfMap map, string subclass = null)
379
                {
9,544✔
380
                        switch (this._reader.Code)
9,544✔
381
                        {
382
                                default:
383
                                        if (!this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Arc]))
9,544✔
384
                                        {
8,088✔
385
                                                return this.readCircle(template, map, DxfSubclassMarker.Circle);
8,088✔
386
                                        }
387
                                        return true;
1,456✔
388
                        }
389
                }
9,544✔
390

391
                private bool readAttributeDefinition(CadEntityTemplate template, DxfMap map, string subclass = null)
392
                {
35,474✔
393
                        DxfClassMap emap = map.SubClasses[template.CadObject.SubclassMarker];
35,474✔
394
                        CadAttributeTemplate tmp = template as CadAttributeTemplate;
35,474✔
395

396
                        switch (this._reader.Code)
35,474!
397
                        {
398
                                case 44:
399
                                case 46:
400
                                        return true;
×
401
                                case 101:
402
                                        var att = tmp.CadObject as AttributeBase;
70✔
403
                                        att.MText = new MText();
70✔
404
                                        CadTextEntityTemplate mtextTemplate = new CadTextEntityTemplate(att.MText);
70✔
405
                                        tmp.MTextTemplate = mtextTemplate;
70✔
406
                                        this.readEntityCodes<MText>(mtextTemplate, this.readTextEntity);
70✔
407
                                        return true;
70✔
408
                                default:
409
                                        if (!this.tryAssignCurrentValue(template.CadObject, emap))
35,404✔
410
                                        {
26,786✔
411
                                                return this.readTextEntity(template, map, DxfSubclassMarker.Text);
26,786✔
412
                                        }
413
                                        return true;
8,618✔
414
                        }
415
                }
35,474✔
416

417
                private bool readTableEntity(CadEntityTemplate template, DxfMap map, string subclass = null)
418
                {
142,236✔
419
                        string mapName = string.IsNullOrEmpty(subclass) ? template.CadObject.SubclassMarker : subclass;
142,236!
420
                        CadTableEntityTemplate tmp = template as CadTableEntityTemplate;
142,236✔
421
                        TableEntity table = tmp.CadObject as TableEntity;
142,236✔
422

423
                        switch (this._reader.Code)
142,236!
424
                        {
425
                                case 1:
426
                                        TableEntity.CellContent content;
427
                                        if (tmp.CurrentCell.Content == null)
2,808!
428
                                        {
2,808✔
429
                                                content = new TableEntity.CellContent();
2,808✔
430
                                                content.CadValue.ValueType = CadValueType.String;
2,808✔
431
                                                tmp.CurrentCell.Contents.Add(content);
2,808✔
432
                                        }
2,808✔
433
                                        else
434
                                        {
×
435
                                                content = tmp.CurrentCell.Content;
×
436
                                        }
×
437

438
                                        if (content.CadValue.Value == null)
2,808!
439
                                        {
2,808✔
440
                                                content.CadValue.SetValue(this._reader.ValueAsString, CadValueType.String);
2,808✔
441
                                        }
2,808✔
442
                                        else
443
                                        {
×
444
                                                string str = content.CadValue.Value as string;
×
445
                                                str += this._reader.ValueAsString;
×
446
                                                content.CadValue.SetValue(str, CadValueType.String);
×
447
                                        }
×
448
                                        return true;
2,808✔
449
                                case 2:
450
                                        if (this.currentSubclass.Equals(DxfSubclassMarker.TableEntity, StringComparison.OrdinalIgnoreCase))
432!
451
                                        {
×
452
                                                content = tmp.CurrentCell.Content;
×
453
                                                if (content.CadValue.Value == null)
×
454
                                                {
×
455
                                                        content.CadValue.SetValue(this._reader.ValueAsString, CadValueType.String);
×
456
                                                }
×
457
                                                else
458
                                                {
×
459
                                                        string str = content.CadValue.Value as string;
×
460
                                                        str += this._reader.ValueAsString;
×
461
                                                        content.CadValue.SetValue(str, CadValueType.String);
×
462
                                                }
×
463
                                        }
×
464
                                        else
465
                                        {
432✔
466
                                                tmp.BlockName = this._reader.ValueAsString;
432✔
467
                                        }
432✔
468
                                        return true;
432✔
469
                                //Border overrides:
470
                                case 177:
471
                                        //Cell override flag value (before AutoCAD 2007)
472
                                        return true;
2,952✔
473
                                case 279:
474
                                        //Lineweight for the top border of the cell; override applied at the cell level
475
                                        tmp.CurrentCell.StyleOverride.TopBorder.LineWeight = (LineWeightType)this._reader.ValueAsShort;
1,512✔
476
                                        return true;
1,512✔
477
                                case 275:
478
                                        //Lineweight for the right border of the cell; override applied at the cell level
479
                                        tmp.CurrentCell.StyleOverride.RightBorder.LineWeight = (LineWeightType)this._reader.ValueAsShort;
432✔
480
                                        return true;
432✔
481
                                case 276:
482
                                        //Lineweight for the bottom border of the cell; override applied at the cell level
483
                                        tmp.CurrentCell.StyleOverride.BottomBorder.LineWeight = (LineWeightType)this._reader.ValueAsShort;
×
484
                                        return true;
×
485
                                case 278:
486
                                        //Lineweight for the left border of the cell; override applied at the cell level
487
                                        tmp.CurrentCell.StyleOverride.LeftBorder.LineWeight = (LineWeightType)this._reader.ValueAsShort;
1,296✔
488
                                        return true;
1,296✔
489
                                case 69:
490
                                        //True color value for the top border of the cell; override applied at the cell level
491
                                        tmp.CurrentCell.StyleOverride.TopBorder.Color = new Color(this._reader.ValueAsShort);
1,512✔
492
                                        return true;
1,512✔
493
                                case 65:
494
                                        //True color value for the right border of the cell; override applied at the cell level
495
                                        tmp.CurrentCell.StyleOverride.RightBorder.Color = new Color(this._reader.ValueAsShort);
432✔
496
                                        return true;
432✔
497
                                case 66:
498
                                        //True color value for the bottom border of the cell; override applied at the cell level
499
                                        tmp.CurrentCell.StyleOverride.BottomBorder.Color = new Color(this._reader.ValueAsShort);
×
500
                                        return true;
×
501
                                case 68:
502
                                        //True color value for the left border of the cell; override applied at the cell level
503
                                        tmp.CurrentCell.StyleOverride.LeftBorder.Color = new Color(this._reader.ValueAsShort);
1,296✔
504
                                        return true;
1,296✔
505
                                case 40:
506
                                        tmp.HorizontalMargin = this._reader.ValueAsDouble;
216✔
507
                                        return true;
216✔
508
                                case 63:
509
                                        tmp.CurrentCell.StyleOverride.BackgroundColor = new Color(this._reader.ValueAsShort);
216✔
510
                                        return true;
216✔
511
                                case 64:
512
                                        tmp.CurrentCell.StyleOverride.ContentColor = new Color(this._reader.ValueAsShort);
216✔
513
                                        return true;
216✔
514
                                case 140:
515
                                        if (tmp.CurrentCellTemplate != null)
5,184✔
516
                                        {
4,536✔
517
                                                tmp.CurrentCellTemplate.FormatTextHeight = this._reader.ValueAsDouble;
4,536✔
518
                                        }
4,536✔
519
                                        return true;
5,184✔
520
                                case 283:
521
                                        tmp.CurrentCell.StyleOverride.IsFillColorOn = this._reader.ValueAsBool;
216✔
522
                                        return true;
216✔
523
                                case 342:
524
                                        tmp.StyleHandle = this._reader.ValueAsHandle;
432✔
525
                                        return true;
432✔
526
                                case 343:
527
                                        tmp.BlockOwnerHandle = this._reader.ValueAsHandle;
432✔
528
                                        return true;
432✔
529
                                case 141:
530
                                        var row = new TableEntity.Row();
2,376✔
531
                                        row.Height = this._reader.ValueAsDouble;
2,376✔
532
                                        table.Rows.Add(row);
2,376✔
533
                                        return true;
2,376✔
534
                                case 142:
535
                                        var col = new TableEntity.Column();
1,728✔
536
                                        col.Width = this._reader.ValueAsDouble;
1,728✔
537
                                        table.Columns.Add(col);
1,728✔
538
                                        return true;
1,728✔
539
                                case 144:
540
                                        tmp.CurrentCellTemplate.FormatTextHeight = this._reader.ValueAsDouble;
432✔
541
                                        return true;
432✔
542
                                case 145:
543
                                        tmp.CurrentCell.Rotation = this._reader.ValueAsDouble;
8,856✔
544
                                        return true;
8,856✔
545
                                case 170:
546
                                        // Per-cell alignment (set when the cell flag at code 91 has the
547
                                        // CellAlignment override bit). Capture it on the cell-level
548
                                        // StyleOverride so callers reading the table back via DXF can
549
                                        // resolve alignment exactly like they do through DWG.
550
                                        if (tmp.CurrentCell != null)
648✔
551
                                        {
648✔
552
                                                tmp.CurrentCell.StyleOverride.HasData = true;
648✔
553
                                                tmp.CurrentCell.StyleOverride.CellAlignment =
648✔
554
                                                        (ACadSharp.Objects.TableStyle.CellAlignmentType)this._reader.ValueAsShort;
648✔
555
                                                tmp.CurrentCell.StyleOverride.PropertyOverrideFlags |=
648✔
556
                                                        ACadSharp.Objects.TableStyle.CellStylePropertyFlags.Alignment;
648✔
557
                                        }
648✔
558
                                        return true;
648✔
559
                                case 171:
560
                                        tmp.CreateCell((TableEntity.CellType)this._reader.ValueAsInt);
8,856✔
561
                                        return true;
8,856✔
562
                                case 172:
563
                                        tmp.CurrentCell.EdgeFlags = this._reader.ValueAsShort;
8,856✔
564
                                        return true;
8,856✔
565
                                case 173:
566
                                        tmp.CurrentCell.MergedValue = this._reader.ValueAsShort;
8,856✔
567
                                        return true;
8,856✔
568
                                case 174:
569
                                        tmp.CurrentCell.AutoFit = this._reader.ValueAsBool;
8,856✔
570
                                        return true;
8,856✔
571
                                case 175:
572
                                        tmp.CurrentCell.BorderWidth = this._reader.ValueAsInt;
8,856✔
573
                                        return true;
8,856✔
574
                                case 176:
575
                                        tmp.CurrentCell.BorderHeight = this._reader.ValueAsInt;
8,856✔
576
                                        return true;
8,856✔
577
                                case 178:
578
                                        tmp.CurrentCell.VirtualEdgeFlag = this._reader.ValueAsShort;
8,856✔
579
                                        return true;
8,856✔
580
                                case 179:
581
                                        //Unknown value
582
                                        return true;
432✔
583
                                case 70:
584
                                        // Table-level flow direction (0 = top to bottom, 1 = bottom to top).
585
                                        // Stored on the table-level CellStyleOverride so callers can read it
586
                                        // through the same API used for round-tripping the rest of the
587
                                        // override flags.
NEW
588
                                        if (this._reader.ValueAsShort == 1)
×
NEW
589
                                        {
×
NEW
590
                                                table.CellStyleOverride.HasData = true;
×
NEW
591
                                                table.CellStyleOverride.TableCellStylePropertyFlags |=
×
NEW
592
                                                        ACadSharp.Objects.TableStyle.CellStylePropertyFlags.FlowDirectionBottomToTop;
×
NEW
593
                                        }
×
NEW
594
                                        return true;
×
595
                                case 301:
596
                                        content = new TableEntity.CellContent();
5,904✔
597
                                        var contentTemplate = new CadTableCellContentTemplate(content);
5,904✔
598
                                        tmp.CurrentCell.Contents.Add(content);
5,904✔
599
                                        var valTemplate = readCadValue(content.CadValue);
5,904✔
600
                                        contentTemplate.CadValueTemplate = valTemplate;
5,904✔
601
                                        return true;
5,904✔
602
                                case 340:
603
                                        tmp.CurrentCellTemplate.ValueHandle = this._reader.ValueAsHandle;
432✔
604
                                        return true;
432✔
605
                                default:
606
                                        if (!this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Insert]))
39,852✔
607
                                        {
38,340✔
608
                                                return this.readEntitySubclassMap(template, map, DxfSubclassMarker.TableEntity);
38,340✔
609
                                        }
610
                                        return true;
1,512✔
611
                        }
612
                }
142,236✔
613

614
                protected CadValueTemplate readCadValue(CadValue value)
615
                {
9,848✔
616
                        this._reader.ReadNext();
9,848✔
617

618
                        CadValueTemplate template = new(value);
9,848✔
619
                        var map = DxfClassMap.Create(value.GetType(), "CadValue");
9,848✔
620

621
                        while (this._reader.Code != 304)
65,384✔
622
                        {
55,536✔
623
                                switch (this._reader.Code)
55,536!
624
                                {
625
                                        case 1:
626
                                                value.SetValue(this._reader.ValueAsString);
3,496✔
627
                                                break;
3,496✔
628
                                        case 2:
629
                                                value.SetValue((value.Value as string) + this._reader.ValueAsString);
×
630
                                                break;
×
631
                                        case 11:
632
                                                XYZ xyz = new XYZ();
280✔
633
                                                xyz.X = this._reader.ValueAsDouble;
280✔
634
                                                value.SetValue(xyz);
280✔
635
                                                break;
280✔
636
                                        case 21:
637
                                                {
280✔
638
                                                        IVector v = value.Value as IVector;
280✔
639
                                                        v[1] = this._reader.ValueAsDouble;
280✔
640
                                                        value.SetValue(v);
280✔
641
                                                }
280✔
642
                                                break;
280✔
643
                                        case 31:
644
                                                {
280✔
645
                                                        IVector v = value.Value as IVector;
280✔
646
                                                        v = v.Convert<XYZ>();
280✔
647
                                                        v[2] = this._reader.ValueAsDouble;
280✔
648
                                                        value.SetValue(v);
280✔
649
                                                }
280✔
650
                                                break;
280✔
651
                                        case 90:
652
                                                value.ValueType = (CadValueType)this._reader.ValueAsInt;
9,848✔
653
                                                break;
9,848✔
654
                                        case 91:
655
                                                value.SetValue(this._reader.ValueAsInt);
280✔
656
                                                break;
280✔
657
                                        case 93:
658
                                                value.Flags = this._reader.ValueAsInt;
9,848✔
659
                                                break;
9,848✔
660
                                        case 140:
661
                                                value.SetValue(this._reader.ValueAsDouble);
1,120✔
662
                                                break;
1,120✔
663
                                        case 330:
664
                                                template.ValueHandle = this._reader.ValueAsHandle;
×
665
                                                break;
×
666
                                        default:
667
                                                if (!this.tryAssignCurrentValue(value, map))
30,104✔
668
                                                {
560✔
669
                                                        this._builder.Notify($"Unhandled dxf code {this._reader.Code} value {this._reader.ValueAsString} at {nameof(readCadValue)} method.", NotificationType.None);
560✔
670
                                                }
560✔
671
                                                break;
30,104✔
672
                                }
673

674
                                this._reader.ReadNext();
55,536✔
675
                        }
55,536✔
676

677
                        return template;
9,848✔
678
                }
9,848✔
679

680
                private bool readTextEntity(CadEntityTemplate template, DxfMap map, string subclass = null)
681
                {
306,634✔
682
                        string mapName = string.IsNullOrEmpty(subclass) ? template.CadObject.SubclassMarker : subclass;
306,634✔
683
                        CadTextEntityTemplate tmp = template as CadTextEntityTemplate;
306,634✔
684

685
                        switch (this._reader.Code)
306,634✔
686
                        {
687
                                case 1 or 3 when tmp.CadObject is MText mtext:
27,506✔
688
                                        mtext.Value += this._reader.ValueAsString;
10,282✔
689
                                        return true;
10,282✔
690
                                case 50 when tmp.CadObject is MText mtext://Read only for MText
510!
691
                                        double angle = this._reader.ValueAsAngle;
×
692
                                        mtext.AlignmentPoint = new XYZ(System.Math.Cos(angle), System.Math.Sin(angle), 0.0);
×
693
                                        return true;
×
694
                                case 7:
695
                                        tmp.StyleName = this._reader.ValueAsString;
3,024✔
696
                                        return true;
3,024✔
697
                                case 101 when tmp.CadObject is MText mtext:
144✔
698
                                        this.readColumnData(mtext);
144✔
699
                                        this.lockPointer = true;
144✔
700
                                        return true;
144✔
701
                                default:
702
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[mapName]);
293,184✔
703
                        }
704
                }
306,634✔
705

706
                private void readColumnData(MText mtext)
707
                {
144✔
708
                        this._reader.ReadNext();
144✔
709
                        while (this._reader.DxfCode != DxfCode.Start)
2,736✔
710
                        {
2,592✔
711
                                switch (this._reader.Code)
2,592!
712
                                {
713
                                        //Element count?
714
                                        case 70:
715
                                                break;
144✔
716
                                        case 71:
717
                                                mtext.ColumnData.ColumnType = (ColumnType)this._reader.ValueAsShort;
144✔
718
                                                break;
144✔
719
                                        case 72:
720
                                                mtext.ColumnData.ColumnCount = this._reader.ValueAsInt;
144✔
721
                                                break;
144✔
722
                                        //X - axis dir 3BD 10
723
                                        case 10:
724
                                        case 20:
725
                                        case 30:
726
                                        //Insertion point 3BD 11
727
                                        case 11:
728
                                        case 21:
729
                                        case 31:
730
                                        //Rect width BD 40
731
                                        case 40:
732
                                        //Rect height BD 41
733
                                        case 41:
734
                                        //Extents width BD 42
735
                                        case 42:
736
                                        //Extents height BD 43
737
                                        case 43:
738
                                                break;
1,440✔
739
                                        case 44:
740
                                                mtext.ColumnData.Width = this._reader.ValueAsDouble;
144✔
741
                                                break;
144✔
742
                                        case 45:
743
                                                mtext.ColumnData.Gutter = this._reader.ValueAsDouble;
144✔
744
                                                break;
144✔
745
                                        case 46:
746
                                                mtext.ColumnData.Heights.Add(this._reader.ValueAsDouble);
144✔
747
                                                break;
144✔
748
                                        case 73:
749
                                                mtext.ColumnData.AutoHeight = this._reader.ValueAsBool;
144✔
750
                                                break;
144✔
751
                                        case 74:
752
                                                mtext.ColumnData.FlowReversed = this._reader.ValueAsBool;
144✔
753
                                                break;
144✔
754
                                        default:
755
                                                this._builder.Notify($"[MText.ColumnData] unkown dxf code {this._reader.Code}.", NotificationType.None);
×
756
                                                break;
×
757
                                }
758

759
                                this._reader.ReadNext();
2,592✔
760
                        }
2,592✔
761
                }
144✔
762

763
                private bool readTolerance(CadEntityTemplate template, DxfMap map, string subclass = null)
764
                {
6,480✔
765
                        CadToleranceTemplate tmp = template as CadToleranceTemplate;
6,480✔
766

767
                        switch (this._reader.Code)
6,480✔
768
                        {
769
                                case 3:
770
                                        tmp.DimensionStyleName = this._reader.ValueAsString;
648✔
771
                                        return true;
648✔
772
                                default:
773
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[template.CadObject.SubclassMarker]);
5,832✔
774
                        }
775
                }
6,480✔
776

777
                private bool readDimension(CadEntityTemplate template, DxfMap map, string subclass = null)
778
                {
72,504✔
779
                        CadDimensionTemplate tmp = template as CadDimensionTemplate;
72,504✔
780

781
                        switch (this._reader.Code)
72,504✔
782
                        {
783
                                case 2:
784
                                        tmp.BlockName = this._reader.ValueAsString;
2,772✔
785
                                        return true;
2,772✔
786
                                case 3:
787
                                        tmp.StyleName = this._reader.ValueAsString;
2,376✔
788
                                        return true;
2,376✔
789
                                case 50:
790
                                        var dim = new DimensionLinear();
252✔
791
                                        tmp.SetDimensionObject(dim);
252✔
792
                                        dim.Rotation = this._reader.ValueAsAngle;
252✔
793
                                        if (!map.SubClasses.ContainsKey(DxfSubclassMarker.LinearDimension))
252✔
794
                                        {
216✔
795
                                                map.SubClasses.Add(DxfSubclassMarker.LinearDimension, DxfClassMap.Create<DimensionLinear>());
216✔
796
                                        }
216✔
797
                                        return true;
252✔
798
                                case 70:
799
                                        //Flags do not have set
800
                                        tmp.SetDimensionFlags((DimensionType)this._reader.ValueAsShort);
2,772✔
801

802
                                        if (tmp.CadObject is CadDimensionTemplate.DimensionPlaceholder placeholder && this._builder.Version < ACadVersion.AC1012)
2,772!
803
                                        {
396✔
804
                                                switch (placeholder.Flags)
396!
805
                                                {
806
                                                        case DimensionType.Linear:
807
                                                                tmp.SetDimensionObject(new DimensionLinear());
108✔
808
                                                                map.SubClasses.Add(DxfSubclassMarker.AlignedDimension, DxfClassMap.Create<DimensionAligned>());
108✔
809
                                                                map.SubClasses.Add(DxfSubclassMarker.LinearDimension, DxfClassMap.Create<DimensionLinear>());
108✔
810
                                                                break;
108✔
811
                                                        case DimensionType.Aligned:
812
                                                                tmp.SetDimensionObject(new DimensionAligned());
72✔
813
                                                                map.SubClasses.Add(DxfSubclassMarker.AlignedDimension, DxfClassMap.Create<DimensionAligned>());
72✔
814
                                                                break;
72✔
815
                                                        case DimensionType.Angular:
816
                                                                tmp.SetDimensionObject(new DimensionAngular2Line());
36✔
817
                                                                map.SubClasses.Add(DxfSubclassMarker.Angular2LineDimension, DxfClassMap.Create<DimensionAngular2Line>());
36✔
818
                                                                break;
36✔
819
                                                        case DimensionType.Diameter:
820
                                                                tmp.SetDimensionObject(new DimensionDiameter());
×
821
                                                                map.SubClasses.Add(DxfSubclassMarker.DiametricDimension, DxfClassMap.Create<DimensionDiameter>());
×
822
                                                                break;
×
823
                                                        case DimensionType.Radius:
824
                                                                tmp.SetDimensionObject(new DimensionRadius());
36✔
825
                                                                map.SubClasses.Add(DxfSubclassMarker.RadialDimension, DxfClassMap.Create<DimensionRadius>());
36✔
826
                                                                break;
36✔
827
                                                        case DimensionType.Angular3Point:
828
                                                                tmp.SetDimensionObject(new DimensionAngular3Pt());
36✔
829
                                                                map.SubClasses.Add(DxfSubclassMarker.Angular3PointDimension, DxfClassMap.Create<DimensionAngular3Pt>());
36✔
830
                                                                break;
36✔
831
                                                        case DimensionType.Ordinate:
832
                                                        case DimensionType.OrdinateTypeX:
833
                                                        case DimensionType.Ordinate | DimensionType.OrdinateTypeX:
834
                                                                tmp.SetDimensionObject(new DimensionOrdinate());
72✔
835
                                                                map.SubClasses.Add(DxfSubclassMarker.OrdinateDimension, DxfClassMap.Create<DimensionOrdinate>());
72✔
836
                                                                break;
72✔
837
                                                        case DimensionType.BlockReference:
838
                                                        case DimensionType.TextUserDefinedLocation:
839
                                                        default:
840
                                                                break;
36✔
841
                                                }
842
                                        }
396✔
843
                                        return true;
2,772✔
844
                                //Measurement - read only
845
                                case 42:
846
                                        return true;
2,376✔
847
                                //Undocumented codes
848
                                case 73:
849
                                case 74:
850
                                case 75:
851
                                case 90:
852
                                case 361:
853
                                        return true;
4,752✔
854
                                case 100:
855
                                        switch (this._reader.ValueAsString)
7,776✔
856
                                        {
857
                                                case DxfSubclassMarker.Dimension:
858
                                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Dimension]);
2,376✔
859
                                                case DxfSubclassMarker.AlignedDimension:
860
                                                        tmp.SetDimensionObject(new DimensionAligned());
1,080✔
861
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionAligned>());
1,080✔
862
                                                        return true;
1,080✔
863
                                                case DxfSubclassMarker.DiametricDimension:
864
                                                        tmp.SetDimensionObject(new DimensionDiameter());
216✔
865
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionDiameter>());
216✔
866
                                                        return true;
216✔
867
                                                case DxfSubclassMarker.Angular2LineDimension:
868
                                                        tmp.SetDimensionObject(new DimensionAngular2Line());
216✔
869
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionAngular2Line>());
216✔
870
                                                        return true;
216✔
871
                                                case DxfSubclassMarker.Angular3PointDimension:
872
                                                        tmp.SetDimensionObject(new DimensionAngular3Pt());
216✔
873
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionAngular3Pt>());
216✔
874
                                                        return true;
216✔
875
                                                case DxfSubclassMarker.RadialDimension:
876
                                                        tmp.SetDimensionObject(new DimensionRadius());
216✔
877
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionRadius>());
216✔
878
                                                        return true;
216✔
879
                                                case DxfSubclassMarker.OrdinateDimension:
880
                                                        tmp.SetDimensionObject(new DimensionOrdinate());
432✔
881
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionOrdinate>());
432✔
882
                                                        return true;
432✔
883
                                                case DxfSubclassMarker.LinearDimension:
884
                                                        return true;
648✔
885
                                                default:
886
                                                        return false;
2,376✔
887
                                        }
888
                                default:
889
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
49,428✔
890
                        }
891
                }
72,504✔
892

893
                protected bool readHatch(CadEntityTemplate template, DxfMap map, string subclass = null)
894
                {
46,224✔
895
                        CadHatchTemplate tmp = template as CadHatchTemplate;
46,224✔
896
                        Hatch hatch = tmp.CadObject;
46,224✔
897

898
                        XY seedPoint = new XY();
46,224✔
899

900
                        switch (this._reader.Code)
46,224!
901
                        {
902
                                case 2:
903
                                        hatch.Pattern.Name = this._reader.ValueAsString;
1,728✔
904
                                        return true;
1,728✔
905
                                case 10:
906
                                        seedPoint.X = this._reader.ValueAsDouble;
3,456✔
907
                                        hatch.SeedPoints.Add(seedPoint);
3,456✔
908
                                        return true;
3,456✔
909
                                case 20:
910
                                        seedPoint = hatch.SeedPoints.LastOrDefault();
3,456✔
911
                                        seedPoint.Y = this._reader.ValueAsDouble;
3,456✔
912
                                        hatch.SeedPoints[hatch.SeedPoints.Count - 1] = seedPoint;
3,456✔
913
                                        return true;
3,456✔
914
                                case 30:
915
                                        hatch.Elevation = this._reader.ValueAsDouble;
1,728✔
916
                                        return true;
1,728✔
917
                                case 53:
918
                                        hatch.PatternAngle = this._reader.ValueAsAngle;
×
919
                                        return true;
×
920
                                //TODO: Check hatch undocumented codes
921
                                case 90:
922
                                        return true;
×
923
                                //Information about the hatch pattern
924
                                case 75:
925
                                        return true;
1,728✔
926
                                //Number of pattern definition lines
927
                                case 78:
928
                                        this.readPattern(hatch.Pattern, this._reader.ValueAsInt);
1,296✔
929
                                        this.lockPointer = true;
1,296✔
930
                                        return true;
1,296✔
931
                                //Number of boundary paths (loops)
932
                                case 91:
933
                                        this.readLoops(tmp, this._reader.ValueAsInt);
1,728✔
934
                                        this.lockPointer = true;
1,728✔
935
                                        return true;
1,728✔
936
                                //Number of seed points
937
                                case 98:
938
                                        return true;
1,080✔
939
                                case 450:
940
                                        hatch.GradientColor.Enabled = this._reader.ValueAsBool;
360✔
941
                                        return true;
360✔
942
                                case 451:
943
                                        hatch.GradientColor.Reserved = this._reader.ValueAsInt;
360✔
944
                                        return true;
360✔
945
                                case 452:
946
                                        hatch.GradientColor.IsSingleColorGradient = this._reader.ValueAsBool;
360✔
947
                                        return true;
360✔
948
                                case 453:
949
                                        //Number of colors
950
                                        return true;
360✔
951
                                case 460:
952
                                        hatch.GradientColor.Angle = this._reader.ValueAsDouble;
360✔
953
                                        return true;
360✔
954
                                case 461:
955
                                        hatch.GradientColor.Shift = this._reader.ValueAsDouble;
360✔
956
                                        return true;
360✔
957
                                case 462:
958
                                        hatch.GradientColor.ColorTint = this._reader.ValueAsDouble;
360✔
959
                                        return true;
360✔
960
                                case 463:
961
                                        GradientColor gradient = new GradientColor();
720✔
962
                                        gradient.Value = this._reader.ValueAsDouble;
720✔
963
                                        hatch.GradientColor.Colors.Add(gradient);
720✔
964
                                        return true;
720✔
965
                                case 63:
966
                                        GradientColor colorByIndex = hatch.GradientColor.Colors.LastOrDefault();
720✔
967
                                        if (colorByIndex != null)
720✔
968
                                        {
720✔
969
                                                colorByIndex.Color = new Color((short)this._reader.ValueAsUShort);
720✔
970
                                        }
720✔
971
                                        return true;
720✔
972
                                case 421:
973
                                        GradientColor colorByRgb = hatch.GradientColor.Colors.LastOrDefault();
720✔
974
                                        if (colorByRgb != null)
720✔
975
                                        {
720✔
976
                                                //TODO: Hatch assign color by true color
977
                                                //TODO: Is always duplicated by 63, is it needed??
978
                                                //colorByRgb.Color = new Color(this._reader.LastValueAsShort);
979
                                        }
720✔
980
                                        return true;
720✔
981
                                case 470:
982
                                        hatch.GradientColor.Name = this._reader.ValueAsString;
360✔
983
                                        return true;
360✔
984
                                default:
985
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[template.CadObject.SubclassMarker]);
24,984✔
986
                        }
987
                }
46,224✔
988

989
                private bool readInsert(CadEntityTemplate template, DxfMap map, string subclass = null)
990
                {
62,582✔
991
                        CadInsertTemplate tmp = template as CadInsertTemplate;
62,582✔
992

993
                        switch (this._reader.Code)
62,582✔
994
                        {
995
                                case 2:
996
                                        tmp.BlockName = this._reader.ValueAsString;
5,851✔
997
                                        return true;
5,851✔
998
                                case 100:
999
                                        //AcDbEntity
1000
                                        //AcDbBlockReference
1001
                                        //AcDbMInsertBlock
1002
                                        return true;
5,878✔
1003
                                case 66:
1004
                                        return true;
504✔
1005
                                default:
1006
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Insert]);
50,349✔
1007
                        }
1008
                }
62,582✔
1009

1010
                private CadEntityTemplate readPolyline()
1011
                {
11,092✔
1012
                        if (this._builder.Version == ACadVersion.Unknown
11,092!
1013
                                || this._builder.Version == ACadVersion.AC1009)
11,092✔
1014
                        {
10,660✔
1015
                                return this.readLegacyPolyline();
10,660✔
1016
                        }
1017

1018
                        CadPolyLineTemplate template = null;
432✔
1019
                        template = new CadPolyLineTemplate();
432✔
1020
                        this.readEntityCodes<Entity>(template, this.readPolyline);
432✔
1021

1022
                        if (template.CadObject is CadPolyLineTemplate.PolyLinePlaceholder)
432!
1023
                        {
×
1024
                                this._builder.Notify($"[{DxfFileToken.EntityPolyline}] Subclass not found, entity discarded", NotificationType.Warning);
×
1025
                                return null;
×
1026
                        }
1027

1028
                        while (this._reader.Code == 0 && this._reader.ValueAsString == DxfFileToken.EntityVertex)
3,024!
1029
                        {
2,592✔
1030
                                var vertexTemplate = this.readEntityCodes<Entity>(new CadVertexTemplate(), this.readVertex);
2,592✔
1031

1032
                                if (vertexTemplate.OwnerHandle == null)
2,592!
1033
                                {
×
1034
                                        vertexTemplate.OwnerHandle = template.CadObject.Handle;
×
1035
                                }
×
1036

1037
                                template.OwnedObjectsHandlers.Add(vertexTemplate.CadObject.Handle);
2,592✔
1038
                                _builder.AddTemplate(vertexTemplate);
2,592✔
1039
                        }
2,592✔
1040

1041
                        while (this._reader.Code == 0 && this._reader.ValueAsString == DxfFileToken.EndSequence)
864!
1042
                        {
432✔
1043
                                var seqend = new Seqend();
432✔
1044
                                var seqendTemplate = new CadEntityTemplate<Seqend>(seqend);
432✔
1045
                                this.readEntityCodes<Seqend>(seqendTemplate, this.readEntitySubclassMap);
432✔
1046

1047
                                if (seqendTemplate.OwnerHandle == null)
432!
1048
                                {
×
1049
                                        seqendTemplate.OwnerHandle = template.CadObject.Handle;
×
1050
                                }
×
1051

1052
                                template.OwnedObjectsHandlers.Add(seqendTemplate.CadObject.Handle);
432✔
1053
                                _builder.AddTemplate(seqendTemplate);
432✔
1054
                        }
432✔
1055

1056
                        return template;
432✔
1057
                }
11,092✔
1058

1059
                private CadEntityTemplate readLegacyPolyline()
1060
                {
10,660✔
1061
                        var polyline = new Polyline2D();
10,660✔
1062
                        CadPolyLineTemplate template = new CadPolyLineTemplate(polyline);
10,660✔
1063
                        this.readEntityCodes<Polyline2D>(template, this.readPolyline);
10,660✔
1064

1065
                        while (this._reader.Code == 0 && this._reader.ValueAsString == DxfFileToken.EntityVertex)
48,700!
1066
                        {
38,040✔
1067
                                Vertex2D v = new Vertex2D();
38,040✔
1068
                                CadVertexTemplate vertexTemplate = new CadVertexTemplate(v);
38,040✔
1069
                                this.readEntityCodes<Vertex2D>(vertexTemplate, this.readVertex);
38,040✔
1070

1071
                                if (vertexTemplate.Vertex.Handle == 0)
38,040!
1072
                                {
×
1073
                                        polyline.Vertices.Add(v);
×
1074
                                }
×
1075
                                else
1076
                                {
38,040✔
1077
                                        template.OwnedObjectsHandlers.Add(vertexTemplate.Vertex.Handle);
38,040✔
1078
                                        this._builder.AddTemplate(vertexTemplate);
38,040✔
1079
                                }
38,040✔
1080
                        }
38,040✔
1081

1082
                        while (this._reader.Code == 0 && this._reader.ValueAsString == DxfFileToken.EndSequence)
21,320!
1083
                        {
10,660✔
1084
                                var seqend = new Seqend();
10,660✔
1085
                                var seqendTemplate = new CadEntityTemplate<Seqend>(seqend);
10,660✔
1086
                                this.readEntityCodes<Seqend>(seqendTemplate, this.readEntitySubclassMap);
10,660✔
1087

1088
                                polyline.Vertices.Seqend = seqend;
10,660✔
1089
                        }
10,660✔
1090

1091
                        return template;
10,660✔
1092
                }
10,660✔
1093

1094
                private bool readPolyline(CadEntityTemplate template, DxfMap map, string subclass = null)
1095
                {
79,656✔
1096
                        CadPolyLineTemplate tmp = template as CadPolyLineTemplate;
79,656✔
1097

1098
                        switch (this._reader.Code)
79,656✔
1099
                        {
1100
                                //DXF: always 0
1101
                                //APP: a “dummy” point; the X and Y values are always 0, and the Z value is the polyline's elevation (in OCS when 2D, WCS when 3D)
1102
                                case 10:
1103
                                case 20:
1104
                                //Obsolete; formerly an “entities follow flag” (optional; ignore if present)
1105
                                case 66:
1106
                                        return true;
33,276✔
1107
                                case 100:
1108
                                        switch (this._reader.ValueAsString)
864!
1109
                                        {
1110
                                                case DxfSubclassMarker.Polyline:
1111
                                                        tmp.SetPolyLineObject(new Polyline2D());
×
1112
                                                        map.SubClasses.Add(DxfSubclassMarker.Polyline, DxfClassMap.Create<Polyline2D>());
×
1113
                                                        return true;
×
1114
                                                case DxfSubclassMarker.Polyline3d:
1115
                                                        tmp.SetPolyLineObject(new Polyline3D());
216✔
1116
                                                        map.SubClasses.Add(DxfSubclassMarker.Polyline3d, DxfClassMap.Create<Polyline3D>());
216✔
1117
                                                        return true;
216✔
1118
                                                case DxfSubclassMarker.PolyfaceMesh:
1119
                                                        tmp.SetPolyLineObject(new PolyfaceMesh());
216✔
1120
                                                        map.SubClasses.Add(DxfSubclassMarker.PolyfaceMesh, DxfClassMap.Create<PolyfaceMesh>());
216✔
1121
                                                        return true;
216✔
1122
                                                case DxfSubclassMarker.PolygonMesh:
1123
                                                        tmp.SetPolyLineObject(new PolygonMesh());
×
1124
                                                        map.SubClasses.Add(DxfSubclassMarker.PolygonMesh, DxfClassMap.Create<PolygonMesh>());
×
1125
                                                        return true;
×
1126
                                                default:
1127
                                                        return false;
432✔
1128
                                        }
1129
                                default:
1130
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
45,516✔
1131
                        }
1132
                }
79,656✔
1133

1134
                private bool readLeader(CadEntityTemplate template, DxfMap map, string subclass = null)
1135
                {
5,400✔
1136
                        CadLeaderTemplate tmp = template as CadLeaderTemplate;
5,400✔
1137

1138
                        switch (this._reader.Code)
5,400✔
1139
                        {
1140
                                case 3:
1141
                                        tmp.DIMSTYLEName = this._reader.ValueAsString;
216✔
1142
                                        return true;
216✔
1143
                                case 10:
1144
                                        tmp.CadObject.Vertices.Add(new XYZ(this._reader.ValueAsDouble, 0, 0));
864✔
1145
                                        return true;
864✔
1146
                                case 20:
1147
                                        XYZ y = tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1];
864✔
1148
                                        y.Y = this._reader.ValueAsDouble;
864✔
1149
                                        tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1] = y;
864✔
1150
                                        return true;
864✔
1151
                                case 30:
1152
                                        XYZ z = tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1];
864✔
1153
                                        z.Z = this._reader.ValueAsDouble;
864✔
1154
                                        tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1] = z;
864✔
1155
                                        return true;
864✔
1156
                                case 340:
1157
                                        tmp.AnnotationHandle = this._reader.ValueAsHandle;
216✔
1158
                                        return true;
216✔
1159
                                //Hook line flag - read only
1160
                                case 75:
1161
                                //Vertices count
1162
                                case 76:
1163
                                        return true;
432✔
1164
                                default:
1165
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
1,944✔
1166
                        }
1167
                }
5,400✔
1168

1169
                private bool readLwPolyline(CadEntityTemplate template, DxfMap map, string subclass = null)
1170
                {
92,547✔
1171
                        CadEntityTemplate<LwPolyline> tmp = template as CadEntityTemplate<LwPolyline>;
92,547✔
1172

1173
                        LwPolyline.Vertex last = tmp.CadObject.Vertices.LastOrDefault();
92,547✔
1174

1175
                        switch (this._reader.Code)
92,547!
1176
                        {
1177
                                case 10:
1178
                                        tmp.CadObject.Vertices.Add(new LwPolyline.Vertex(new XY(this._reader.ValueAsDouble, 0)));
22,012✔
1179
                                        return true;
22,012✔
1180
                                case 20:
1181
                                        if (last is not null)
22,012✔
1182
                                        {
22,012✔
1183
                                                last.Location = new XY(last.Location.X, this._reader.ValueAsDouble);
22,012✔
1184
                                        }
22,012✔
1185
                                        return true;
22,012✔
1186
                                case 40:
1187
                                        if (last is not null)
2,160✔
1188
                                        {
2,160✔
1189
                                                last.StartWidth = this._reader.ValueAsDouble;
2,160✔
1190
                                        }
2,160✔
1191
                                        return true;
2,160✔
1192
                                case 41:
1193
                                        if (last is not null)
2,160✔
1194
                                        {
2,160✔
1195
                                                last.EndWidth = this._reader.ValueAsDouble;
2,160✔
1196
                                        }
2,160✔
1197
                                        return true;
2,160✔
1198
                                case 42:
1199
                                        if (last is not null)
2,952✔
1200
                                        {
2,952✔
1201
                                                last.Bulge = this._reader.ValueAsDouble;
2,952✔
1202
                                        }
2,952✔
1203
                                        return true;
2,952✔
1204
                                case 50:
1205
                                        if (last is not null)
×
1206
                                        {
×
1207
                                                last.CurveTangent = this._reader.ValueAsDouble;
×
1208
                                        }
×
1209
                                        return true;
×
1210
                                //Obsolete; formerly an “entities follow flag” (optional; ignore if present)
1211
                                case 66:
1212
                                //Vertex count
1213
                                case 90:
1214
                                        return true;
4,966✔
1215
                                case 91:
1216
                                        if (last is not null)
×
1217
                                        {
×
1218
                                                last.Id = this._reader.ValueAsInt;
×
1219
                                        }
×
1220
                                        return true;
×
1221
                                default:
1222
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
36,285✔
1223
                        }
1224
                }
92,547✔
1225

1226
                private bool readMesh(CadEntityTemplate template, DxfMap map, string subclass = null)
1227
                {
38,016✔
1228
                        CadMeshTemplate tmp = template as CadMeshTemplate;
38,016✔
1229

1230
                        switch (this._reader.Code)
38,016✔
1231
                        {
1232
                                case 100:
1233
                                        if (this._reader.ValueAsString.Equals(DxfSubclassMarker.Mesh, StringComparison.OrdinalIgnoreCase))
864✔
1234
                                        {
432✔
1235
                                                tmp.SubclassMarker = true;
432✔
1236
                                        }
432✔
1237
                                        return true;
864✔
1238
                                //Count of sub-entity which property has been overridden
1239
                                case 90:
1240
                                        //TODO: process further entities
1241
                                        return true;
432✔
1242
                                case 92:
1243
                                        if (!tmp.SubclassMarker)
648✔
1244
                                        {
216✔
1245
                                                return false;
216✔
1246
                                        }
1247

1248
                                        int nvertices = this._reader.ValueAsInt;
432✔
1249
                                        for (int i = 0; i < nvertices; i++)
55,296✔
1250
                                        {
27,216✔
1251
                                                this._reader.ReadNext();
27,216✔
1252
                                                double x = this._reader.ValueAsDouble;
27,216✔
1253
                                                this._reader.ReadNext();
27,216✔
1254
                                                double y = this._reader.ValueAsDouble;
27,216✔
1255
                                                this._reader.ReadNext();
27,216✔
1256
                                                double z = this._reader.ValueAsDouble;
27,216✔
1257
                                                tmp.CadObject.Vertices.Add(new XYZ(x, y, z));
27,216✔
1258
                                        }
27,216✔
1259
                                        return true;
432✔
1260
                                case 93:
1261
                                        int size = this._reader.ValueAsInt;
432✔
1262
                                        this._reader.ReadNext();
432✔
1263

1264
                                        int indexes = 0;
432✔
1265
                                        for (int i = 0; i < size; i += indexes + 1)
59,616✔
1266
                                        {
29,376✔
1267
                                                indexes = this._reader.ValueAsInt;
29,376✔
1268
                                                this._reader.ReadNext();
29,376✔
1269

1270
                                                int[] face = new int[indexes];
29,376✔
1271
                                                for (int j = 0; j < indexes; j++)
283,392✔
1272
                                                {
112,320✔
1273
                                                        face[j] = this._reader.ValueAsInt;
112,320✔
1274

1275
                                                        if ((i + j + 2) < size)
112,320✔
1276
                                                        {
111,888✔
1277
                                                                this._reader.ReadNext();
111,888✔
1278
                                                        }
111,888✔
1279
                                                }
112,320✔
1280

1281
                                                tmp.CadObject.Faces.Add(face);
29,376✔
1282
                                        }
29,376✔
1283

1284
                                        return true;
432✔
1285
                                case 94:
1286
                                        int numEdges = this._reader.ValueAsInt;
432✔
1287
                                        this._reader.ReadNext();
432✔
1288
                                        for (int i = 0; i < numEdges; i++)
113,184✔
1289
                                        {
56,160✔
1290
                                                Mesh.Edge edge = new Mesh.Edge();
56,160✔
1291

1292
                                                edge.Start = this._reader.ValueAsInt;
56,160✔
1293
                                                this._reader.ReadNext();
56,160✔
1294
                                                edge.End = this._reader.ValueAsInt;
56,160✔
1295

1296
                                                if (i < numEdges - 1)
56,160✔
1297
                                                {
55,728✔
1298
                                                        this._reader.ReadNext();
55,728✔
1299
                                                }
55,728✔
1300

1301
                                                tmp.CadObject.Edges.Add(edge);
56,160✔
1302
                                        }
56,160✔
1303

1304
                                        return true;
432✔
1305
                                case 95:
1306
                                        this._reader.ReadNext();
432✔
1307
                                        for (int i = 0; i < tmp.CadObject.Edges.Count; i++)
113,184✔
1308
                                        {
56,160✔
1309
                                                Mesh.Edge edge = tmp.CadObject.Edges[i];
56,160✔
1310
                                                edge.Crease = this._reader.ValueAsDouble;
56,160✔
1311

1312
                                                tmp.CadObject.Edges[i] = edge;
56,160✔
1313

1314
                                                if (i < tmp.CadObject.Edges.Count - 1)
56,160✔
1315
                                                {
55,728✔
1316
                                                        this._reader.ReadNext();
55,728✔
1317
                                                }
55,728✔
1318
                                        }
56,160✔
1319

1320
                                        return true;
432✔
1321
                                default:
1322
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
34,776✔
1323
                        }
1324
                }
38,016✔
1325

1326
                private bool readMLine(CadEntityTemplate template, DxfMap map, string subclass = null)
1327
                {
56,160✔
1328
                        CadMLineTemplate tmp = template as CadMLineTemplate;
56,160✔
1329

1330
                        switch (this._reader.Code)
56,160✔
1331
                        {
1332
                                // String of up to 32 characters. The name of the style used for this mline. An entry for this style must exist in the MLINESTYLE dictionary.
1333
                                // Do not modify this field without also updating the associated entry in the MLINESTYLE dictionary
1334
                                case 2:
1335
                                        tmp.MLineStyleName = this._reader.ValueAsString;
648✔
1336
                                        return true;
648✔
1337
                                case 72:
1338
                                        tmp.NVertex = this._reader.ValueAsInt;
648✔
1339
                                        return true;
648✔
1340
                                case 73:
1341
                                        tmp.NElements = this._reader.ValueAsInt;
648✔
1342
                                        return true;
648✔
1343
                                case 340:
1344
                                        tmp.MLineStyleHandle = this._reader.ValueAsHandle;
648✔
1345
                                        return true;
648✔
1346
                                default:
1347
                                        if (!tmp.TryReadVertex(this._reader.Code, this._reader.Value))
53,568✔
1348
                                        {
9,072✔
1349
                                                return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
9,072✔
1350
                                        }
1351
                                        return true;
44,496✔
1352
                        }
1353
                }
56,160✔
1354

1355
                private bool readMLeader(CadEntityTemplate template, DxfMap map, string subclass = null)
1356
                {
152,496✔
1357
                        CadMLeaderTemplate tmp = template as CadMLeaderTemplate;
152,496✔
1358

1359
                        switch (this._reader.Code)
152,496✔
1360
                        {
1361
                                case 270:
1362
                                        //f270 Version
1363
                                        return true;
1,620✔
1364
                                case 300:
1365
                                        this.readMultiLeaderObjectContextData(tmp.CadMLeaderAnnotContextTemplate);
3,240✔
1366
                                        return true;
3,240✔
1367
                                case 340:
1368
                                        tmp.LeaderStyleHandle = this._reader.ValueAsHandle;
3,240✔
1369
                                        return true;
3,240✔
1370
                                case 341:
1371
                                        tmp.LeaderLineTypeHandle = this._reader.ValueAsHandle;
3,240✔
1372
                                        return true;
3,240✔
1373
                                case 343:
1374
                                        tmp.MTextStyleHandle = this._reader.ValueAsHandle;
3,240✔
1375
                                        return true;
3,240✔
1376
                                default:
1377
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
137,916✔
1378
                        }
1379
                }
152,496✔
1380

1381
                private void readMultiLeaderObjectContextData(CadMLeaderAnnotContextTemplate template)
1382
                {
3,240✔
1383
                        this._reader.ReadNext();
3,240✔
1384

1385
                        var map = DxfClassMap.Create<MultiLeaderObjectContextData>();
3,240✔
1386
                        var contextData = template.CadObject as MultiLeaderObjectContextData;
3,240✔
1387

1388
                        bool end = false;
3,240✔
1389
                        while (this._reader.DxfCode != DxfCode.Start)
181,440✔
1390
                        {
181,440✔
1391
                                switch (this._reader.Code)
181,440✔
1392
                                {
1393
                                        case 301 when this._reader.ValueAsString.Equals("}"):
3,240✔
1394
                                                end = true;
3,240✔
1395
                                                break;
3,240✔
1396
                                        case 302 when this._reader.ValueAsString.Equals("LEADER{"):
3,240✔
1397
                                                contextData.LeaderRoots.Add(this.readMultiLeaderLeader(template));
3,240✔
1398
                                                break;
3,240✔
1399
                                        case 340:
1400
                                                template.TextStyleHandle = this._reader.ValueAsHandle;
3,240✔
1401
                                                break;
3,240✔
1402
                                        default:
1403
                                                if (!this.tryAssignCurrentValue(contextData, map))
171,720!
1404
                                                {
×
1405
                                                        this._builder.Notify($"[AcDbMLeaderObjectContextData] Unhandled dxf code {this._reader.Code} with value {this._reader.ValueAsString}", NotificationType.None);
×
1406
                                                }
×
1407
                                                break;
171,720✔
1408
                                }
1409

1410
                                if (end)
181,440✔
1411
                                {
3,240✔
1412
                                        break;
3,240✔
1413
                                }
1414

1415
                                this._reader.ReadNext();
178,200✔
1416
                        }
178,200✔
1417
                }
3,240✔
1418

1419
                private MultiLeaderObjectContextData.LeaderRoot readMultiLeaderLeader(CadMLeaderAnnotContextTemplate template)
1420
                {
3,240✔
1421
                        MultiLeaderObjectContextData.LeaderRoot root = new();
3,240✔
1422
                        var map = DxfClassMap.Create(root.GetType(), nameof(MultiLeaderObjectContextData.LeaderRoot));
3,240✔
1423

1424
                        this._reader.ReadNext();
3,240✔
1425

1426
                        bool end = false;
3,240✔
1427
                        while (this._reader.DxfCode != DxfCode.Start)
40,500✔
1428
                        {
40,500✔
1429
                                switch (this._reader.Code)
40,500✔
1430
                                {
1431
                                        case 303 when this._reader.ValueAsString.Equals("}"):
3,240✔
1432
                                                end = true;
3,240✔
1433
                                                break;
3,240✔
1434
                                        case 304 when this._reader.ValueAsString.Equals("LEADER_LINE{"):
3,240✔
1435
                                                var lineTemplate = new LeaderLineTemplate();
3,240✔
1436
                                                template.LeaderLineTemplates.Add(lineTemplate);
3,240✔
1437
                                                root.Lines.Add(this.readMultiLeaderLine(lineTemplate));
3,240✔
1438
                                                break;
3,240✔
1439
                                        default:
1440
                                                if (!this.tryAssignCurrentValue(root, map))
34,020!
1441
                                                {
×
1442
                                                        this._builder.Notify($"[LeaderRoot] Unhandled dxf code {this._reader.Code} with value {this._reader.ValueAsString}", NotificationType.None);
×
1443
                                                }
×
1444
                                                break;
34,020✔
1445
                                }
1446

1447
                                if (end)
40,500✔
1448
                                {
3,240✔
1449
                                        break;
3,240✔
1450
                                }
1451

1452
                                this._reader.ReadNext();
37,260✔
1453
                        }
37,260✔
1454

1455
                        return root;
3,240✔
1456
                }
3,240✔
1457

1458
                private MultiLeaderObjectContextData.LeaderLine readMultiLeaderLine(LeaderLineTemplate template)
1459
                {
3,240✔
1460
                        MultiLeaderObjectContextData.LeaderLine line = template.LeaderLine;
3,240✔
1461
                        var map = DxfClassMap.Create(line.GetType(), nameof(MultiLeaderObjectContextData.LeaderLine));
3,240✔
1462

1463
                        this._reader.ReadNext();
3,240✔
1464

1465
                        bool end = false;
3,240✔
1466
                        while (this._reader.DxfCode != DxfCode.Start)
16,200✔
1467
                        {
16,200✔
1468
                                switch (this._reader.Code)
16,200✔
1469
                                {
1470
                                        case 10:
1471
                                                XYZ pt = new XYZ(this._reader.ValueAsDouble, 0, 0);
3,240✔
1472
                                                line.Points.Add(pt);
3,240✔
1473
                                                break;
3,240✔
1474
                                        case 20:
1475
                                                pt = line.Points[line.Points.Count - 1];
3,240✔
1476
                                                pt.Y = this._reader.ValueAsDouble;
3,240✔
1477
                                                line.Points[line.Points.Count - 1] = pt;
3,240✔
1478
                                                break;
3,240✔
1479
                                        case 30:
1480
                                                pt = line.Points[line.Points.Count - 1];
3,240✔
1481
                                                pt.Z = this._reader.ValueAsDouble;
3,240✔
1482
                                                line.Points[line.Points.Count - 1] = pt;
3,240✔
1483
                                                break;
3,240✔
1484
                                        case 305 when this._reader.ValueAsString.Equals("}"):
3,240✔
1485
                                                end = true;
3,240✔
1486
                                                break;
3,240✔
1487
                                        default:
1488
                                                if (!this.tryAssignCurrentValue(line, map))
3,240!
1489
                                                {
×
1490
                                                        this._builder.Notify($"[LeaderLine] Unhandled dxf code {this._reader.Code} with value {this._reader.ValueAsString}", NotificationType.None);
×
1491
                                                }
×
1492
                                                break;
3,240✔
1493
                                }
1494

1495
                                if (end)
16,200✔
1496
                                {
3,240✔
1497
                                        break;
3,240✔
1498
                                }
1499

1500
                                this._reader.ReadNext();
12,960✔
1501
                        }
12,960✔
1502

1503
                        return line;
3,240✔
1504
                }
3,240✔
1505

1506
                private bool readShape(CadEntityTemplate template, DxfMap map, string subclass = null)
1507
                {
2,412✔
1508
                        CadShapeTemplate tmp = template as CadShapeTemplate;
2,412✔
1509

1510
                        switch (this._reader.Code)
2,412✔
1511
                        {
1512
                                case 2:
1513
                                        tmp.ShapeFileName = this._reader.ValueAsString;
252✔
1514
                                        return true;
252✔
1515
                                default:
1516
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
2,160✔
1517
                        }
1518
                }
2,412✔
1519

1520
                private bool readWipeoutBase(CadEntityTemplate template, DxfMap map, string subclass = null)
1521
                {
12,744✔
1522
                        CadWipeoutBaseTemplate tmp = template as CadWipeoutBaseTemplate;
12,744✔
1523
                        CadWipeoutBase wipeout = tmp.CadObject as CadWipeoutBase;
12,744✔
1524

1525
                        switch (this._reader.Code)
12,744✔
1526
                        {
1527
                                case 91:
1528
                                        var nvertices = this._reader.ValueAsInt;
432✔
1529
                                        for (int i = 0; i < nvertices; i++)
3,888✔
1530
                                        {
1,512✔
1531
                                                this._reader.ReadNext();
1,512✔
1532
                                                var x = this._reader.ValueAsDouble;
1,512✔
1533
                                                this._reader.ReadNext();
1,512✔
1534
                                                var y = this._reader.ValueAsDouble;
1,512✔
1535

1536
                                                wipeout.ClipBoundaryVertices.Add(new XY(x, y));
1,512✔
1537
                                        }
1,512✔
1538

1539
                                        this._reader.ReadNext();
432✔
1540

1541
                                        return this.checkEntityEnd(template, map, subclass, this.readWipeoutBase);
432✔
1542
                                case 340:
1543
                                        tmp.ImgDefHandle = this._reader.ValueAsHandle;
432✔
1544
                                        return true;
432✔
1545
                                case 360:
1546
                                        tmp.ImgReactorHandle = this._reader.ValueAsHandle;
432✔
1547
                                        return true;
432✔
1548
                                default:
1549
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
11,448✔
1550
                        }
1551
                }
12,744✔
1552

1553
                private bool readOle2Frame(CadEntityTemplate template, DxfMap map, string subclass = null)
1554
                {
×
1555
                        CadOle2FrameTemplate tmp = template as CadOle2FrameTemplate;
×
1556

1557
                        switch (this._reader.Code)
×
1558
                        {
1559
                                //End of data
1560
                                case 1:
1561
                                //Length of binary data
1562
                                case 90:
1563
                                //Undocumented
1564
                                case 73:
1565
                                        return true;
×
1566
                                case 310:
1567
                                        tmp.Chunks.Add(this._reader.ValueAsBinaryChunk);
×
1568
                                        return true;
×
1569
                                default:
1570
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
×
1571
                        }
1572
                }
×
1573

1574
                private bool readModelerGeometry(CadEntityTemplate template, DxfMap map, string subclass = null)
1575
                {
306,654✔
1576
                        CadSolid3DTemplate tmp = template as CadSolid3DTemplate;
306,654✔
1577
                        string mapName = string.IsNullOrEmpty(subclass) ? template.CadObject.SubclassMarker : subclass;
306,654✔
1578
                        var geometry = template.CadObject as ModelerGeometry;
306,654✔
1579

1580
                        switch (this._reader.Code)
306,654✔
1581
                        {
1582
                                case 1:
1583
                                case 3:
1584
                                        geometry.ProprietaryData.AppendLine(this._reader.ValueAsString);
39,924✔
1585
                                        return true;
39,924✔
1586
                                case 2:
1587
                                        geometry.Guid = new Guid(this._reader.ValueAsString);
216✔
1588
                                        return true;
216✔
1589
                                case 290:
1590
                                        return true;
216✔
1591
                                default:
1592
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[mapName]);
266,298✔
1593
                        }
1594
                }
306,654✔
1595

1596
                private bool readSolid3d(CadEntityTemplate template, DxfMap map, string subclass = null)
1597
                {
36,936✔
1598
                        CadSolid3DTemplate tmp = template as CadSolid3DTemplate;
36,936✔
1599

1600
                        switch (this._reader.Code)
36,936✔
1601
                        {
1602
                                case 350:
1603
                                        tmp.HistoryHandle = this._reader.ValueAsHandle;
288✔
1604
                                        return true;
288✔
1605
                                default:
1606
                                        return this.readModelerGeometry(template, map, DxfSubclassMarker.ModelerGeometry);
36,648✔
1607
                        }
1608
                }
36,936✔
1609

1610
                private bool readSpline(CadEntityTemplate template, DxfMap map, string subclass = null)
1611
                {
15,120✔
1612
                        CadSplineTemplate tmp = template as CadSplineTemplate;
15,120✔
1613

1614
                        XYZ controlPoint;
1615
                        XYZ fitPoint;
1616

1617
                        switch (this._reader.Code)
15,120!
1618
                        {
1619
                                case 10:
1620
                                        controlPoint = new CSMath.XYZ(this._reader.ValueAsDouble, 0, 0);
1,728✔
1621
                                        tmp.CadObject.ControlPoints.Add(controlPoint);
1,728✔
1622
                                        return true;
1,728✔
1623
                                case 20:
1624
                                        controlPoint = tmp.CadObject.ControlPoints.LastOrDefault();
1,728✔
1625
                                        controlPoint.Y = this._reader.ValueAsDouble;
1,728✔
1626
                                        tmp.CadObject.ControlPoints[tmp.CadObject.ControlPoints.Count - 1] = controlPoint;
1,728✔
1627
                                        return true;
1,728✔
1628
                                case 30:
1629
                                        controlPoint = tmp.CadObject.ControlPoints.LastOrDefault();
1,728✔
1630
                                        controlPoint.Z = this._reader.ValueAsDouble;
1,728✔
1631
                                        tmp.CadObject.ControlPoints[tmp.CadObject.ControlPoints.Count - 1] = controlPoint;
1,728✔
1632
                                        return true;
1,728✔
1633
                                case 11:
1634
                                        fitPoint = new CSMath.XYZ(this._reader.ValueAsDouble, 0, 0);
×
1635
                                        tmp.CadObject.FitPoints.Add(fitPoint);
×
1636
                                        return true;
×
1637
                                case 21:
1638
                                        fitPoint = tmp.CadObject.FitPoints.LastOrDefault();
×
1639
                                        fitPoint.Y = this._reader.ValueAsDouble;
×
1640
                                        tmp.CadObject.FitPoints[tmp.CadObject.FitPoints.Count - 1] = fitPoint;
×
1641
                                        return true;
×
1642
                                case 31:
1643
                                        fitPoint = tmp.CadObject.FitPoints.LastOrDefault();
×
1644
                                        fitPoint.Z = this._reader.ValueAsDouble;
×
1645
                                        tmp.CadObject.FitPoints[tmp.CadObject.FitPoints.Count - 1] = fitPoint;
×
1646
                                        return true;
×
1647
                                case 40:
1648
                                        tmp.CadObject.Knots.Add(this._reader.ValueAsDouble);
3,456✔
1649
                                        return true;
3,456✔
1650
                                case 41:
1651
                                        tmp.CadObject.Weights.Add(this._reader.ValueAsDouble);
×
1652
                                        return true;
×
1653
                                case 72:
1654
                                case 73:
1655
                                case 74:
1656
                                        return true;
1,296✔
1657
                                default:
1658
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
5,184✔
1659
                        }
1660
                }
15,120✔
1661

1662
                private bool readUnderlayEntity<T>(CadEntityTemplate template, DxfMap map, string subclass = null)
1663
                        where T : PdfUnderlayDefinition
1664
                {
3,420✔
1665
                        CadUnderlayTemplate<T> tmp = template as CadUnderlayTemplate<T>;
3,420✔
1666

1667
                        switch (this._reader.Code)
3,420✔
1668
                        {
1669
                                case 340:
1670
                                        tmp.DefinitionHandle = this._reader.ValueAsHandle;
216✔
1671
                                        return true;
216✔
1672
                                default:
1673
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
3,204✔
1674
                        }
1675
                }
3,420✔
1676

1677
                private bool readVertex(CadEntityTemplate template, DxfMap map, string subclass = null)
1678
                {
252,690✔
1679
                        CadVertexTemplate tmp = template as CadVertexTemplate;
252,690✔
1680

1681
                        switch (this._reader.Code)
252,690✔
1682
                        {
1683
                                case 100:
1684
                                        switch (this._reader.ValueAsString)
7,344!
1685
                                        {
1686
                                                case DxfSubclassMarker.Vertex:
1687
                                                        return true;
2,160✔
1688
                                                case DxfSubclassMarker.PolylineVertex:
1689
                                                        tmp.SetVertexObject(new Vertex2D());
×
1690
                                                        map.SubClasses.Add(DxfSubclassMarker.PolylineVertex, DxfClassMap.Create<Vertex2D>());
×
1691
                                                        return true;
×
1692
                                                case DxfSubclassMarker.Polyline3dVertex:
1693
                                                        tmp.SetVertexObject(new Vertex3D());
1,080✔
1694
                                                        map.SubClasses.Add(DxfSubclassMarker.Polyline3dVertex, DxfClassMap.Create<Vertex3D>());
1,080✔
1695
                                                        return true;
1,080✔
1696
                                                case DxfSubclassMarker.PolyfaceMeshVertex:
1697
                                                        tmp.SetVertexObject(new VertexFaceMesh());
1,080✔
1698
                                                        map.SubClasses.Add(DxfSubclassMarker.PolyfaceMeshVertex, DxfClassMap.Create<VertexFaceMesh>());
1,080✔
1699
                                                        return true;
1,080✔
1700
                                                case DxfSubclassMarker.PolyfaceMeshFace:
1701
                                                        tmp.SetVertexObject(new VertexFaceRecord());
432✔
1702
                                                        map.SubClasses.Add(DxfSubclassMarker.PolyfaceMeshFace, DxfClassMap.Create<VertexFaceRecord>());
432✔
1703
                                                        return true;
432✔
1704
                                                case DxfSubclassMarker.PolygonMeshVertex:
1705
                                                        tmp.SetVertexObject(new PolygonMeshVertex());
×
1706
                                                        map.SubClasses.Add(DxfSubclassMarker.PolygonMeshVertex, DxfClassMap.Create<PolygonMeshVertex>());
×
1707
                                                        return true;
×
1708
                                                default:
1709
                                                        return false;
2,592✔
1710
                                        }
1711
                                default:
1712
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
245,346✔
1713
                        }
1714
                }
252,690✔
1715

1716
                private bool readViewport(CadEntityTemplate template, DxfMap map, string subclass = null)
1717
                {
72,724✔
1718
                        CadViewportTemplate tmp = template as CadViewportTemplate;
72,724✔
1719

1720
                        switch (this._reader.Code)
72,724!
1721
                        {
1722
                                //Undocumented
1723
                                case 67:
1724
                                case 68:
1725
                                        return true;
2,664✔
1726
                                case 69:
1727
                                        tmp.ViewportId = this._reader.ValueAsShort;
1,332✔
1728
                                        return true;
1,332✔
1729
                                case 331:
1730
                                        tmp.FrozenLayerHandles.Add(this._reader.ValueAsHandle);
×
1731
                                        return true;
×
1732
                                case 348:
1733
                                        tmp.VisualStyleHandle = this._reader.ValueAsHandle;
832✔
1734
                                        return true;
832✔
1735
                                default:
1736
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Viewport]);
67,896✔
1737
                        }
1738
                }
72,724✔
1739

1740
                private bool readEntitySubclassMap(CadEntityTemplate template, DxfMap map, string subclass = null)
1741
                {
855,836✔
1742
                        string mapName = string.IsNullOrEmpty(subclass) ? template.CadObject.SubclassMarker : subclass;
855,836✔
1743

1744
                        switch (this._reader.Code)
855,836✔
1745
                        {
1746
                                default:
1747
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[mapName]);
855,836✔
1748
                        }
1749
                }
855,836✔
1750

1751
                protected void readExtendedData(Dictionary<string, List<ExtendedDataRecord>> edata)
1752
                {
36,252✔
1753
                        List<ExtendedDataRecord> records = new();
36,252✔
1754
                        edata.Add(this._reader.ValueAsString, records);
36,252✔
1755

1756
                        this._reader.ReadNext();
36,252✔
1757

1758
                        while (this._reader.DxfCode >= DxfCode.ExtendedDataAsciiString)
296,377✔
1759
                        {
271,630✔
1760
                                if (this._reader.DxfCode == DxfCode.ExtendedDataRegAppName)
271,630✔
1761
                                {
11,505✔
1762
                                        this.readExtendedData(edata);
11,505✔
1763
                                        break;
11,505✔
1764
                                }
1765

1766
                                ExtendedDataRecord record = null;
260,125✔
1767
                                double x = 0;
260,125✔
1768
                                double y = 0;
260,125✔
1769
                                double z = 0;
260,125✔
1770

1771
                                switch (this._reader.DxfCode)
260,125✔
1772
                                {
1773
                                        case DxfCode.ExtendedDataAsciiString:
1774
                                        case DxfCode.ExtendedDataRegAppName:
1775
                                                record = new ExtendedDataString(this._reader.ValueAsString);
24,915✔
1776
                                                break;
24,915✔
1777
                                        case DxfCode.ExtendedDataControlString:
1778
                                                record = new ExtendedDataControlString(this._reader.ValueAsString == "}");
14,276✔
1779
                                                break;
14,276✔
1780
                                        case DxfCode.ExtendedDataLayerName:
1781
                                                if (this._builder.Layers.TryGetValue(this._reader.ValueAsString, out Layer layer))
252✔
1782
                                                {
238✔
1783
                                                        record = new ExtendedDataLayer(layer.Handle);
238✔
1784
                                                }
238✔
1785
                                                else
1786
                                                {
14✔
1787
                                                        this._builder.Notify($"[XData] Could not found the linked Layer {this._reader.ValueAsString}.", NotificationType.Warning);
14✔
1788
                                                }
14✔
1789
                                                break;
252✔
1790
                                        case DxfCode.ExtendedDataBinaryChunk:
1791
                                                record = new ExtendedDataBinaryChunk(this._reader.ValueAsBinaryChunk);
72✔
1792
                                                break;
72✔
1793
                                        case DxfCode.ExtendedDataHandle:
1794
                                                record = new ExtendedDataHandle(this._reader.ValueAsHandle);
2,761✔
1795
                                                break;
2,761✔
1796
                                        case DxfCode.ExtendedDataXCoordinate:
1797
                                                x = this._reader.ValueAsDouble;
2,689✔
1798
                                                this._reader.ReadNext();
2,689✔
1799
                                                y = this._reader.ValueAsDouble;
2,689✔
1800
                                                this._reader.ReadNext();
2,689✔
1801
                                                z = this._reader.ValueAsDouble;
2,689✔
1802

1803
                                                record = new ExtendedDataCoordinate(
2,689✔
1804
                                                        new XYZ(
2,689✔
1805
                                                                x,
2,689✔
1806
                                                                y,
2,689✔
1807
                                                                z)
2,689✔
1808
                                                        );
2,689✔
1809
                                                break;
2,689✔
1810
                                        case DxfCode.ExtendedDataWorldXCoordinate:
1811
                                                x = this._reader.ValueAsDouble;
1,296✔
1812
                                                this._reader.ReadNext();
1,296✔
1813
                                                y = this._reader.ValueAsDouble;
1,296✔
1814
                                                this._reader.ReadNext();
1,296✔
1815
                                                z = this._reader.ValueAsDouble;
1,296✔
1816

1817
                                                record = new ExtendedDataWorldCoordinate(
1,296✔
1818
                                                        new XYZ(
1,296✔
1819
                                                                x,
1,296✔
1820
                                                                y,
1,296✔
1821
                                                                z)
1,296✔
1822
                                                        );
1,296✔
1823
                                                break;
1,296✔
1824
                                        case DxfCode.ExtendedDataWorldXDisp:
1825
                                                x = this._reader.ValueAsDouble;
252✔
1826
                                                this._reader.ReadNext();
252✔
1827
                                                y = this._reader.ValueAsDouble;
252✔
1828
                                                this._reader.ReadNext();
252✔
1829
                                                z = this._reader.ValueAsDouble;
252✔
1830

1831
                                                record = new ExtendedDataDisplacement(
252✔
1832
                                                        new XYZ(
252✔
1833
                                                                x,
252✔
1834
                                                                y,
252✔
1835
                                                                z)
252✔
1836
                                                        );
252✔
1837
                                                break;
252✔
1838
                                        case DxfCode.ExtendedDataWorldXDir:
1839
                                                x = this._reader.ValueAsDouble;
252✔
1840
                                                this._reader.ReadNext();
252✔
1841
                                                y = this._reader.ValueAsDouble;
252✔
1842
                                                this._reader.ReadNext();
252✔
1843
                                                z = this._reader.ValueAsDouble;
252✔
1844

1845
                                                record = new ExtendedDataDirection(
252✔
1846
                                                        new XYZ(
252✔
1847
                                                                x,
252✔
1848
                                                                y,
252✔
1849
                                                                z)
252✔
1850
                                                        );
252✔
1851
                                                break;
252✔
1852
                                        case DxfCode.ExtendedDataReal:
1853
                                                record = new ExtendedDataReal(this._reader.ValueAsDouble);
126,479✔
1854
                                                break;
126,479✔
1855
                                        case DxfCode.ExtendedDataDist:
1856
                                                record = new ExtendedDataDistance(this._reader.ValueAsDouble);
252✔
1857
                                                break;
252✔
1858
                                        case DxfCode.ExtendedDataScale:
1859
                                                record = new ExtendedDataScale(this._reader.ValueAsDouble);
252✔
1860
                                                break;
252✔
1861
                                        case DxfCode.ExtendedDataInteger16:
1862
                                                record = new ExtendedDataInteger16(this._reader.ValueAsShort);
73,899✔
1863
                                                break;
73,899✔
1864
                                        case DxfCode.ExtendedDataInteger32:
1865
                                                record = new ExtendedDataInteger32((int)this._reader.ValueAsInt);
10,174✔
1866
                                                break;
10,174✔
1867
                                        default:
1868
                                                this._builder.Notify($"Unknown code for extended data: {this._reader.DxfCode}", NotificationType.Warning);
2,304✔
1869
                                                break;
2,304✔
1870
                                }
1871

1872
                                if (record != null)
260,125✔
1873
                                {
257,807✔
1874
                                        records.Add(record);
257,807✔
1875
                                }
257,807✔
1876

1877
                                this._reader.ReadNext();
260,125✔
1878
                        }
260,125✔
1879
                }
36,252✔
1880

1881
                private void readPattern(HatchPattern pattern, int nlines)
1882
                {
1,296✔
1883
                        //Jump 78 code
1884
                        this._reader.ReadNext();
1,296✔
1885

1886
                        for (int i = 0; i < nlines; i++)
196,560✔
1887
                        {
96,984✔
1888
                                HatchPattern.Line line = new HatchPattern.Line();
96,984✔
1889
                                XY basePoint = new XY();
96,984✔
1890
                                XY offset = new XY();
96,984✔
1891

1892
                                bool end = false;
96,984✔
1893
                                HashSet<int> codes = new();
96,984✔
1894

1895
                                while (!end)
680,184✔
1896
                                {
678,888✔
1897
                                        if (codes.Contains(this._reader.Code))
678,888✔
1898
                                        {
95,688✔
1899
                                                break;
95,688✔
1900
                                        }
1901
                                        else
1902
                                        {
583,200✔
1903
                                                codes.Add(this._reader.Code);
583,200✔
1904
                                        }
583,200✔
1905

1906
                                        switch (this._reader.Code)
583,200!
1907
                                        {
1908
                                                case 53:
1909
                                                        line.Angle = this._reader.ValueAsAngle;
96,984✔
1910
                                                        break;
96,984✔
1911
                                                case 43:
1912
                                                        basePoint.X = this._reader.ValueAsDouble;
96,984✔
1913
                                                        break;
96,984✔
1914
                                                case 44:
1915
                                                        basePoint.Y = this._reader.ValueAsDouble;
96,984✔
1916
                                                        line.BasePoint = basePoint;
96,984✔
1917
                                                        break;
96,984✔
1918
                                                case 45:
1919
                                                        offset.X = this._reader.ValueAsDouble;
96,984✔
1920
                                                        line.Offset = offset;
96,984✔
1921
                                                        break;
96,984✔
1922
                                                case 46:
1923
                                                        offset.Y = this._reader.ValueAsDouble;
96,984✔
1924
                                                        line.Offset = offset;
96,984✔
1925
                                                        break;
96,984✔
1926
                                                //Number of dash length items
1927
                                                case 79:
1928
                                                        int ndash = this._reader.ValueAsInt;
96,984✔
1929
                                                        for (int j = 0; j < ndash; j++)
581,040✔
1930
                                                        {
193,536✔
1931
                                                                this._reader.ReadNext();
193,536✔
1932
                                                                line.DashLengths.Add(this._reader.ValueAsDouble);
193,536✔
1933
                                                        }
193,536✔
1934
                                                        break;
96,984✔
1935
                                                case 49:
1936
                                                        line.DashLengths.Add(this._reader.ValueAsDouble);
×
1937
                                                        break;
×
1938
                                                default:
1939
                                                        end = true;
1,296✔
1940
                                                        break;
1,296✔
1941
                                        }
1942
                                        this._reader.ReadNext();
583,200✔
1943
                                }
583,200✔
1944

1945
                                pattern.Lines.Add(line);
96,984✔
1946
                        }
96,984✔
1947
                }
1,296✔
1948

1949
                private void readLoops(CadHatchTemplate template, int count)
1950
                {
1,728✔
1951
                        if (this._reader.Code == 91)
1,728✔
1952
                                this._reader.ReadNext();
1,728✔
1953

1954
                        for (int i = 0; i < count; i++)
6,912✔
1955
                        {
1,728✔
1956
                                if (this._reader.Code != 92)
1,728!
1957
                                {
×
1958
                                        this._builder.Notify($"Boundary path should start with code 92 but was {this._reader.Code}");
×
1959
                                        break;
×
1960
                                }
1961

1962
                                CadHatchTemplate.CadBoundaryPathTemplate path = this.readLoop();
1,728✔
1963
                                if (path != null)
1,728✔
1964
                                        template.PathTemplates.Add(path);
1,728✔
1965
                        }
1,728✔
1966
                }
1,728✔
1967

1968
                private CadHatchTemplate.CadBoundaryPathTemplate readLoop()
1969
                {
1,728✔
1970
                        CadHatchTemplate.CadBoundaryPathTemplate template = new CadHatchTemplate.CadBoundaryPathTemplate();
1,728✔
1971
                        var flags = (BoundaryPathFlags)this._reader.ValueAsInt;
1,728✔
1972
                        template.Path.Flags = flags;
1,728✔
1973

1974
                        if (flags.HasFlag(BoundaryPathFlags.Polyline))
1,728✔
1975
                        {
648✔
1976
                                Hatch.BoundaryPath.Polyline pl = this.readPolylineBoundary();
648✔
1977
                                template.Path.Edges.Add(pl);
648✔
1978
                        }
648✔
1979
                        else
1980
                        {
1,080✔
1981
                                this._reader.ReadNext();
1,080✔
1982

1983
                                if (this._reader.Code != 93)
1,080!
1984
                                {
×
1985
                                        this._builder.Notify($"Edge Boundary path should start with code 93 but was {this._reader.Code}");
×
1986
                                        return null;
×
1987
                                }
1988

1989
                                int edges = this._reader.ValueAsInt;
1,080✔
1990
                                this._reader.ReadNext();
1,080✔
1991

1992
                                for (int i = 0; i < edges; i++)
10,800✔
1993
                                {
4,320✔
1994
                                        var edge = this.readEdge();
4,320✔
1995
                                        if (edge != null)
4,320✔
1996
                                                template.Path.Edges.Add(edge);
4,320✔
1997
                                }
4,320✔
1998
                        }
1,080✔
1999

2000
                        bool end = false;
1,728✔
2001
                        while (!end)
6,696✔
2002
                        {
4,968✔
2003
                                switch (this._reader.Code)
4,968✔
2004
                                {
2005
                                        //Number of source boundary objects
2006
                                        case 97:
2007
                                                break;
1,728✔
2008
                                        case 330:
2009
                                                template.Handles.Add(this._reader.ValueAsHandle);
1,512✔
2010
                                                break;
1,512✔
2011
                                        default:
2012
                                                end = true;
1,728✔
2013
                                                continue;
1,728✔
2014
                                }
2015

2016
                                this._reader.ReadNext();
3,240✔
2017
                        }
3,240✔
2018

2019
                        return template;
1,728✔
2020
                }
1,728✔
2021

2022
                private Hatch.BoundaryPath.Polyline readPolylineBoundary()
2023
                {
648✔
2024
                        Hatch.BoundaryPath.Polyline boundary = new Hatch.BoundaryPath.Polyline();
648✔
2025

2026
                        this._reader.ReadNext();
648✔
2027

2028
                        if (this._reader.Code != 72)
648!
2029
                        {
×
2030
                                this._builder.Notify($"Polyline Boundary path should start with code 72 but was {this._reader.Code}");
×
2031
                                return null;
×
2032
                        }
2033

2034
                        bool end = false;
648✔
2035
                        bool hasBulge = false;
648✔
2036
                        while (!end)
3,240✔
2037
                        {
2,592✔
2038
                                switch (this._reader.Code)
2,592✔
2039
                                {
2040
                                        case 72:
2041
                                                hasBulge = this._reader.ValueAsBool;
648✔
2042
                                                break;
648✔
2043
                                        case 73:
2044
                                                boundary.IsClosed = this._reader.ValueAsBool;
648✔
2045
                                                break;
648✔
2046
                                        case 93:
2047
                                                int nvertices = this._reader.ValueAsInt;
648✔
2048
                                                this._reader.ReadNext();
648✔
2049

2050
                                                for (int i = 0; i < nvertices; i++)
6,480✔
2051
                                                {
2,592✔
2052
                                                        double bulge = 0.0;
2,592✔
2053

2054
                                                        //10
2055
                                                        double x = this._reader.ValueAsDouble;
2,592✔
2056
                                                        this._reader.ReadNext();
2,592✔
2057
                                                        //20
2058
                                                        double y = this._reader.ValueAsDouble;
2,592✔
2059
                                                        this._reader.ReadNext();
2,592✔
2060

2061
                                                        if (hasBulge)
2,592!
2062
                                                        {
×
2063
                                                                //42
2064
                                                                bulge = this._reader.ValueAsDouble;
×
2065
                                                                this._reader.ReadNext();
×
2066
                                                        }
×
2067

2068
                                                        boundary.Vertices.Add(new XYZ(x, y, bulge));
2,592✔
2069
                                                }
2,592✔
2070
                                                continue;
648✔
2071
                                        default:
2072
                                                end = true;
648✔
2073
                                                continue;
648✔
2074
                                }
2075

2076
                                this._reader.ReadNext();
1,296✔
2077
                        }
1,296✔
2078

2079
                        return boundary;
648✔
2080
                }
648✔
2081

2082
                private Hatch.BoundaryPath.Edge readEdge()
2083
                {
4,320✔
2084
                        if (this._reader.Code != 72)
4,320!
2085
                        {
×
2086
                                this._builder.Notify($"Edge Boundary path should define the type with code 72 but was {this._reader.Code}");
×
2087
                                return null;
×
2088
                        }
2089

2090
                        Hatch.BoundaryPath.EdgeType type = (Hatch.BoundaryPath.EdgeType)this._reader.ValueAsInt;
4,320✔
2091
                        this._reader.ReadNext();
4,320✔
2092

2093
                        switch (type)
4,320!
2094
                        {
2095
                                case Hatch.BoundaryPath.EdgeType.Line:
2096
                                        Hatch.BoundaryPath.Line line = new Hatch.BoundaryPath.Line();
4,320✔
2097
                                        while (true)
21,600✔
2098
                                        {
21,600✔
2099
                                                switch (this._reader.Code)
21,600✔
2100
                                                {
2101
                                                        case 10:
2102
                                                                line.Start = new XY(this._reader.ValueAsDouble, line.Start.Y);
4,320✔
2103
                                                                break;
4,320✔
2104
                                                        case 20:
2105
                                                                line.Start = new XY(line.Start.X, this._reader.ValueAsDouble);
4,320✔
2106
                                                                break;
4,320✔
2107
                                                        case 11:
2108
                                                                line.End = new XY(this._reader.ValueAsDouble, line.End.Y);
4,320✔
2109
                                                                break;
4,320✔
2110
                                                        case 21:
2111
                                                                line.End = new XY(line.End.X, this._reader.ValueAsDouble);
4,320✔
2112
                                                                break;
4,320✔
2113
                                                        default:
2114
                                                                return line;
4,320✔
2115
                                                }
2116

2117
                                                this._reader.ReadNext();
17,280✔
2118
                                        }
17,280✔
2119
                                case Hatch.BoundaryPath.EdgeType.CircularArc:
2120
                                        Hatch.BoundaryPath.Arc arc = new Hatch.BoundaryPath.Arc();
×
2121
                                        while (true)
×
2122
                                        {
×
2123
                                                switch (this._reader.Code)
×
2124
                                                {
2125
                                                        case 10:
2126
                                                                arc.Center = new XY(this._reader.ValueAsDouble, arc.Center.Y);
×
2127
                                                                break;
×
2128
                                                        case 20:
2129
                                                                arc.Center = new XY(arc.Center.X, this._reader.ValueAsDouble);
×
2130
                                                                break;
×
2131
                                                        case 40:
2132
                                                                arc.Radius = this._reader.ValueAsDouble;
×
2133
                                                                break;
×
2134
                                                        case 50:
2135
                                                                arc.StartAngle = MathHelper.DegToRad(this._reader.ValueAsDouble);
×
2136
                                                                break;
×
2137
                                                        case 51:
2138
                                                                arc.EndAngle = MathHelper.DegToRad(this._reader.ValueAsDouble);
×
2139
                                                                break;
×
2140
                                                        case 73:
2141
                                                                arc.CounterClockWise = this._reader.ValueAsBool;
×
2142
                                                                break;
×
2143
                                                        default:
2144
                                                                return arc;
×
2145
                                                }
2146

2147
                                                this._reader.ReadNext();
×
2148
                                        }
×
2149
                                case Hatch.BoundaryPath.EdgeType.EllipticArc:
2150
                                        Hatch.BoundaryPath.Ellipse ellipse = new Hatch.BoundaryPath.Ellipse();
×
2151
                                        while (true)
×
2152
                                        {
×
2153
                                                switch (this._reader.Code)
×
2154
                                                {
2155
                                                        case 10:
2156
                                                                ellipse.Center = new XY(this._reader.ValueAsDouble, ellipse.Center.Y);
×
2157
                                                                break;
×
2158
                                                        case 20:
2159
                                                                ellipse.Center = new XY(ellipse.Center.X, this._reader.ValueAsDouble);
×
2160
                                                                break;
×
2161
                                                        case 11:
2162
                                                                ellipse.MajorAxisEndPoint = new XY(this._reader.ValueAsDouble, ellipse.Center.Y);
×
2163
                                                                break;
×
2164
                                                        case 21:
2165
                                                                ellipse.MajorAxisEndPoint = new XY(ellipse.Center.X, this._reader.ValueAsDouble);
×
2166
                                                                break;
×
2167
                                                        case 40:
2168
                                                                ellipse.RadiusRatio = this._reader.ValueAsDouble;
×
2169
                                                                break;
×
2170
                                                        case 50:
2171
                                                                ellipse.StartAngle = MathHelper.DegToRad(this._reader.ValueAsDouble);
×
2172
                                                                break;
×
2173
                                                        case 51:
2174
                                                                ellipse.EndAngle = MathHelper.DegToRad(this._reader.ValueAsDouble);
×
2175
                                                                break;
×
2176
                                                        case 73:
2177
                                                                ellipse.CounterClockWise = this._reader.ValueAsBool;
×
2178
                                                                break;
×
2179
                                                        default:
2180
                                                                return ellipse;
×
2181
                                                }
2182

2183
                                                this._reader.ReadNext();
×
2184
                                        }
×
2185
                                case Hatch.BoundaryPath.EdgeType.Spline:
2186
                                        Hatch.BoundaryPath.Spline spline = new Hatch.BoundaryPath.Spline();
×
2187
                                        int nKnots = 0;
×
2188
                                        int nCtrlPoints = 0;
×
2189
                                        int nFitPoints = 0;
×
2190

2191
                                        XYZ controlPoint = new XYZ();
×
2192
                                        XY fitPoint = new XY();
×
2193

2194
                                        while (true)
×
2195
                                        {
×
2196
                                                switch (this._reader.Code)
×
2197
                                                {
2198
                                                        case 10:
2199
                                                                controlPoint = new XYZ(this._reader.ValueAsDouble, 0, 1);
×
2200
                                                                break;
×
2201
                                                        case 20:
2202
                                                                controlPoint = new XYZ(controlPoint.X, this._reader.ValueAsDouble, controlPoint.Z);
×
2203
                                                                spline.ControlPoints.Add(controlPoint);
×
2204
                                                                break;
×
2205
                                                        case 11:
2206
                                                                fitPoint = new XY(this._reader.ValueAsDouble, 0);
×
2207
                                                                break;
×
2208
                                                        case 21:
2209
                                                                fitPoint = new XY(fitPoint.X, this._reader.ValueAsDouble);
×
2210
                                                                spline.FitPoints.Add(fitPoint);
×
2211
                                                                break;
×
2212
                                                        case 42:
2213
                                                                var last = spline.ControlPoints[spline.ControlPoints.Count - 1];
×
2214
                                                                spline.ControlPoints[spline.ControlPoints.Count - 1] = new XYZ(last.X, last.Y, this._reader.ValueAsDouble);
×
2215
                                                                break;
×
2216
                                                        case 12:
2217
                                                                spline.StartTangent = new XY(this._reader.ValueAsDouble, spline.StartTangent.Y);
×
2218
                                                                break;
×
2219
                                                        case 22:
2220
                                                                spline.StartTangent = new XY(spline.StartTangent.X, this._reader.ValueAsDouble);
×
2221
                                                                break;
×
2222
                                                        case 13:
2223
                                                                spline.EndTangent = new XY(this._reader.ValueAsDouble, spline.EndTangent.Y);
×
2224
                                                                break;
×
2225
                                                        case 23:
2226
                                                                spline.EndTangent = new XY(spline.EndTangent.X, this._reader.ValueAsDouble);
×
2227
                                                                break;
×
2228
                                                        case 94:
2229
                                                                spline.Degree = this._reader.ValueAsInt;
×
2230
                                                                break;
×
2231
                                                        case 73:
2232
                                                                spline.IsRational = this._reader.ValueAsBool;
×
2233
                                                                break;
×
2234
                                                        case 74:
2235
                                                                spline.IsPeriodic = this._reader.ValueAsBool;
×
2236
                                                                break;
×
2237
                                                        case 95:
2238
                                                                nKnots = this._reader.ValueAsInt;
×
2239
                                                                break;
×
2240
                                                        case 96:
2241
                                                                nCtrlPoints = this._reader.ValueAsInt;
×
2242
                                                                break;
×
2243
                                                        case 97:
2244
                                                                nFitPoints = this._reader.ValueAsInt;
×
2245
                                                                break;
×
2246
                                                        case 40:
2247
                                                                spline.Knots.Add(this._reader.ValueAsDouble);
×
2248
                                                                break;
×
2249
                                                        default:
2250
                                                                return spline;
×
2251
                                                }
2252

2253
                                                this._reader.ReadNext();
×
2254
                                        }
×
2255
                        }
2256

2257
                        return null;
×
2258
                }
4,320✔
2259

2260
                private void readDefinedGroups(CadTemplate template)
2261
                {
72,392✔
2262
                        this.readDefinedGroups(out ulong? xdict, out HashSet<ulong> reactorsHandles);
72,392✔
2263

2264
                        if (xdict.HasValue)
72,392✔
2265
                        {
10,457✔
2266
                                template.XDictHandle = xdict;
10,457✔
2267
                        }
10,457✔
2268
                        template.ReactorsHandles.UnionWith(reactorsHandles);
72,392✔
2269
                }
72,392✔
2270

2271
                private void readDefinedGroups(out ulong? xdictHandle, out HashSet<ulong> reactors)
2272
                {
72,613✔
2273
                        xdictHandle = null;
72,613✔
2274
                        reactors = new HashSet<ulong>();
72,613✔
2275

2276
                        switch (this._reader.ValueAsString)
72,613✔
2277
                        {
2278
                                case DxfFileToken.DictionaryToken:
2279
                                        this._reader.ReadNext();
10,678✔
2280
                                        xdictHandle = this._reader.ValueAsHandle;
10,678✔
2281
                                        this._reader.ReadNext();
10,678✔
2282
                                        Debug.Assert(this._reader.DxfCode == DxfCode.ControlString);
10,678✔
2283
                                        return;
10,678✔
2284
                                case DxfFileToken.ReactorsToken:
2285
                                        reactors = this.readReactors();
59,764✔
2286
                                        break;
59,764✔
2287
                                case DxfFileToken.BlkRefToken:
2288
                                default:
2289
                                        do
2290
                                        {
5,638✔
2291
                                                this._reader.ReadNext();
5,638✔
2292
                                        }
5,638✔
2293
                                        while (this._reader.DxfCode != DxfCode.ControlString);
5,638✔
2294
                                        return;
2,171✔
2295
                        }
2296
                }
72,613✔
2297

2298
                private HashSet<ulong> readReactors()
2299
                {
59,764✔
2300
                        HashSet<ulong> reactors = new();
59,764✔
2301

2302
                        this._reader.ReadNext();
59,764✔
2303

2304
                        while (this._reader.DxfCode != DxfCode.ControlString)
126,428✔
2305
                        {
66,664✔
2306
                                reactors.Add(this._reader.ValueAsHandle);
66,664✔
2307

2308
                                this._reader.ReadNext();
66,664✔
2309
                        }
66,664✔
2310

2311
                        return reactors;
59,764✔
2312
                }
59,764✔
2313

2314
                protected bool tryAssignCurrentValue(object cadObject, DxfMap map)
2315
                {
59✔
2316
                        if (string.IsNullOrEmpty(this.currentSubclass))
59✔
2317
                        {
6✔
2318
                                return false;
6✔
2319
                        }
2320

2321
                        if (map.SubClasses.TryGetValue(this.currentSubclass, out var subClass))
53!
2322
                        {
53✔
2323
                                return this.tryAssignCurrentValue(cadObject, subClass);
53✔
2324
                        }
2325
                        else
2326
                        {
×
2327
                                return false;
×
2328
                        }
2329
                }
59✔
2330

2331
                protected bool tryAssignCurrentValue(object cadObject, DxfClassMap map)
2332
                {
4,458,169✔
2333
                        try
2334
                        {
4,458,169✔
2335
                                //Use this method only if the value is not a link between objects
2336
                                if (map.DxfProperties.TryGetValue(this._reader.Code, out DxfProperty dxfProperty))
4,458,169✔
2337
                                {
2,344,626✔
2338
                                        if (dxfProperty.ReferenceType.HasFlag(DxfReferenceType.Count))
2,344,626✔
2339
                                        {
13,723✔
2340
                                                return true;
13,723✔
2341
                                        }
2342

2343
                                        if (dxfProperty.ReferenceType.HasFlag(DxfReferenceType.Handle)
2,330,903✔
2344
                                                || dxfProperty.ReferenceType.HasFlag(DxfReferenceType.Name))
2,330,903✔
2345
                                        {
17,354✔
2346
                                                return false;
17,354✔
2347
                                        }
2348

2349
                                        object value = this._reader.Value;
2,313,549✔
2350

2351
                                        if (dxfProperty.ReferenceType.HasFlag(DxfReferenceType.IsAngle))
2,313,549✔
2352
                                        {
26,314✔
2353
                                                value = MathHelper.DegToRad((double)value);
26,314✔
2354
                                        }
26,314✔
2355

2356
                                        dxfProperty.SetValue(this._reader.Code, cadObject, value);
2,313,549✔
2357

2358
                                        return true;
2,313,549✔
2359
                                }
2360
                        }
2,113,543✔
2361
                        catch (Exception ex)
×
2362
                        {
×
2363
                                if (!this._builder.Configuration.Failsafe)
×
2364
                                {
×
2365
                                        throw ex;
×
2366
                                }
2367
                                else
2368
                                {
×
2369
                                        this._builder.Notify("An error occurred while assigning a property using mapper", NotificationType.Error, ex);
×
2370
                                }
×
2371
                        }
×
2372

2373
                        return false;
2,113,543✔
2374
                }
4,458,169✔
2375
        }
2376
}
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