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

DomCR / ACadSharp / 10540806999

24 Aug 2024 06:59PM UTC coverage: 75.987% (-0.03%) from 76.015%
10540806999

push

github

web-flow
Merge pull request #431 from DomCR/issue-405_multiline-att

Issue-405 Implement Attribute Multiline

4840 of 7031 branches covered (68.84%)

Branch coverage included in aggregate %.

66 of 96 new or added lines in 7 files covered. (68.75%)

20 existing lines in 3 files now uncovered.

19298 of 24735 relevant lines covered (78.02%)

33047.81 hits per line

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

78.87
/src/ACadSharp/IO/DXF/DxfStreamReader/DxfSectionReaderBase.cs
1
using ACadSharp.Entities;
2
using ACadSharp.IO.Templates;
3
using CSMath;
4
using System;
5
using System.Collections.Generic;
6
using System.Diagnostics;
7
using System.Linq;
8

9
namespace ACadSharp.IO.DXF
10
{
11
        internal abstract class DxfSectionReaderBase
12
        {
13
                public delegate bool ReadEntityDelegate<T>(CadEntityTemplate template, DxfMap map, string subclass = null) where T : Entity;
14

15
                protected readonly IDxfStreamReader _reader;
16
                protected readonly DxfDocumentBuilder _builder;
17

18
                public DxfSectionReaderBase(IDxfStreamReader reader, DxfDocumentBuilder builder)
508✔
19
                {
508✔
20
                        this._reader = reader;
508✔
21
                        this._builder = builder;
508✔
22
                }
508✔
23

24
                public abstract void Read();
25

26
                protected void readCommonObjectData(out string name, out ulong handle, out ulong? ownerHandle, out ulong? xdictHandle, out List<ulong> reactors)
27
                {
1,224✔
28
                        name = null;
1,224✔
29
                        handle = 0;
1,224✔
30
                        ownerHandle = null;
1,224✔
31
                        xdictHandle = null;
1,224✔
32
                        reactors = new List<ulong>();
1,224✔
33

34
                        if (this._reader.DxfCode == DxfCode.Start
1,224!
35
                                        || this._reader.DxfCode == DxfCode.Subclass)
1,224✔
36
                                this._reader.ReadNext();
×
37

38
                        //Loop until the common data end
39
                        while (this._reader.DxfCode != DxfCode.Start
4,860✔
40
                                        && this._reader.DxfCode != DxfCode.Subclass)
4,860✔
41
                        {
3,636✔
42
                                switch (this._reader.Code)
3,636!
43
                                {
44
                                        //Table name
45
                                        case 2:
46
                                                name = this._reader.ValueAsString;
1,224✔
47
                                                break;
1,224✔
48
                                        //Handle
49
                                        case 5:
50
                                        case 105:
51
                                                handle = this._reader.ValueAsHandle;
1,080✔
52
                                                break;
1,080✔
53
                                        //Start of application - defined group
54
                                        case 102:
55
                                                this.readDefinedGroups(out xdictHandle, out reactors);
108✔
56
                                                break;
108✔
57
                                        //Soft - pointer ID / handle to owner BLOCK_RECORD object
58
                                        case 330:
59
                                                ownerHandle = this._reader.ValueAsHandle;
1,080✔
60
                                                break;
1,080✔
61
                                        case 71:
62
                                        //Number of entries for dimension style table
63
                                        case 340:
64
                                        //Dimension table has the handles of the styles at the begining
65
                                        default:
66
                                                this._builder.Notify($"Unhandeled dxf code {this._reader.Code} at line {this._reader.Position}.");
144✔
67
                                                break;
144✔
68
                                }
69

70
                                this._reader.ReadNext();
3,636✔
71
                        }
3,636✔
72
                }
1,224✔
73

74
                [Obsolete("Only needed for SortEntitiesTable but it should be removed")]
75
                protected void readCommonObjectData(CadTemplate template)
76
                {
192✔
77
                        while (this._reader.DxfCode != DxfCode.Subclass)
768✔
78
                        {
576✔
79
                                switch (this._reader.Code)
576!
80
                                {
81
                                        //object name
82
                                        case 0:
83
                                                Debug.Assert(template.CadObject.ObjectName == this._reader.ValueAsString);
×
84
                                                break;
×
85
                                        //Handle
86
                                        case 5:
87
                                                template.CadObject.Handle = this._reader.ValueAsHandle;
192✔
88
                                                break;
192✔
89
                                        //Start of application - defined group
90
                                        case 102:
91
                                                this.readDefinedGroups(template);
192✔
92
                                                break;
192✔
93
                                        //Soft - pointer ID / handle to owner BLOCK_RECORD object
94
                                        case 330:
95
                                                template.OwnerHandle = this._reader.ValueAsHandle;
192✔
96
                                                break;
192✔
97
                                        default:
98
                                                this._builder.Notify($"Unhandeled dxf code {this._reader.Code} at line {this._reader.Position}.", NotificationType.None);
×
99
                                                break;
×
100
                                }
101

102
                                this._reader.ReadNext();
576✔
103
                        }
576✔
104
                }
192✔
105

106
                protected void readCommonCodes(CadTemplate template, out bool isExtendedData, DxfMap map = null)
107
                {
357,648✔
108
                        isExtendedData = false;
357,648✔
109

110
                        switch (this._reader.Code)
357,648✔
111
                        {
112
                                //Handle
113
                                case 5:
114
                                        template.CadObject.Handle = this._reader.ValueAsHandle;
94,642✔
115
                                        break;
94,642✔
116
                                //Check with mapper
117
                                case 100:
118
                                        if (map != null && !map.SubClasses.ContainsKey(this._reader.ValueAsString))
66,328!
119
                                                this._builder.Notify($"[{template.CadObject.ObjectName}] Unidentified subclass {this._reader.ValueAsString}", NotificationType.Warning);
60✔
120
                                        break;
66,328✔
121
                                //Start of application - defined group
122
                                case 102:
123
                                        this.readDefinedGroups(template);
22,062✔
124
                                        break;
22,062✔
125
                                //Soft - pointer ID / handle to owner BLOCK_RECORD object
126
                                case 330:
127
                                        template.OwnerHandle = this._reader.ValueAsHandle;
52,130✔
128
                                        break;
52,130✔
129
                                case 1001:
130
                                        isExtendedData = true;
7,512✔
131
                                        this.readExtendedData(template.EDataTemplateByAppName);
7,512✔
132
                                        break;
7,512✔
133
                                default:
134
                                        this._builder.Notify($"[{template.CadObject.SubclassMarker}] Unhandeled dxf code {this._reader.Code} with value {this._reader.ValueAsString}", NotificationType.None);
114,974✔
135
                                        break;
114,974✔
136
                        }
137
                }
357,648✔
138

139
                protected CadEntityTemplate readEntity()
140
                {
62,880✔
141
                        switch (this._reader.ValueAsString)
62,880!
142
                        {
143
                                case DxfFileToken.EntityAttribute:
144
                                        return this.readEntityCodes<AttributeEntity>(new CadAttributeTemplate(new AttributeEntity()), this.readAttributeDefinition);
504✔
145
                                case DxfFileToken.EntityAttributeDefinition:
146
                                        return this.readEntityCodes<AttributeDefinition>(new CadAttributeTemplate(new AttributeDefinition()), this.readAttributeDefinition);
560✔
147
                                case DxfFileToken.EntityArc:
148
                                        return this.readEntityCodes<Arc>(new CadEntityTemplate<Arc>(), this.readArc);
350✔
149
                                case DxfFileToken.EntityCircle:
150
                                        return this.readEntityCodes<Circle>(new CadEntityTemplate<Circle>(), this.readEntitySubclassMap);
490✔
151
                                case DxfFileToken.EntityDimension:
152
                                        return this.readEntityCodes<Dimension>(new CadDimensionTemplate(), this.readDimension);
1,008✔
153
                                case DxfFileToken.Entity3DFace:
154
                                        return this.readEntityCodes<Face3D>(new CadEntityTemplate<Face3D>(), this.readEntitySubclassMap);
126✔
155
                                case DxfFileToken.EntityEllipse:
156
                                        return this.readEntityCodes<Ellipse>(new CadEntityTemplate<Ellipse>(), this.readEntitySubclassMap);
108✔
157
                                case DxfFileToken.EntityLeader:
158
                                        return this.readEntityCodes<Leader>(new CadLeaderTemplate(), this.readLeader);
108✔
159
                                case DxfFileToken.EntityLine:
160
                                        return this.readEntityCodes<Line>(new CadEntityTemplate<Line>(), this.readEntitySubclassMap);
11,620✔
161
                                case DxfFileToken.EntityLwPolyline:
162
                                        return this.readEntityCodes<LwPolyline>(new CadEntityTemplate<LwPolyline>(), this.readLwPolyline);
1,164✔
163
                                case DxfFileToken.EntityMesh:
164
                                        return this.readEntityCodes<Mesh>(new CadMeshTemplate(), this.readMesh);
216✔
165
                                case DxfFileToken.EntityHatch:
166
                                        return this.readEntityCodes<Hatch>(new CadHatchTemplate(), this.readHatch);
432✔
167
                                case DxfFileToken.EntityInsert:
168
                                        return this.readEntityCodes<Insert>(new CadInsertTemplate(), this.readInsert);
1,116✔
169
                                case DxfFileToken.EntityMText:
170
                                        return this.readEntityCodes<MText>(new CadTextEntityTemplate(new MText()), this.readTextEntity);
2,076✔
171
                                case DxfFileToken.EntityMLine:
172
                                        return this.readEntityCodes<MLine>(new CadMLineTemplate(), this.readMLine);
324✔
173
                                case DxfFileToken.EntityPdfUnderlay:
174
                                        return this.readEntityCodes<PdfUnderlay>(new CadPdfUnderlayTemplate(), this.readUnderlayEntity);
×
175
                                case DxfFileToken.EntityPoint:
176
                                        return this.readEntityCodes<Point>(new CadEntityTemplate<Point>(), this.readEntitySubclassMap);
3,556✔
177
                                case DxfFileToken.EntityPolyline:
178
                                        return this.readPolyline();
4,692✔
179
                                case DxfFileToken.EntityRay:
180
                                        return this.readEntityCodes<Ray>(new CadEntityTemplate<Ray>(), this.readEntitySubclassMap);
108✔
181
                                case DxfFileToken.EndSequence:
182
                                        return this.readEntityCodes<Seqend>(new CadEntityTemplate<Seqend>(), this.readEntitySubclassMap);
4,944✔
183
                                case DxfFileToken.EntitySolid:
184
                                        return this.readEntityCodes<Solid>(new CadEntityTemplate<Solid>(), this.readEntitySubclassMap);
6,206✔
185
                                case DxfFileToken.EntityText:
186
                                        return this.readEntityCodes<TextEntity>(new CadTextEntityTemplate(new TextEntity()), this.readTextEntity);
3,536✔
187
                                case DxfFileToken.EntityTolerance:
188
                                        return this.readEntityCodes<Tolerance>(new CadToleranceTemplate(new Tolerance()), this.readTolerance);
324✔
189
                                case DxfFileToken.EntityVertex:
190
                                        return this.readEntityCodes<Entity>(new CadVertexTemplate(), this.readVertex);
17,812✔
191
                                case DxfFileToken.EntityViewport:
192
                                        return this.readEntityCodes<Viewport>(new CadViewportTemplate(), this.readViewport);
636✔
193
                                case DxfFileToken.EntityShape:
194
                                        return this.readEntityCodes<Shape>(new CadShapeTemplate(new Shape()), this.readShape);
108✔
195
                                case DxfFileToken.EntitySpline:
196
                                        return this.readEntityCodes<Spline>(new CadSplineTemplate(), this.readSpline);
216✔
197
                                case DxfFileToken.EntityXline:
198
                                        return this.readEntityCodes<XLine>(new CadEntityTemplate<XLine>(), this.readEntitySubclassMap);
108✔
199
                                default:
200
                                        DxfMap map = DxfMap.Create<Entity>();
432✔
201
                                        CadUnknownEntityTemplate unknownEntityTemplate = null;
432✔
202
                                        if (this._builder.DocumentToBuild.Classes.TryGetByName(this._reader.ValueAsString, out Classes.DxfClass dxfClass))
432✔
203
                                        {
384✔
204
                                                this._builder.Notify($"Entity not supported read as an UnknownEntity: {this._reader.ValueAsString}", NotificationType.NotImplemented);
384✔
205
                                                unknownEntityTemplate = new CadUnknownEntityTemplate(new UnknownEntity(dxfClass));
384✔
206
                                        }
384✔
207
                                        else
208
                                        {
48✔
209
                                                this._builder.Notify($"Entity not supported: {this._reader.ValueAsString}", NotificationType.NotImplemented);
48✔
210
                                        }
48✔
211

212
                                        this._reader.ReadNext();
432✔
213

214
                                        do
215
                                        {
69,018✔
216
                                                if (unknownEntityTemplate != null && this._builder.KeepUnknownEntities)
69,018✔
217
                                                {
7,642✔
218
                                                        this.readCommonEntityCodes(unknownEntityTemplate, out bool isExtendedData, map);
7,642✔
219
                                                        if (isExtendedData)
7,642✔
220
                                                                continue;
6✔
221
                                                }
7,636✔
222

223
                                                this._reader.ReadNext();
69,012✔
224
                                        }
69,012✔
225
                                        while (this._reader.DxfCode != DxfCode.Start);
69,018✔
226

227
                                        if (this._builder.Configuration.KeepUnknownEntities)
432✔
228
                                        {
48✔
229
                                                return unknownEntityTemplate;
48✔
230
                                        }
231
                                        else
232
                                        {
384✔
233
                                                return null;
384✔
234
                                        }
235
                        }
236
                }
62,880✔
237

238
                protected CadEntityTemplate readEntityCodes<T>(CadEntityTemplate template, ReadEntityDelegate<T> readEntity)
239
                        where T : Entity
240
                {
62,482✔
241
                        this._reader.ReadNext();
62,482✔
242

243
                        DxfMap map = DxfMap.Create<T>();
62,482✔
244

245
                        while (this._reader.DxfCode != DxfCode.Start)
784,148✔
246
                        {
721,666✔
247
                                if (!readEntity(template, map))
721,666✔
248
                                {
326,702✔
249
                                        this.readCommonEntityCodes(template, out bool isExtendedData, map);
326,702✔
250
                                        if (isExtendedData)
326,702✔
251
                                                continue;
2,602✔
252
                                }
324,100✔
253

254
                                if (this._reader.DxfCode != DxfCode.Start)
719,064✔
255
                                        this._reader.ReadNext();
719,030✔
256
                        }
719,064✔
257

258
                        return template;
62,482✔
259
                }
62,482✔
260

261
                protected void readCommonEntityCodes(CadEntityTemplate template, out bool isExtendedData, DxfMap map = null)
262
                {
351,224✔
263
                        isExtendedData = false;
351,224✔
264
                        switch (this._reader.Code)
351,224✔
265
                        {
266
                                case 6:
267
                                        template.LineTypeName = this._reader.ValueAsString;
9,140✔
268
                                        break;
9,140✔
269
                                case 8:
270
                                        template.LayerName = this._reader.ValueAsString;
67,024✔
271
                                        break;
67,024✔
272
                                //Absent or zero indicates entity is in model space. 1 indicates entity is in paper space (optional).
273
                                case 67:
274
                                        break;
608✔
275
                                //Number of bytes Proxy entity graphics data
276
                                case 92:
277
                                case 160:
278
                                //Proxy entity graphics data
279
                                case 310:
280
                                        break;
17,024✔
281
                                case 347:
282
                                        template.MaterialHandle = this._reader.ValueAsHandle;
72✔
283
                                        break;
72✔
284
                                default:
285
                                        if (!this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Entity]))
257,356✔
286
                                        {
229,108✔
287
                                                this.readCommonCodes(template, out isExtendedData, map);
229,108✔
288
                                        }
229,108✔
289
                                        break;
257,356✔
290
                        }
291
                }
