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

DomCR / ACadSharp / 13723607028

07 Mar 2025 03:14PM UTC coverage: 75.346% (-0.8%) from 76.11%
13723607028

Pull #457

github

web-flow
Merge 1ebca662a into a1ba04cda
Pull Request #457: Geometric transform

5484 of 8001 branches covered (68.54%)

Branch coverage included in aggregate %.

150 of 519 new or added lines in 40 files covered. (28.9%)

283 existing lines in 12 files now uncovered.

21823 of 28241 relevant lines covered (77.27%)

74185.34 hits per line

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

41.21
/src/ACadSharp/Entities/MText.cs
1
using ACadSharp.Attributes;
2
using ACadSharp.Tables;
3
using CSMath;
4
using System;
5
using System.Collections.Generic;
6

7
namespace ACadSharp.Entities
8
{
9
        /// <summary>
10
        /// Represents a <see cref="MText"/> entity.
11
        /// </summary>
12
        /// <remarks>
13
        /// Object name <see cref="DxfFileToken.EntityMText"/> <br/>
14
        /// Dxf class name <see cref="DxfSubclassMarker.MText"/>
15
        /// </remarks>
16
        [DxfName(DxfFileToken.EntityMText)]
17
        [DxfSubClass(DxfSubclassMarker.MText)]
18
        public partial class MText : Entity, IText
19
        {
20
                /// <inheritdoc/>
21
                public override ObjectType ObjectType => ObjectType.MTEXT;
1✔
22

23
                /// <inheritdoc/>
24
                public override string ObjectName => DxfFileToken.EntityMText;
1,334✔
25

26
                /// <inheritdoc/>
27
                public override string SubclassMarker => DxfSubclassMarker.MText;
126,038✔
28

29
                /// <summary>
30
                /// A 3D WCS coordinate representing the insertion or origin point.
31
                /// </summary>
32
                [DxfCodeValue(10, 20, 30)]
33
                public XYZ InsertPoint { get; set; } = XYZ.Zero;
57,273✔
34

35
                /// <summary>
36
                /// Specifies the three-dimensional normal unit vector for the object.
37
                /// </summary>
38
                [DxfCodeValue(210, 220, 230)]
39
                public XYZ Normal { get; set; } = XYZ.AxisZ;
16,532✔
40

41
                /// <inheritdoc/>
42
                [DxfCodeValue(40)]
43
                public double Height
44
                {
45
                        get => this._height;
749✔
46
                        set
47
                        {
11,354✔
48
                                if (value < 0)
11,354!
49
                                        throw new ArgumentOutOfRangeException("Height value cannot be negative.");
×
50
                                else
51
                                        this._height = value;
11,354✔
52
                        }
11,354✔
53
                }
54

55
                /// <summary>
56
                /// Reference rectangle width.
57
                /// </summary>
58
                [DxfCodeValue(41)]
59
                public double RectangleWidth { get; set; }
12,103✔
60

61
                /// <summary>
62
                /// Reference rectangle height.
63
                /// </summary>
64
                [DxfCodeValue(46)]
65
                public double RectangleHeight { get; set; }
7,716✔
66

67
                /// <summary>
68
                /// Attachment point
69
                /// </summary>
70
                [DxfCodeValue(71)]
71
                public AttachmentPointType AttachmentPoint { get; set; } = AttachmentPointType.TopLeft;
23,318✔
72

73
                /// <summary>
74
                /// Drawing direction
75
                /// </summary>
76
                [DxfCodeValue(72)]
77
                public DrawingDirectionType DrawingDirection { get; set; }
12,099✔
78

79
                /// <inheritdoc/>
80
                [DxfCodeValue(1)]
81
                public string Value { get; set; } = string.Empty;
35,140✔
82

83
                /// <inheritdoc/>
84
                [DxfCodeValue(DxfReferenceType.Name | DxfReferenceType.Optional, 7)]
85
                public TextStyle Style
86
                {
87
                        get { return this._style; }
36,546✔
88
                        set
89
                        {
4,752✔
90
                                if (value == null)
4,752!
91
                                {
×
92
                                        throw new ArgumentNullException(nameof(value));
×
93
                                }
94

95
                                if (this.Document != null)
4,752✔
96
                                {
4,522✔
97
                                        this._style = this.updateTable(value, this.Document.TextStyles);
4,522✔
98
                                }
4,522✔
99
                                else
100
                                {
230✔
101
                                        this._style = value;
230✔
102
                                }
230✔
103
                        }
4,752✔
104
                }
105

106
                /// <summary>
107
                /// X-axis direction vector(in WCS)
108
                /// </summary>
109
                /// <remarks>
110
                /// A group code 50 (rotation angle in radians) passed as DXF input is converted to the equivalent direction vector (if both a code 50 and codes 11, 21, 31 are passed, the last one wins). This is provided as a convenience for conversions from text objects
111
                /// </remarks>
112
                [DxfCodeValue(11, 21, 31)]
113
                public XYZ AlignmentPoint
114
                {
115
                        get => this._alignmentPoint;
4,613✔
116
                        set
117
                        {
8,432✔
118
                                this._alignmentPoint = value;
8,432✔
119
                                this._rotation = new XY(this._alignmentPoint.X, this._alignmentPoint.Y).GetAngle();
8,432✔
120
                        }
8,432✔
121
                }
122

123
                /// <summary>
124
                /// Horizontal width of the characters that make up the mtext entity.
125
                /// This value will always be equal to or less than the value of group code 41 
126
                /// </summary>
127
                /// <remarks>
128
                /// read-only, ignored if supplied
129
                /// </remarks>
130
                [DxfCodeValue(DxfReferenceType.Ignored, 42)]
131
                public double HorizontalWidth { get; set; } = 0.9;
11,359✔
132

133
                /// <summary>
134
                /// Vertical height of the mtext entity
135
                /// </summary>
136
                /// <remarks>
137
                /// read-only, ignored if supplied
138
                /// </remarks>
139
                [DxfCodeValue(DxfReferenceType.Ignored, 43)]
140
                public double VerticalHeight { get; set; } = 0.2;
11,359✔
141

142
                /// <summary>
143
                /// Specifies the rotation angle for the object.
144
                /// </summary>
145
                /// <value>
146
                /// The rotation angle in radians.
147
                /// </value>
148
                [DxfCodeValue(DxfReferenceType.IsAngle, 50)]
149
                public double Rotation
150
                {
151
                        get => this._rotation;
×
152
                        set
153
                        {
4✔
154
                                this._rotation = value;
4✔
155
                                this.AlignmentPoint = new XYZ(Math.Cos(this._rotation), Math.Sin(this._rotation), 0.0);
4✔
156
                        }
4✔
157
                }
158

159
                /// <summary>
160
                /// Mtext line spacing style 
161
                /// </summary>
162
                [DxfCodeValue(73)]
163
                public LineSpacingStyleType LineSpacingStyle { get; set; }
11,453✔
164

165
                /// <summary>
166
                /// Mtext line spacing factor.
167
                /// </summary>
168
                /// <remarks>
169
                /// Percentage of default (3-on-5) line spacing to be applied.Valid values range from 0.25 to 4.00
170
                /// </remarks>
171
                [DxfCodeValue(44)]
172
                public double LineSpacing { get; set; } = 1.0;
22,676✔
173

174
                /// <summary>
175
                /// Background fill setting
176
                /// </summary>
177
                [DxfCodeValue(90)]
178
                public BackgroundFillFlags BackgroundFillFlags { get; set; } = BackgroundFillFlags.None;
18,580✔
179

180
                /// <summary>
181
                /// Determines how much border there is around the text.
182
                /// </summary>
183
                [DxfCodeValue(45)]
184
                public double BackgroundScale { get; set; } = 1.5;
11,614✔
185

186
                /// <summary>
187
                /// Background fill color 
188
                /// </summary>
189
                /// <remarks>
190
                /// Color to use for background fill when group code 90 is 1.
191
                /// </remarks>
192
                [DxfCodeValue(63, 420, 430)]
193
                public Color BackgroundColor { get; set; }
259✔
194

195
                /// <summary>
196
                /// Transparency of background fill color
197
                /// </summary>
198
                [DxfCodeValue(441)]
199
                public Transparency BackgroundTransparency { get; set; }
259✔
200

201
                public TextColumn Column { get; set; } = new TextColumn();
13,363✔
202

203
                public bool IsAnnotative { get; set; } = false;
12,591✔
204

205
                private double _height = 1.0;
11,219✔
206

207
                private XYZ _alignmentPoint = XYZ.AxisX;
11,219✔
208

209
                private double _rotation = 0.0;
11,219✔
210

211
                private TextStyle _style = TextStyle.Default;
11,219✔
212

213
                /// <inheritdoc/>
214
                public MText() : base() { }
33,657✔
215

216
                /// <inheritdoc/>
217
                public override void ApplyTransform(Transform transform)
NEW
218
                {
×
NEW
219
                        XYZ newInsert = transform.ApplyTransform(this.InsertPoint);
×
NEW
220
                        XYZ newNormal = this.transformNormal(transform, this.Normal);
×
221

NEW
222
                        var transformation = this.getWorldMatrix(transform, Normal, newNormal, out Matrix3 transOW, out Matrix3 transWO);
×
223

NEW
224
                        transWO = transWO.Transpose();
×
225

NEW
226
                        List<XY> uv = applyRotation(
×
NEW
227
                                new[]
×
NEW
228
                                {
×
NEW
229
                                        XY.AxisX, XY.AxisY
×
NEW
230
                                },
×
NEW
231
                                this.Rotation);
×
232

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

239
                        // the MText entity does not support non-uniform scaling
NEW
240
                        double scale = newUvector.GetLength();
×
241

NEW
242
                        v = transOW * new XYZ(uv[1].X, uv[1].Y, 0.0);
×
NEW
243
                        v = transformation * v;
×
NEW
244
                        v = transWO * v;
×
NEW
245
                        XY newVvector = new XY(v.X, v.Y);
×
246

NEW
247
                        double newRotation = newUvector.GetAngle();
×
248

NEW
249
                        if (XY.Cross(newUvector, newVvector) < 0.0)
×
NEW
250
                        {
×
NEW
251
                                if (newUvector.Dot(uv[0]) < 0.0)
×
NEW
252
                                {
×
NEW
253
                                        newRotation += 180;
×
254

NEW
255
                                        switch (this.AttachmentPoint)
×
256
                                        {
257
                                                case AttachmentPointType.TopLeft:
NEW
258
                                                        this.AttachmentPoint = AttachmentPointType.TopRight;
×
NEW
259
                                                        break;
×
260
                                                case AttachmentPointType.TopRight:
NEW
261
                                                        this.AttachmentPoint = AttachmentPointType.TopLeft;
×
NEW
262
                                                        break;
×
263
                                                case AttachmentPointType.MiddleLeft:
NEW
264
                                                        this.AttachmentPoint = AttachmentPointType.MiddleRight;
×
NEW
265
                                                        break;
×
266
                                                case AttachmentPointType.MiddleRight:
NEW
267
                                                        this.AttachmentPoint = AttachmentPointType.MiddleLeft;
×
NEW
268
                                                        break;
×
269
                                                case AttachmentPointType.BottomLeft:
NEW
270
                                                        this.AttachmentPoint = AttachmentPointType.BottomRight;
×
NEW
271
                                                        break;
×
272
                                                case AttachmentPointType.BottomRight:
NEW
273
                                                        this.AttachmentPoint = AttachmentPointType.BottomLeft;
×
NEW
274
                                                        break;
×
275
                                        }
NEW
276
                                }
×
277
                                else
NEW
278
                                {
×
NEW
279
                                        switch (this.AttachmentPoint)
×
280
                                        {
281
                                                case AttachmentPointType.TopLeft:
NEW
282
                                                        this.AttachmentPoint = AttachmentPointType.BottomLeft;
×
NEW
283
                                                        break;
×
284
                                                case AttachmentPointType.TopCenter:
NEW
285
                                                        this.AttachmentPoint = AttachmentPointType.BottomCenter;
×
NEW
286
                                                        break;
×
287
                                                case AttachmentPointType.TopRight:
NEW
288
                                                        this.AttachmentPoint = AttachmentPointType.BottomRight;
×
NEW
289
                                                        break;
×
290
                                                case AttachmentPointType.BottomLeft:
NEW
291
                                                        this.AttachmentPoint = AttachmentPointType.TopLeft;
×
NEW
292
                                                        break;
×
293
                                                case AttachmentPointType.BottomCenter:
NEW
294
                                                        this.AttachmentPoint = AttachmentPointType.TopCenter;
×
NEW
295
                                                        break;
×
296
                                                case AttachmentPointType.BottomRight:
NEW
297
                                                        this.AttachmentPoint = AttachmentPointType.TopRight;
×
NEW
298
                                                        break;
×
299
                                        }
NEW
300
                                }
×
NEW
301
                        }
×
302

NEW
303
                        double newHeight = this.Height * scale;
×
NEW
304
                        newHeight = MathHelper.IsZero(newHeight) ? MathHelper.Epsilon : newHeight;
×
305

NEW
306
                        this.InsertPoint = newInsert;
×
NEW
307
                        this.Normal = newNormal;
×
NEW
308
                        this.Rotation = newRotation;
×
NEW
309
                        this.Height = newHeight;
×
NEW
310
                        this.RectangleWidth *= scale;
×
NEW
311
                }
×
312

313
                /// <inheritdoc/>
314
                public override BoundingBox GetBoundingBox()
315
                {
1✔
316
                        return new BoundingBox(this.InsertPoint);
1✔
317
                }
1✔
318

319
                /// <inheritdoc/>
320
                public override CadObject Clone()
321
                {
122✔
322
                        MText clone = (MText)base.Clone();
122✔
323

324
                        clone.Style = (TextStyle)(this.Style?.Clone());
122!
325
                        clone.Column = this.Column?.Clone();
122!
326

327
                        return clone;
122✔
328
                }
122✔
329

330
                internal override void AssignDocument(CadDocument doc)
331
                {
11,241✔
332
                        base.AssignDocument(doc);
11,241✔
333

334
                        this._style = this.updateTable(this.Style, doc.TextStyles);
11,241✔
335

336
                        doc.DimensionStyles.OnRemove += this.tableOnRemove;
11,241✔
337
                }
11,241✔
338

339
                internal override void UnassignDocument()
340
                {
70✔
341
                        this.Document.DimensionStyles.OnRemove -= this.tableOnRemove;
70✔
342

343
                        base.UnassignDocument();
70✔
344

345
                        this.Style = (TextStyle)this.Style.Clone();
70✔
346
                }
70✔
347

348
                protected override void tableOnRemove(object sender, CollectionChangedEventArgs e)
349
                {
×
350
                        base.tableOnRemove(sender, e);
×
351

352
                        if (e.Item.Equals(this.Style))
×
353
                        {
×
354
                                this.Style = this.Document.TextStyles[TextStyle.DefaultName];
×
355
                        }
×
356
                }
×
357
        }
358
}
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