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

DomCR / ACadSharp / 17737836230

15 Sep 2025 03:12PM UTC coverage: 2.092% (-76.2%) from 78.245%
17737836230

push

github

web-flow
Merge pull request #790 from DomCR/addflag-refactor

addflag refactor

141 of 9225 branches covered (1.53%)

Branch coverage included in aggregate %.

0 of 93 new or added lines in 10 files covered. (0.0%)

24910 existing lines in 372 files now uncovered.

724 of 32119 relevant lines covered (2.25%)

5.76 hits per line

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

0.0
/src/ACadSharp/Entities/TextEntity.cs
1
using ACadSharp.Attributes;
2
using ACadSharp.Tables;
3
using CSMath;
4
using CSUtilities.Extensions;
5
using System;
6
using System.Collections.Generic;
7

8
namespace ACadSharp.Entities
9
{
10
        /// <summary>
11
        /// Represents a <see cref="TextEntity"/>
12
        /// </summary>
13
        /// <remarks>
14
        /// Object name <see cref="DxfFileToken.EntityText"/> <br/>
15
        /// Dxf class name <see cref="DxfSubclassMarker.Text"/>
16
        /// </remarks>
17
        [DxfName(DxfFileToken.EntityText)]
18
        [DxfSubClass(DxfSubclassMarker.Text)]
19
        public class TextEntity : Entity, IText
20
        {
21
                /// <summary>
22
                /// Second alignment point (in OCS)
23
                /// </summary>
24
                /// <remarks>
25
                /// This value is meaningful only if the value of a 72 or 73 group is nonzero (if the justification is anything other than baseline/left)
26
                /// </remarks>
27
                [DxfCodeValue(DxfReferenceType.Optional, 11, 21, 31)]
UNCOV
28
                public XYZ AlignmentPoint { get; set; }
×
29

30
                /// <inheritdoc/>
31
                [DxfCodeValue(40)]
32
                public double Height
33
                {
UNCOV
34
                        get => _height;
×
35
                        set
UNCOV
36
                        {
×
UNCOV
37
                                if (value < 0)
×
38
                                        throw new ArgumentOutOfRangeException("Height value cannot be negative.");
×
39
                                else
UNCOV
40
                                        this._height = value;
×
UNCOV
41
                        }
×
42
                }
43

44
                /// <summary>
45
                /// Horizontal text justification type.
46
                /// </summary>
47
                [DxfCodeValue(72)]
UNCOV
48
                public TextHorizontalAlignment HorizontalAlignment { get; set; } = TextHorizontalAlignment.Left;
×
49

50
                /// <summary>
51
                /// First alignment point(in OCS)
52
                /// </summary>
53
                [DxfCodeValue(10, 20, 30)]
UNCOV
54
                public XYZ InsertPoint { get; set; } = XYZ.Zero;
×
55

56
                /// <summary>
57
                /// Mirror flags.
58
                /// </summary>
59
                [DxfCodeValue(71)]
NEW
60
                public TextMirrorFlag Mirror { get => _mirror; set => _mirror = value; }
×
61
                /// <summary>
62
                /// Specifies the three-dimensional normal unit vector for the object.
63
                /// </summary>
64
                [DxfCodeValue(210, 220, 230)]
UNCOV
65
                public XYZ Normal { get; set; } = XYZ.AxisZ;
×
66

67
                /// <inheritdoc/>
UNCOV
68
                public override string ObjectName => DxfFileToken.EntityText;
×
69

70
                /// <inheritdoc/>
UNCOV
71
                public override ObjectType ObjectType => ObjectType.TEXT;
×
72

73
                /// <summary>
74
                /// Specifies the oblique angle of the object.
75
                /// </summary>
76
                /// <value>
77
                /// The angle in radians within the range of -85 to +85 degrees. A positive angle denotes a lean to the right; a negative value will have 2*PI added to it to convert it to its positive equivalent.
78
                /// </value>
79
                [DxfCodeValue(DxfReferenceType.IsAngle, 51)]
UNCOV
80
                public double ObliqueAngle { get; set; } = 0.0;
×
81

82
                /// <inheritdoc/>
83
                [DxfCodeValue(DxfReferenceType.IsAngle, 50)]
UNCOV
84
                public double Rotation { get; set; }
×
85

86
                /// <inheritdoc/>
87
                [DxfCodeValue(DxfReferenceType.Name | DxfReferenceType.Optional, 7)]
88
                public TextStyle Style
89
                {
UNCOV
90
                        get { return this._style; }
×
91
                        set
UNCOV
92
                        {
×
UNCOV
93
                                if (value == null)
×
94
                                {
×
95
                                        throw new ArgumentNullException(nameof(value));
×
96
                                }
97

UNCOV
98
                                if (this.Document != null)
×
UNCOV
99
                                {
×
UNCOV
100
                                        this._style = CadObject.updateCollection(value, this.Document.TextStyles);
×
UNCOV
101
                                }
×
102
                                else
UNCOV
103
                                {
×
UNCOV
104
                                        this._style = value;
×
UNCOV
105
                                }
×
UNCOV
106
                        }
×
107
                }
108

109
                /// <inheritdoc/>
UNCOV
110
                public override string SubclassMarker => DxfSubclassMarker.Text;
×
111

112
                /// <summary>
113
                /// Specifies the distance a 2D object is extruded above or below its elevation.
114
                /// </summary>
115
                [DxfCodeValue(39)]
UNCOV
116
                public double Thickness { get; set; } = 0.0;
×
117

118
                /// <inheritdoc/>
119
                /// <value>
120
                /// The maximum length is 256 characters.
121
                /// </value>
122
                [DxfCodeValue(1)]
123
                public string Value
124
                {
125
                        get
UNCOV
126
                        {
×
UNCOV
127
                                return _value;
×
UNCOV
128
                        }
×
129
                        set
UNCOV
130
                        {
×
UNCOV
131
                                if (value.Length > 256)
×
132
                                        throw new ArgumentException($"Text length cannot be supiror than 256, current: {value.Length}");
×
133
                                else
UNCOV
134
                                        this._value = value;
×
UNCOV
135
                        }
×
136
                }
137

138
                /// <summary>
139
                /// Vertical text justification type.
140
                /// </summary>
141
                [DxfCodeValue(DxfReferenceType.Optional, 73)]
UNCOV
142
                public virtual TextVerticalAlignmentType VerticalAlignment { get; set; } = TextVerticalAlignmentType.Baseline;
×
143

144
                /// <summary>
145
                /// Relative X scale factor—widt
146
                /// </summary>
147
                /// <remarks>
148
                /// This value is also adjusted when fit-type text is used
149
                /// </remarks>
150
                [DxfCodeValue(DxfReferenceType.Optional, 41)]
UNCOV
151
                public double WidthFactor { get; set; } = 1.0;
×
152

UNCOV
153
                private double _height = 0.0;
×
UNCOV
154
                private TextStyle _style = TextStyle.Default;
×
UNCOV
155
                private string _value = string.Empty;
×
NEW
156
                private TextMirrorFlag _mirror = TextMirrorFlag.None;
×
157

UNCOV
158
                public TextEntity() : base()
×
UNCOV
159
                {
×
UNCOV
160
                }
×
161

162
                /// <inheritdoc/>
163
                public override void ApplyTransform(Transform transform)
UNCOV
164
                {
×
UNCOV
165
                        bool mirrText = this.Mirror.HasFlag(TextMirrorFlag.Backward);
×
166

UNCOV
167
                        XYZ newInsert = transform.ApplyTransform(this.InsertPoint);
×
UNCOV
168
                        XYZ newNormal = this.transformNormal(transform, this.Normal);
×
169

UNCOV
170
                        var transformation = this.getWorldMatrix(transform, Normal, newNormal, out Matrix3 transOW, out Matrix3 transWO);
×
171

UNCOV
172
                        List<XY> uv = applyRotation(
×
UNCOV
173
                                new[]
×
UNCOV
174
                                {
×
UNCOV
175
                                        this.WidthFactor * this.Height * XY.AxisX,
×
UNCOV
176
                                        new XY(this.Height * Math.Tan(this.ObliqueAngle), this.Height)
×
UNCOV
177
                                },
×
UNCOV
178
                                this.Rotation);
×
179

180
                        XYZ v;
UNCOV
181
                        v = transOW * new XYZ(uv[0].X, uv[0].Y, 0.0);
×
UNCOV
182
                        v = transformation * v;
×
UNCOV
183
                        v = transWO * v;
×
UNCOV
184
                        XY newUvector = new XY(v.X, v.Y);
×
185

UNCOV
186
                        v = transOW * new XYZ(uv[1].X, uv[1].Y, 0.0);
×
UNCOV
187
                        v = transformation * v;
×
UNCOV
188
                        v = transWO * v;
×
UNCOV
189
                        XY newVvector = new XY(v.X, v.Y);
×
190

UNCOV
191
                        double newRotation = newUvector.GetAngle();
×
UNCOV
192
                        double newObliqueAngle = newVvector.GetAngle();
×
193

UNCOV
194
                        if (mirrText)
×
195
                        {
×
196
                                if (XY.Cross(newUvector, newVvector) < 0)
×
197
                                {
×
198
                                        newObliqueAngle = MathHelper.HalfPI - (newRotation - newObliqueAngle);
×
199
                                        if (!(this.HorizontalAlignment.HasFlag(TextHorizontalAlignment.Fit)
×
200
                                                || this.HorizontalAlignment.HasFlag(TextHorizontalAlignment.Aligned)))
×
201
                                        {
×
202
                                                newRotation += Math.PI;
×
203
                                        }
×
204

NEW
205
                                        this._mirror.RemoveFlag(TextMirrorFlag.Backward);
×
206
                                }
×
207
                                else
208
                                {
×
209
                                        newObliqueAngle = MathHelper.HalfPI + (newRotation - newObliqueAngle);
×
210
                                }
×
211
                        }
×
212
                        else
UNCOV
213
                        {
×
UNCOV
214
                                if (XY.Cross(newUvector, newVvector) < 0.0)
×
215
                                {
×
216
                                        newObliqueAngle = MathHelper.HalfPI - (newRotation - newObliqueAngle);
×
217

218
                                        if (newUvector.Dot(uv[0]) < 0.0)
×
219
                                        {
×
220
                                                newRotation += Math.PI;
×
221

222
                                                switch (this.HorizontalAlignment)
×
223
                                                {
224
                                                        case TextHorizontalAlignment.Left:
225
                                                                this.HorizontalAlignment = TextHorizontalAlignment.Right;
×
226
                                                                break;
×
227
                                                        case TextHorizontalAlignment.Right:
228
                                                                this.HorizontalAlignment = TextHorizontalAlignment.Left;
×
229
                                                                break;
×
230
                                                }
231
                                        }
×
232
                                        else
233
                                        {
×
234
                                                switch (this.VerticalAlignment)
×
235
                                                {
236
                                                        case TextVerticalAlignmentType.Top:
237
                                                                this.VerticalAlignment = TextVerticalAlignmentType.Bottom;
×
238
                                                                break;
×
239
                                                        case TextVerticalAlignmentType.Bottom:
240
                                                                this.VerticalAlignment = TextVerticalAlignmentType.Top;
×
241
                                                                break;
×
242
                                                }
243
                                        }
×
244
                                }
×
245
                                else
UNCOV
246
                                {
×
UNCOV
247
                                        newObliqueAngle = MathHelper.HalfPI + (newRotation - newObliqueAngle);
×
UNCOV
248
                                }
×
UNCOV
249
                        }
×
250

251
                        // the oblique angle is defined between -85 and 85 degrees
UNCOV
252
                        double maxOblique = MathHelper.DegToRad(85);
×
UNCOV
253
                        double minOblique = -maxOblique;
×
UNCOV
254
                        if (newObliqueAngle > Math.PI)
×
255
                        {
×
256
                                newObliqueAngle = Math.PI - newObliqueAngle;
×
257
                        }
×
258

UNCOV
259
                        if (newObliqueAngle < minOblique)
×
260
                        {
×
261
                                newObliqueAngle = minOblique;
×
262
                        }
×
UNCOV
263
                        else if (newObliqueAngle > maxOblique)
×
UNCOV
264
                        {
×
UNCOV
265
                                newObliqueAngle = maxOblique;
×
UNCOV
266
                        }
×
267

268
                        // the height must be greater than zero, the cos is always positive between -85 and 85
UNCOV
269
                        double newHeight = newVvector.GetLength() * Math.Cos(newObliqueAngle);
×
UNCOV
270
                        newHeight = MathHelper.IsZero(newHeight) ? MathHelper.Epsilon : newHeight;
×
271

272
                        // the width factor is defined between 0.01 and 100
UNCOV
273
                        double newWidthFactor = newUvector.GetLength() / newHeight;
×
UNCOV
274
                        if (newWidthFactor < 0.01)
×
UNCOV
275
                        {
×
UNCOV
276
                                newWidthFactor = 0.01;
×
UNCOV
277
                        }
×
278
                        else if (newWidthFactor > 100)
×
279
                        {
×
280
                                newWidthFactor = 100;
×
281
                        }
×
282

UNCOV
283
                        this.InsertPoint = newInsert;
×
UNCOV
284
                        this.Normal = newNormal;
×
UNCOV
285
                        this.Rotation = newRotation;
×
UNCOV
286
                        this.Height = newHeight;
×
UNCOV
287
                        this.WidthFactor = newWidthFactor;
×
UNCOV
288
                        this.ObliqueAngle = newObliqueAngle;
×
UNCOV
289
                }
×
290

291
                /// <inheritdoc/>
292
                public override CadObject Clone()
UNCOV
293
                {
×
UNCOV
294
                        TextEntity clone = (TextEntity)base.Clone();
×
UNCOV
295
                        clone.Style = (TextStyle)this.Style.Clone();
×
UNCOV
296
                        return clone;
×
UNCOV
297
                }
×
298

299
                /// <inheritdoc/>
300
                public override BoundingBox GetBoundingBox()
UNCOV
301
                {
×
UNCOV
302
                        return new BoundingBox(this.InsertPoint);
×
UNCOV
303
                }
×
304

305
                internal override void AssignDocument(CadDocument doc)
UNCOV
306
                {
×
UNCOV
307
                        base.AssignDocument(doc);
×
308

UNCOV
309
                        this._style = CadObject.updateCollection(this.Style, doc.TextStyles);
×
310

UNCOV
311
                        doc.DimensionStyles.OnRemove += this.tableOnRemove;
×
UNCOV
312
                }
×
313

314
                internal override void UnassignDocument()
UNCOV
315
                {
×
UNCOV
316
                        this.Document.DimensionStyles.OnRemove -= this.tableOnRemove;
×
317

UNCOV
318
                        base.UnassignDocument();
×
319

UNCOV
320
                        this.Style = (TextStyle)this.Style.Clone();
×
UNCOV
321
                }
×
322

323
                protected override void tableOnRemove(object sender, CollectionChangedEventArgs e)
324
                {
×
325
                        base.tableOnRemove(sender, e);
×
326

327
                        if (e.Item.Equals(this.Style))
×
328
                        {
×
329
                                this.Style = this.Document.TextStyles[TextStyle.DefaultName];
×
330
                        }
×
331
                }
×
332
        }
333
}
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