351,224✔
292

293
                private bool readArc(CadEntityTemplate template, DxfMap map, string subclass = null)
294
                {
4,576✔
295
                        switch (this._reader.Code)
4,576✔
296
                        {
297
                                default:
298
                                        if (!this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Arc]))
4,576✔
299
                                        {
3,876✔
300
                                                return this.readEntitySubclassMap(template, map, DxfSubclassMarker.Circle);
3,876✔
301
                                        }
302
                                        return true;
700✔
303
                        }
304
                }
4,576✔
305

306
                private bool readAttributeDefinition(CadEntityTemplate template, DxfMap map, string subclass = null)
307
                {
17,150✔
308
                        DxfClassMap emap = map.SubClasses[template.CadObject.SubclassMarker];
17,150✔
309
                        CadAttributeTemplate tmp = template as CadAttributeTemplate;
17,150✔
310

311
                        switch (this._reader.Code)
17,150!
312
                        {
313
                                case 44:
314
                                case 46:
NEW
315
                                        return true;
×
316
                                case 101:
317
                                        var att = tmp.CadObject as AttributeBase;
34✔
318
                                        att.MText = new MText();
34✔
319
                                        CadTextEntityTemplate mtextTemplate = new CadTextEntityTemplate(att.MText);
34✔
320
                                        tmp.MTextTemplate = mtextTemplate;
34✔
321
                                        this.readEntityCodes<MText>(mtextTemplate, this.readTextEntity);
34✔
322
                                        return true;
34✔
323
                                default:
324
                                        if (!this.tryAssignCurrentValue(template.CadObject, emap))
17,116✔
325
                                        {
12,962✔
326
                                                return this.readTextEntity(template, map, DxfSubclassMarker.Text);
12,962✔
327
                                        }
328
                                        return true;
4,154✔
329
                        }
330
                }
