diff --git a/src/ACadSharp.Tests/IO/LocalSampleTests.cs b/src/ACadSharp.Tests/IO/LocalSampleTests.cs index ccc68222..90feff3d 100644 --- a/src/ACadSharp.Tests/IO/LocalSampleTests.cs +++ b/src/ACadSharp.Tests/IO/LocalSampleTests.cs @@ -48,7 +48,6 @@ public void ReadUserDxf(FileModel test) return; CadDocument doc = DxfReader.Read(test.Path, this.onNotification); - doc.Header.Version = ACadVersion.AC1032; } [Theory] diff --git a/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs b/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs index 7d3e35e5..a71a2432 100644 --- a/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs +++ b/src/ACadSharp.Tests/IO/WriterSingleObjectTests.cs @@ -31,6 +31,7 @@ static WriterSingleObjectTests() Data.Add(new(nameof(SingleCaseGenerator.SingleEllipse))); Data.Add(new(nameof(SingleCaseGenerator.SingleLine))); Data.Add(new(nameof(SingleCaseGenerator.ViewZoom))); + Data.Add(new(nameof(SingleCaseGenerator.SingleMLeader))); Data.Add(new(nameof(SingleCaseGenerator.SingleMLine))); Data.Add(new(nameof(SingleCaseGenerator.EntityColorByLayer))); Data.Add(new(nameof(SingleCaseGenerator.EntityColorTrueColor))); @@ -648,6 +649,32 @@ public void SingleLine() this.Document.Entities.Add(line); } + public void SingleMLeader() + { + MultiLeader mleader = new MultiLeader(); + mleader.PathType = MultiLeaderPathType.StraightLineSegments; + mleader.PropertyOverrideFlags = MultiLeaderPropertyOverrideFlags.ContentType | MultiLeaderPropertyOverrideFlags.TextAlignment | MultiLeaderPropertyOverrideFlags.EnableUseDefaultMText; + + mleader.ContextData.ContentBasePoint = new XYZ(1.8599999999999999, 1.5, 0); + mleader.ContextData.BasePoint = new XYZ(0, 0, 0); + mleader.ContextData.TextLabel = "This is my test MLEader"; + + var root = new MultiLeaderAnnotContext.LeaderRoot + { + ConnectionPoint = new XYZ(1.5, 1.5, 0), + ContentValid = true, + Direction = XYZ.AxisX, + LandingDistance = 0.36, + }; + MultiLeaderAnnotContext.LeaderLine leaderLine = new MultiLeaderAnnotContext.LeaderLine(); + leaderLine.PathType = MultiLeaderPathType.StraightLineSegments; + leaderLine.Points.Add(XYZ.Zero); + root.Lines.Add(leaderLine); + mleader.ContextData.LeaderRoots.Add(root); + + this.Document.Entities.Add(mleader); + } + public void SingleMLine() { //It creates a valid dxf but the MLine is wrongly drawn diff --git a/src/ACadSharp/Entities/MultiLeader.cs b/src/ACadSharp/Entities/MultiLeader.cs index 648b178b..25144a4a 100644 --- a/src/ACadSharp/Entities/MultiLeader.cs +++ b/src/ACadSharp/Entities/MultiLeader.cs @@ -19,12 +19,6 @@ namespace ACadSharp.Entities [DxfSubClass(DxfSubclassMarker.MultiLeader)] public partial class MultiLeader : Entity { - private MultiLeaderStyle _style = MultiLeaderStyle.Default; - private TextStyle _textStyle = TextStyle.Default; - private LineType _leaderLineType = LineType.ByLayer; - private BlockRecord _arrowhead; - private BlockRecord _blockContent; - /// /// Gets or sets a representing the arrowhead /// (see ) to be displayed with every leader line. @@ -67,7 +61,7 @@ public BlockRecord Arrowhead /// /// [DxfCodeValue(42)] - public double ArrowheadSize { get; set; } + public double ArrowheadSize { get; set; } = 0.18; /// /// Gets a list of objects representing @@ -76,12 +70,87 @@ public BlockRecord Arrowhead /// public IList BlockAttributes { get; private set; } = new List(); + /// + /// Gets a containing elements + /// to be drawn as content for the multileader. + /// This property overrides the value from + /// when the flag is set (see + /// property). + /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + [DxfCodeValue(DxfReferenceType.Handle, 344)] + public BlockRecord BlockContent + { + get { return this._blockContent; } + set + { + this._blockContent = this.updateTable(value, this.Document?.BlockRecords); + } + } + + /// + /// Gets or sets the block-content color. + /// This property overrides the value from + /// when the flag is set (see + /// property). + /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + [DxfCodeValue(93)] + public Color BlockContentColor { get; set; } = Color.ByBlock; + + /// + /// Gets or sets a value indicating whether the multileader connects to the content-block extents + /// or to the content-block base point + /// when the flag is set in the + /// property. + /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + [DxfCodeValue(176)] + public BlockContentConnectionType BlockContentConnection { get; set; } = BlockContentConnectionType.BlockExtents; + + /// + /// Gets or sets the rotation of the block content of the multileader. + /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + [DxfCodeValue(DxfReferenceType.IsAngle, 43)] + public double BlockContentRotation { get; set; } = 0.0; + + /// + /// Gets or sets the scale factor for block content. + /// This property overrides the value from + /// when the flag is set (see + /// property). + /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + [DxfCodeValue(10, 20, 30)] + public XYZ BlockContentScale { get; set; } = new XYZ(1); + /// /// Gets or sets a value indicating whether the content of this /// is a text label, a content block, or a tolerance. /// [DxfCodeValue(172)] - public LeaderContentType ContentType { get; set; } + public LeaderContentType ContentType { get; set; } = LeaderContentType.MText; /// /// Contains the multileader content (block/text) and the leaders. @@ -92,7 +161,7 @@ public BlockRecord Arrowhead /// Enable Annotation Scale /// [DxfCodeValue(293)] - public bool EnableAnnotationScale { get; set; } + public bool EnableAnnotationScale { get; set; } = false; /// /// Gets or sets a value indicating that leader lines of this @@ -102,7 +171,7 @@ public BlockRecord Arrowhead /// property. /// [DxfCodeValue(291)] - public bool EnableDogleg { get; set; } + public bool EnableDogleg { get; set; } = true; /// /// Gets or sets a value indicating whether landing is enabled. @@ -111,12 +180,12 @@ public BlockRecord Arrowhead /// property. /// [DxfCodeValue(290)] - public bool EnableLanding { get; set; } + public bool EnableLanding { get; set; } = true; /// /// Leader extended to text /// - public bool ExtendedToText { get; set; } + public bool ExtendedToText { get; set; } = false; /// /// Gets or sets the landing distance, i.e. the length of the dogleg, for this . @@ -132,7 +201,7 @@ public BlockRecord Arrowhead /// /// [DxfCodeValue(41)] - public double LandingDistance { get; set; } + public double LandingDistance { get; set; } = 0.36; // TODO Additional Line Type? see Entity.LineType. /// @@ -185,7 +254,7 @@ public LineType LeaderLineType /// property. /// [DxfCodeValue(171)] - public LineweightType LeaderLineWeight { get; set; } + public LineweightType LeaderLineWeight { get; set; } = LineweightType.ByBlock; /// /// Gets or sets color of the leader lines of this @@ -201,7 +270,7 @@ public LineType LeaderLineType /// property. /// [DxfCodeValue(91)] - public Color LineColor { get; set; } + public Color LineColor { get; set; } = Color.ByBlock; /// public override string ObjectName => DxfFileToken.EntityMultiLeader; @@ -217,7 +286,7 @@ public LineType LeaderLineType /// property. /// [DxfCodeValue(170)] - public MultiLeaderPathType PathType { get; set; } + public MultiLeaderPathType PathType { get; set; } = MultiLeaderPathType.StraightLineSegments; /// /// Gets or sets a value containing a list of flags indicating which multileader @@ -226,7 +295,7 @@ public LineType LeaderLineType /// or the attached . /// [DxfCodeValue(90)] - public MultiLeaderPropertyOverrideFlags PropertyOverrideFlags { get; set; } + public MultiLeaderPropertyOverrideFlags PropertyOverrideFlags { get; set; } = MultiLeaderPropertyOverrideFlags.None; /// /// Gets or sets a scale factor (see ). @@ -241,7 +310,7 @@ public LineType LeaderLineType /// assumed to be relevant. /// [DxfCodeValue(45)] - public double ScaleFactor { get; set; } + public double ScaleFactor { get; set; } = 1; /// /// Gets a providing reusable style information @@ -272,7 +341,11 @@ public MultiLeaderStyle Style /// public override string SubclassMarker => DxfSubclassMarker.MultiLeader; - #region Text Menu Properties + /// + /// Text Align in IPE (meaning unknown) + /// + [DxfCodeValue(178)] + public short TextAligninIPE { get; set; } = 0; /// /// Gets or sets the text alignement type. @@ -288,9 +361,8 @@ public MultiLeaderStyle Style /// /// [DxfCodeValue(175)] - public TextAlignmentType TextAlignment { get; set; } + public TextAlignmentType TextAlignment { get; set; } = TextAlignmentType.Left; - // TODO How to set this value? /// /// Gets or sets a value indicating the text angle. /// This property overrides the value from @@ -298,7 +370,91 @@ public MultiLeaderStyle Style /// property). /// [DxfCodeValue(174)] - public TextAngleType TextAngle { get; set; } + public TextAngleType TextAngle { get; set; } = TextAngleType.Horizontal; + + // TODO According to the OpenDesign_Specification_for_.dwg_files + // a list of arror head AND a list of block attributes can occur. + // If both list are empty it ist expected that two BL-fields should + // occur yielding count=0 for both lists. But when we read two + // BL-fields we get out of sync. If we read one BL-field everything + // works fine. + // We do not understand what a list of arroheads can be used for, + // and we do not know how to create such a list. + // The documentation for arrowheads list in OpenDesign_Specification_for_.dwg_files + // and the DXF Reference are contradicting. + // Decision: + // Ommit the Arrowheads property, + // try to keep the block attributes. + /// + /// Gets or sets the Text attachment direction for text or block contents. + /// This property overrides the value from + /// when the flag is set in the + /// property. + /// + /// + /// + /// This property defines whether the leaders attach to the left/right of the content block/text, + /// or attach to the top/bottom. + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. + /// + /// + /// + /// A . + /// + [DxfCodeValue(271)] + public TextAttachmentDirectionType TextAttachmentDirection { get; set; } = TextAttachmentDirectionType.Horizontal; + + /// + /// Gets or sets a value indicating the text attachment point. + /// + /// + /// The Open Design Specification for DWG files documents this property as Justification, + /// the DXF reference as Text Attachments point. + /// + /// This property is also exposed by the class + /// (). + /// The property always has the same value + /// and seems to have the respective value as . + /// The property is to be used. + /// + /// + [DxfCodeValue(179)] + public TextAttachmentPointType TextAttachmentPoint { get; set; } = TextAttachmentPointType.Left; + + /// + /// Gets or sets the text bottom attachment type (see ). + /// This property override the value from + /// when the flag is set (see + /// property). + /// + /// + /// This property is also exposed by the class. Values + /// should be equal, the value is + /// assumed to be used. + /// + /// + /// A having the values + /// 9 = Center, + /// 10 = Underline and Center + /// can be used ("vertical" attachment types). + /// + [DxfCodeValue(272)] + [Obsolete("Use ContextData.TextBottomAttachment instead.")] + public TextAttachmentType TextBottomAttachment + { + get + { + return this.ContextData.TextBottomAttachment; + } + set + { + this.ContextData.TextBottomAttachment = value; + } + } /// /// Gets or sets the color for the display of the text label. @@ -312,7 +468,14 @@ public MultiLeaderStyle Style /// assumed to be used. /// [DxfCodeValue(92)] - public Color TextColor { get; set; } + public Color TextColor { get; set; } = Color.ByBlock; + + // public IList Arrowheads { get; } = new List(); + /// + /// Text Direction Negative + /// + [DxfCodeValue(294)] + public bool TextDirectionNegative { get; set; } = false; /// /// Gets or sets a value indicating that the text label is to be drawn with a frame. @@ -321,7 +484,7 @@ public MultiLeaderStyle Style /// property). /// [DxfCodeValue(292)] - public bool TextFrame { get; set; } + public bool TextFrame { get; set; } = false; /// /// Gets or sets the text left attachment type (see ). @@ -339,7 +502,18 @@ public MultiLeaderStyle Style /// ("horizontal" attachment types). /// [DxfCodeValue(173)] - public TextAttachmentType TextLeftAttachment { get; set; } + [Obsolete("Use ContextData.TextLeftAttachment instead.")] + public TextAttachmentType TextLeftAttachment + { + get + { + return this.ContextData.TextLeftAttachment; + } + set + { + this.ContextData.TextLeftAttachment = value; + } + } /// /// Gets or sets the text right attachment type (see ). @@ -357,7 +531,18 @@ public MultiLeaderStyle Style /// ("horizontal" attachment types). /// [DxfCodeValue(95)] - public TextAttachmentType TextRightAttachment { get; set; } + [Obsolete("Use ContextData.TextRightAttachment instead.")] + public TextAttachmentType TextRightAttachment + { + get + { + return this.ContextData.TextRightAttachment; + } + set + { + this.ContextData.TextRightAttachment = value; + } + } /// /// Gets or sets the to be used to display the text label of this @@ -377,7 +562,7 @@ public TextStyle TextStyle { get { return this._textStyle; } set - { + { if (value == null) { throw new ArgumentNullException(nameof(value)); @@ -394,175 +579,6 @@ public TextStyle TextStyle } } - #endregion Text Menu Properties - - #region Block Content Properties - - /// - /// Gets a containing elements - /// to be drawn as content for the multileader. - /// This property overrides the value from - /// when the flag is set (see - /// property). - /// - /// - /// This property is also exposed by the class. Values - /// should be equal, the value is - /// assumed to be used. - /// - [DxfCodeValue(DxfReferenceType.Handle, 344)] - public BlockRecord BlockContent - { - get { return this._blockContent; } - set - { - this._blockContent = this.updateTable(value, this.Document?.BlockRecords); - } - } - - - /// - /// Gets or sets the block-content color. - /// This property overrides the value from - /// when the flag is set (see - /// property). - /// - /// - /// This property is also exposed by the class. Values - /// should be equal, the value is - /// assumed to be used. - /// - [DxfCodeValue(93)] - public Color BlockContentColor { get; set; } - - /// - /// Gets or sets a value indicating whether the multileader connects to the content-block extents - /// or to the content-block base point - /// when the flag is set in the - /// property. - /// - /// - /// This property is also exposed by the class. Values - /// should be equal, the value is - /// assumed to be used. - /// - [DxfCodeValue(176)] - public BlockContentConnectionType BlockContentConnection { get; set; } - - /// - /// Gets or sets the rotation of the block content of the multileader. - /// - /// - /// This property is also exposed by the class. Values - /// should be equal, the value is - /// assumed to be used. - /// - [DxfCodeValue(DxfReferenceType.IsAngle, 43)] - public double BlockContentRotation { get; set; } - - /// - /// Gets or sets the scale factor for block content. - /// This property overrides the value from - /// when the flag is set (see - /// property). - /// - /// - /// This property is also exposed by the class. Values - /// should be equal, the value is - /// assumed to be used. - /// - [DxfCodeValue(10, 20, 30)] - public XYZ BlockContentScale { get; set; } - - #endregion Block Content Properties - - // TODO According to the OpenDesign_Specification_for_.dwg_files - // a list of arror head AND a list of block attributes can occur. - // If both list are empty it ist expected that two BL-fields should - // occur yielding count=0 for both lists. But when we read two - // BL-fields we get out of sync. If we read one BL-field everything - // works fine. - // We do not understand what a list of arroheads can be used for, - // and we do not know how to create such a list. - // The documentation for arrowheads list in OpenDesign_Specification_for_.dwg_files - // and the DXF Reference are contradicting. - // Decision: - // Ommit the Arrowheads property, - // try to keep the block attributes. - - /// - /// Text Align in IPE (meaning unknown) - /// - [DxfCodeValue(178)] - public short TextAligninIPE { get; set; } - - /// - /// Gets or sets the Text attachment direction for text or block contents. - /// This property overrides the value from - /// when the flag is set in the - /// property. - /// - /// - /// - /// This property defines whether the leaders attach to the left/right of the content block/text, - /// or attach to the top/bottom. - /// - /// The value for all leader lines can be overridden for each individual leader line by the - /// property when the - /// flag is set in the - /// property. - /// - /// - /// - /// A . - /// - [DxfCodeValue(271)] - public TextAttachmentDirectionType TextAttachmentDirection { get; set; } - - /// - /// Gets or sets a value indicating the text attachment point. - /// - /// - /// The Open Design Specification for DWG files documents this property as Justification, - /// the DXF reference as Text Attachments point. - /// - /// This property is also exposed by the class - /// (). - /// The property always has the same value - /// and seems to have the respective value as . - /// The property is to be used. - /// - /// - [DxfCodeValue(179)] - public TextAttachmentPointType TextAttachmentPoint { get; set; } - - /// - /// Gets or sets the text bottom attachment type (see ). - /// This property override the value from - /// when the flag is set (see - /// property). - /// - /// - /// This property is also exposed by the class. Values - /// should be equal, the value is - /// assumed to be used. - /// - /// - /// A having the values - /// 9 = Center, - /// 10 = Underline and Center - /// can be used ("vertical" attachment types). - /// - [DxfCodeValue(272)] - public TextAttachmentType TextBottomAttachment { get; set; } - - // public IList Arrowheads { get; } = new List(); - /// - /// Text Direction Negative - /// - [DxfCodeValue(294)] - public bool TextDirectionNegative { get; set; } - /// /// Gets or sets the text top attachment type (see ). /// This property override the value from @@ -581,7 +597,24 @@ public BlockRecord BlockContent /// can be used ("vertical" attachment types). /// [DxfCodeValue(273)] - public TextAttachmentType TextTopAttachment { get; set; } + [Obsolete("Use ContextData.TextTopAttachment instead.")] + public TextAttachmentType TextTopAttachment + { + get + { + return this.ContextData.TextTopAttachment; + } + set + { + this.ContextData.TextTopAttachment = value; + } + } + + private BlockRecord _arrowhead; + private BlockRecord _blockContent; + private LineType _leaderLineType = LineType.ByLayer; + private MultiLeaderStyle _style = MultiLeaderStyle.Default; + private TextStyle _textStyle = TextStyle.Default; /// public override void ApplyTransform(Transform transform) @@ -610,6 +643,12 @@ public override CadObject Clone() return clone; } + /// + public override BoundingBox GetBoundingBox() + { + return BoundingBox.Null; + } + internal override void AssignDocument(CadDocument doc) { base.AssignDocument(doc); @@ -646,7 +685,8 @@ internal override void UnassignDocument() this._blockContent = (BlockRecord)this._blockContent?.Clone(); } - protected override void tableOnRemove(object sender, CollectionChangedEventArgs e) { + protected override void tableOnRemove(object sender, CollectionChangedEventArgs e) + { base.tableOnRemove(sender, e); if (e.Item.Equals(this._style)) @@ -670,12 +710,5 @@ protected override void tableOnRemove(object sender, CollectionChangedEventArgs this._blockContent = null; } } - - - /// - public override BoundingBox GetBoundingBox() - { - return BoundingBox.Null; - } } } \ No newline at end of file diff --git a/src/ACadSharp/Entities/MultiLeaderPropertyOverrideFlags.cs b/src/ACadSharp/Entities/MultiLeaderPropertyOverrideFlags.cs index 49c7ec62..0c602c4c 100644 --- a/src/ACadSharp/Entities/MultiLeaderPropertyOverrideFlags.cs +++ b/src/ACadSharp/Entities/MultiLeaderPropertyOverrideFlags.cs @@ -131,7 +131,6 @@ public enum MultiLeaderPropertyOverrideFlags : int /// BlockContentConnection = 0x800000, - /// /// Override property. /// diff --git a/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs b/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs index 18486902..70af3420 100644 --- a/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs +++ b/src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs @@ -1054,10 +1054,6 @@ private CadTemplate readUnlistedType(short classNumber) template = this.readMultiLeader(); break; case "MLEADERSTYLE": - if (!this.R2010Plus) { - this.notify($"MLEADERSTYLE is not supported for {this._version}.", NotificationType.Warning); - return null; - } template = this.readMultiLeaderStyle(); break; case "PDFDEFINITION": @@ -3129,12 +3125,14 @@ private CadTemplate readMultiLeader() // Multileader Common data // 340 Leader StyleId (handle) template.LeaderStyleHandle = this.handleReference(); + //BL 90 Property Override Flags (int32) mLeader.PropertyOverrideFlags = (MultiLeaderPropertyOverrideFlags)this._objectReader.ReadBitLong(); //BS 170 LeaderLineType (short) mLeader.PathType = (MultiLeaderPathType)this._objectReader.ReadBitShort(); //CMC 91 Leade LineColor (Color) mLeader.LineColor = this._mergedReaders.ReadCmColor(); + //H 341 LeaderLineTypeID (handle/LineType) template.LeaderLineTypeHandle = this.handleReference(); @@ -3144,9 +3142,9 @@ private CadTemplate readMultiLeader() mLeader.EnableLanding = this._objectReader.ReadBit(); //B 291 Enable Dogleg mLeader.EnableDogleg = this._objectReader.ReadBit(); - // 41 Dogleg Length / Landing distance mLeader.LandingDistance = this._objectReader.ReadBitDouble(); + // 342 Arrowhead ID template.ArrowheadHandle = this.handleReference(); @@ -3154,6 +3152,7 @@ private CadTemplate readMultiLeader() mLeader.ArrowheadSize = this._objectReader.ReadBitDouble(); //BS 172 Content Type mLeader.ContentType = (LeaderContentType)this._objectReader.ReadBitShort(); + //H 343 Text Style ID (handle/TextStyle) template.MTextStyleHandle = this.handleReference(); @@ -3161,6 +3160,7 @@ private CadTemplate readMultiLeader() mLeader.TextLeftAttachment = (TextAttachmentType)this._objectReader.ReadBitShort(); // 95 Text Right Attachment Type mLeader.TextRightAttachment = (TextAttachmentType)this._objectReader.ReadBitShort(); + // 174 Text Angle Type mLeader.TextAngle = (TextAngleType)this._objectReader.ReadBitShort(); // 175 Text Alignment Type @@ -3523,8 +3523,11 @@ private CadTemplate readMultiLeaderStyle() this.readCommonNonEntityData(template); - // BS 179 Version expected: 2 - var version = this._objectReader.ReadBitShort(); + if (this.R2010Plus) + { + // BS 179 Version expected: 2 + var version = this._objectReader.ReadBitShort(); + } // BS 170 Content type (see paragraph on LEADER for more details). mLeaderStyle.ContentType = (LeaderContentType)this._objectReader.ReadBitShort(); @@ -3533,7 +3536,7 @@ private CadTemplate readMultiLeaderStyle() // BS 172 Draw leader order (0 = draw leader head first, 1 = draw leader tail first) mLeaderStyle.LeaderDrawOrder = (LeaderDrawOrderType)this._objectReader.ReadBitShort(); // BL 90 Maximum number of points for leader - mLeaderStyle.MaxLeaderSegmentsPoints = this._objectReader.ReadBitShort(); + mLeaderStyle.MaxLeaderSegmentsPoints = this._objectReader.ReadBitLong(); // BD 40 First segment angle (radians) mLeaderStyle.FirstSegmentAngleConstraint = this._objectReader.ReadBitDouble(); // BD 41 Second segment angle (radians) @@ -3542,8 +3545,10 @@ private CadTemplate readMultiLeaderStyle() mLeaderStyle.PathType = (MultiLeaderPathType)this._objectReader.ReadBitShort(); // CMC 91 Leader line color mLeaderStyle.LineColor = this._mergedReaders.ReadCmColor(); + // H 340 Leader line type handle (hard pointer) template.LeaderLineTypeHandle = this.handleReference(); + // BL 92 Leader line weight mLeaderStyle.LeaderLineWeight = (LineweightType)this._objectReader.ReadBitLong(); // B 290 Is landing enabled? @@ -3556,25 +3561,25 @@ private CadTemplate readMultiLeaderStyle() mLeaderStyle.LandingDistance = this._objectReader.ReadBitDouble(); // TV 3 Style description mLeaderStyle.Description = this._mergedReaders.ReadVariableText(); + // H 341 Arrow head block handle (hard pointer) template.ArrowheadHandle = this.handleReference(); + // BD 44 Arrow head size mLeaderStyle.ArrowheadSize = this._objectReader.ReadBitDouble(); // TV 300 Text default mLeaderStyle.DefaultTextContents = this._mergedReaders.ReadVariableText(); + // H 342 Text style handle (hard pointer) template.MTextStyleHandle = this.handleReference(); + // BS 174 Left attachment (see paragraph on LEADER for more details). mLeaderStyle.TextLeftAttachment = (TextAttachmentType)this._objectReader.ReadBitShort(); // BS 178 Right attachment (see paragraph on LEADER for more details). mLeaderStyle.TextRightAttachment = (TextAttachmentType)this._objectReader.ReadBitShort(); - if (this.R2010Plus) - {// IF IsNewFormat OR DXF file - // BS 175 Text angle type (see paragraph on LEADER for more details). - mLeaderStyle.TextAngle = (TextAngleType)this._objectReader.ReadBitShort(); - - } // END IF IsNewFormat OR DXF file - // BS 176 Text alignment type + // BS 175 Text angle type (see paragraph on LEADER for more details). + mLeaderStyle.TextAngle = (TextAngleType)this._objectReader.ReadBitShort(); + // BS 176 Text alignment type mLeaderStyle.TextAlignment = (TextAlignmentType)this._objectReader.ReadBitShort(); // CMC 93 Text color mLeaderStyle.TextColor = this._mergedReaders.ReadCmColor(); @@ -3582,15 +3587,14 @@ private CadTemplate readMultiLeaderStyle() mLeaderStyle.TextHeight = this._objectReader.ReadBitDouble(); // B 292 Text frame enabled mLeaderStyle.TextFrame = this._objectReader.ReadBit(); - if (this.R2010Plus) - {// IF IsNewFormat OR DXF file - // B 297 Always align text left - mLeaderStyle.TextAlignAlwaysLeft = this._objectReader.ReadBit(); - }// END IF IsNewFormat OR DXF file - // BD 46 Align space + // B 297 Always align text left + mLeaderStyle.TextAlignAlwaysLeft = this._objectReader.ReadBit(); + // BD 46 Align space mLeaderStyle.AlignSpace = this._objectReader.ReadBitDouble(); + // H 343 Block handle (hard pointer) template.BlockContentHandle = this.handleReference(); + // CMC 94 Block color mLeaderStyle.BlockContentColor = this._mergedReaders.ReadCmColor(); // 3BD 47,49,140 Block scale vector @@ -3615,15 +3619,21 @@ private CadTemplate readMultiLeaderStyle() // BD 143 Break size mLeaderStyle.BreakGapSize = this._objectReader.ReadBitDouble(); - // BS 271 Attachment direction (see paragraph on LEADER for more details). - mLeaderStyle.TextAttachmentDirection = (TextAttachmentDirectionType)this._objectReader.ReadBitShort(); - // BS 273 Top attachment (see paragraph on LEADER for more details). - mLeaderStyle.TextBottomAttachment = (TextAttachmentType)this._objectReader.ReadBitShort(); - // BS 272 Bottom attachment (see paragraph on LEADER for more details). - mLeaderStyle.TextTopAttachment = (TextAttachmentType)this._objectReader.ReadBitShort(); + if (this.R2010Plus) + { + // BS 271 Attachment direction (see paragraph on LEADER for more details). + mLeaderStyle.TextAttachmentDirection = (TextAttachmentDirectionType)this._objectReader.ReadBitShort(); + // BS 273 Top attachment (see paragraph on LEADER for more details). + mLeaderStyle.TextBottomAttachment = (TextAttachmentType)this._objectReader.ReadBitShort(); + // BS 272 Bottom attachment (see paragraph on LEADER for more details). + mLeaderStyle.TextTopAttachment = (TextAttachmentType)this._objectReader.ReadBitShort(); + } - // B 298 Undocumented, found in DXF - mLeaderStyle.UnknownFlag298 = this._objectReader.ReadBit(); + if (this.R2013Plus) + { + // B 298 Undocumented, found in DXF + mLeaderStyle.UnknownFlag298 = this._objectReader.ReadBit(); + } return template; } diff --git a/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs b/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs index 8fc41fb3..a7ca09b0 100644 --- a/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs +++ b/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs @@ -1143,7 +1143,7 @@ private void writeMultiLeader(MultiLeader multiLeader) this._writer.WriteBitLong((int)multiLeader.PropertyOverrideFlags); // 170 LeaderLineType (short) this._writer.WriteBitShort((short)multiLeader.PathType); - // 91 Leade LineColor (Color) + // 91 Leader LineColor (Color) this._writer.WriteCmColor(multiLeader.LineColor); // 341 LeaderLineTypeID (handle/LineType) this._writer.HandleReference(DwgReferenceType.HardPointer, multiLeader.LeaderLineType); diff --git a/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Objects.cs b/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Objects.cs index 5066fcfa..2001a45e 100644 --- a/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Objects.cs +++ b/src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Objects.cs @@ -28,8 +28,6 @@ private void writeObject(CadObject obj) { case EvaluationGraph: case Material: - case MultiLeaderAnnotContext: - case MultiLeaderStyle when !this.R2010Plus: case SortEntitiesTable: case UnknownNonGraphicalObject: case VisualStyle: @@ -532,14 +530,12 @@ private void writeMLineStyle(MLineStyle mlineStyle) private void writeMultiLeaderStyle(MultiLeaderStyle mLeaderStyle) { - if (!R2010Plus) + if (this.R2010Plus) { - return; + // BS 179 Version expected: 2 + this._writer.WriteBitShort(2); } - // BS 179 Version expected: 2 - this._writer.WriteBitShort(2); - // BS 170 Content type (see paragraph on LEADER for more details). this._writer.WriteBitShort((short)mLeaderStyle.ContentType); // BS 171 Draw multi-leader order (0 = draw content first, 1 = draw leader first) @@ -547,7 +543,7 @@ private void writeMultiLeaderStyle(MultiLeaderStyle mLeaderStyle) // BS 172 Draw leader order (0 = draw leader head first, 1 = draw leader tail first) this._writer.WriteBitShort((short)mLeaderStyle.LeaderDrawOrder); // BL 90 Maximum number of points for leader - this._writer.WriteBitShort((short)mLeaderStyle.MaxLeaderSegmentsPoints); + this._writer.WriteBitLong((short)mLeaderStyle.MaxLeaderSegmentsPoints); // BD 40 First segment angle (radians) this._writer.WriteBitDouble(mLeaderStyle.FirstSegmentAngleConstraint); // BD 41 Second segment angle (radians) @@ -556,8 +552,10 @@ private void writeMultiLeaderStyle(MultiLeaderStyle mLeaderStyle) this._writer.WriteBitShort((short)mLeaderStyle.PathType); // CMC 91 Leader line color this._writer.WriteCmColor(mLeaderStyle.LineColor); + // H 340 Leader line type handle (hard pointer) this._writer.HandleReference(DwgReferenceType.HardPointer, mLeaderStyle.LeaderLineType); + // BL 92 Leader line weight this._writer.WriteBitLong((short)mLeaderStyle.LeaderLineWeight); // B 290 Is landing enabled? @@ -570,25 +568,24 @@ private void writeMultiLeaderStyle(MultiLeaderStyle mLeaderStyle) this._writer.WriteBitDouble(mLeaderStyle.LandingDistance); // TV 3 Style description this._writer.WriteVariableText(mLeaderStyle.Description); + // H 341 Arrow head block handle (hard pointer) this._writer.HandleReference(DwgReferenceType.HardPointer, mLeaderStyle.Arrowhead); + // BD 44 Arrow head size this._writer.WriteBitDouble(mLeaderStyle.ArrowheadSize); // TV 300 Text default this._writer.WriteVariableText(mLeaderStyle.DefaultTextContents); + // H 342 Text style handle (hard pointer) this._writer.HandleReference(DwgReferenceType.HardPointer, mLeaderStyle.TextStyle); + // BS 174 Left attachment (see paragraph on LEADER for more details). this._writer.WriteBitShort((short)mLeaderStyle.TextLeftAttachment); // BS 178 Right attachment (see paragraph on LEADER for more details). this._writer.WriteBitShort((short)mLeaderStyle.TextRightAttachment); - if (R2010Plus) - { - // IF IsNewFormat OR DXF file - // BS 175 Text angle type (see paragraph on LEADER for more details). - this._writer.WriteBitShort((short)mLeaderStyle.TextAngle); - // END IF IsNewFormat OR DXF file - } + // BS 175 Text angle type (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextAngle); // BS 176 Text alignment type this._writer.WriteBitShort((short)mLeaderStyle.TextAlignment); // CMC 93 Text color @@ -597,17 +594,14 @@ private void writeMultiLeaderStyle(MultiLeaderStyle mLeaderStyle) this._writer.WriteBitDouble(mLeaderStyle.TextHeight); // B 292 Text frame enabled this._writer.WriteBit(mLeaderStyle.TextFrame); - if (R2010Plus) - { - // IF IsNewFormat OR DXF file - // B 297 Always align text left - this._writer.WriteBit(mLeaderStyle.TextAlignAlwaysLeft); - // END IF IsNewFormat OR DXF file - } + // B 297 Always align text left + this._writer.WriteBit(mLeaderStyle.TextAlignAlwaysLeft); // BD 46 Align space this._writer.WriteBitDouble(mLeaderStyle.AlignSpace); + // H 343 Block handle (hard pointer) this._writer.HandleReference(DwgReferenceType.HardPointer, mLeaderStyle.BlockContent); + // CMC 94 Block color this._writer.WriteCmColor(mLeaderStyle.BlockContentColor); // 3BD 47,49,140 Block scale vector @@ -632,15 +626,21 @@ private void writeMultiLeaderStyle(MultiLeaderStyle mLeaderStyle) // BD 143 Break size this._writer.WriteBitDouble(mLeaderStyle.BreakGapSize); - // BS 271 Attachment direction (see paragraph on LEADER for more details). - this._writer.WriteBitShort((short)mLeaderStyle.TextAttachmentDirection); - // BS 273 Top attachment (see paragraph on LEADER for more details). - this._writer.WriteBitShort((short)mLeaderStyle.TextBottomAttachment); - // BS 272 Bottom attachment (see paragraph on LEADER for more details). - this._writer.WriteBitShort((short)mLeaderStyle.TextTopAttachment); + if (this.R2010Plus) + { + // BS 271 Attachment direction (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextAttachmentDirection); + // BS 273 Top attachment (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextBottomAttachment); + // BS 272 Bottom attachment (see paragraph on LEADER for more details). + this._writer.WriteBitShort((short)mLeaderStyle.TextTopAttachment); + } - // B 298 Undocumented, found in DXF - this._writer.WriteBit(mLeaderStyle.UnknownFlag298); + if (this.R2013Plus) + { + // B 298 Undocumented, found in DXF + this._writer.WriteBit(mLeaderStyle.UnknownFlag298); + } } private void writePlotSettings(PlotSettings plot) diff --git a/src/ACadSharp/IO/Templates/CadMLeaderStyleTemplate.cs b/src/ACadSharp/IO/Templates/CadMLeaderStyleTemplate.cs index 5467e9c8..b02ba05d 100644 --- a/src/ACadSharp/IO/Templates/CadMLeaderStyleTemplate.cs +++ b/src/ACadSharp/IO/Templates/CadMLeaderStyleTemplate.cs @@ -5,15 +5,17 @@ namespace ACadSharp.IO.Templates { internal class CadMLeaderStyleTemplate : CadTemplate { - public CadMLeaderStyleTemplate(MultiLeaderStyle entry) : base(entry) { } + public ulong ArrowheadHandle { get; internal set; } - public ulong LeaderLineTypeHandle { get; internal set; } + public ulong BlockContentHandle { get; internal set; } - public ulong ArrowheadHandle { get; internal set; } + public ulong LeaderLineTypeHandle { get; internal set; } public ulong MTextStyleHandle { get; internal set; } - public ulong BlockContentHandle { get; internal set; } + public CadMLeaderStyleTemplate(MultiLeaderStyle entry) : base(entry) + { + } public override void Build(CadDocumentBuilder builder) { @@ -24,9 +26,11 @@ public override void Build(CadDocumentBuilder builder) this.CadObject.LeaderLineType = lineType; } - //if (builder.TryGetCadObject(this.ArrowheadHandle, out Arr arrowhead)) { - // this.CadObject.Arrowhead = arrowhead; - //} + if (builder.TryGetCadObject(this.ArrowheadHandle, out BlockRecord arrowhead)) + { + this.CadObject.Arrowhead = arrowhead; + } + if (builder.TryGetCadObject(this.MTextStyleHandle, out TextStyle textStyle)) { this.CadObject.TextStyle = textStyle; @@ -38,4 +42,4 @@ public override void Build(CadDocumentBuilder builder) } } } -} +} \ No newline at end of file diff --git a/src/ACadSharp/Objects/MultiLeaderAnnotContext.cs b/src/ACadSharp/Objects/MultiLeaderAnnotContext.cs index 8cea6d3e..148c8a7a 100644 --- a/src/ACadSharp/Objects/MultiLeaderAnnotContext.cs +++ b/src/ACadSharp/Objects/MultiLeaderAnnotContext.cs @@ -7,80 +7,14 @@ using CSMath; - -namespace ACadSharp.Objects { - +namespace ACadSharp.Objects +{ /// /// This class represents a subset ob the properties of the MLeaderAnnotContext /// object, that are embedded into the MultiLeader entity. /// public partial class MultiLeaderAnnotContext : NonGraphicalObject { - private TextStyle _textStyle = TextStyle.Default; - private BlockRecord _blockContent; - - public override ObjectType ObjectType => ObjectType.UNLISTED; - - /// - public override string SubclassMarker => DxfSubclassMarker.MultiLeaderAnnotContext; - - /// - public override string ObjectName => DxfFileToken.ObjectMLeaderContextData; - - - /// - /// Gets the list of objects of the multileader. - /// - /// - /// A can have one or two leader roots having one ore more - /// leader lines each. - /// - public IList LeaderRoots { get; private set; } = new List(); - - /// - /// Gets or sets a scale factor (see ). - /// This property overrides the value from - /// when the flag is set (see - /// property). - /// The scale factor is applied by AutoCAD. - /// - /// - /// - /// The following properties entered in AutoCAD are multiplied with this scale factor: - /// - /// , , , - /// , and the elements of . - /// - /// The is adjusted. - /// - /// - [DxfCodeValue(40)] - public double ScaleFactor { get; set; } - - // TODO - /// - /// Gets or sets the content base point. This point is identical with the landing end - /// point of the first leader. - /// - /// - /// This point - /// - [DxfCodeValue(10, 20, 30)] - public XYZ ContentBasePoint { get; set; } - - /// - /// Get or sets the text height for the lext label of the multileader - /// (see ). - /// This property overrides the value from - /// when the flag is set in the - /// property. - /// - /// - /// The value returned is the value entered in AutoCAD multiplied with the . - /// - [DxfCodeValue(41)] - public double TextHeight { get; set; } - /// /// Gets or sets the arrowhead size (see ) /// for every leader line. @@ -92,7 +26,7 @@ public partial class MultiLeaderAnnotContext : NonGraphicalObject /// /// The value for all leader lines can be overridden for each individual leader line by the /// property when the - /// flag is set in the + /// flag is set in the /// property. /// /// This property is also exposed by the class @@ -104,71 +38,88 @@ public partial class MultiLeaderAnnotContext : NonGraphicalObject /// The value returned is the value entered in AutoCAD multiplied with the . /// [DxfCodeValue(140)] - public double ArrowheadSize { get; set; } + public double ArrowheadSize { get; set; } = 0.18; + // TODO Create test cases /// - /// Gets or sets the landing gap (see ). - /// This property overrides the value from - /// when the flag is set (see - /// property). + /// Background fill color /// - [DxfCodeValue(145)] - public double LandingGap { get; set; } + [DxfCodeValue(91)] + public Color BackgroundFillColor { get; set; } = Color.ByBlock; + // TODO Create test cases /// - /// Gets or sets the text top attachment type (see ). - /// This property overrides the value from - /// when the flag is set (see - /// property). + /// Is background fill enabled /// - /// - /// This property is also exposed by the class - /// (). - /// Values should be equal, the value of this property is assumed to be used. - /// - /// - /// A having the values 0-8 - /// can be used ("horizontal" attachment types). - /// - [DxfCodeValue(174)] - public TextAttachmentType TextLeftAttachment { get; set; } + [DxfCodeValue(291)] + public bool BackgroundFillEnabled { get; set; } = false; + // TODO Create test cases /// - /// Gets or sets the text top attachment type (see ). + /// Is background mask fill on + /// + [DxfCodeValue(292)] + public bool BackgroundMaskFillOn { get; set; } = false; + + // TODO Create test cases + /// + /// Background scale factor + /// + [DxfCodeValue(141)] + public double BackgroundScaleFactor { get; set; } = 0.0d; + + // TODO Create test cases + /// + /// Background transparency + /// + [DxfCodeValue(92)] + public int BackgroundTransparency { get; set; } = 0; + + /// + /// Base direction + /// + [DxfCodeValue(111, 121, 131)] + public XYZ BaseDirection { get; set; } = XYZ.AxisX; + + /// + /// Base point + /// + [DxfCodeValue(110, 120, 130)] + public XYZ BasePoint { get; set; } = XYZ.Zero; + + /// + /// Base vertical + /// + [DxfCodeValue(112, 122, 132)] + public XYZ BaseVertical { get; set; } = XYZ.AxisY; + + /// + /// Gets a containing elements + /// to be drawn as content for the multileader. + /// + [DxfCodeValue(DxfReferenceType.Handle, 341)] + public BlockRecord BlockContent + { + get { return this._blockContent; } + set + { + this._blockContent = this.updateTable(value, this.Document?.BlockRecords); + } + } + + /// + /// Gets or sets the block-content color. /// This property overrides the value from - /// when the flag is set (see + /// when the flag is set (see /// property). /// /// /// This property is also exposed by the class - /// (). + /// (). /// Values should be equal, the value of this property is assumed to be used. /// - /// - /// A having the values 0-8 - /// can be used ("horizontal" attachment types). - /// - [DxfCodeValue(175)] - public TextAttachmentType TextRightAttachment { get; set; } - - /// - /// Gets or sets the text alignment, i.e. the alignment of text lines if the a multiline - /// text label, relative to the . - /// This property overrides the value from - /// when the flag is set in the - /// property. - /// - /// - /// This property contains the alignment value specified in AutoCAD rather than - /// and seems always to be consistent with - /// . - /// - /// Note that when changing this value the must be changed - /// accordingly. - /// - /// - [DxfCodeValue(176)] - public TextAlignmentType TextAlignment { get; set; } + [DxfCodeValue(93)] + public Color BlockContentColor { get; set; } = Color.ByBlock; /// /// Gets or sets a value indicating whether the multileader connects to the content-block extents @@ -183,89 +134,58 @@ public partial class MultiLeaderAnnotContext : NonGraphicalObject /// Values should be equal, the value of this property is assumed to be used. /// [DxfCodeValue(177)] - public BlockContentConnectionType BlockContentConnection { get; set; } - - // TODO Check dependency of HasTextContent, HasContentBlock and MultiLeader.ContentType - /// - /// Gets or sets a value indicating that the mutileader has a text label. - /// - [DxfCodeValue(290)] - public bool HasTextContents { get; set; } + public BlockContentConnectionType BlockContentConnection { get; set; } = BlockContentConnectionType.BlockExtents; /// - /// Gets or sets a string containg the text tat is to be dispayed a s text label of the - /// multileader. + /// Gets or sets the location of the böock content of the multileader. /// /// - /// The string may contain MTEXT markups to specify new-lines, font, size, style, etc. + /// This location is evaluated by AutoCAD from the /// - [DxfCodeValue(304)] - public string TextLabel { get; set; } + [DxfCodeValue(15, 25, 35)] + public XYZ BlockContentLocation { get; set; } = XYZ.Zero; /// - /// Gets or sets the normal vector for the text label of the multileader. + /// Gets or sets the normal vector for the block content of the multileader. /// - [DxfCodeValue(11, 21, 31)] - public XYZ TextNormal { get; set; } + [DxfCodeValue(14, 24, 34)] + public XYZ BlockContentNormal { get; set; } = XYZ.Zero; /// - /// Gets or sets the to be used to display the text label of the - /// multileader. - /// This property overrides the value from - /// when the flag is set in the - /// property. + /// Gets or sets the rotation of the block content of the multileader. /// /// /// This property is also exposed by the class - /// (). + /// (). /// Values should be equal, the value of this property is assumed to be used. /// - [DxfCodeValue(DxfReferenceType.Handle, 340)] - public TextStyle TextStyle - { - get { return this._textStyle; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - if (this.Document != null) - { - this._textStyle = this.updateTable(value, this.Document.TextStyles); - } - else - { - this._textStyle = value; - } - } - } - + /// + /// The rotation angle in radians. + /// + [DxfCodeValue(DxfReferenceType.IsAngle, 46)] + public double BlockContentRotation { get; set; } = 0; /// - /// Gets or sets the location of the text label of the multileader. + /// Gets or sets the scale factor for block content. + /// This property overrides the value from + /// when the flag is set (see + /// property). /// /// - /// This location is evaluated by AutoCAD from the + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. /// - [DxfCodeValue(12, 22, 32)] - public XYZ TextLocation { get; set; } - - /// - /// Direction - /// - [DxfCodeValue(13, 23, 33)] - public XYZ Direction { get; set; } + [DxfCodeValue(16, 26, 36)] + public XYZ BlockContentScale { get; set; } = XYZ.Zero; + // TODO /// - /// Gets or sets the rotation of the text label of the multileader. + /// Boundary height (DXF Reference: TextHeight) + /// Value seems to be always zero. /// - /// - /// The rotation angle in radians. - /// - [DxfCodeValue(DxfReferenceType.IsAngle, 42)] - public double TextRotation { get; set; } + [DxfCodeValue(44)] + public double BoundaryHeight { get; set; } // TODO /// @@ -275,48 +195,57 @@ public TextStyle TextStyle [DxfCodeValue(43)] public double BoundaryWidth { get; set; } - // TODO + // TODO Create test cases /// - /// Boundary height (DXF Reference: TextHeight) - /// Value seems to be always zero. + /// Column flow reversed /// - [DxfCodeValue(44)] - public double BoundaryHeight { get; set; } + [DxfCodeValue(294)] + public bool ColumnFlowReversed { get; set; } + // TODO Create test cases /// - /// Gets or sets the line-spacing factor for the display of the text label. + /// Column gutter /// - [DxfCodeValue(45)] - public double LineSpacingFactor { get; set; } + [DxfCodeValue(143)] + public double ColumnGutter { get; set; } + // TODO Create test cases /// - /// Gets or sets the line spacing style for the display of the text label. + /// Get a list of column sizes /// - [DxfCodeValue(170)] - public LineSpacingStyle LineSpacing { get; set; } + [DxfCodeValue(144)] + public IList ColumnSizes { get; } = new List(); + // TODO Create test cases /// - /// Gets or sets the color for the display of the text label + /// Column type (ODA writes 0) /// - [DxfCodeValue(90)] - public Color TextColor { get; set; } + [DxfCodeValue(173)] + public short ColumnType { get; set; } + // TODO Create test cases /// - /// Gets or sets a value indicating the text attachment point. + /// Column width /// - /// - /// In the Open Design Specification this property is documented as Alignment, in DXF - /// reference as Text Attachment. It is not clear what the meaning of this property - /// is in contrast to the property. The value seems to be always - /// consistent. - /// - /// This property is also exposed by the class - /// (). - /// Values should be equal, the value of this property is assumed to be used. - /// + [DxfCodeValue(142)] + public double ColumnWidth { get; set; } + + // TODO + /// + /// Gets or sets the content base point. This point is identical with the landing end + /// point of the first leader. + /// + /// + /// This point /// - [DxfCodeValue(171)] - public TextAttachmentPointType TextAttachmentPoint { get; set; } + [DxfCodeValue(10, 20, 30)] + public XYZ ContentBasePoint { get; set; } + + /// + /// Direction. + /// + [DxfCodeValue(13, 23, 33)] + public XYZ Direction { get; set; } = XYZ.AxisX; // TODO What is exactly ment by "flow direction"? // When the value is not Horizontal line breaks in text label have to be ignored. @@ -325,211 +254,269 @@ public TextStyle TextStyle /// Gets or sets a value indicating the flow direction. /// [DxfCodeValue(172)] - public FlowDirectionType FlowDirection { get; set; } + public FlowDirectionType FlowDirection { get; set; } = FlowDirectionType.ByStyle; - // TODO Create test cases + // TODO Check dependency of HasTextContent, HasContentBlock and MultiLeader.ContentType /// - /// Background fill color + /// Gets or sets a value indicating that the multileader has a content block. /// - [DxfCodeValue(91)] - public Color BackgroundFillColor { get; set; } + [DxfCodeValue(296)] + public bool HasContentsBlock { get; set; } = false; - // TODO Create test cases + // TODO Check dependency of HasTextContent, HasContentBlock and MultiLeader.ContentType /// - /// Background scale factor + /// Gets or sets a value indicating that the mutileader has a text label. /// - [DxfCodeValue(141)] - public double BackgroundScaleFactor { get; set; } + [DxfCodeValue(290)] + public bool HasTextContents { get; set; } = false; - // TODO Create test cases /// - /// Background transparency + /// Gets or sets the landing gap (see ). + /// This property overrides the value from + /// when the flag is set (see + /// property). /// - [DxfCodeValue(92)] - public int BackgroundTransparency { get; set; } + [DxfCodeValue(145)] + public double LandingGap { get; set; } = 0.09; - // TODO Create test cases /// - /// Is background fill enabled + /// Gets the list of objects of the multileader. /// - [DxfCodeValue(291)] - public bool BackgroundFillEnabled { get; set; } + /// + /// A can have one or two leader roots having one ore more + /// leader lines each. + /// + public IList LeaderRoots { get; private set; } = new List(); - // TODO Create test cases /// - /// Is background mask fill on + /// Gets or sets the line spacing style for the display of the text label. /// - [DxfCodeValue(292)] - public bool BackgroundMaskFillOn { get; set; } + [DxfCodeValue(170)] + public LineSpacingStyle LineSpacing { get; set; } = LineSpacingStyle.AtLeast; - // TODO Create test cases /// - /// Column type (ODA writes 0) + /// Gets or sets the line-spacing factor for the display of the text label. /// - [DxfCodeValue(173)] - public short ColumnType { get; set; } + [DxfCodeValue(45)] + public double LineSpacingFactor { get; set; } = 1.0d; - // TODO Create test cases /// - /// Is text height automatic? + /// Is normal reversed? /// - [DxfCodeValue(293)] - public bool TextHeightAutomatic { get; set; } + [DxfCodeValue(297)] + public bool NormalReversed { get; set; } - // TODO Create test cases - /// - /// Column width - /// - [DxfCodeValue(142)] - public double ColumnWidth { get; set; } + /// + public override string ObjectName => DxfFileToken.ObjectMLeaderContextData; + + public override ObjectType ObjectType => ObjectType.UNLISTED; - // TODO Create test cases /// - /// Column gutter + /// Gets or sets a scale factor (see ). + /// This property overrides the value from + /// when the flag is set (see + /// property). + /// The scale factor is applied by AutoCAD. /// - [DxfCodeValue(143)] - public double ColumnGutter { get; set; } + /// + /// + /// The following properties entered in AutoCAD are multiplied with this scale factor: + /// + /// , , , + /// , and the elements of . + /// + /// The is adjusted. + /// + /// + [DxfCodeValue(40)] + public double ScaleFactor { get; set; } = 1; + + /// + public override string SubclassMarker => DxfSubclassMarker.MultiLeaderAnnotContext; - // TODO Create test cases /// - /// Column flow reversed + /// Gets or sets the text alignment, i.e. the alignment of text lines if the a multiline + /// text label, relative to the . + /// This property overrides the value from + /// when the flag is set in the + /// property. /// - [DxfCodeValue(294)] - public bool ColumnFlowReversed { get; set; } + /// + /// This property contains the alignment value specified in AutoCAD rather than + /// and seems always to be consistent with + /// . + /// + /// Note that when changing this value the must be changed + /// accordingly. + /// + /// + [DxfCodeValue(176)] + public TextAlignmentType TextAlignment { get; set; } = TextAlignmentType.Left; - // TODO Create test cases /// - /// Get a list of column sizes + /// Gets or sets a value indicating the text attachment point. /// - [DxfCodeValue(144)] - public IList ColumnSizes { get; } = new List(); + /// + /// In the Open Design Specification this property is documented as Alignment, in DXF + /// reference as Text Attachment. It is not clear what the meaning of this property + /// is in contrast to the property. The value seems to be always + /// consistent. + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// + /// + [DxfCodeValue(171)] + public TextAttachmentPointType TextAttachmentPoint { get; set; } = TextAttachmentPointType.Left; - // TODO Create test cases /// - /// Word break + /// Gets or sets the text bottom attachment type (see ). + /// This property override the value from + /// when the flag is set (see + /// property). /// - [DxfCodeValue(295)] - public bool WordBreak { get; set; } + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// + /// + /// A having the values + /// 9 = Center, + /// 10 = Underline and Center + /// can be used ("vertical" attachment types). + /// + [DxfCodeValue(272)] + public TextAttachmentType TextBottomAttachment { get; set; } = TextAttachmentType.CenterOfText; - // TODO Check dependency of HasTextContent, HasContentBlock and MultiLeader.ContentType /// - /// Gets or sets a value indicating that the multileader has a content block. + /// Gets or sets the color for the display of the text label /// - [DxfCodeValue(296)] - public bool HasContentsBlock { get; set; } + [DxfCodeValue(90)] + public Color TextColor { get; set; } + //Sublcass doesn't exist in the dxf specification /// - /// Gets a containing elements - /// to be drawn as content for the multileader. + /// Get or sets the text height for the lext label of the multileader + /// (see ). + /// This property overrides the value from + /// when the flag is set in the + /// property. /// - [DxfCodeValue(DxfReferenceType.Handle, 341)] - public BlockRecord BlockContent - { - get { return this._blockContent; } - set - { - this._blockContent = this.updateTable(value, this.Document?.BlockRecords); - } - } + /// + /// The value returned is the value entered in AutoCAD multiplied with the . + /// + [DxfCodeValue(41)] + public double TextHeight { get; set; } = 0.18; + // TODO Create test cases /// - /// Gets or sets the normal vector for the block content of the multileader. + /// Is text height automatic? /// - [DxfCodeValue(14, 24, 34)] - public XYZ BlockContentNormal { get; set; } + [DxfCodeValue(293)] + public bool TextHeightAutomatic { get; set; } = false; /// - /// Gets or sets the location of the böock content of the multileader. + /// Gets or sets a string containg the text tat is to be dispayed a s text label of the + /// multileader. /// /// - /// This location is evaluated by AutoCAD from the + /// The string may contain MTEXT markups to specify new-lines, font, size, style, etc. /// - [DxfCodeValue(15, 25, 35)] - public XYZ BlockContentLocation { get; set; } + [DxfCodeValue(304)] + public string TextLabel { get; set; } = string.Empty; /// - /// Gets or sets the scale factor for block content. + /// Gets or sets the text top attachment type (see ). /// This property overrides the value from - /// when the flag is set (see + /// when the flag is set (see /// property). /// /// /// This property is also exposed by the class - /// (). + /// (). /// Values should be equal, the value of this property is assumed to be used. /// - [DxfCodeValue(16, 26, 36)] - public XYZ BlockContentScale { get; set; } + /// + /// A having the values 0-8 + /// can be used ("horizontal" attachment types). + /// + [DxfCodeValue(174)] + public TextAttachmentType TextLeftAttachment { get; set; } = TextAttachmentType.MiddleOfTopLine; /// - /// Gets or sets the rotation of the block content of the multileader. + /// Gets or sets the location of the text label of the multileader. /// - /// - /// This property is also exposed by the class - /// (). - /// Values should be equal, the value of this property is assumed to be used. - /// - /// - /// The rotation angle in radians. - /// - [DxfCodeValue(DxfReferenceType.IsAngle, 46)] - public double BlockContentRotation { get; set; } + [DxfCodeValue(12, 22, 32)] + public XYZ TextLocation { get; set; } /// - /// Gets or sets the block-content color. + /// Gets or sets the normal vector for the text label of the multileader. + /// + [DxfCodeValue(11, 21, 31)] + public XYZ TextNormal { get; set; } = XYZ.AxisZ; + + /// + /// Gets or sets the text top attachment type (see ). /// This property overrides the value from - /// when the flag is set (see + /// when the flag is set (see /// property). /// /// /// This property is also exposed by the class - /// (). + /// (). /// Values should be equal, the value of this property is assumed to be used. /// - [DxfCodeValue(93)] - public Color BlockContentColor { get; set; } - - /// - /// Gets a array of 16 doubles containg the complete transformation - /// matrix. - /// - /// - /// - /// Order of transformation is: - /// - /// - /// Rotation, - /// OCS to WCS (using normal vector), - /// Scaling (using scale vector), - /// Translation (using location) - /// - /// - [DxfCodeValue(93)] - public Matrix4 TransformationMatrix { get; set; } - - /// - /// Base point - /// - [DxfCodeValue(110, 120, 130)] - public XYZ BasePoint { get; set; } + /// + /// A having the values 0-8 + /// can be used ("horizontal" attachment types). + /// + [DxfCodeValue(175)] + public TextAttachmentType TextRightAttachment { get; set; } = TextAttachmentType.MiddleOfTopLine; /// - /// Base direction + /// Gets or sets the rotation of the text label of the multileader. /// - [DxfCodeValue(111, 121, 131)] - public XYZ BaseDirection { get; set; } + /// + /// The rotation angle in radians. + /// + [DxfCodeValue(DxfReferenceType.IsAngle, 42)] + public double TextRotation { get; set; } = 0.0d; /// - /// Base vertical + /// Gets or sets the to be used to display the text label of the + /// multileader. + /// This property overrides the value from + /// when the flag is set in the + /// property. /// - [DxfCodeValue(112, 122, 132)] - public XYZ BaseVertical { get; set; } + /// + /// This property is also exposed by the class + /// (). + /// Values should be equal, the value of this property is assumed to be used. + /// + [DxfCodeValue(DxfReferenceType.Handle, 340)] + public TextStyle TextStyle + { + get { return this._textStyle; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } - /// - /// Is normal reversed? - /// - [DxfCodeValue(297)] - public bool NormalReversed { get; set; } + if (this.Document != null) + { + this._textStyle = this.updateTable(value, this.Document.TextStyles); + } + else + { + this._textStyle = value; + } + } + } /// /// Gets or sets the text top attachment type (see ). @@ -549,34 +536,43 @@ public BlockRecord BlockContent /// can be used ("vertical" attachment types). /// [DxfCodeValue(273)] - public TextAttachmentType TextTopAttachment { get; set; } + public TextAttachmentType TextTopAttachment { get; set; } = TextAttachmentType.CenterOfText; /// - /// Gets or sets the text bottom attachment type (see ). - /// This property override the value from - /// when the flag is set (see - /// property). + /// Gets a array of 16 doubles containg the complete transformation + /// matrix. /// /// - /// This property is also exposed by the class - /// (). - /// Values should be equal, the value of this property is assumed to be used. + /// + /// Order of transformation is: + /// + /// + /// Rotation, + /// OCS to WCS (using normal vector), + /// Scaling (using scale vector), + /// Translation (using location) + /// /// - /// - /// A having the values - /// 9 = Center, - /// 10 = Underline and Center - /// can be used ("vertical" attachment types). - /// - [DxfCodeValue(272)] - public TextAttachmentType TextBottomAttachment { get; set; } + [DxfCodeValue(93)] + public Matrix4 TransformationMatrix { get; set; } = Matrix4.Zero; + + // TODO Create test cases + /// + /// Word break + /// + [DxfCodeValue(295)] + public bool WordBreak { get; set; } = false; + + private BlockRecord _blockContent; + private TextStyle _textStyle = TextStyle.Default; /// /// Initializes a new instance of a . /// public MultiLeaderAnnotContext() : base() { } - public override CadObject Clone() { + public override CadObject Clone() + { MultiLeaderAnnotContext clone = (MultiLeaderAnnotContext)base.Clone(); clone._textStyle = (TextStyle)this._textStyle.Clone(); diff --git a/src/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs b/src/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs index c9ed368f..b14ca16f 100644 --- a/src/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs +++ b/src/ACadSharp/Objects/MultiLeaderAnnotContextClasses.cs @@ -35,7 +35,7 @@ public LeaderRoot() { } /// Unknown (ODA writes true) /// [DxfCodeValue(291)] - public bool Unknown { get; set; } + internal bool Unknown { get; set; } = true; /// /// Connection point @@ -107,7 +107,8 @@ public object Clone() /// public struct StartEndPointPair : ICloneable { - public StartEndPointPair(XYZ startPoint, XYZ endPoint) { + public StartEndPointPair(XYZ startPoint, XYZ endPoint) + { StartPoint = startPoint; EndPoint = endPoint; } @@ -140,7 +141,7 @@ public object Clone() public class LeaderLine : ICloneable { internal CadDocument Document { get; set; } - private LineType _lineType; + private LineType _lineType = null; public LeaderLine() { } @@ -176,13 +177,13 @@ public LeaderLine() { } /// Leader type /// [DxfCodeValue(170)] - public MultiLeaderPathType PathType { get; set; } + public MultiLeaderPathType PathType { get; set; } = MultiLeaderPathType.StraightLineSegments; /// /// Line color /// [DxfCodeValue(92)] - public Color LineColor { get; set; } + public Color LineColor { get; set; } = Color.ByBlock; /// /// Line type diff --git a/src/ACadSharp/Objects/MultiLeaderStyle.cs b/src/ACadSharp/Objects/MultiLeaderStyle.cs index 9fa46b96..d90e07d1 100644 --- a/src/ACadSharp/Objects/MultiLeaderStyle.cs +++ b/src/ACadSharp/Objects/MultiLeaderStyle.cs @@ -17,553 +17,398 @@ namespace ACadSharp.Objects [DxfSubClass(DxfSubclassMarker.MLeaderStyle)] public class MultiLeaderStyle : NonGraphicalObject { - private LineType _leaderLineType = LineType.ByLayer; - private TextStyle _textStyle = TextStyle.Default; - private BlockRecord _arrowhead; - private BlockRecord _blockContent; - - - /// - /// Default multiline style name - /// - public const string DefaultName = "Standard"; - /// /// Gets the default MLine style /// public static MultiLeaderStyle Default { get { return new MultiLeaderStyle(DefaultName); } } - /// - public override ObjectType ObjectType => ObjectType.UNLISTED; - - /// - public override string ObjectName => DxfFileToken.ObjectMLeaderStyle; - - /// - public override string SubclassMarker => DxfSubclassMarker.MLeaderStyle; - - /// - /// Gets or sets a value indicating the content type for the multileader. - /// - /// - /// - /// This value can be overridden by the property when the - /// flag is set in the - /// property. - /// - /// - [DxfCodeValue(170)] - public LeaderContentType ContentType { get; set; } - - // TODO What is the meaning of this property? Is it relevant for drawing a multileader? - /// - /// DrawMLeaderOrder Type - /// - [DxfCodeValue(171)] - public MultiLeaderDrawOrderType MultiLeaderDrawOrder { get; set; } - - // TODO What is the meaning of this property? Is it relevant for drawing a multileader? - /// - /// DrawLeaderOrder Type - /// - [DxfCodeValue(172)] - public LeaderDrawOrderType LeaderDrawOrder { get; set; } - - /// - /// Gets or sets the max number of segments when a new leader is being created for a multileader. - /// - /// - /// This property supports creating and editing a multileader but has no meaning for - /// the display of multileaders. - /// - [DxfCodeValue(90)] - public int MaxLeaderSegmentsPoints { get; set; } - - /// - /// Gets or sets a snap angle value for the first leader segment when a leader line - /// is being created for the mutileader. - /// - /// - /// This property supports creating and editing a multileader but has no meaning for - /// the display of multileaders. - /// - /// - /// An angle value in radians or zero if no angle contstraint is set. - /// - [DxfCodeValue(40)] - public double FirstSegmentAngleConstraint { get; set; } - + // TODO What is the meaning of this property? /// - /// Gets or sets a snap angle value for the second leader segment when a leader line - /// is being created for the mutileader. + /// Align Space /// - /// - /// This property supports creating and editing a multileader but has no meaning for - /// the display of multileaders. - /// - /// - /// An angle value in radians or zero if no angle contstraint is set. - /// - [DxfCodeValue(41)] - public double SecondSegmentAngleConstraint { get; set; } + [DxfCodeValue(46)] + public double AlignSpace { get; set; } = 0.0; /// - /// Gets or sets a value indicating whether leaders are to be displayed as polyline, - /// a spline curve or invisible. This setting applies for all leader lines of the - /// multileader. + /// Gets or sets a representing the arrowhead + /// to be displayed with every leader line. /// /// /// - /// This value can be overridden by the property when the - /// flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. /// /// The value for all leader lines can be overridden for each individual leader line by the - /// property when the - /// flag is set in the + /// property when the + /// flag is set in the /// property. /// /// - [DxfCodeValue(173)] - public MultiLeaderPathType PathType { get; set; } + [DxfCodeValue(DxfReferenceType.Handle, 341)] + public BlockRecord Arrowhead + { + get { return this._arrowhead; } + set + { + this._arrowhead = this.updateTable(value, this.Document?.BlockRecords); + } + } /// - /// Gets or sets color to be applied all leader lines of the multileader. + /// Gests or sets the arrowhead size. /// /// /// - /// This value can be overridden by the property when the - /// flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. /// /// The value for all leader lines can be overridden for each individual leader line by the - /// property when the - /// flag is set in the + /// property when the + /// flag is set in the /// property. /// /// - [DxfCodeValue(91)] - public Color LineColor { get; set; } + [DxfCodeValue(44)] + public double ArrowheadSize { get; set; } = 0.18; /// - /// Gets or sets a object specifying line-type properties for the - /// musltileader. This setting applies for all leader lines of the multileader. + /// Gets a containing elements + /// to be drawn as content for the multileader. /// /// /// - /// This setting can be overridden by the property - /// when the flag is set in the + /// Thw standard content block can be overridden by the + /// property when the flag is set in the /// property. - /// - /// The setting for all leader lines can be overridden for each individual leader line by the - /// property when the - /// flag is set in the - /// property. /// /// - [DxfCodeValue(DxfReferenceType.Handle, 340)] - public LineType LeaderLineType + [DxfCodeValue(DxfReferenceType.Handle, 343)] + public BlockRecord BlockContent { - get { return this._leaderLineType; } + get { return this._blockContent; } set { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - if (this.Document != null) - { - this._leaderLineType = this.updateTable(value, this.Document.LineTypes); - } - else - { - this._leaderLineType = value; - } + this._blockContent = this.updateTable(value, this.Document?.BlockRecords); } } /// - /// Gets or sets a value specifying the lineweight to be applied to all leader lines of the multileader. - /// - /// - /// - /// This value can be overridden by the property when the - /// flag is set in the - /// property. - /// - /// The value for all leader lines can be overridden for each individual leader line by the - /// property when the - /// flag is set in the - /// property. - /// - /// - [DxfCodeValue(92)] - public LineweightType LeaderLineWeight { get; set; } - - // TODO It seems that this value indicates that for a new leader that is being created - // with this landing i.e. a dogleg is enabled. - // But why can this value be overridden? - // - /// - /// Gets or sets a value indicating whether landing is enabled. + /// Gets or sets the block-content color. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. /// /// - [DxfCodeValue(290)] - public bool EnableLanding { get; set; } + [DxfCodeValue(94)] + public Color BlockContentColor { get; set; } = Color.ByBlock; /// - /// Gets or sets the landing gap. This is the distance between the leader end point or, if present, - /// the end of the dogleg and the text label or the content block. + /// Gets or sets a value indicating whether the multileader connects to the content-block extents + /// or to the content-block base point. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. /// /// - [DxfCodeValue(42)] - public double LandingGap { get; set; } + [DxfCodeValue(177)] + public BlockContentConnectionType BlockContentConnection { get; set; } /// - /// Gets or sets a value indicating that leader lines are to be drawn with a dogleg. + /// Gets or sets the block content rotation. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. - /// - /// Note that this setting has no effect when the - /// is . /// /// - [DxfCodeValue(291)] - public bool EnableDogleg { get; set; } + [DxfCodeValue(DxfReferenceType.IsAngle, 141)] + public double BlockContentRotation { get; set; } = 0.0; /// - /// Gets or sets the landing distance, i.e. the length of the dogleg. + /// Gets or sets the scale factor for block content. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. /// /// - [DxfCodeValue(43)] - public double LandingDistance { get; set; } - - /// - /// Gets or sets a text containing the description of this . - /// - [DxfCodeValue(3)] - public string Description { get; set; } + [DxfCodeValue(47, 49, 140)] + public XYZ BlockContentScale { get; set; } = new XYZ(1); + // TODO What is the meaning of this property? /// - /// Gets or sets a representing the arrowhead - /// to be displayed with every leader line. + /// Break Gap Size /// - /// - /// - /// This value can be overridden by the property - /// when the flag is set in the - /// property. - /// - /// The value for all leader lines can be overridden for each individual leader line by the - /// property when the - /// flag is set in the - /// property. - /// - /// - [DxfCodeValue(DxfReferenceType.Handle, 341)] - public BlockRecord Arrowhead - { - get { return this._arrowhead; } - set - { - this._arrowhead = this.updateTable(value, this.Document?.BlockRecords); - } - } + [DxfCodeValue(143)] + public double BreakGapSize { get; set; } = 0.125; /// - /// Gests or sets the arrowhead size. + /// Gets or sets a value indicating the content type for the multileader. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property when the + /// flag is set in the /// property. - /// - /// The value for all leader lines can be overridden for each individual leader line by the - /// property when the - /// flag is set in the - /// property. /// /// - [DxfCodeValue(44)] - public double ArrowheadSize { get; set; } + [DxfCodeValue(170)] + public LeaderContentType ContentType { get; set; } = LeaderContentType.MText; /// /// Gests or sets a default text that is to be set when a mutileader is being created /// with this . /// [DxfCodeValue(300)] - public string DefaultTextContents { get; set; } + public string DefaultTextContents { get; set; } = string.Empty; /// - /// Gets or sets the to be used to display the text label of the - /// multileader. + /// Gets or sets a text containing the description of this . /// - /// - /// - /// This value can be overridden by the property - /// when the flag is set in the - /// property. - /// - /// - [DxfCodeValue(DxfReferenceType.Handle, 342)] - public TextStyle TextStyle - { - get { return this._textStyle; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } + [DxfCodeValue(3)] + public string Description { get; set; } = string.Empty; - if (this.Document != null) - { - this._textStyle = this.updateTable(value, this.Document.TextStyles); - } - else - { - this._textStyle = value; - } - } - } + // TODO: Cannot be overridden? Is this property only relevant in AutoCAD? + /// + /// Gets or sets a value indicating whether rotation of the block content is enabled. + /// + [DxfCodeValue(294)] + public bool EnableBlockContentRotation { get; set; } + // TODO: Cannot be overridden? Is this property only relevant in AutoCAD? /// - /// Gets or sets the Text Left Attachment Type. - /// This value controls the position of the connection point of the leader - /// attached to the left side of the text label. + /// Gets or sets a value indicating whether scaling of the block content is enabled. /// - /// - /// - /// This value can be overridden by the property - /// when the flag is set in the - /// property. - /// - /// This property is only relevant if is - /// and a leader attached - /// to the left side of the text label exists. - /// - /// - /// - /// A having the values 0-8 - /// can be used ("horizontal" attachment types). - /// - [DxfCodeValue(174)] - public TextAttachmentType TextLeftAttachment { get; set; } + [DxfCodeValue(293)] + public bool EnableBlockContentScale { get; set; } - // TODO How to set this value? /// - /// Gets or sets a value indicating the text angle. + /// Gets or sets a value indicating that leader lines are to be drawn with a dogleg. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. + /// + /// Note that this setting has no effect when the + /// is . /// /// - [DxfCodeValue(175)] - public TextAngleType TextAngle { get; set; } + [DxfCodeValue(291)] + public bool EnableDogleg { get; set; } = true; + // TODO It seems that this value indicates that for a new leader that is being created + // with this landing i.e. a dogleg is enabled. + // But why can this value be overridden? + // /// - /// Gets or sets the text alignment, i.e. the alignment of text lines if the a multiline - /// text label, relative to the . + /// Gets or sets a value indicating whether landing is enabled. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. /// /// - [DxfCodeValue(176)] - public TextAlignmentType TextAlignment { get; set; } + [DxfCodeValue(290)] + public bool EnableLanding { get; set; } = true; /// - /// Gets or sets the Text Right Attachment Type. - /// This value controls the position of the connection point of the leader - /// attached to the right side of the text label. + /// Gets or sets a snap angle value for the first leader segment when a leader line + /// is being created for the mutileader. /// /// - /// - /// This value can be overridden by the property - /// when the flag is set in the - /// property. - /// - /// This property is only relevant if is - /// and a leader attached - /// to the right side of the text label exists. - /// + /// This property supports creating and editing a multileader but has no meaning for + /// the display of multileaders. /// /// - /// A having the values 0-8 - /// can be used ("horizontal" attachment types). + /// An angle value in radians or zero if no angle contstraint is set. /// - [DxfCodeValue(178)] - public TextAttachmentType TextRightAttachment { get; set; } + [DxfCodeValue(40)] + public double FirstSegmentAngleConstraint { get; set; } /// - /// Gest or sets the color for the text label of the multileader. + /// Is Annotative /// - /// - /// - /// This value can be overridden by the property - /// when the flag is set in the - /// property. - /// - /// - [DxfCodeValue(93)] - public Color TextColor { get; set; } + [DxfCodeValue(296)] + public bool IsAnnotative { get; set; } /// - /// Gest or sets the text height for the text label of the multileader. + /// Gets or sets the landing distance, i.e. the length of the dogleg. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. /// /// - [DxfCodeValue(45)] - public double TextHeight { get; set; } + [DxfCodeValue(43)] + public double LandingDistance { get; set; } = 0.36; /// - /// Gets or sets a value indicating that the text label is to be drawn with a frame. + /// Gets or sets the landing gap. This is the distance between the leader end point or, if present, + /// the end of the dogleg and the text label or the content block. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property + /// when the flag is set in the /// property. /// /// - [DxfCodeValue(292)] - public bool TextFrame { get; set; } - - // TODO Is this property only relevant for new leaders? - /// - /// Text Align Always Left - /// - [DxfCodeValue(297)] - public bool TextAlignAlwaysLeft { get; set; } + [DxfCodeValue(42)] + public double LandingGap { get; set; } = 0.09; - // TODO What is the meaning of this property? + // TODO What is the meaning of this property? Is it relevant for drawing a multileader? /// - /// Align Space + /// DrawLeaderOrder Type /// - [DxfCodeValue(46)] - public double AlignSpace { get; set; } + [DxfCodeValue(172)] + public LeaderDrawOrderType LeaderDrawOrder { get; set; } /// - /// Gets a containing elements - /// to be drawn as content for the multileader. + /// Gets or sets a object specifying line-type properties for the + /// musltileader. This setting applies for all leader lines of the multileader. /// /// /// - /// Thw standard content block can be overridden by the - /// property when the flag is set in the + /// This setting can be overridden by the property + /// when the flag is set in the /// property. + /// + /// The setting for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. /// /// - [DxfCodeValue(DxfReferenceType.Handle, 343)] - public BlockRecord BlockContent + [DxfCodeValue(DxfReferenceType.Handle, 340)] + public LineType LeaderLineType { - get { return this._blockContent; } - set { - this._blockContent = this.updateTable(value, this.Document?.BlockRecords); + get { return this._leaderLineType; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + if (this.Document != null) + { + this._leaderLineType = this.updateTable(value, this.Document.LineTypes); + } + else + { + this._leaderLineType = value; + } } } /// - /// Gets or sets the block-content color. + /// Gets or sets a value specifying the lineweight to be applied to all leader lines of the multileader. + /// + /// + /// + /// This value can be overridden by the property when the + /// flag is set in the + /// property. + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. + /// + /// + [DxfCodeValue(92)] + public LineweightType LeaderLineWeight { get; set; } = LineweightType.ByBlock; + + /// + /// Gets or sets color to be applied all leader lines of the multileader. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property when the + /// flag is set in the /// property. + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. /// /// - [DxfCodeValue(94)] - public Color BlockContentColor { get; set; } + [DxfCodeValue(91)] + public Color LineColor { get; set; } /// - /// Gets or sets the scale factor for block content. + /// Gets or sets the max number of segments when a new leader is being created for a multileader. /// /// - /// - /// This value can be overridden by the property - /// when the flag is set in the - /// property. - /// + /// This property supports creating and editing a multileader but has no meaning for + /// the display of multileaders. /// - [DxfCodeValue(47, 49, 140)] - public XYZ BlockContentScale { get; set; } + [DxfCodeValue(90)] + public int MaxLeaderSegmentsPoints { get; set; } = 2; - // TODO: Cannot be overridden? Is this property only relevant in AutoCAD? + // TODO What is the meaning of this property? Is it relevant for drawing a multileader? /// - /// Gets or sets a value indicating whether scaling of the block content is enabled. + /// DrawMLeaderOrder Type /// - [DxfCodeValue(293)] - public bool EnableBlockContentScale { get; set; } + [DxfCodeValue(171)] + public MultiLeaderDrawOrderType MultiLeaderDrawOrder { get; set; } + + /// + public override string ObjectName => DxfFileToken.ObjectMLeaderStyle; + + /// + public override ObjectType ObjectType => ObjectType.UNLISTED; /// - /// Gets or sets the block content rotation. + /// Overwrite Property Value /// /// - /// - /// This value can be overridden by the property - /// when the flag is set in the - /// property. - /// + /// Property changed, meaning not totally clear + /// might be set to true if something changed after loading, + /// or might be used to trigger updates in dependent MLeaders. + /// sequence seems to be different in DXF /// - [DxfCodeValue(DxfReferenceType.IsAngle, 141)] - public double BlockContentRotation { get; set; } - - // TODO: Cannot be overridden? Is this property only relevant in AutoCAD? - /// - /// Gets or sets a value indicating whether rotation of the block content is enabled. - /// - [DxfCodeValue(294)] - public bool EnableBlockContentRotation { get; set; } + [DxfCodeValue(295)] + public bool OverwritePropertyValue { get; set; } /// - /// Gets or sets a value indicating whether the multileader connects to the content-block extents - /// or to the content-block base point. + /// Gets or sets a value indicating whether leaders are to be displayed as polyline, + /// a spline curve or invisible. This setting applies for all leader lines of the + /// multileader. /// /// /// - /// This value can be overridden by the property - /// when the flag is set in the + /// This value can be overridden by the property when the + /// flag is set in the /// property. + /// + /// The value for all leader lines can be overridden for each individual leader line by the + /// property when the + /// flag is set in the + /// property. /// /// - [DxfCodeValue(177)] - public BlockContentConnectionType BlockContentConnection { get; set; } + [DxfCodeValue(173)] + public MultiLeaderPathType PathType { get; set; } /// /// Gets or sets the scale factor for the , , @@ -577,32 +422,59 @@ public BlockRecord BlockContent /// /// [DxfCodeValue(142)] - public double ScaleFactor { get; set; } + public double ScaleFactor { get; set; } = 1; /// - /// Overwrite Property Value + /// Gets or sets a snap angle value for the second leader segment when a leader line + /// is being created for the mutileader. /// /// - /// Property changed, meaning not totally clear - /// might be set to true if something changed after loading, - /// or might be used to trigger updates in dependent MLeaders. - /// sequence seems to be different in DXF + /// This property supports creating and editing a multileader but has no meaning for + /// the display of multileaders. /// - [DxfCodeValue(295)] - public bool OverwritePropertyValue { get; set; } + /// + /// An angle value in radians or zero if no angle contstraint is set. + /// + [DxfCodeValue(41)] + public double SecondSegmentAngleConstraint { get; set; } + + /// + public override string SubclassMarker => DxfSubclassMarker.MLeaderStyle; + + // TODO Is this property only relevant for new leaders? + /// + /// Text Align Always Left + /// + [DxfCodeValue(297)] + public bool TextAlignAlwaysLeft { get; set; } /// - /// Is Annotative + /// Gets or sets the text alignment, i.e. the alignment of text lines if the a multiline + /// text label, relative to the . /// - [DxfCodeValue(296)] - public bool IsAnnotative { get; set; } + /// + /// + /// This value can be overridden by the property + /// when the flag is set in the + /// property. + /// + /// + [DxfCodeValue(176)] + public TextAlignmentType TextAlignment { get; set; } - // TODO What is the meaning of this property? + // TODO How to set this value? /// - /// Break Gap Size + /// Gets or sets a value indicating the text angle. /// - [DxfCodeValue(143)] - public double BreakGapSize { get; set; } + /// + /// + /// This value can be overridden by the property + /// when the flag is set in the + /// property. + /// + /// + [DxfCodeValue(175)] + public TextAngleType TextAngle { get; set; } = TextAngleType.Horizontal; // TODO Check // whether this property is relevant for both text an block content @@ -620,7 +492,7 @@ public BlockRecord BlockContent /// /// The value for all leader lines can be overridden for each individual leader line by the /// property when the - /// flag is set in the + /// flag is set in the /// property. /// /// @@ -653,7 +525,125 @@ public BlockRecord BlockContent /// can be used ("vertical" attachment types). /// [DxfCodeValue(272)] - public TextAttachmentType TextBottomAttachment { get; set; } + public TextAttachmentType TextBottomAttachment { get; set; } + + /// + /// Get or sets the color for the text label of the multileader. + /// + /// + /// + /// This value can be overridden by the property + /// when the flag is set in the + /// property. + /// + /// + [DxfCodeValue(93)] + public Color TextColor { get; set; } = Color.ByBlock; + + /// + /// Gets or sets a value indicating that the text label is to be drawn with a frame. + /// + /// + /// + /// This value can be overridden by the property + /// when the flag is set in the + /// property. + /// + /// + [DxfCodeValue(292)] + public bool TextFrame { get; set; } + + /// + /// Get or sets the text height for the text label of the multileader. + /// + /// + /// + /// This value can be overridden by the property + /// when the flag is set in the + /// property. + /// + /// + [DxfCodeValue(45)] + public double TextHeight { get; set; } = 0.18; + + /// + /// Gets or sets the Text Left Attachment Type. + /// This value controls the position of the connection point of the leader + /// attached to the left side of the text label. + /// + /// + /// + /// This value can be overridden by the property + /// when the flag is set in the + /// property. + /// + /// This property is only relevant if is + /// and a leader attached + /// to the left side of the text label exists. + /// + /// + /// + /// A having the values 0-8 + /// can be used ("horizontal" attachment types). + /// + [DxfCodeValue(174)] + public TextAttachmentType TextLeftAttachment { get; set; } + + /// + /// Gets or sets the Text Right Attachment Type. + /// This value controls the position of the connection point of the leader + /// attached to the right side of the text label. + /// + /// + /// + /// This value can be overridden by the property + /// when the flag is set in the + /// property. + /// + /// This property is only relevant if is + /// and a leader attached + /// to the right side of the text label exists. + /// + /// + /// + /// A having the values 0-8 + /// can be used ("horizontal" attachment types). + /// + [DxfCodeValue(178)] + public TextAttachmentType TextRightAttachment { get; set; } + + /// + /// Gets or sets the to be used to display the text label of the + /// multileader. + /// + /// + /// + /// This value can be overridden by the property + /// when the flag is set in the + /// property. + /// + /// + [DxfCodeValue(DxfReferenceType.Handle, 342)] + public TextStyle TextStyle + { + get { return this._textStyle; } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + if (this.Document != null) + { + this._textStyle = this.updateTable(value, this.Document.TextStyles); + } + else + { + this._textStyle = value; + } + } + } /// /// Gets or sets the text top attachment type. @@ -684,7 +674,20 @@ public BlockRecord BlockContent /// Undocumented in ODS and DXF-ref boolean, found in DXF /// [DxfCodeValue(298)] - public bool UnknownFlag298 { get; set; } + internal bool UnknownFlag298 { get; set; } + + /// + /// Default multiline style name + /// + public const string DefaultName = "Standard"; + + private BlockRecord _arrowhead; + + private BlockRecord _blockContent; + + private LineType _leaderLineType = LineType.ByLayer; + + private TextStyle _textStyle = TextStyle.Default; /// /// Initializes a new instance of the class. @@ -700,12 +703,13 @@ public MultiLeaderStyle(string name) : base() this.Name = name; } + /// public override CadObject Clone() { MultiLeaderStyle clone = (MultiLeaderStyle)base.Clone(); clone.TextStyle = (TextStyle)this._textStyle.Clone(); clone.LeaderLineType = (LineType)this._leaderLineType.Clone(); - + clone.Arrowhead = (BlockRecord)this._arrowhead?.Clone(); clone.BlockContent = (BlockRecord)this._blockContent?.Clone(); @@ -763,4 +767,4 @@ protected virtual void tableOnRemove(object sender, CollectionChangedEventArgs e } } } -} +} \ No newline at end of file diff --git a/src/CSUtilities b/src/CSUtilities index d0925279..6805b613 160000 --- a/src/CSUtilities +++ b/src/CSUtilities @@ -1 +1 @@ -Subproject commit d0925279e5505c8e028b78c36f0b99de55841341 +Subproject commit 6805b613b13b5ca5565df3f5b6a31003b6af59d0