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

DomCR / ACadSharp / 16398964386

20 Jul 2025 10:35AM UTC coverage: 75.157% (+0.1%) from 75.043%
16398964386

Pull #715

github

web-flow
Merge 48c4080d8 into 402a39408
Pull Request #715: Issue 712 pdfunderlay writer

5902 of 8639 branches covered (68.32%)

Branch coverage included in aggregate %.

174 of 253 new or added lines in 18 files covered. (68.77%)

12 existing lines in 3 files now uncovered.

23525 of 30515 relevant lines covered (77.09%)

80246.14 hits per line

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

44.74
/src/ACadSharp/Entities/UnderlayEntity.cs
1
using ACadSharp.Attributes;
2
using ACadSharp.Objects;
3
using ACadSharp.Objects.Collections;
4
using CSMath;
5
using System;
6
using System.Collections.Generic;
7

8
namespace ACadSharp.Entities
9
{
10
        /// <summary>
11
        /// Common base class for all underlay entities, like <see cref="PdfUnderlay" />.
12
        /// </summary>
13
        [DxfSubClass(null, true)]
14
        public abstract class UnderlayEntity<T> : Entity
15
                where T : UnderlayDefinition
16
        {
17
                /// <summary>
18
                /// 2d points in OCS/ECS.
19
                /// </summary>
20
                /// <remarks>
21
                /// If only two, then they are the lower left and upper right corner points of a clip rectangle. <br/>
22
                /// If more than two, then they are the vertices of a clipping polygon.
23
                /// </remarks>
24
                [DxfCollectionCodeValue(11, 21)]
25
                public List<XY> ClipBoundaryVertices { get; set; } = new List<XY>();
387✔
26

27
                /// <summary>
28
                /// Contrast.
29
                /// </summary>
30
                /// <remarks>
31
                /// 0-100; default = 50
32
                /// </remarks>
33
                [DxfCodeValue(281)]
34
                public byte Contrast
35
                {
36
                        get { return this._contrast; }
78✔
37
                        set
38
                        {
361✔
39
                                if (value < 0 || value > 100)
361!
UNCOV
40
                                {
×
UNCOV
41
                                        throw new ArgumentException($"Invalid Brightness value: {value}, must be in range 0-100");
×
42
                                }
43

44
                                this._contrast = value;
361✔
45
                        }
361✔
46
                }
47

48
                /// <summary>
49
                /// The AcDbUnderlayDefinition object.
50
                /// </summary>
51
                [DxfCodeValue(DxfReferenceType.Handle, 340)]
52
                public T Definition
53
                {
54
                        get { return this._definition; }
1,281✔
55
                        set
56
                        {
375✔
57
                                if (value == null)
375!
NEW
58
                                {
×
NEW
59
                                        throw new ArgumentNullException(nameof(value));
×
60
                                }
61

62
                                if (this.Document != null)
375✔
63
                                {
349✔
64
                                        this._definition = this.updateCollection(value, this.getDocumentCollection(this.Document));
349✔
65
                                }
349✔
66
                                else
67
                                {
26✔
68
                                        this._definition = value;
26✔
69
                                }
26✔
70
                        }
375✔
71
                }
72

73
                /// <summary>
74
                /// Fade.
75
                /// </summary>
76
                /// <value>
77
                /// Range: 0 - 100 <br/>
78
                /// Default: 0
79
                /// </value>
80
                [DxfCodeValue(282)]
81
                public byte Fade
82
                {
83
                        get { return this._fade; }
78✔
84
                        set
85
                        {
361✔
86
                                if (value < 0 || value > 100)
361!
UNCOV
87
                                {
×
UNCOV
88
                                        throw new ArgumentException($"Invalid Brightness value: {value}, must be in range 0-100");
×
89
                                }
90

91
                                this._fade = value;
361✔
92
                        }
361✔
93
                }
94

95
                /// <summary>
96
                /// Underlay display options.
97
                /// </summary>
98
                [DxfCodeValue(280)]
99
                public UnderlayDisplayFlags Flags { get; set; } = UnderlayDisplayFlags.Default;
748✔
100

101
                /// <summary>
102
                /// Insertion point(in WCS).
103
                /// </summary>
104
                [DxfCodeValue(10, 20, 30)]
105
                public XYZ InsertPoint { get; set; }
1,527✔
106

107
                /// <summary>
108
                /// Specifies the three-dimensional normal unit vector for the object.
109
                /// </summary>
110
                [DxfCodeValue(210, 220, 230)]
111
                public XYZ Normal { get; set; } = XYZ.AxisZ;
494✔
112

113
                /// <summary>
114
                /// Specifies the rotation angle for the object.
115
                /// </summary>
116
                /// <value>
117
                /// The rotation angle in radians.
118
                /// </value>
119
                [DxfCodeValue(DxfReferenceType.IsAngle, 50)]
120
                public double Rotation { get; set; } = 0.0;
494✔
121

122
                /// <inheritdoc/>
123
                public override string SubclassMarker => DxfSubclassMarker.Underlay;
3,382✔
124

125
                /// <summary>
126
                /// X scale factor.
127
                /// </summary>
128
                [DxfCodeValue(41)]
129
                public double XScale
130
                {
131
                        get
132
                        {
×
133
                                return this._xscale;
×
134
                        }
×
135
                        set
136
                        {
133✔
137
                                if (value.Equals(0))
133!
138
                                {
×
139
                                        string name = nameof(this.XScale);
×
140
                                        throw new ArgumentOutOfRangeException(name, value, $"{name} value must be none zero.");
×
141
                                }
142
                                this._xscale = value;
133✔
143
                        }
133✔
144
                }
145

146
                /// <summary>
147
                /// Y scale factor.
148
                /// </summary>
149
                [DxfCodeValue(42)]
150
                public double YScale
151
                {
152
                        get
153
                        {
×
154
                                return this._yscale;
×
155
                        }
×
156
                        set
157
                        {
133✔
158
                                if (value.Equals(0))
133!
159
                                {
×
160
                                        string name = nameof(this.YScale);
×
161
                                        throw new ArgumentOutOfRangeException(name, value, $"{name} value must be none zero.");
×
162
                                }
163
                                this._yscale = value;
133✔
164
                        }
133✔
165
                }
166

167
                /// <summary>
168
                /// Z scale factor.
169
                /// </summary>
170
                [DxfCodeValue(43)]
171
                public double ZScale
172
                {
173
                        get
174
                        {
×
175
                                return this._zscale;
×
176
                        }
×
177
                        set
178
                        {
133✔
179
                                if (value.Equals(0))
133!
180
                                {
×
181
                                        string name = nameof(this.ZScale);
×
182
                                        throw new ArgumentOutOfRangeException(name, value, $"{name} value must be none zero.");
×
183
                                }
184
                                this._zscale = value;
133✔
185
                        }
133✔
186
                }
187

188
                private byte _contrast = 100;
361✔
189

190
                private T _definition;
191

192
                private byte _fade = 0;
361✔
193

194
                private double _xscale = 1;
361✔
195

196
                private double _yscale = 1;
361✔
197

198
                private double _zscale = 1;
361✔
199

200
                /// <summary>
201
                /// Initializes a new instance of the <see cref="UnderlayEntity{T}" /> class.
202
                /// </summary>
203
                /// <param name="definition"></param>
NEW
204
                public UnderlayEntity(T definition)
×
NEW
205
                {
×
NEW
206
                        this.Definition = definition;
×
NEW
207
                }
×
208

209
                internal UnderlayEntity()
361✔
210
                {
361✔
211
                }
361✔
212

213
                /// <inheritdoc/>
214
                public override void ApplyTransform(Transform transform)
215
                {
×
216
                        XYZ newPosition = transform.ApplyTransform(this.InsertPoint);
×
217
                        XYZ newNormal = this.transformNormal(transform, Normal);
×
218

219
                        var transformation = getWorldMatrix(transform, newNormal, this.Normal, out Matrix3 transOW, out Matrix3 transWO);
×
220

221
                        List<XY> uv = applyRotation(
×
222
                                new[]
×
223
                                {
×
224
                                        XY.AxisX, XY.AxisY
×
225
                                },
×
226
                                this.Rotation);
×
227

228
                        XYZ v;
229
                        v = transOW * new XYZ(uv[0].X, uv[0].Y, 0.0);
×
230
                        v = transformation * v;
×
231
                        v = transWO * v;
×
232
                        XY newUvector = new XY(v.X, v.Y);
×
233

234
                        v = transOW * new XYZ(uv[1].X, uv[1].Y, 0.0);
×
235
                        v = transformation * v;
×
236
                        v = transWO * v;
×
237
                        XY newVvector = new XY(v.X, v.Y);
×
238

239
                        int sign = Math.Sign(transformation.m00 * transformation.m11 * transformation.m22) < 0 ? -1 : 1;
×
240

241
                        double newRotation = (sign * newUvector).GetAngle();
×
242

243
                        this.InsertPoint = newPosition;
×
244
                        this.Normal = newNormal;
×
245
                        this.Rotation = newRotation;
×
246
                        this.XScale = transform.Scale.X * this.XScale;
×
247
                        this.YScale = transform.Scale.Y * this.YScale;
×
248
                        this.ZScale = transform.Scale.Z * this.ZScale;
×
249
                }
×
250

251
                /// <inheritdoc/>
252
                public override CadObject Clone()
NEW
253
                {
×
NEW
254
                        UnderlayEntity<T> clone = (UnderlayEntity<T>)base.Clone();
×
255

NEW
256
                        clone.Definition = (T)this.Definition?.Clone();
×
257

NEW
258
                        return clone;
×
NEW
259
                }
×
260

261
                /// <inheritdoc/>
262
                public override BoundingBox GetBoundingBox()
UNCOV
263
                {
×
UNCOV
264
                        return BoundingBox.Null;
×
UNCOV
265
                }
×
266

267
                internal override void AssignDocument(CadDocument doc)
268
                {
375✔
269
                        base.AssignDocument(doc);
375✔
270

271
                        this._definition = this.updateCollection(this.Definition, getDocumentCollection(doc));
375✔
272

273
                        this.Document.PdfDefinitions.OnRemove += this.imageDefinitionsOnRemove;
375✔
274
                }
375✔
275

276
                internal override void UnassignDocument()
277
                {
26✔
278
                        this.Document.ImageDefinitions.OnRemove -= this.imageDefinitionsOnRemove;
26✔
279

280
                        base.UnassignDocument();
26✔
281

282
                        this.Definition = (T)this.Definition?.Clone();
26!
283
                }
26✔
284

285
                protected abstract ObjectDictionaryCollection<T> getDocumentCollection(CadDocument document);
286

287
                private void imageDefinitionsOnRemove(object sender, CollectionChangedEventArgs e)
NEW
288
                {
×
NEW
289
                        if (e.Item.Equals(this.Definition))
×
NEW
290
                        {
×
NEW
291
                                this.Definition = null;
×
NEW
292
                        }
×
NEW
293
                }
×
294
        }
295
}
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