17,150✔
331

332
                private bool readTextEntity(CadEntityTemplate template, DxfMap map, string subclass = null)
333
                {
84,134✔
334
                        string mapName = string.IsNullOrEmpty(subclass) ? template.CadObject.SubclassMarker : subclass;
84,134✔
335
                        CadTextEntityTemplate tmp = template as CadTextEntityTemplate;
84,134✔
336

337
                        switch (this._reader.Code)
84,134✔
338
                        {
339
                                //TODO: Implement multiline text def codes
340
                                case 1 or 3 when tmp.CadObject is MText mtext:
8,114✔
341
                                        mtext.Value += this._reader.ValueAsString;
3,514✔
342
                                        return true;
3,514✔
343
                                case 70:
344
                                case 74:
345
                                case 101:
346
                                        return true;
216✔
347
                                case 7:
348
                                        tmp.StyleName = this._reader.ValueAsString;
504✔
349
                                        return true;
504✔
350
                                default:
351
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[mapName]);
79,900✔
352
                        }
353
                }
84,134✔
354

355
                private bool readTolerance(CadEntityTemplate template, DxfMap map, string subclass = null)
356
                {
3,240✔
357
                        CadToleranceTemplate tmp = template as CadToleranceTemplate;
3,240✔
358

359
                        switch (this._reader.Code)
3,240✔
360
                        {
361
                                case 3:
362
                                        tmp.DimensionStyleName = this._reader.ValueAsString;
324✔
363
                                        return true;
324✔
364
                                default:
365
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[template.CadObject.SubclassMarker]);
2,916✔
366
                        }
367
                }
3,240✔
368

369
                private bool readDimension(CadEntityTemplate template, DxfMap map, string subclass = null)
370
                {
26,046✔
371
                        CadDimensionTemplate tmp = template as CadDimensionTemplate;
26,046✔
372

373
                        switch (this._reader.Code)
26,046✔
374
                        {
375
                                case 2:
376
                                        tmp.BlockName = this._reader.ValueAsString;
1,008✔
377
                                        return true;
1,008✔
378
                                case 3:
379
                                        tmp.StyleName = this._reader.ValueAsString;
864✔
380
                                        return true;
864✔
381
                                case 50:
382
                                        var dim = new DimensionLinear();
126✔
383
                                        tmp.SetDimensionObject(dim);
126✔
384
                                        dim.Rotation = CSMath.MathUtils.DegToRad(this._reader.ValueAsDouble);
126✔
385
                                        map.SubClasses.Add(DxfSubclassMarker.LinearDimension, DxfClassMap.Create<DimensionLinear>());
126✔
386
                                        return true;
126✔
387
                                case 70:
388
                                        //Flags do not have set
389
                                        tmp.SetDimensionFlags((DimensionType)this._reader.ValueAsShort);
1,008✔
390
                                        return true;
1,008✔
391
                                //Measurement - read only
392
                                case 42:
393
                                        return true;
864✔
394
                                //Undocumented codes
395
                                case 73:
396
                                case 74:
397
                                case 75:
398
                                case 90:
399
                                case 361:
400
                                        return true;
1,728✔
401
                                case 100:
402
                                        switch (this._reader.ValueAsString)
2,700✔
403
                                        {
404
                                                case DxfSubclassMarker.Dimension:
405
                                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Dimension]);
864✔
406
                                                case DxfSubclassMarker.AlignedDimension:
407
                                                        tmp.SetDimensionObject(new DimensionAligned());
216✔
408
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionAligned>());
216✔
409
                                                        return true;
216✔
410
                                                case DxfSubclassMarker.DiametricDimension:
411
                                                        tmp.SetDimensionObject(new DimensionDiameter());
108✔
412
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionDiameter>());
108✔
413
                                                        return true;
108✔
414
                                                case DxfSubclassMarker.Angular2LineDimension:
415
                                                        tmp.SetDimensionObject(new DimensionAngular2Line());
108✔
416
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionAngular2Line>());
108✔
417
                                                        return true;
108✔
418
                                                case DxfSubclassMarker.Angular3PointDimension:
419
                                                        tmp.SetDimensionObject(new DimensionAngular3Pt());
108✔
420
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionAngular3Pt>());
108✔
421
                                                        return true;
108✔
422
                                                case DxfSubclassMarker.RadialDimension:
423
                                                        tmp.SetDimensionObject(new DimensionRadius());
108✔
424
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionRadius>());
108✔
425
                                                        return true;
108✔
426
                                                case DxfSubclassMarker.OrdinateDimension:
427
                                                        tmp.SetDimensionObject(new DimensionOrdinate());
216✔
428
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionOrdinate>());
216✔
429
                                                        return true;
216✔
430
                                                case DxfSubclassMarker.LinearDimension:
431
                                                        return true;
108✔
432
                                                default:
433
                                                        return false;
864✔
434
                                        }
435
                                default:
436
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
17,748✔
437
                        }
438
                }
26,046✔
439

440
                protected bool readHatch(CadEntityTemplate template, DxfMap map, string subclass = null)
441
                {
24,840✔
442
                        CadHatchTemplate tmp = template as CadHatchTemplate;
24,840✔
443
                        Hatch hatch = tmp.CadObject;
24,840✔
444

445
                        bool isFirstSeed = true;
24,840✔
446
                        XY seedPoint = new XY();
24,840✔
447

448
                        switch (this._reader.Code)
24,840!
449
                        {
450
                                case 2:
451
                                        tmp.HatchPatternName = this._reader.ValueAsString;
432✔
452
                                        return true;
432✔
453
                                case 10:
454
                                        seedPoint.X = this._reader.ValueAsDouble;
864✔
455
                                        return true;
864✔
456
                                case 20:
457
                                        if (!isFirstSeed)
864!
458
                                        {
×
459
                                                seedPoint.Y = this._reader.ValueAsDouble;
×
460
                                                hatch.SeedPoints.Add(seedPoint);
×
461
                                        }
×
462
                                        return true;
864✔
463
                                case 30:
464
                                        hatch.Elevation = this._reader.ValueAsDouble;
432✔
465
                                        isFirstSeed = false;
432✔
466
                                        return true;
432✔
467
                                //TODO: Check hatch undocumented codes
468
                                case 43:
469
                                case 44:
470
                                case 45:
471
                                case 46:
472
                                case 49:
473
                                case 53:
474
                                case 79:
475
                                case 90:
476
                                        return true;
12,744✔
477
                                //Information about the hatch pattern
478
                                case 75:
479
                                        return true;
×
480
                                //Number of pattern definition lines
481
                                case 78:
482
                                        return true;
216✔
483
                                //Number of boundary paths (loops)
484
                                case 91:
485
                                        this.readLoops(tmp, this._reader.ValueAsInt);
432✔
486
                                        return true;
432✔
487
                                //Number of seed points
488
                                case 98:
489
                                        return true;
432✔
490
                                case 450:
491
                                        hatch.GradientColor.Enabled = this._reader.ValueAsBool;
180✔
492
                                        return true;
180✔
493
                                case 451:
494
                                        hatch.GradientColor.Reserved = this._reader.ValueAsInt;
180✔
495
                                        return true;
180✔
496
                                case 452:
497
                                        hatch.GradientColor.IsSingleColorGradient = this._reader.ValueAsBool;
180✔
498
                                        return true;
180✔
499
                                case 453:
500
                                        //Number of colors
501
                                        return true;
180✔
502
                                case 460:
503
                                        hatch.GradientColor.Angle = this._reader.ValueAsDouble;
180✔
504
                                        return true;
180✔
505
                                case 461:
506
                                        hatch.GradientColor.Shift = this._reader.ValueAsDouble;
180✔
507
                                        return true;
180✔
508
                                case 462:
509
                                        hatch.GradientColor.ColorTint = this._reader.ValueAsDouble;
180✔
510
                                        return true;
180✔
511
                                case 463:
512
                                        GradientColor gradient = new GradientColor();
360✔
513
                                        gradient.Value = this._reader.ValueAsDouble;
360✔
514
                                        hatch.GradientColor.Colors.Add(gradient);
360✔
515
                                        return true;
360✔
516
                                case 63:
517
                                        GradientColor colorByIndex = hatch.GradientColor.Colors.LastOrDefault();
360✔
518
                                        if (colorByIndex != null)
360✔
519
                                        {
360✔
520
                                                colorByIndex.Color = new Color((short)this._reader.ValueAsUShort);
360✔
521
                                        }
360✔
522
                                        return true;
360✔
523
                                case 421:
524
                                        GradientColor colorByRgb = hatch.GradientColor.Colors.LastOrDefault();
360✔
525
                                        if (colorByRgb != null)
360✔
526
                                        {
360✔
527
                                                //TODO: Hatch assign color by true color
528
                                                //TODO: Is always duplicated by 63, is it needed??
529
                                                //colorByRgb.Color = new Color(this._reader.LastValueAsShort);
530
                                        }
360✔
531
                                        return true;
360✔
532
                                case 470:
533
                                        hatch.GradientColor.Name = this._reader.ValueAsString;
180✔
534
                                        return true;
180✔
535
                                default:
536
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[template.CadObject.SubclassMarker]);
5,904✔
537
                        }
