Skip to content

Commit

Permalink
Merge pull request #431 from DomCR/issue-405_multiline-att
Browse files Browse the repository at this point in the history
Issue-405 Implement Attribute Multiline
  • Loading branch information
DomCR authored Aug 24, 2024
2 parents 995cdf5 + 5ad337f commit 9c57548
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 40 deletions.
9 changes: 5 additions & 4 deletions src/ACadSharp/Entities/AttributeBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,21 @@ public string Tag
}

/// <summary>
/// Attribute flags
/// Attribute flags.
/// </summary>
[DxfCodeValue(70)]
public AttributeFlags Flags { get; set; }

/// <summary>
/// MText flag
/// Attribute type.
/// </summary>
//[DxfCodeValue(280)]
//TODO: Check the dxf code of Attribute type.
[DxfCodeValue(71)]
public AttributeType AttributeType { get; set; } = AttributeType.SingleLine;

public bool IsReallyLocked { get; set; }

public MText MText { get; set; }

private string _tag = string.Empty;

public AttributeBase() : base() { }
Expand Down
42 changes: 36 additions & 6 deletions src/ACadSharp/IO/DWG/DwgStreamReaders/DwgObjectReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,17 @@ private void readCommonEntityData(CadEntityTemplate template)

//R13 - R14 Only:
if (this._version >= ACadVersion.AC1012 && this._version <= ACadVersion.AC1014)
{
this.updateHandleReader();
}

this.readEntityMode(template);
}

