From 8e9b81431f347123ab5da9e8a6f0ab6693d56ac6 Mon Sep 17 00:00:00 2001 From: haplokuon Date: Mon, 16 Nov 2020 16:25:37 +0100 Subject: [PATCH] [2020/11/16] * The AttributeDefiniton and Attribute Value property are now stored as strings. The user will be responsible on how to convert this value to and from the string. In the end this value is always stored in a DXF file as a string (code 1), and how the conversion is done from a generic object value may differ from user to user. --- TestDxfDocument/Program.cs | 18 ++-- doc/Changelog.txt | 6 ++ netDxf/Entities/Attribute.cs | 68 ++++++++++--- netDxf/Entities/AttributeDefinition.cs | 57 +++++++++-- netDxf/IO/DxfReader.cs | 128 ++++++++++++------------- netDxf/IO/DxfWriter.cs | 26 ++--- 6 files changed, 189 insertions(+), 114 deletions(-) diff --git a/TestDxfDocument/Program.cs b/TestDxfDocument/Program.cs index 8f78a8cb..4ca01497 100644 --- a/TestDxfDocument/Program.cs +++ b/TestDxfDocument/Program.cs @@ -1522,7 +1522,7 @@ private static void TestModelSpaceBlock() AttributeDefinition attdef = new AttributeDefinition("MyAttribute") { Prompt = "Enter a value:", - Value = 0, + Value = "0", Position = Vector3.Zero, Layer = new Layer("MyLayer") { @@ -1582,7 +1582,7 @@ private static void TestModelSpaceBlock() AttributeDefinition def = new AttributeDefinition("AttDefOutsideBlock") { Prompt = "Enter value:", - Value = 0, + Value = "0", Color = AciColor.Blue, Position = new Vector3(0, 30, 0) }; @@ -3693,7 +3693,7 @@ public static void LoadAndSaveBlocks() AttributeDefinition attdef = new AttributeDefinition("MyAttribute") { Prompt = "Enter a value:", - Value = 0, + Value = "0", Position = Vector3.Zero, Layer = new Layer("MyLayer") { @@ -3753,7 +3753,7 @@ public static void LoadAndSaveBlocks() AttributeDefinition def = new AttributeDefinition("AttDefOutsideBlock") { Prompt = "Enter value:", - Value = 0, + Value = "0", Color = AciColor.Blue, Position = new Vector3(0, 30, 0) }; @@ -4304,7 +4304,7 @@ private static void BlockWithAttributes() // this is the text prompt shown to introduce the attribute value when a new Insert entity is inserted into the drawing attdef.Prompt = "InfoText"; // optionally we can set a default value for new Insert entities - attdef.Value = 0; + attdef.Value = "0"; // the attribute definition position is in local coordinates to the Insert entity to which it belongs attdef.Position = new Vector3(1, 1, 0); @@ -4355,7 +4355,7 @@ private static void BlockWithAttributes() insert1.TransformAttributes(); // Once the insert has been created we can modify the attributes properties, the list cannot be modified only the items stored in it - insert1.Attributes[0].Value = 24; + insert1.Attributes[0].Value = 24.ToString(); // Modifying directly the layer might not get the desired results. Create one or get one from the layers table, modify it and assign it to the insert // One thing to note, if there is already a layer with the same name, the existing one in the layers table will override the new one, when the entity is added to the document. @@ -4378,7 +4378,7 @@ private static void BlockWithAttributes() Insert insert2 = new Insert(block, new Vector3(10, 5, 0)); // as before now we can change the insert2 attribute value - insert2.Attributes[0].Value = 34; + insert2.Attributes[0].Value = 34.ToString(); // additionally we can insert extended data information XData xdata1 = new XData(new ApplicationRegistry("netDxf")); @@ -7503,10 +7503,10 @@ private static void WriteNestedInsert() nestedBlock.AttributeDefinitions.Add(attdef); Insert nestedInsert = new Insert(nestedBlock, new Vector3(0, 0, 0)); // the position will be relative to the position of the insert that nest it - nestedInsert.Attributes[0].Value = 24; + nestedInsert.Attributes[0].Value = 24.ToString(); Insert nestedInsert2 = new Insert(nestedBlock, new Vector3(-20, 0, 0)); // the position will be relative to the position of the insert that nest it - nestedInsert2.Attributes[0].Value = -20; + nestedInsert2.Attributes[0].Value = (-20).ToString(); Block block = new Block("MyBlock"); block.Entities.Add(new Line(new Vector3(-5, -5, 0), new Vector3(5, 5, 0))); diff --git a/doc/Changelog.txt b/doc/Changelog.txt index 29ecc9d6..6fc144d7 100644 --- a/doc/Changelog.txt +++ b/doc/Changelog.txt @@ -1,5 +1,11 @@ ## Change history +### [2020/11/16] +* The AttributeDefiniton and Attribute Value property are now stored as strings. + The user will be responsible on how to convert this value to and from the string. + In the end this value is always stored in a DXF file as a string (code 1), + and how the conversion is done from a generic object value may differ from user to user. + ### [2020/11/14] * Now it is possible to change the ImageDefinition of an Image entity. * Now it is possible to change the UnderlayDefinition of an Underlay entity. diff --git a/netDxf/Entities/Attribute.cs b/netDxf/Entities/Attribute.cs index 99e3b4cf..5844aaec 100644 --- a/netDxf/Entities/Attribute.cs +++ b/netDxf/Entities/Attribute.cs @@ -105,7 +105,7 @@ protected virtual TextStyle OnTextStyleChangedEvent(TextStyle oldTextStyle, Text private AttributeDefinition definition; private string tag; - private object attValue; + private string attValue; private TextStyle style; private Vector3 position; private AttributeFlags flags; @@ -122,9 +122,10 @@ protected virtual TextStyle OnTextStyleChangedEvent(TextStyle oldTextStyle, Text #region constructor - internal Attribute() + internal Attribute(string tag) : base(DxfObjectCode.Attribute) { + this.tag = string.IsNullOrEmpty(tag) ? string.Empty : tag; } /// @@ -135,7 +136,9 @@ public Attribute(AttributeDefinition definition) : base(DxfObjectCode.Attribute) { if (definition == null) + { throw new ArgumentNullException(nameof(definition)); + } this.color = definition.Color; this.layer = definition.Layer; @@ -175,7 +178,9 @@ public AciColor Color set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.color = value; } } @@ -189,7 +194,9 @@ public Layer Layer set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.layer = this.OnLayerChangedEvent(this.layer, value); } } @@ -203,7 +210,9 @@ public Linetype Linetype set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.linetype = this.OnLinetypeChangedEvent(this.linetype, value); } } @@ -226,7 +235,9 @@ public Transparency Transparency set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.transparency = value; } } @@ -240,7 +251,9 @@ public double LinetypeScale set { if (value <= 0) + { throw new ArgumentOutOfRangeException(nameof(value), value, "The line type scale must be greater than zero."); + } this.linetypeScale = value; } } @@ -264,7 +277,9 @@ public Vector3 Normal { this.normal = Vector3.Normalize(value); if (Vector3.IsNaN(this.normal)) + { throw new ArgumentException("The normal can not be the zero vector.", nameof(value)); + } } } @@ -293,7 +308,6 @@ public AttributeDefinition Definition public string Tag { get { return this.tag; } - internal set { this.tag = value; } } /// @@ -309,7 +323,9 @@ public double Height set { if (value <= 0) + { throw new ArgumentOutOfRangeException(nameof(value), value, "The height should be greater than zero."); + } this.height = value; } } @@ -324,7 +340,9 @@ public double Width set { if (value <= 0) + { throw new ArgumentOutOfRangeException(nameof(value), value, "The Text width must be greater than zero."); + } this.width = value; } } @@ -342,7 +360,9 @@ public double WidthFactor set { if (value <= 0) + { throw new ArgumentOutOfRangeException(nameof(value), value, "The width factor should be greater than zero."); + } this.widthFactor = value; } } @@ -357,7 +377,9 @@ public double ObliqueAngle set { if (value < -85.0 || value > 85.0) + { throw new ArgumentOutOfRangeException(nameof(value), value, "The oblique angle valid values range from -85 to 85."); + } this.obliqueAngle = value; } } @@ -365,10 +387,10 @@ public double ObliqueAngle /// /// Gets or sets the attribute value. /// - public object Value + public string Value { get { return this.attValue; } - set { this.attValue = value; } + set { this.attValue = string.IsNullOrEmpty(value) ? string.Empty : value; } } /// @@ -383,7 +405,9 @@ public TextStyle Style set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.style = this.OnTextStyleChangedEvent(this.style, value); } } @@ -456,15 +480,24 @@ public void TransformBy(Matrix3 transformation, Vector3 translation) { bool mirrText; if (this.Owner == null) + { mirrText = Text.DefaultMirrText; - else if(this.Owner.Owner == null) + } + else if (this.Owner.Owner == null) + { mirrText = Text.DefaultMirrText; + } else + { mirrText = this.Owner.Owner.Record.Owner.Owner.DrawingVariables.MirrText; + } Vector3 newPosition = transformation * this.Position + translation; Vector3 newNormal = transformation * this.Normal; - if (Vector3.Equals(Vector3.Zero, newNormal)) newNormal = this.Normal; + if (Vector3.Equals(Vector3.Zero, newNormal)) + { + newNormal = this.Normal; + } Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal); @@ -499,7 +532,10 @@ public void TransformBy(Matrix3 transformation, Vector3 translation) if (Vector2.CrossProduct(newUvector, newVvector) < 0) { newObliqueAngle = 90 - (newRotation - newObliqueAngle); - if(!(this.Alignment == TextAlignment.Fit || this.Alignment == TextAlignment.Aligned)) newRotation += 180; + if (!(this.Alignment == TextAlignment.Fit || this.Alignment == TextAlignment.Aligned)) + { + newRotation += 180; + } this.IsBackward = !this.IsBackward; } else @@ -579,11 +615,18 @@ public void TransformBy(Matrix3 transformation, Vector3 translation) // the oblique angle is defined between -85 and 85 degrees newObliqueAngle = MathHelper.NormalizeAngle(newObliqueAngle); if (newObliqueAngle > 180) + { newObliqueAngle = 180 - newObliqueAngle; + } + if (newObliqueAngle < -85) + { newObliqueAngle = -85; + } else if (newObliqueAngle > 85) + { newObliqueAngle = 85; + } // the height must be greater than zero, the cos is always positive between -85 and 85 double newHeight = newVvector.Modulus() * Math.Cos(newObliqueAngle * MathHelper.DegToRad); @@ -591,10 +634,14 @@ public void TransformBy(Matrix3 transformation, Vector3 translation) // the width factor is defined between 0.01 and 100 double newWidthFactor = newUvector.Modulus() / newHeight; - if(newWidthFactor<0.01) + if (newWidthFactor < 0.01) + { newWidthFactor = 0.01; + } else if (newWidthFactor > 100) + { newWidthFactor = 100; + } this.Position = newPosition; this.Normal = newNormal; @@ -629,7 +676,7 @@ public void TransformBy(Matrix4 transformation) /// A new Attribute that is a copy of this instance. public object Clone() { - Attribute entity = new Attribute + Attribute entity = new Attribute(this.tag) { //Attribute properties Layer = (Layer) this.Layer.Clone(), @@ -641,7 +688,6 @@ public object Clone() Normal = this.Normal, IsVisible = this.isVisible, Definition = (AttributeDefinition) this.definition?.Clone(), - Tag = this.tag, Height = this.height, Width = this.width, WidthFactor = this.widthFactor, diff --git a/netDxf/Entities/AttributeDefinition.cs b/netDxf/Entities/AttributeDefinition.cs index 7ceb7c09..5f45f60c 100644 --- a/netDxf/Entities/AttributeDefinition.cs +++ b/netDxf/Entities/AttributeDefinition.cs @@ -97,7 +97,7 @@ protected virtual TextStyle OnTextStyleChangedEvent(TextStyle oldTextStyle, Text private readonly string tag; private string prompt; - private object attValue; + private string attValue; private TextStyle style; private Vector3 position; private AttributeFlags flags; @@ -143,7 +143,9 @@ public AttributeDefinition(string tag, double textHeight, TextStyle style) : base(DxfObjectCode.AttributeDefinition) { if (string.IsNullOrEmpty(tag)) + { throw new ArgumentNullException(nameof(tag)); + } this.tag = tag; this.flags = AttributeFlags.None; @@ -151,10 +153,14 @@ public AttributeDefinition(string tag, double textHeight, TextStyle style) this.attValue = null; this.position = Vector3.Zero; if (style == null) + { throw new ArgumentNullException(nameof(style)); + } this.style = style; if (textHeight <= 0.0) + { throw new ArgumentOutOfRangeException(nameof(textHeight), this.attValue, "The attribute definition text height must be greater than zero."); + } this.height = textHeight; this.width = 1.0; this.widthFactor = style.WidthFactor; @@ -187,7 +193,9 @@ public AciColor Color set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.color = value; } } @@ -201,7 +209,9 @@ public Layer Layer set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.layer = this.OnLayerChangedEvent(this.layer, value); } } @@ -215,7 +225,9 @@ public Linetype Linetype set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.linetype = this.OnLinetypeChangedEvent(this.linetype, value); } } @@ -238,7 +250,9 @@ public Transparency Transparency set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.transparency = value; } } @@ -252,7 +266,9 @@ public double LinetypeScale set { if (value <= 0) + { throw new ArgumentOutOfRangeException(nameof(value), value, "The line type scale must be greater than zero."); + } this.linetypeScale = value; } } @@ -276,7 +292,9 @@ public Vector3 Normal { this.normal = Vector3.Normalize(value); if (Vector3.IsNaN(this.normal)) + { throw new ArgumentException("The normal can not be the zero vector.", nameof(value)); + } } } @@ -330,7 +348,9 @@ public double Width set { if (value <= 0) + { throw new ArgumentOutOfRangeException(nameof(value), value, "The Text width must be greater than zero."); + } this.width = value; } } @@ -348,7 +368,9 @@ public double WidthFactor set { if (value <= 0) + { throw new ArgumentOutOfRangeException(nameof(value), value, "The width factor should be greater than zero."); + } this.widthFactor = value; } } @@ -363,7 +385,9 @@ public double ObliqueAngle set { if (value < -85.0 || value > 85.0) + { throw new ArgumentOutOfRangeException(nameof(value), value, "The oblique angle valid values range from -85 to 85."); + } this.obliqueAngle = value; } } @@ -371,10 +395,10 @@ public double ObliqueAngle /// /// Gets or sets the attribute default value. /// - public object Value + public string Value { get { return this.attValue; } - set { this.attValue = value; } + set { this.attValue = string.IsNullOrEmpty(value) ? string.Empty : value; } } /// @@ -389,7 +413,9 @@ public TextStyle Style set { if (value == null) + { throw new ArgumentNullException(nameof(value)); + } this.style = this.OnTextStyleChangedEvent(this.style, value); } } @@ -473,7 +499,10 @@ public void TransformBy(Matrix3 transformation, Vector3 translation) Vector3 newPosition = transformation * this.Position + translation; Vector3 newNormal = transformation * this.Normal; - if (Vector3.Equals(Vector3.Zero, newNormal)) newNormal = this.Normal; + if (Vector3.Equals(Vector3.Zero, newNormal)) + { + newNormal = this.Normal; + } Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal); @@ -508,7 +537,10 @@ public void TransformBy(Matrix3 transformation, Vector3 translation) if (Vector2.CrossProduct(newUvector, newVvector) < 0) { newObliqueAngle = 90 - (newRotation - newObliqueAngle); - if(!(this.Alignment == TextAlignment.Fit || this.Alignment == TextAlignment.Aligned)) newRotation += 180; + if (!(this.Alignment == TextAlignment.Fit || this.Alignment == TextAlignment.Aligned)) + { + newRotation += 180; + } this.IsBackward = !this.IsBackward; } else @@ -588,11 +620,18 @@ public void TransformBy(Matrix3 transformation, Vector3 translation) // the oblique angle is defined between -85 and 85 degrees newObliqueAngle = MathHelper.NormalizeAngle(newObliqueAngle); if (newObliqueAngle > 180) + { newObliqueAngle = 180 - newObliqueAngle; + } + if (newObliqueAngle < -85) + { newObliqueAngle = -85; + } else if (newObliqueAngle > 85) + { newObliqueAngle = 85; + } // the height must be greater than zero, the cos is always positive between -85 and 85 double newHeight = newVvector.Modulus() * Math.Cos(newObliqueAngle * MathHelper.DegToRad); @@ -600,10 +639,14 @@ public void TransformBy(Matrix3 transformation, Vector3 translation) // the width factor is defined between 0.01 and 100 double newWidthFactor = newUvector.Modulus() / newHeight; - if(newWidthFactor<0.01) + if (newWidthFactor < 0.01) + { newWidthFactor = 0.01; + } else if (newWidthFactor > 100) + { newWidthFactor = 100; + } this.Position = newPosition; this.Normal = newNormal; @@ -665,7 +708,9 @@ public object Clone() }; foreach (XData data in this.XData.Values) + { entity.XData.Add((XData) data.Clone()); + } return entity; } diff --git a/netDxf/IO/DxfReader.cs b/netDxf/IO/DxfReader.cs index bfc8250c..5fe09ebc 100644 --- a/netDxf/IO/DxfReader.cs +++ b/netDxf/IO/DxfReader.cs @@ -310,7 +310,6 @@ public DxfDocument Read(Stream stream, IEnumerable supportFolders) Debug.Assert(false, string.Format("Unknown section {0}.", this.chunk.ReadString())); this.ReadUnknowData(); break; - //throw new Exception(string.Format("Unknown section {0}.", this.chunk.ReadString())); } } this.chunk.Next(); @@ -1365,10 +1364,9 @@ private ApplicationRegistry ReadApplicationId() } } + Debug.Assert(TableObject.IsValidName(appId), "Table object name is not valid."); if (!TableObject.IsValidName(appId)) { - Debug.Assert(false, "Table object name is not valid."); - return null; } @@ -2015,10 +2013,9 @@ private DimensionStyle ReadDimensionStyle() } } + Debug.Assert(TableObject.IsValidName(name), "Table object name is not valid."); if (!TableObject.IsValidName(name)) { - Debug.Assert(false, "Table object name is not valid."); - return null; } @@ -2340,9 +2337,9 @@ private Layer ReadLayer() } } + Debug.Assert(TableObject.IsValidName(name), string.Format("Table object name \"{0}\" is not valid.", name)); if (!TableObject.IsValidName(name)) { - Debug.Assert(false, string.Format("Table object name \"{0}\" is not valid.", name)); return null; } @@ -2454,9 +2451,9 @@ private Linetype ReadLinetype(out bool isComplex) } } + Debug.Assert(TableObject.IsValidName(name), "Table object name is not valid."); if (!TableObject.IsValidName(name)) { - Debug.Assert(false, "Table object name is not valid."); return null; } @@ -2656,21 +2653,21 @@ private DxfObject ReadTextStyle() if (isShapeStyle) { // file cannot be null or empty + Debug.Assert(!string.IsNullOrEmpty(file), "File path is null or empty."); if (string.IsNullOrEmpty(file)) { - Debug.Assert(false, "File path is null or empty."); file = FileNotValid; } // basic check if file is a file path - if (file.IndexOfAny(Path.GetInvalidPathChars()) == 0) + Debug.Assert(file.IndexOfAny(Path.GetInvalidPathChars()) == -1, "File path contains invalid characters: " + file); + if (file.IndexOfAny(Path.GetInvalidPathChars()) != -1) { - Debug.Assert(false, "File path contains invalid characters: " + file); file = FileNotValid; } //ShapeStyle shapeStyle = new ShapeStyle(Path.GetFileNameWithoutExtension(file), file, height, widthFactor, obliqueAngle); - ShapeStyle shapeStyle = new ShapeStyle("ShapeStyle" + ++this.shapeStyleCounter, file, height, widthFactor, obliqueAngle); + ShapeStyle shapeStyle = new ShapeStyle("ShapeStyle - " + ++this.shapeStyleCounter, file, height, widthFactor, obliqueAngle); if (xData.Count > 0) { this.tableEntryXData.Add(shapeStyle, xData); @@ -2679,9 +2676,9 @@ private DxfObject ReadTextStyle() } // text styles + Debug.Assert(TableObject.IsValidName(name), "Table object name is not valid."); if (!TableObject.IsValidName(name)) { - Debug.Assert(false, "Table object name is not valid."); return null; } @@ -2707,19 +2704,18 @@ private DxfObject ReadTextStyle() TextStyle style; // basic check if file is a file path + Debug.Assert(file.IndexOfAny(Path.GetInvalidPathChars()) == -1, "File path contains invalid characters."); if (file.IndexOfAny(Path.GetInvalidPathChars()) != -1) { - Debug.Assert(false, "File path contains invalid characters."); - return null; } // the information stored in the extended data takes precedence before the font file (this is only applicable for true type fonts) if (string.IsNullOrEmpty(fontFamily)) { + Debug.Assert(!string.IsNullOrEmpty(file), "File path is null or empty."); if (string.IsNullOrEmpty(file)) { - Debug.Assert(false, "File path is null or empty."); file = "simplex.shx"; } else @@ -2847,10 +2843,9 @@ private UCS ReadUCS() } } + Debug.Assert(TableObject.IsValidName(name), "Table object name is not valid."); if (!TableObject.IsValidName(name)) { - Debug.Assert(false, "Table object name is not valid."); - return null; } @@ -2997,10 +2992,9 @@ private VPort ReadVPort() return null; } + Debug.Assert(TableObject.IsValidName(name), "Table object name is not valid."); if (!TableObject.IsValidName(name)) { - Debug.Assert(false, "Table object name is not valid."); - return null; } @@ -3155,17 +3149,15 @@ private Block ReadBlock() if (type.HasFlag(BlockTypeFlags.XRef)) { + Debug.Assert(!string.IsNullOrEmpty(xrefFile), "File path is null or empty."); if (string.IsNullOrEmpty(xrefFile)) { - Debug.Assert(false, "File path is null or empty."); - xrefFile = FileNotValid; } - if (xrefFile.IndexOfAny(Path.GetInvalidPathChars()) == 0) + Debug.Assert(xrefFile.IndexOfAny(Path.GetInvalidPathChars()) == -1, "File path contains invalid characters: " + xrefFile); + if (xrefFile.IndexOfAny(Path.GetInvalidPathChars()) != -1) { - Debug.Assert(false, "File path contains invalid characters: " + xrefFile); - xrefFile = FileNotValid; } @@ -3232,7 +3224,7 @@ private AttributeDefinition ReadAttributeDefinition() { string tag = string.Empty; string text = string.Empty; - object value = null; + string value = string.Empty; AttributeFlags flags = AttributeFlags.None; Vector3 firstAlignmentPoint = Vector3.Zero; Vector3 secondAlignmentPoint = Vector3.Zero; @@ -3252,6 +3244,10 @@ private AttributeDefinition ReadAttributeDefinition() { switch (this.chunk.Code) { + case 1: + value = this.DecodeEncodedNonAsciiCharacters(this.chunk.ReadString()); + this.chunk.Next(); + break; case 2: tag = this.DecodeEncodedNonAsciiCharacters(this.chunk.ReadString()); this.chunk.Next(); @@ -3260,10 +3256,6 @@ private AttributeDefinition ReadAttributeDefinition() text = this.DecodeEncodedNonAsciiCharacters(this.chunk.ReadString()); this.chunk.Next(); break; - case 1: - value = this.DecodeEncodedNonAsciiCharacters(this.chunk.ReadString()); - this.chunk.Next(); - break; case 70: flags = (AttributeFlags) this.chunk.ReadShort(); this.chunk.Next(); @@ -3347,10 +3339,7 @@ private AttributeDefinition ReadAttributeDefinition() xData.Add(data); break; default: - if (this.chunk.Code >= 1000 && this.chunk.Code <= 1071) - { - throw new Exception("The extended data of an entity must start with the application registry code."); - } + Debug.Assert(!(this.chunk.Code >= 1000 && this.chunk.Code <= 1071), "The extended data of an entity must start with the application registry code."); this.chunk.Next(); break; } @@ -3452,7 +3441,9 @@ private Attribute ReadAttribute(Block block, bool isBlockEntity = false) break; case 62: // ACI color code if (!color.UseTrueColor) + { color = AciColor.FromCadIndex(this.chunk.ReadShort()); + } this.chunk.Next(); break; case 440: //transparency @@ -3486,9 +3477,9 @@ private Attribute ReadAttribute(Block block, bool isBlockEntity = false) } } - string atttag = null; - AttributeDefinition attdef = null; - object value = null; + AttributeDefinition attDef = null; + string attTag = string.Empty; + string value = string.Empty; this.chunk.Next(); while (this.chunk.Code != 0) @@ -3496,12 +3487,12 @@ private Attribute ReadAttribute(Block block, bool isBlockEntity = false) switch (this.chunk.Code) { case 2: - atttag = this.DecodeEncodedNonAsciiCharacters(this.chunk.ReadString()); - // seems that some programs might export insert entities with attributes which definitions are not defined in the block + attTag = this.DecodeEncodedNonAsciiCharacters(this.chunk.ReadString()); + // seems that some programs may export insert entities with attributes which definitions are not defined in the block // if it is not present the insert attribute will have a null definition if (!isBlockEntity) { - block.AttributeDefinitions.TryGetValue(atttag, out attdef); + block.AttributeDefinitions.TryGetValue(attTag, out attDef); } this.chunk.Next(); break; @@ -3592,10 +3583,7 @@ private Attribute ReadAttribute(Block block, bool isBlockEntity = false) xData.Add(data); break; default: - if (this.chunk.Code >= 1000 && this.chunk.Code <= 1071) - { - throw new Exception("The extended data of an entity must start with the application registry code."); - } + Debug.Assert(!(this.chunk.Code >= 1000 && this.chunk.Code <= 1071), "The extended data of an entity must start with the application registry code."); this.chunk.Next(); break; } @@ -3605,21 +3593,28 @@ private Attribute ReadAttribute(Block block, bool isBlockEntity = false) Vector3 ocsBasePoint; - if (alignment == TextAlignment.BaselineLeft) + switch (alignment) { - ocsBasePoint = firstAlignmentPoint; - } - else if (alignment == TextAlignment.Fit || alignment == TextAlignment.Aligned) - { - width = (secondAlignmentPoint - firstAlignmentPoint).Modulus(); - ocsBasePoint = firstAlignmentPoint; + case TextAlignment.BaselineLeft: + ocsBasePoint = firstAlignmentPoint; + break; + case TextAlignment.Fit: + case TextAlignment.Aligned: + width = (secondAlignmentPoint - firstAlignmentPoint).Modulus(); + ocsBasePoint = firstAlignmentPoint; + break; + default: + ocsBasePoint = secondAlignmentPoint; + break; } - else + + Debug.Assert(!string.IsNullOrEmpty(attTag), "The attribute tag cannot be null or empty."); + if (string.IsNullOrEmpty(attTag)) { - ocsBasePoint = secondAlignmentPoint; + return null; } - Attribute attribute = new Attribute + Attribute attribute = new Attribute(attTag) { Handle = handle, Color = color, @@ -3629,8 +3624,7 @@ private Attribute ReadAttribute(Block block, bool isBlockEntity = false) LinetypeScale = linetypeScale, Transparency = transparency, IsVisible = isVisible, - Definition = attdef, - Tag = atttag, + Definition = attDef, Position = MathHelper.Transform(ocsBasePoint, normal, CoordinateSystem.Object, CoordinateSystem.World), Normal = normal, Alignment = alignment, @@ -3712,7 +3706,9 @@ private DxfObject ReadEntity(bool isBlockEntity) break; case 62: //ACI color code if (!color.UseTrueColor) + { color = AciColor.FromCadIndex(this.chunk.ReadShort()); + } this.chunk.Next(); break; case 420: //the entity uses true color @@ -3735,7 +3731,9 @@ private DxfObject ReadEntity(bool isBlockEntity) case 48: //line type scale linetypeScale = this.chunk.ReadDouble(); if (linetypeScale <= 0.0) + { linetypeScale = 1.0; + } this.chunk.Next(); break; case 60: //object visibility @@ -9783,17 +9781,15 @@ private ImageDefinition ReadImageDefinition() } } + Debug.Assert(!string.IsNullOrEmpty(file), "File path is null or empty."); if (string.IsNullOrEmpty(file)) { - Debug.Assert(false, "File path is null or empty."); - file = FileNotValid; } - if (file.IndexOfAny(Path.GetInvalidPathChars()) == 0) + Debug.Assert(file.IndexOfAny(Path.GetInvalidPathChars()) == -1, "File path contains invalid characters: " + file); + if (file.IndexOfAny(Path.GetInvalidPathChars()) != -1) { - Debug.Assert(false, "File path contains invalid characters: " + file); - file = FileNotValid; } @@ -10490,17 +10486,15 @@ private UnderlayDefinition ReadUnderlayDefinition(UnderlayType type) } } + Debug.Assert(!string.IsNullOrEmpty(file), "File path is null or empty."); if (string.IsNullOrEmpty(file)) { - Debug.Assert(false, "File path is null or empty."); - file = FileNotValid; } - if (file.IndexOfAny(Path.GetInvalidPathChars()) == 0) + Debug.Assert(file.IndexOfAny(Path.GetInvalidPathChars()) == -1, "File path contains invalid characters: " + file); + if (file.IndexOfAny(Path.GetInvalidPathChars()) != -1) { - Debug.Assert(false, "File path contains invalid characters: " + file); - file = FileNotValid; } @@ -11379,13 +11373,11 @@ private ApplicationRegistry GetApplicationRegistry(string name) private Block GetBlock(string name) { Block block; + Debug.Assert(this.doc.Blocks.TryGetValue(name, out block), "The block with name " + name + " does not exist."); if (this.doc.Blocks.TryGetValue(name, out block)) { return block; } - - Debug.Assert(false, "The block with name " + name + " does not exist."); - return this.doc.Blocks.Add(new Block(name)); } diff --git a/netDxf/IO/DxfWriter.cs b/netDxf/IO/DxfWriter.cs index 489e3f20..3b56e3ec 100644 --- a/netDxf/IO/DxfWriter.cs +++ b/netDxf/IO/DxfWriter.cs @@ -4328,10 +4328,14 @@ private void WriteAttributeDefinition(AttributeDefinition def, Layout layout) this.chunk.Write(62, def.Color.Index); if (def.Color.UseTrueColor) + { this.chunk.Write(420, AciColor.ToTrueColor(def.Color)); + } if (def.Transparency.Value >= 0) + { this.chunk.Write(440, Transparency.ToAlphaValue(def.Transparency)); + } this.chunk.Write(6, this.EncodeNonAsciiCharacters(def.Linetype.Name)); @@ -4349,13 +4353,7 @@ private void WriteAttributeDefinition(AttributeDefinition def, Layout layout) this.chunk.Write(40, def.Height); - object value = def.Value; - if (value == null) - this.chunk.Write(1, string.Empty); - else if (value is string) - this.chunk.Write(1, this.EncodeNonAsciiCharacters((string) value)); - else - this.chunk.Write(1, value.ToString()); + this.chunk.Write(1, this.EncodeNonAsciiCharacters(def.Value)); switch (def.Alignment) { @@ -4521,19 +4519,7 @@ private void WriteAttribute(Attribute attrib) this.chunk.Write(7, this.EncodeNonAsciiCharacters(attrib.Style.Name)); - object value = attrib.Value; - if (value == null) - { - this.chunk.Write(1, string.Empty); - } - else if (value is string) - { - this.chunk.Write(1, this.EncodeNonAsciiCharacters((string) value)); - } - else - { - this.chunk.Write(1, value.ToString()); - } + this.chunk.Write(1, this.EncodeNonAsciiCharacters(attrib.Value)); switch (attrib.Alignment) {