538
                }
24,840✔
539

540
                private bool readInsert(CadEntityTemplate template, DxfMap map, string subclass = null)
541
                {
11,264✔
542
                        CadInsertTemplate tmp = template as CadInsertTemplate;
11,264✔
543

544
                        switch (this._reader.Code)
11,264✔
545
                        {
546
                                case 2:
547
                                        tmp.BlockName = this._reader.ValueAsString;
1,116✔
548
                                        return true;
1,116✔
549
                                case 66:
550
                                        return true;
252✔
551
                                default:
552
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
9,896✔
553
                        }
554
                }
11,264✔
555

556
                private CadEntityTemplate readPolyline()
557
                {
4,692✔
558
                        CadPolyLineTemplate template = null;
4,692✔
559

560
                        if (this._builder.Version == ACadVersion.Unknown)
4,692!
561
                        {
×
562
                                var polyline = new Polyline2D();
×
563
                                template = new CadPolyLineTemplate(polyline);
×
564
                                this.readEntityCodes<Polyline2D>(template, this.readPolyline);
×
565

566
                                while (this._reader.Code == 0 && this._reader.ValueAsString == DxfFileToken.EntityVertex)
×
567
                                {
×
568
                                        Vertex2D v = new Vertex2D();
×
569
                                        CadVertexTemplate vertexTemplate = new CadVertexTemplate(v);
×
570
                                        this.readEntityCodes<Vertex2D>(vertexTemplate, this.readVertex);
×
571

572
                                        if (vertexTemplate.Vertex.Handle == 0)
×
573
                                        {
×
574
                                                template.PolyLine.Vertices.Add(vertexTemplate.Vertex);
×
575
                                        }
×
576
                                        else
577
                                        {
×
578
                                                template.VertexHandles.Add(vertexTemplate.Vertex.Handle);
×
579
                                                this._builder.AddTemplate(vertexTemplate);
×
580
                                        }
×
581
                                }
×
582

583
                                while (this._reader.Code == 0 && this._reader.ValueAsString == DxfFileToken.EndSequence)
×
584
                                {
×
585
                                        var seqend = new Seqend();
×
586
                                        var seqendTemplate = new CadEntityTemplate<Seqend>(seqend);
×
587
                                        this.readEntityCodes<Seqend>(seqendTemplate, this.readEntitySubclassMap);
×
588

589
                                        this._builder.AddTemplate(seqendTemplate);
×
590

591
                                        template.SeqendHandle = seqend.Handle;
×
592
                                }
×
593
                        }
×
594
                        else
595
                        {
4,692✔
596
                                template = new CadPolyLineTemplate();
4,692✔
597
                                this.readEntityCodes<Entity>(template, this.readPolyline);
4,692✔
598
                        }
4,692✔
599

600
                        if (template.CadObject is CadPolyLineTemplate.PolyLinePlaceholder)
4,692✔
601
                        {
4,476✔
602
                                this._builder.Notify($"[{DxfFileToken.EntityPolyline}] Subclass not found, entity discarded", NotificationType.Warning);
4,476✔
603
                                return null;
4,476✔
604
                        }
605

606
                        return template;
216✔
607
                }
4,692✔
608

609
                private bool readPolyline(CadEntityTemplate template, DxfMap map, string subclass = null)
610
                {
33,794✔
611
                        CadPolyLineTemplate tmp = template as CadPolyLineTemplate;
33,794✔
612

613
                        switch (this._reader.Code)
33,794✔
614
                        {
615
                                //DXF: always 0
616
                                //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)
617
                                case 10:
618
                                case 20:
619
                                //Obsolete; formerly an “entities follow flag” (optional; ignore if present)
620
                                case 66:
621
                                //Polygon mesh M vertex count (optional; default = 0)
622
                                case 71:
623
                                //Polygon mesh N vertex count(optional; default = 0)
624
                                case 72:
625
                                //Smooth surface M density(optional; default = 0)
626
                                case 73:
627
                                //Smooth surface N density (optional; default = 0)
628
                                case 74:
629
                                        return true;
14,328✔
630
                                case 100:
631
                                        switch (this._reader.ValueAsString)
432!
632
                                        {
633
                                                case DxfSubclassMarker.Polyline:
634
                                                        tmp.SetPolyLineObject(new Polyline2D());
×
635
                                                        map.SubClasses.Add(DxfSubclassMarker.Polyline, DxfClassMap.Create<Polyline2D>());
×
636
                                                        return true;
×
637
                                                case DxfSubclassMarker.Polyline3d:
638
                                                        tmp.SetPolyLineObject(new Polyline3D());
108✔
639
                                                        map.SubClasses.Add(DxfSubclassMarker.Polyline3d, DxfClassMap.Create<Polyline3D>());
108✔
640
                                                        return true;
108✔
641
                                                case DxfSubclassMarker.PolyfaceMesh:
642
                                                        tmp.SetPolyLineObject(new PolyfaceMesh());
108✔
643
                                                        map.SubClasses.Add(DxfSubclassMarker.PolyfaceMesh, DxfClassMap.Create<PolyfaceMesh>());
108✔
644
                                                        return true;
108✔
645
                                                default:
646
                                                        return false;
216✔
647
                                        }
648
                                default:
649
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
19,034✔
650
                        }
651
                }
33,794✔
652

653
                private bool readLeader(CadEntityTemplate template, DxfMap map, string subclass = null)
654
                {
2,700✔
655
                        CadLeaderTemplate tmp = template as CadLeaderTemplate;
2,700✔
656

657
                        switch (this._reader.Code)
2,700✔
658
                        {
659
                                case 3:
660
                                        tmp.DIMSTYLEName = this._reader.ValueAsString;
108✔
661
                                        return true;
108✔
662
                                case 10:
663
                                        tmp.CadObject.Vertices.Add(new XYZ(this._reader.ValueAsDouble, 0, 0));
432✔
664
                                        return true;
432✔
665
                                case 20:
666
                                        XYZ y = tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1];
432✔
667
                                        y.Y = this._reader.ValueAsDouble;
432✔
668
                                        tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1] = y;
432✔
669
                                        return true;
432✔
670
                                case 30:
671
                                        XYZ z = tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1];
432✔
672
                                        z.Z = this._reader.ValueAsDouble;
432✔
673
                                        tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1] = z;
432✔
674
                                        return true;
432✔
675
                                case 340:
676
                                        tmp.AnnotationHandle = this._reader.ValueAsHandle;