private void readEntityMode(CadEntityTemplate template)
{
//Get the cad object as an entity
Entity entity = template.CadObject;

//Common:
//6B : Flags
Expand Down Expand Up @@ -1073,23 +1083,23 @@ private CadTemplate readText()
private CadTemplate readAttribute()
{
AttributeEntity att = new AttributeEntity();
CadTextEntityTemplate template = new CadTextEntityTemplate(att);
CadAttributeTemplate template = new CadAttributeTemplate(att);

this.readCommonTextData(template);

this.readCommonAttData(att);
this.readCommonAttData(template);

return template;
}

private CadTemplate readAttributeDefinition()
{
AttributeDefinition attdef = new AttributeDefinition();
CadTextEntityTemplate template = new CadTextEntityTemplate(attdef);
CadAttributeTemplate template = new CadAttributeTemplate(attdef);

this.readCommonTextData(template);

this.readCommonAttData(attdef);
this.readCommonAttData(template);

//R2010+:
if (this.R2010Plus)
Expand Down Expand Up @@ -1206,8 +1216,10 @@ private void readCommonTextData(CadTextEntityTemplate template)
template.StyleHandle = this.handleReference();
}

private void readCommonAttData(AttributeBase att)
private void readCommonAttData(CadAttributeTemplate template)
{
AttributeBase att = template.CadObject as AttributeBase;

//R2010+:
if (this.R2010Plus)
{
Expand All @@ -1229,6 +1241,14 @@ private void readCommonAttData(AttributeBase att)
//MTEXT fields … Here all fields of an embedded MTEXT object
//are written, starting from the Entmode
//(entity mode). The owner handle can be 0.
att.MText = new MText();
CadTextEntityTemplate mtextTemplate = new CadTextEntityTemplate(att.MText);
template.MTextTemplate = mtextTemplate;

this.readEntityMode(mtextTemplate);

this.readMText(mtextTemplate, false);

short dataSize = this._objectReader.ReadBitShort();
if (dataSize > 0)
{
Expand Down Expand Up @@ -2585,7 +2605,17 @@ private CadTemplate readMText()
MText mtext = new MText();
CadTextEntityTemplate template = new CadTextEntityTemplate(mtext);

this.readCommonEntityData(template);
return this.readMText(template, true);
}

private CadTemplate readMText(CadTextEntityTemplate template, bool readCommonData)
{
MText mtext = template.CadObject as MText;

if (readCommonData)
{
this.readCommonEntityData(template);
}

//Insertion pt3 BD 10 First picked point. (Location relative to text depends on attachment point (71).)
mtext.InsertPoint = this._objectReader.Read3BitDouble();
Expand Down
12 changes: 11 additions & 1 deletion src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ private void writeCommonEntityData(Entity entity)
this._writer.SavePositonForSize();
}

this.writeEntityMode(entity);
}

private void writeEntityMode(Entity entity)
{
//FE: Entity mode(entmode). Generally, this indicates whether or not the owner
//relative handle reference is present.The values go as follows:

Expand All @@ -190,7 +195,7 @@ private void writeCommonEntityData(Entity entity)
this._writer.Write2Bits(entmode);
if (entmode == 0)
{
this._writer.HandleReference(DwgReferenceType.SoftPointer, entity.Owner.Handle);
this._writer.HandleReference(DwgReferenceType.SoftPointer, entity.Owner);
}

this.writeReactorsAndDictionaryHandle(entity);
Expand Down Expand Up @@ -371,6 +376,11 @@ private void writeReactorsAndDictionaryHandle(CadObject cadObject)

private byte getEntMode(Entity entity)
{
if (entity.Owner == null)
{
return 0;
}

if (entity.Owner.Handle == this._document.PaperSpace.Handle)
{
return 0b01;
Expand Down
52 changes: 34 additions & 18 deletions src/ACadSharp/IO/DWG/DwgStreamWriters/DwgObjectWriter.Entities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,15 @@ private void writeCommonAttData(AttributeBase att)
{
this._writer.WriteByte((byte)att.AttributeType);

if (att.AttributeType == AttributeType.MultiLine || att.AttributeType == AttributeType.ConstantMultiLine)
if (att.AttributeType == AttributeType.MultiLine ||
att.AttributeType == AttributeType.ConstantMultiLine)
{
throw new NotImplementedException("Multiple line Attribute not implemented");
this.writeEntityMode(att.MText);

this.writeMText(att.MText);

//TODO: Write attribute MText data
this._writer.WriteBitShort(0);
}
}

Expand Down Expand Up @@ -1158,7 +1164,7 @@ private void writeMultiLeader(MultiLeader multiLeader)
this._writer.WriteBitShort((short)multiLeader.ContentType);
// 343 Text Style ID (handle/TextStyle)
this._writer.HandleReference(DwgReferenceType.HardPointer, multiLeader.TextStyle); // Hard/soft??
// 173 Text Left Attachment Type
// 173 Text Left Attachment Type
this._writer.WriteBitShort((short)multiLeader.TextLeftAttachment);
// 95 Text Right Attachement Type
this._writer.WriteBitShort((short)multiLeader.TextRightAttachment);
Expand All @@ -1172,7 +1178,7 @@ private void writeMultiLeader(MultiLeader multiLeader)
this._writer.WriteBit(multiLeader.TextFrame);
// 344 Block Content ID
this._writer.HandleReference(DwgReferenceType.HardPointer, multiLeader.BlockContent); // Hard/soft??
// 93 Block Content Color
// 93 Block Content Color
this._writer.WriteCmColor(multiLeader.BlockContentColor);
// 10 Block Content Scale
this._writer.Write3BitDouble(multiLeader.BlockContentScale);
Expand All @@ -1188,7 +1194,8 @@ private void writeMultiLeader(MultiLeader multiLeader)
// BL Number of Block Labels
int blockLabelCount = multiLeader.BlockAttributes.Count;
this._writer.WriteBitLong(blockLabelCount);
for (int bl = 0; bl < blockLabelCount; bl++) {
for (int bl = 0; bl < blockLabelCount; bl++)
{
// 330 Block Attribute definition handle (hard pointer)
MultiLeader.BlockAttribute blockAttribute = multiLeader.BlockAttributes[bl];
this._writer.HandleReference(DwgReferenceType.HardPointer, blockAttribute.AttributeDefinition);
Expand All @@ -1209,27 +1216,31 @@ private void writeMultiLeader(MultiLeader multiLeader)
// 45 BD ScaleFactor
this._writer.WriteBitDouble(multiLeader.ScaleFactor);

if (this.R2010Plus) {
if (this.R2010Plus)
{
// 271 Text attachment direction for MText contents
this._writer.WriteBitShort((short)multiLeader.TextAttachmentDirection);
this._writer.WriteBitShort((short)multiLeader.TextAttachmentDirection);
// 272 Bottom text attachment direction (sequence my be interchanged)
this._writer.WriteBitShort((short)multiLeader.TextBottomAttachment);
// 273 Top text attachment direction
this._writer.WriteBitShort((short)multiLeader.TextTopAttachment);
}

if (R2013Plus) {
if (R2013Plus)
{
// 295 Leader extended to text
this._writer.WriteBit(multiLeader.ExtendedToText);
}
}

private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext) {
private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext)
{

// BL - Number of leader roots
int leaderRootCount = annotContext.LeaderRoots.Count;
this._writer.WriteBitLong(leaderRootCount);
for (int i = 0; i < leaderRootCount; i++) {
for (int i = 0; i < leaderRootCount; i++)
{
writeLeaderRoot(annotContext.LeaderRoots[i]);
}

Expand All @@ -1254,7 +1265,8 @@ private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext)
this._writer.WriteBitShort((short)annotContext.BlockContentConnection);
// B 290 Has text contents
this._writer.WriteBit(annotContext.HasTextContents);
if (annotContext.HasTextContents) {
if (annotContext.HasTextContents)
{
// TV 304 Text label
this._writer.WriteVariableText(annotContext.TextLabel);
// 3BD 11 Normal vector
Expand Down Expand Up @@ -1306,7 +1318,8 @@ private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext)
// BD 144 Column size
int columnSizesCount = annotContext.ColumnSizes.Count;
this._writer.WriteBitLong(columnSizesCount);
for (int i = 0; i < columnSizesCount; i++) {
for (int i = 0; i < columnSizesCount; i++)
{
this._writer.WriteBitDouble(annotContext.ColumnSizes[i]);
}

Expand All @@ -1315,8 +1328,9 @@ private void writeMultiLeaderAnnotContext(MultiLeaderAnnotContext annotContext)
// B Unknown
this._writer.WriteBit(false);
}

else if (annotContext.HasContentsBlock) {

else if (annotContext.HasContentsBlock)
{
this._writer.WriteBit(annotContext.HasContentsBlock);

//B 296 Has contents block
Expand Down Expand Up @@ -1429,15 +1443,17 @@ private void writeLeaderLine(MultiLeaderAnnotContext.LeaderLine leaderLine)
// BL - Number of points
// 3BD 10 Point
this._writer.WriteBitLong(leaderLine.Points.Count);
foreach (XYZ point in leaderLine.Points) {
foreach (XYZ point in leaderLine.Points)
{
// 3BD 10 Point
this._writer.Write3BitDouble(point);
}

// Add optional Break Info (one or more)
// BL Break info count
this._writer.WriteBitLong(leaderLine.BreakInfoCount);
if (leaderLine.BreakInfoCount > 0) {
if (leaderLine.BreakInfoCount > 0)
{
// BL 90 Segment index
this._writer.WriteBitLong(leaderLine.SegmentIndex);

Expand All @@ -1455,7 +1471,8 @@ private void writeLeaderLine(MultiLeaderAnnotContext.LeaderLine leaderLine)
// BL 91 Leader line index
this._writer.WriteBitLong(leaderLine.Index);

if (this.R2010Plus) {
if (this.R2010Plus)
{
// BS 170 Leader type(0 = invisible leader, 1 = straight leader, 2 = spline leader)
this._writer.WriteBitShort((short)leaderLine.PathType);
// CMC 92 Line color
Expand Down Expand Up @@ -2019,7 +2036,6 @@ private void writeTextEntity(TextEntity text)

private void writeMText(MText mtext)
{

//Insertion pt3 BD 10 First picked point. (Location relative to text depends on attachment point (71).)
this._writer.Write3BitDouble(mtext.InsertPoint);
//Extrusion 3BD 210 Undocumented; appears in DXF and entget, but ACAD doesn't even bother to adjust it to unit length.
Expand Down
13 changes: 9 additions & 4 deletions src/ACadSharp/IO/DXF/DxfStreamReader/DxfSectionReaderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ protected CadEntityTemplate readEntity()
switch (this._reader.ValueAsString)
{
case DxfFileToken.EntityAttribute:
return this.readEntityCodes<AttributeEntity>(new CadTextEntityTemplate(new AttributeEntity()), this.readAttributeDefinition);
return this.readEntityCodes<AttributeEntity>(new CadAttributeTemplate(new AttributeEntity()), this.readAttributeDefinition);
case DxfFileToken.EntityAttributeDefinition:
return this.readEntityCodes<AttributeDefinition>(new CadTextEntityTemplate(new AttributeDefinition()), this.readAttributeDefinition);
return this.readEntityCodes<AttributeDefinition>(new CadAttributeTemplate(new AttributeDefinition()), this.readAttributeDefinition);
case DxfFileToken.EntityArc:
return this.readEntityCodes<Arc>(new CadEntityTemplate<Arc>(), this.readArc);
case DxfFileToken.EntityCircle:
Expand Down Expand Up @@ -306,14 +306,19 @@ private bool readArc(CadEntityTemplate template, DxfMap map, string subclass = n
private bool readAttributeDefinition(CadEntityTemplate template, DxfMap map, string subclass = null)
{
DxfClassMap emap = map.SubClasses[template.CadObject.SubclassMarker];
CadTextEntityTemplate tmp = template as CadTextEntityTemplate;
CadAttributeTemplate tmp = template as CadAttributeTemplate;

switch (this._reader.Code)
{
//TODO: Implement multiline attribute def codes
case 44:
case 46:
return true;
case 101:
var att = tmp.CadObject as AttributeBase;
att.MText = new MText();
CadTextEntityTemplate mtextTemplate = new CadTextEntityTemplate(att.MText);
tmp.MTextTemplate = mtextTemplate;
this.readEntityCodes<MText>(mtextTemplate, this.readTextEntity);
return true;
default:
if (!this.tryAssignCurrentValue(template.CadObject, emap))
Expand Down
Loading

0 comments on commit 9c57548

Please sign in to comment.