108✔
677
                                        return true;
108✔
678
                                //Vertices count
679
                                case 76:
680
                                        return true;
108✔
681
                                default:
682
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
1,080✔
683
                        }
684
                }
2,700✔
685

686
                private bool readLwPolyline(CadEntityTemplate template, DxfMap map, string subclass = null)
687
                {
24,768✔
688
                        CadEntityTemplate<LwPolyline> tmp = template as CadEntityTemplate<LwPolyline>;
24,768✔
689

690
                        LwPolyline.Vertex last = tmp.CadObject.Vertices.LastOrDefault();
24,768✔
691

692
                        switch (this._reader.Code)
24,768!
693
                        {
694
                                case 10:
695
                                        tmp.CadObject.Vertices.Add(new LwPolyline.Vertex(new XY(this._reader.ValueAsDouble, 0)));
5,724✔
696
                                        return true;
5,724✔
697
                                case 20:
698
                                        if (last is not null)
5,724✔
699
                                        {
5,724✔
700
                                                last.Location = new XY(last.Location.X, this._reader.ValueAsDouble);
5,724✔
701
                                        }
5,724✔
702
                                        return true;
5,724✔
703
                                case 40:
704
                                        if (last is not null)
1,080✔
705
                                        {
1,080✔
706
                                                last.StartWidth = this._reader.ValueAsDouble;
1,080✔
707
                                        }
1,080✔
708
                                        return true;
1,080✔
709
                                case 41:
710
                                        if (last is not null)
1,080✔
711
                                        {
1,080✔
712
                                                last.EndWidth = this._reader.ValueAsDouble;
1,080✔
713
                                        }
1,080✔
714
                                        return true;
1,080✔
715
                                case 42:
716
                                        if (last is not null)
1,440✔
717
                                        {
1,440✔
718
                                                last.Bulge = this._reader.ValueAsDouble;
1,440✔
719
                                        }
1,440✔
720
                                        return true;
1,440✔
721
                                case 50:
722
                                        if (last is not null)
×
723
                                        {
×
724
                                                last.CurveTangent = this._reader.ValueAsDouble;
×
725
                                        }
×
726
                                        return true;
×
727
                                //Obsolete; formerly an “entities follow flag” (optional; ignore if present)
728
                                case 66:
729
                                //Vertex count
730
                                case 90:
731
                                        return true;
1,164✔
732
                                case 91:
733
                                        if (last is not null)
×
734
                                        {
×
735
                                                last.Id = this._reader.ValueAsInt;
×
736
                                        }
×
737
                                        return true;
×
738
                                default:
739
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
8,556✔
740
                        }
741
                }
24,768✔
742

743
                private bool readMesh(CadEntityTemplate template, DxfMap map, string subclass = null)
744
                {
19,008✔
745
                        CadMeshTemplate tmp = template as CadMeshTemplate;
19,008✔
746

747
                        switch (this._reader.Code)
19,008✔
748
                        {
749
                                case 100:
750
                                        if (this._reader.ValueAsString.Equals(DxfSubclassMarker.Mesh, StringComparison.OrdinalIgnoreCase))
432✔
751
                                        {
216✔
752
                                                tmp.SubclassMarker = true;
216✔
753
                                        }
216✔
754
                                        return true;
432✔
755
                                //Count of sub-entity which property has been overridden
756
                                case 90:
757
                                        //TODO: process further entities
758
                                        return true;
216✔
759
                                case 92:
760
                                        if (!tmp.SubclassMarker)
324✔
761
                                        {
108✔
762
                                                return false;
108✔
763
                                        }
764

765
                                        int nvertices = this._reader.ValueAsInt;
216✔
766
                                        for (int i = 0; i < nvertices; i++)
27,648✔
767
                                        {
13,608✔
768
                                                this._reader.ReadNext();
13,608✔
769
                                                double x = this._reader.ValueAsDouble;
13,608✔
770
                                                this._reader.ReadNext();
13,608✔
771
                                                double y = this._reader.ValueAsDouble;
13,608✔
772
                                                this._reader.ReadNext();
13,608✔
773
                                                double z = this._reader.ValueAsDouble;
13,608✔
774
                                                tmp.CadObject.Vertices.Add(new XYZ(x, y, z));
13,608✔
775
                                        }
13,608✔
776
                                        return true;
216✔
777
                                case 93:
778
                                        int size = this._reader.ValueAsInt;
216✔
779
                                        this._reader.ReadNext();
216✔
780

781
                                        int indexes = 0;
216✔
782
                                        for (int i = 0; i < size; i += indexes + 1)
29,808✔
783
                                        {
14,688✔
784
                                                indexes = this._reader.ValueAsInt;
14,688✔
785
                                                this._reader.ReadNext();
14,688✔
786

787
                                                int[] face = new int[indexes];
14,688✔
788
                                                for (int j = 0; j < indexes; j++)
141,696✔
789
                                                {
56,160✔
790
                                                        face[j] = this._reader.ValueAsInt;
56,160✔
791

792
                                                        if ((i + j + 2) < size)
56,160✔
793
                                                        {
55,944✔
794
                                                                this._reader.ReadNext();
55,944✔
795
                                                        }
55,944✔
796
                                                }
56,160✔
797

798
                                                tmp.CadObject.Faces.Add(face);
14,688✔
799
                                        }
14,688✔
800

801
                                        Debug.Assert(this._reader.Code == 90);
216✔
802

803
                                        return true;
216✔
804
                                case 94:
805
                                        int numEdges = this._reader.ValueAsInt;
216✔
806
                                        this._reader.ReadNext();
216✔
807
                                        for (int i = 0; i < numEdges; i++)
56,592✔
808
                                        {
28,080✔
809
                                                Mesh.Edge edge = new Mesh.Edge();
28,080✔
810

811
                                                edge.Start = this._reader.ValueAsInt;
28,080✔
812
                                                this._reader.ReadNext();
28,080✔
813
                                                edge.End = this._reader.ValueAsInt;
28,080✔
814

815
                                                if (i < numEdges - 1)
28,080✔
816
                                                {
27,864✔
817
                                                        this._reader.ReadNext();
27,864✔
818
                                                }
27,864✔
819

820
                                                tmp.CadObject.Edges.Add(edge);
28,080✔
821
                                        }
28,080✔
822

823
                                        Debug.Assert(this._reader.Code == 90);
216✔
824

825
                                        return true;
216✔
826
                                case 95:
827
                                        this._reader.ReadNext();
216✔
828
                                        for (int i = 0; i < tmp.CadObject.Edges.Count; i++)
56,592✔
829
                                        {
28,080✔
830
                                                Mesh.Edge edge = tmp.CadObject.Edges[i];
28,080✔
831
                                                edge.Crease = this._reader.ValueAsDouble;
28,080✔
832

833
                                                tmp.CadObject.Edges[i] = edge;
28,080✔
834

835
                                                if (i < tmp.CadObject.Edges.Count - 1)
28,080✔
836
                                                {
27,864✔
837
                                                        this._reader.ReadNext();
27,864✔
838
                                                }
27,864✔
839
                                        }
28,080✔
840

841
                                        Debug.Assert(this._reader.Code == 140);
216✔
842

843
                                        return true;
216✔
844
                                default:
845
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
17,388✔
846
                        }
847
                }
19,008✔
848

849
                private bool readMLine(CadEntityTemplate template, DxfMap map, string subclass = null)
850
                {
28,080✔
851
                        CadMLineTemplate tmp = template as CadMLineTemplate;
28,080✔
852

853
                        switch (this._reader.Code)
28,080✔
854
                        {
855
                                // 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.
856
                                // Do not modify this field without also updating the associated entry in the MLINESTYLE dictionary
857
                                case 2:
858
                                        tmp.MLineStyleName = this._reader.ValueAsString;
324✔
859
                                        return true;
324✔
860
                                case 72:
861
                                        tmp.NVertex = this._reader.ValueAsInt;
324✔
862
                                        return true;
324✔
863
                                case 73:
864
                                        tmp.NElements = this._reader.ValueAsInt;
324✔
865
                                        return true;
324✔
866
                                case 340:
867
                                        tmp.MLineStyleHandle = this._reader.ValueAsHandle;
324✔
868
                                        return true;
324✔
869
                                default:
870
                                        if (!tmp.TryReadVertex(this._reader.Code, this._reader.Value))
26,784✔
871
                                        {
4,536✔
872
                                                return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
4,536✔
873
                                        }
874
                                        return true;
22,248✔
875
                        }
876
                }
28,080✔
877

878
                private bool readShape(CadEntityTemplate template, DxfMap map, string subclass = null)
879
                {
1,080✔
880
                        CadShapeTemplate tmp = template as CadShapeTemplate;
1,080✔
881

882
                        switch (this._reader.Code)
1,080✔
883
                        {
884
                                case 2:
885
                                        tmp.ShapeFileName = this._reader.ValueAsString;
108✔
886
                                        return true;
108✔
887
                                default:
888
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
972✔
889
                        }
890
                }
1,080✔
891

892
                private bool readSpline(CadEntityTemplate template, DxfMap map, string subclass = null)
893
                {
7,560✔
894
                        CadSplineTemplate tmp = template as CadSplineTemplate;
7,560✔
895

896
                        XYZ controlPoint;
897

898
                        switch (this._reader.Code)
7,560!
899
                        {
900
                                case 10:
901
                                        controlPoint = new CSMath.XYZ(this._reader.ValueAsDouble, 0, 0);
864✔
902
                                        tmp.CadObject.ControlPoints.Add(controlPoint);
864✔
903
                                        return true;
864✔
904
                                case 20:
905
                                        controlPoint = tmp.CadObject.ControlPoints.LastOrDefault();
864✔
906
                                        controlPoint.Y = this._reader.ValueAsDouble;
864✔
907
                                        tmp.CadObject.ControlPoints[tmp.CadObject.ControlPoints.Count - 1] = controlPoint;
864✔
908
                                        return true;
864✔
909
                                case 30:
910
                                        controlPoint = tmp.CadObject.ControlPoints.LastOrDefault();
864✔
911
                                        controlPoint.Z = this._reader.ValueAsDouble;
864✔
912
                                        tmp.CadObject.ControlPoints[tmp.CadObject.ControlPoints.Count - 1] = controlPoint;
864✔
913
                                        return true;
864✔
914
                                case 40:
915
                                        tmp.CadObject.Knots.Add(this._reader.ValueAsDouble);
1,728✔
916
                                        return true;
1,728✔
917
                                case 41:
918
                                        tmp.CadObject.Weights.Add(this._reader.ValueAsDouble);
×
919
                                        return true;
×
920
                                case 72:
921
                                case 73:
922
                                case 74:
923
                                        return true;
648✔
924
                                default:
925
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
2,592✔
926
                        }
927
                }
7,560✔
928

929
                private bool readUnderlayEntity(CadEntityTemplate template, DxfMap map, string subclass = null)
930
                {
×
931
                        CadPdfUnderlayTemplate tmp = template as CadPdfUnderlayTemplate;
×
932

933
                        switch (this._reader.Code)
×
934
                        {
935
                                case 340:
936
                                        tmp.DefinitionHandle = this._reader.ValueAsHandle;
×
937
                                        return true;
×
938
                                default:
939
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
×
940
                        }
941
                }
×
942

943
                private bool readVertex(CadEntityTemplate template, DxfMap map, string subclass = null)
944
                {
112,188✔
945
                        CadVertexTemplate tmp = template as CadVertexTemplate;
112,188✔
946

947
                        switch (this._reader.Code)
112,188✔
948
                        {
949
                                //Polyface mesh vertex index
950
                                case 71:
951
                                case 72:
952
                                case 73:
953
                                case 74:
954
                                        return true;
882✔
955
                                case 100:
956
                                        switch (this._reader.ValueAsString)
3,672!
957
                                        {
958
                                                case DxfSubclassMarker.Vertex:
959
                                                        return true;
1,080✔
960
                                                case DxfSubclassMarker.PolylineVertex:
961
                                                        tmp.SetVertexObject(new Vertex2D());
×
962
                                                        map.SubClasses.Add(DxfSubclassMarker.PolylineVertex, DxfClassMap.Create<Vertex2D>());
×
963
                                                        return true;
×
964
                                                case DxfSubclassMarker.Polyline3dVertex:
965
                                                        tmp.SetVertexObject(new Vertex3D());
540✔
966
                                                        map.SubClasses.Add(DxfSubclassMarker.Polyline3dVertex, DxfClassMap.Create<Vertex3D>());
540✔
967
                                                        return true;
540✔
968
                                                case DxfSubclassMarker.PolyfaceMeshVertex:
969
                                                        tmp.SetVertexObject(new VertexFaceMesh());
540✔
970
                                                        map.SubClasses.Add(DxfSubclassMarker.PolyfaceMeshVertex, DxfClassMap.Create<VertexFaceMesh>());
540✔
971
                                                        return true;
540✔
972
                                                case DxfSubclassMarker.PolyfaceMeshFace:
973
                                                        tmp.SetVertexObject(new VertexFaceRecord());
216✔
974
                                                        map.SubClasses.Add(DxfSubclassMarker.PolyfaceMeshFace, DxfClassMap.Create<VertexFaceRecord>());
216✔
975
                                                        return true;
216✔
976
                                                default:
977
                                                        return false;
1,296✔
978
                                        }
979
                                default:
980
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
107,634✔
981
                        }
982
                }
112,188✔
983

984
                private bool readViewport(CadEntityTemplate template, DxfMap map, string subclass = null)
985
                {
34,696✔
986
                        CadViewportTemplate tmp = template as CadViewportTemplate;
34,696✔
987

988
                        switch (this._reader.Code)
34,696!
989
                        {
990
                                //Undocumented
991
                                case 67:
992
                                case 68:
993
                                        return true;
1,272✔
994
                                case 69:
995
                                        tmp.ViewportId = this._reader.ValueAsShort;
636✔
996
                                        return true;
636✔
997
                                case 331:
998
                                        tmp.FrozenLayerHandles.Add(this._reader.ValueAsHandle);
×
999
                                        return true;
×
1000
                                case 348:
1001
                                        tmp.VisualStyleHandle = this._reader.ValueAsHandle;
400✔
1002
                                        return true;
400✔
1003
                                default:
1004
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Viewport]);
32,388✔
1005
                        }
1006
                }
34,696✔
1007

1008
                private bool readEntitySubclassMap(CadEntityTemplate template, DxfMap map, string subclass = null)
1009
                {
303,380✔
1010
                        string mapName = string.IsNullOrEmpty(subclass) ? template.CadObject.SubclassMarker : subclass;
303,380✔
1011

1012
                        switch (this._reader.Code)
303,380✔
1013
                        {
1014
                                default:
1015
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[mapName]);
303,380✔
1016
                        }
1017
                }
303,380✔
1018

1019
                protected void readExtendedData(Dictionary<string, ExtendedData> edata)
1020
                {
10,959✔
1021
                        ExtendedData extendedData = new ExtendedData();
10,959✔
1022
                        edata.Add(this._reader.ValueAsString, extendedData);
10,959✔
1023

1024
                        this._reader.ReadNext();
10,959✔
1025

1026
                        while (this._reader.DxfCode >= DxfCode.ExtendedDataAsciiString)
53,797✔
1027
                        {
46,186✔
1028
                                if (this._reader.DxfCode == DxfCode.ExtendedDataRegAppName)
46,186✔
1029
                                {
3,348✔
1030
                                        this.readExtendedData(edata);
3,348✔
1031
                                        break;
3,348✔
1032
                                }
1033

1034
                                extendedData.Data.Add(new ExtendedDataRecord(this._reader.DxfCode, this._reader.Value));
42,838✔
1035

1036
                                this._reader.ReadNext();
42,838✔
1037
                        }
42,838✔
1038
                }
10,959✔
1039

1040
                private void readLoops(CadHatchTemplate template, int count)
1041
                {
432✔
1042
                        if (this._reader.Code == 91)
432✔
1043
                                this._reader.ReadNext();
432✔
1044

1045
                        for (int i = 0; i < count; i++)
1,728✔
1046
                        {
432✔
1047
                                if (this._reader.Code != 92)
432!
1048
                                {
×
1049
                                        this._builder.Notify($"Boundary path should start with code 92 but was {this._reader.Code}");
×
1050
                                        break;
×
1051
                                }
1052

1053
                                CadHatchTemplate.CadBoundaryPathTemplate path = this.readLoop();
432✔
1054
                                if (path != null)
432✔
1055
                                        template.PathTempaltes.Add(path);
432✔
1056
                        }
432✔
1057
                }
432✔
1058

1059
                private CadHatchTemplate.CadBoundaryPathTemplate readLoop()
1060
                {
432✔
1061
                        CadHatchTemplate.CadBoundaryPathTemplate template = new CadHatchTemplate.CadBoundaryPathTemplate();
432✔
1062
                        template.Path.Flags = (BoundaryPathFlags)this._reader.ValueAsInt;
432✔
1063

1064
                        if (template.Path.Flags.HasFlag(BoundaryPathFlags.Polyline))
432!
1065
                        {
×
1066
                                Hatch.BoundaryPath.Polyline pl = this.readPolylineBoundary();
×
1067
                                template.Path.Edges.Add(pl);
×
1068
                        }
×
1069
                        else
1070
                        {
432✔
1071
                                this._reader.ReadNext();
432✔
1072

1073
                                if (this._reader.Code != 93)
432!
1074
                                {
×
1075
                                        this._builder.Notify($"Edge Boundary path should start with code 93 but was {this._reader.Code}");
×
1076
                                        return null;
×
1077
                                }
1078

1079
                                int edges = this._reader.ValueAsInt;
432✔
1080
                                this._reader.ReadNext();
432✔
1081

1082
                                for (int i = 0; i < edges; i++)
4,320✔
1083
                                {
1,728✔
1084
                                        var edge = this.readEdge();
1,728✔
1085
                                        if (edge != null)
1,728✔
1086
                                                template.Path.Edges.Add(edge);
1,728✔
1087
                                }
1,728✔
1088
                        }
432✔
1089

1090
                        bool end = false;
432✔
1091
                        while (!end)
1,728✔
1092
                        {
1,296✔
1093
                                switch (this._reader.Code)
1,296✔
1094
                                {
1095
                                        //Number of source boundary objects
1096
                                        case 97:
1097
                                                break;
432✔
1098
                                        case 330:
1099
                                                template.Handles.Add(this._reader.ValueAsHandle);
432✔
1100
                                                break;
432✔
1101
                                        default:
1102
                                                end = true;
432✔
1103
                                                continue;
432✔
1104
                                }
1105

1106
                                this._reader.ReadNext();
864✔
1107
                        }
864✔
1108

1109
                        return template;
432✔
1110
                }
432✔
1111

1112
                private Hatch.BoundaryPath.Polyline readPolylineBoundary()
1113
                {
×
1114
                        Hatch.BoundaryPath.Polyline boundary = new Hatch.BoundaryPath.Polyline();
×
1115

1116
                        this._reader.ReadNext();
×
1117

1118
                        if (this._reader.Code != 72)
×
1119
                        {
×
1120
                                this._builder.Notify($"Polyline Boundary path should start with code 72 but was {this._reader.Code}");
×
1121
                                return null;
×
1122
                        }
1123

1124
                        //72
1125
                        bool hasBulge = this._reader.ValueAsBool;
×
1126
                        this._reader.ReadNext();
×
1127

1128
                        //73
1129
                        bool isClosed = this._reader.ValueAsBool;
×
1130
                        this._reader.ReadNext();
×
1131

1132
                        //93
1133
                        int nvertices = this._reader.ValueAsInt;
×
1134
                        this._reader.ReadNext();
×
1135

1136
                        for (int i = 0; i < nvertices; i++)
×
1137
                        {
×
1138
                                double bulge = 0.0;
×
1139

1140
                                //10
1141
                                double x = this._reader.ValueAsDouble;
×
1142
                                this._reader.ReadNext();
×
1143
                                //20
1144
                                double y = this._reader.ValueAsDouble;
×
1145
                                this._reader.ReadNext();
×
1146

1147
                                if (hasBulge)
×
1148
                                {
×
1149
                                        //42
1150
                                        bulge = this._reader.ValueAsDouble;
×
1151
                                        this._reader.ReadNext();
×
1152
                                }
×
1153

1154
                                boundary.Vertices.Add(new XYZ(x, y, bulge));
×
1155
                        }
×
1156

1157
                        return boundary;
×
1158
                }
×
1159

1160
                private Hatch.BoundaryPath.Edge readEdge()
1161
                {
1,728✔
1162
                        if (this._reader.Code != 72)
1,728!
1163
                        {
×
1164
                                this._builder.Notify($"Edge Boundary path should should define the type with code 72 but was {this._reader.Code}");
×
1165
                                return null;
×
1166
                        }
1167

1168
                        Hatch.BoundaryPath.EdgeType type = (Hatch.BoundaryPath.EdgeType)this._reader.ValueAsInt;
1,728✔
1169
                        this._reader.ReadNext();
1,728✔
1170

1171
                        switch (type)
1,728!
1172
                        {
1173
                                case Hatch.BoundaryPath.EdgeType.Line:
1174
                                        Hatch.BoundaryPath.Line line = new Hatch.BoundaryPath.Line();
1,728✔
1175
                                        while (true)
8,640✔
1176
                                        {
8,640✔
1177
                                                switch (this._reader.Code)
8,640✔
1178
                                                {
1179
                                                        case 10:
1180
                                                                line.Start = new XY(this._reader.ValueAsDouble, line.Start.Y);
1,728✔
1181
                                                                break;
1,728✔
1182
                                                        case 20:
1183
                                                                line.Start = new XY(line.Start.X, this._reader.ValueAsDouble);
1,728✔
1184
                                                                break;
1,728✔
1185
                                                        case 11:
1186
                                                                line.End = new XY(this._reader.ValueAsDouble, line.End.Y);
1,728✔
1187
                                                                break;
1,728✔
1188
                                                        case 21:
1189
                                                                line.End = new XY(line.End.X, this._reader.ValueAsDouble);
1,728✔
1190
                                                                break;
1,728✔
1191
                                                        default:
1192
                                                                return line;
1,728✔
1193
                                                }
1194

1195
                                                this._reader.ReadNext();
6,912✔
1196
                                        }
6,912✔
1197
                                case Hatch.BoundaryPath.EdgeType.CircularArc:
1198
                                        Hatch.BoundaryPath.Arc arc = new Hatch.BoundaryPath.Arc();
×
1199
                                        while (true)
×
1200
                                        {
×
1201
                                                switch (this._reader.Code)
×
1202
                                                {
1203
                                                        case 10:
1204
                                                                arc.Center = new XY(this._reader.ValueAsDouble, arc.Center.Y);
×
1205
                                                                break;
×
1206
                                                        case 20:
1207
                                                                arc.Center = new XY(arc.Center.X, this._reader.ValueAsDouble);
×
1208
                                                                break;
×
1209
                                                        case 40:
1210
                                                                arc.Radius = this._reader.ValueAsDouble;
×
1211
                                                                break;
×
1212
                                                        case 50:
1213
                                                                arc.StartAngle = this._reader.ValueAsDouble;
×
1214
                                                                break;
×
1215
                                                        case 51:
1216
                                                                arc.EndAngle = this._reader.ValueAsDouble;
×
1217
                                                                break;
×
1218
                                                        case 73:
1219
                                                                arc.CounterClockWise = this._reader.ValueAsBool;
×
1220
                                                                break;
×
1221
                                                        default:
1222
                                                                return arc;
×
1223
                                                }
1224

1225
                                                this._reader.ReadNext();
×
1226
                                        }
×
1227
                                case Hatch.BoundaryPath.EdgeType.EllipticArc:
1228
                                        Hatch.BoundaryPath.Ellipse ellipse = new Hatch.BoundaryPath.Ellipse();
×
1229
                                        while (true)
×
1230
                                        {
×
1231
                                                switch (this._reader.Code)
×
1232
                                                {
1233
                                                        case 10:
1234
                                                                ellipse.Center = new XY(this._reader.ValueAsDouble, ellipse.Center.Y);
×
1235
                                                                break;
×
1236
                                                        case 20:
1237
                                                                ellipse.Center = new XY(ellipse.Center.X, this._reader.ValueAsDouble);
×
1238
                                                                break;
×
1239
                                                        case 11:
1240
                                                                ellipse.MajorAxisEndPoint = new XY(this._reader.ValueAsDouble, ellipse.Center.Y);
×
1241
                                                                break;
×
1242
                                                        case 21:
1243
                                                                ellipse.MajorAxisEndPoint = new XY(ellipse.Center.X, this._reader.ValueAsDouble);
×
1244
                                                                break;
×
1245
                                                        case 40:
1246
                                                                ellipse.MinorToMajorRatio = this._reader.ValueAsDouble;
×
1247
                                                                break;
×
1248
                                                        case 50:
1249
                                                                ellipse.StartAngle = this._reader.ValueAsDouble;
×
1250
                                                                break;
×
1251
                                                        case 51:
1252
                                                                ellipse.EndAngle = this._reader.ValueAsDouble;
×
1253
                                                                break;
×
1254
                                                        case 73:
1255
                                                                ellipse.CounterClockWise = this._reader.ValueAsBool;
×
1256
                                                                break;
×
1257
                                                        default:
1258
                                                                return ellipse;
×
1259
                                                }
1260

1261
                                                this._reader.ReadNext();
×
1262
                                        }
×
1263
                                case Hatch.BoundaryPath.EdgeType.Spline:
1264
                                        Hatch.BoundaryPath.Spline spline = new Hatch.BoundaryPath.Spline();
×
1265
                                        int nKnots = 0;
×
1266
                                        int nCtrlPoints = 0;
×
1267
                                        int nFitPoints = 0;
×
1268

1269
                                        XYZ controlPoint = new XYZ();
×
1270
                                        XY fitPoint = new XY();
×
1271

1272
                                        while (true)
×
1273
                                        {
×
1274
                                                switch (this._reader.Code)
×
1275
                                                {
1276
                                                        case 10:
1277
                                                                controlPoint = new XYZ(this._reader.ValueAsDouble, 0, 1);
×
1278
                                                                break;
×
1279
                                                        case 20:
1280
                                                                controlPoint = new XYZ(controlPoint.X, this._reader.ValueAsDouble, controlPoint.Z);
×
1281
                                                                spline.ControlPoints.Add(controlPoint);
×
1282
                                                                break;
×
1283
                                                        case 11:
1284
                                                                fitPoint = new XY(this._reader.ValueAsDouble, 0);
×
1285
                                                                break;
×
1286
                                                        case 21:
1287
                                                                fitPoint = new XY(fitPoint.X, this._reader.ValueAsDouble);
×
1288
                                                                spline.FitPoints.Add(fitPoint);
×
1289
                                                                break;
×
1290
                                                        case 42:
1291
                                                                var last = spline.ControlPoints[spline.ControlPoints.Count - 1];
×
1292
                                                                spline.ControlPoints[spline.ControlPoints.Count - 1] = new XYZ(last.X, last.Y, this._reader.ValueAsDouble);
×
1293
                                                                break;
×
1294
                                                        case 12:
1295
                                                                spline.StartTangent = new XY(this._reader.ValueAsDouble, spline.StartTangent.Y);
×
1296
                                                                break;
×
1297
                                                        case 22:
1298
                                                                spline.StartTangent = new XY(spline.StartTangent.X, this._reader.ValueAsDouble);
×
1299
                                                                break;
×
1300
                                                        case 13:
1301
                                                                spline.EndTangent = new XY(this._reader.ValueAsDouble, spline.EndTangent.Y);
×
1302
                                                                break;
×
1303
                                                        case 23:
1304
                                                                spline.EndTangent = new XY(spline.EndTangent.X, this._reader.ValueAsDouble);
×
1305
                                                                break;
×
1306
                                                        case 94:
1307
                                                                spline.Degree = this._reader.ValueAsInt;
×
1308
                                                                break;
×
1309
                                                        case 73:
1310
                                                                spline.Rational = this._reader.ValueAsBool;
×
1311
                                                                break;
×
1312
                                                        case 74:
1313
                                                                spline.Periodic = this._reader.ValueAsBool;
×
1314
                                                                break;
×
1315
                                                        case 95:
1316
                                                                nKnots = this._reader.ValueAsInt;
×
1317
                                                                break;
×
1318
                                                        case 96:
1319
                                                                nCtrlPoints = this._reader.ValueAsInt;
×
1320
                                                                break;
×
1321
                                                        case 97:
1322
                                                                nFitPoints = this._reader.ValueAsInt;
×
1323
                                                                break;
×
1324
                                                        case 40:
1325
                                                                spline.Knots.Add(this._reader.ValueAsDouble);
×
1326
                                                                break;
×
1327
                                                        default:
1328
                                                                return spline;
×
1329
                                                }
1330

1331
                                                this._reader.ReadNext();
×
1332
                                        }
×
1333
                        }
1334

1335
                        return null;
×
1336
                }
1,728✔
1337

1338
                private void readDefinedGroups(CadTemplate template)
1339
                {
22,254✔
1340
                        this.readDefinedGroups(out ulong? xdict, out List<ulong> reactorsHandles);
22,254✔
1341

1342
                        template.XDictHandle = xdict;
22,254✔
1343
                        template.ReactorsHandles = reactorsHandles;
22,254✔
1344
                }
22,254✔
1345

1346
                private void readDefinedGroups(out ulong? xdictHandle, out List<ulong> reactors)
1347
                {
22,362✔
1348
                        xdictHandle = null;
22,362✔
1349
                        reactors = new List<ulong>();
22,362✔
1350

1351
                        switch (this._reader.ValueAsString)
22,362✔
1352
                        {
1353
                                case DxfFileToken.DictionaryToken:
1354
                                        this._reader.ReadNext();
4,298✔
1355
                                        xdictHandle = this._reader.ValueAsHandle;
4,298✔
1356
                                        this._reader.ReadNext();
4,298✔
1357
                                        Debug.Assert(this._reader.DxfCode == DxfCode.ControlString);
4,298✔
1358
                                        return;
4,298✔
1359
                                case DxfFileToken.ReactorsToken:
1360
                                        reactors = this.readReactors();
17,632✔
1361
                                        break;
17,632✔
1362
                                case DxfFileToken.BlkRefToken:
1363
                                default:
1364
                                        do
1365
                                        {
1,080✔
1366
                                                this._reader.ReadNext();
1,080✔
1367
                                        }
1,080✔
1368
                                        while (this._reader.DxfCode != DxfCode.ControlString);
1,080✔
1369
                                        return;
432✔
1370
                        }
1371
                }
22,362✔
1372

1373
                private List<ulong> readReactors()
1374
                {
17,632✔
1375
                        List<ulong> reactors = new List<ulong>();
17,632✔
1376

1377
                        this._reader.ReadNext();
17,632✔
1378

1379
                        while (this._reader.DxfCode != DxfCode.ControlString)
36,668✔
1380
                        {
19,036✔
1381
                                this._reader.ReadNext();
19,036✔
1382
                        }
19,036✔
1383

1384
                        return reactors;
17,632✔
1385
                }
17,632✔
1386

1387
                protected bool tryAssignCurrentValue(CadObject cadObject, DxfClassMap map)
1388
                {
1,223,704✔
1389
                        try
1390
                        {
1,223,704✔
1391
                                //Use this method only if the value is not a link between objects
1392
                                if (map.DxfProperties.TryGetValue(this._reader.Code, out DxfProperty dxfProperty))
1,223,704✔
1393
                                {
508,188✔
1394
                                        if (dxfProperty.ReferenceType.HasFlag(DxfReferenceType.Handle)
508,188✔
1395
                                                || dxfProperty.ReferenceType.HasFlag(DxfReferenceType.Name)
508,188✔
1396
                                                || dxfProperty.ReferenceType.HasFlag(DxfReferenceType.Count))
508,188✔
1397
                                        {
27,576✔
1398
                                                return false;
27,576✔
1399
                                        }
1400

1401
                                        object value = this._reader.Value;
480,612✔
1402

1403
                                        if (dxfProperty.ReferenceType.HasFlag(DxfReferenceType.IsAngle))
480,612✔
1404
                                        {
3,516✔
1405
                                                value = (double)value * MathUtils.DegToRadFactor;
3,516✔
1406
                                        }
3,516✔
1407

1408
                                        dxfProperty.SetValue(this._reader.Code, cadObject, value);
480,612✔
1409

1410
                                        return true;
480,612✔
1411
                                }
1412
                        }
715,516✔
1413
                        catch (Exception ex)
×
1414
                        {
×
1415
                                if (!this._builder.Configuration.Failsafe)
×
1416
                                {
×
1417
                                        throw ex;
×
1418
                                }
1419
                                else
1420
                                {
×
1421
                                        this._builder.Notify("An error occurred while assiging a property using mapper", NotificationType.Error, ex);
×
1422
                                }
×
1423
                        }
×
1424

1425
                        return false;
715,516✔
1426
                }
1,223,704✔
1427
        }
1428
}
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