Exemple #1
0
        public void renameBlockInside(string find, string replace)
        {
            foreach (_Db.ObjectId btrId in _c.blockTable)
            {
                _Db.BlockTableRecord btr = _c.trans.GetObject(btrId, _Db.OpenMode.ForWrite) as _Db.BlockTableRecord;

                foreach (_Db.ObjectId bid in btr)
                {
                    _Db.Entity currentEntity = _c.trans.GetObject(bid, _Db.OpenMode.ForWrite) as _Db.Entity;

                    if (currentEntity == null)
                    {
                        continue;
                    }
                    if (currentEntity is _Db.MText)
                    {
                        _Db.MText txt = currentEntity as _Db.MText;
                        txt.Contents = txt.Contents.Replace(find, replace);
                        txt.DowngradeOpen();
                    }
                    if (currentEntity is _Db.DBText)
                    {
                        _Db.DBText txt = currentEntity as _Db.DBText;
                        txt.TextString = txt.TextString.Replace(find, replace);
                    }
                }
            }
        }
Exemple #2
0
        // Database extensions
        ///<summary>
        /// Create a piece of text of a specified size at a specified location.
        ///</summary>
        ///<param name="norm">The normal to the text object.</param>
        ///<param name="pt">The position for the text.</param>
        ///<param name="conts">The contents of the text.</param>
        ///<param name="size">The size of the text.</param>
        public static void CreateText(

            this _AcDb.Database db, _AcGe.Vector3d norm, _AcGe.Point3d pt, string conts, double size

            )
        {
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var ms =
                    tr.GetObject(
                        _AcDb.SymbolUtilityServices.GetBlockModelSpaceId(db),
                        _AcDb.OpenMode.ForWrite

                        ) as _AcDb.BlockTableRecord;

                if (ms != null)
                {
                    var txt = new _AcDb.DBText();
                    txt.Normal         = norm;
                    txt.Position       = pt;
                    txt.Justify        = _AcDb.AttachmentPoint.MiddleCenter;
                    txt.AlignmentPoint = pt;
                    txt.TextString     = conts;
                    txt.Height         = size;

                    var id = ms.AppendEntity(txt);
                    tr.AddNewlyCreatedDBObject(txt, true);
                }

                tr.Commit();
            }
        }
Exemple #3
0
        public static void ManualInsertText(AcDb.DBText oText)
        {
            using (AcDb.Transaction tr = db.TransactionManager.StartTransaction())
            {
                AcDb.BlockTableRecord btr = (AcDb.BlockTableRecord)tr.GetObject(db.CurrentSpaceId, AcDb.OpenMode.ForWrite);

                oText.Normal = ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis;

                btr.AppendEntity(oText);
                tr.AddNewlyCreatedDBObject(oText, true);

                TextPlacementJig pj = new TextPlacementJig(oText);

                AcEd.PromptStatus stat = AcEd.PromptStatus.Keyword;
                while (stat == AcEd.PromptStatus.Keyword)
                {
                    AcEd.PromptResult res = ed.Drag(pj);
                    stat = res.Status;
                    if (stat != AcEd.PromptStatus.OK && stat != AcEd.PromptStatus.Keyword)
                    {
                        return;
                    }
                }
                tr.Commit();
                //return (DBText)pj.Entity;
            }
        }
        public static void ManualInsertbAttribute(string nameBlock)
        {
            using (AcDb.Transaction tr = db.TransactionManager.StartTransaction())
            {
                AcDb.BlockTable blockTable = (AcDb.BlockTable)tr.GetObject(db.BlockTableId, AcDb.OpenMode.ForRead);
                if (!blockTable.Has(nameBlock))
                {
                    ed.WriteMessage("\nНезнайдено блок '{0}' у таблиці блоків креслення.", nameBlock);
                    return;
                }
                AcDb.BlockTableRecord curSpace       = (AcDb.BlockTableRecord)tr.GetObject(db.CurrentSpaceId, AcDb.OpenMode.ForWrite);
                AcDb.BlockReference   blockReference = new AcDb.BlockReference(AcGe.Point3d.Origin, blockTable[nameBlock]);
                blockReference.TransformBy(ed.CurrentUserCoordinateSystem);
                curSpace.AppendEntity(blockReference);
                tr.AddNewlyCreatedDBObject(blockReference, true);

                AcDb.BlockTableRecord btr = (AcDb.BlockTableRecord)tr.GetObject(blockTable[nameBlock], AcDb.OpenMode.ForRead);
                AcDb.DBText           text;
                foreach (AcDb.ObjectId id in btr)
                {
                    if (id.ObjectClass.Name == "AcDbAttributeDefinition")
                    {
                        AcDb.AttributeDefinition attDef =
                            (AcDb.AttributeDefinition)tr.GetObject(id, AcDb.OpenMode.ForRead);

                        text = new AcDb.DBText
                        {
                            TextString = "jig_test"
                        };

                        TextPlacementJig jig = new TextPlacementJig(text);

                        //PromptResult pr = ed.Drag(jig);

                        AcEd.PromptStatus stat = AcEd.PromptStatus.Keyword;
                        while (stat == AcEd.PromptStatus.Keyword)
                        {
                            AcEd.PromptResult pr = ed.Drag(jig);
                            stat = pr.Status;
                            if (stat != AcEd.PromptStatus.OK && stat != AcEd.PromptStatus.Keyword)
                            {
                                return;
                            }
                        }

                        AcDb.AttributeReference attRef = new AcDb.AttributeReference();
                        attRef.SetAttributeFromBlock(attDef, blockReference.BlockTransform);
                        AcDb.ObjectId attId = blockReference.AttributeCollection.AppendAttribute(attRef);
                        tr.AddNewlyCreatedDBObject(attRef, true);


                        tr.Commit();
                        //if (pr.Status != PromptStatus.OK) blockReference.Erase();
                    }
                }

                //tr.Commit();
            }
        }
Exemple #5
0
        private void alfa(_Db.ObjectId id, ref List <_Db.Dimension> dims, ref List <_Db.BlockReference> blocks, ref List <_Db.MText> txts)
        {
            _Db.DBObject currentEntity = _c.trans.GetObject(id, _Db.OpenMode.ForWrite, false) as _Db.DBObject;

            if (currentEntity == null)
            {
                return;
            }

            else if (currentEntity is _Db.BlockReference)
            {
                _Db.BlockReference blockRef = currentEntity as _Db.BlockReference;

                _Db.BlockTableRecord block = null;
                if (blockRef.IsDynamicBlock)
                {
                    block = _c.trans.GetObject(blockRef.DynamicBlockTableRecord, _Db.OpenMode.ForRead) as _Db.BlockTableRecord;
                }
                else
                {
                    block = _c.trans.GetObject(blockRef.BlockTableRecord, _Db.OpenMode.ForRead) as _Db.BlockTableRecord;
                }

                if (block != null)
                {
                    blocks.Add(blockRef);
                }
            }
            else if (currentEntity is _Db.Dimension)
            {
                _Db.Dimension dim = currentEntity as _Db.Dimension;
                dims.Add(dim);
            }
            else if (currentEntity is _Db.MText)
            {
                _Db.MText br = currentEntity as _Db.MText;
                txts.Add(br);
            }
            else if (currentEntity is _Db.DBText)
            {
                _Db.DBText br = currentEntity as _Db.DBText;

                _Db.MText myMtext = new _Db.MText();
                myMtext.Contents   = br.TextString;
                myMtext.Location   = br.Position;
                myMtext.TextHeight = br.Height;
                txts.Add(myMtext);
            }
            else if (currentEntity is _Db.MLeader)
            {
                _Db.MLeader br = currentEntity as _Db.MLeader;

                if (br.ContentType == _Db.ContentType.MTextContent)
                {
                    _Db.MText leaderText = br.MText;
                    txts.Add(leaderText);
                }
            }
        }
Exemple #6
0
 public static AcDb.DBText CreateText(AcGe.Point3d insertPoint, string textValue)
 {
     AcDb.DBText text = new AcDb.DBText
     {
         TextString = textValue,
         Position   = insertPoint
     };
     return(text);
 }
Exemple #7
0
        protected override bool Update()
        {
            AcDb.DBText txt = (AcDb.DBText)Entity;

            txt.Position = _position;
            txt.Height   = _txtSize;
            txt.Rotation = _angle;

            return(true);
        }
Exemple #8
0
        public void InsertTextPlacementJig()
        {
            AcDb.DBText oText = new AcDb.DBText
            {
                TextString = "Test String TExt",
                Height     = 5.33
            };

            //ServiceSimpleElements.ManualInsertText(oText);
        }
Exemple #9
0
        private List <_Db.MText> getAllText(string layer)
        {
            List <_Db.MText> txt = new List <_Db.MText>();

            _Db.BlockTableRecord btr = _c.trans.GetObject(_c.modelSpace.Id, _Db.OpenMode.ForWrite) as _Db.BlockTableRecord;

            foreach (_Db.ObjectId id in btr)
            {
                _Db.Entity currentEntity = _c.trans.GetObject(id, _Db.OpenMode.ForWrite, false) as _Db.Entity;

                if (currentEntity != null)
                {
                    if (currentEntity is _Db.MText)
                    {
                        _Db.MText br = currentEntity as _Db.MText;
                        if (br.Layer == layer)
                        {
                            txt.Add(br);
                        }
                    }

                    if (currentEntity is _Db.DBText)
                    {
                        _Db.DBText br = currentEntity as _Db.DBText;
                        if (br.Layer == layer)
                        {
                            _Db.MText myMtext = new _Db.MText();
                            myMtext.Contents = br.TextString;
                            myMtext.Location = br.Position;
                            txt.Add(myMtext);
                        }
                    }

                    if (currentEntity is _Db.MLeader)
                    {
                        _Db.MLeader br = currentEntity as _Db.MLeader;
                        if (br.Layer == layer)
                        {
                            if (br.ContentType == _Db.ContentType.MTextContent)
                            {
                                _Db.MText leaderText = br.MText;
                                txt.Add(leaderText);
                            }
                        }
                    }
                }
            }

            return(txt);
        }
Exemple #10
0
        private List <_Db.MText> getSelectedText()
        {
            List <_Db.MText> txt = new List <_Db.MText>();

            _Ed.PromptSelectionResult selection = _c.ed.GetSelection();
            if (selection.Status == _Ed.PromptStatus.OK)
            {
                _Db.ObjectId[] objIds = selection.Value.GetObjectIds();

                foreach (_Db.ObjectId objId in objIds)
                {
                    _Db.Entity currentEntity = _c.trans.GetObject(objId, _Db.OpenMode.ForRead) as _Db.Entity;

                    if (currentEntity == null)
                    {
                        continue;
                    }

                    if (currentEntity is _Db.MText)
                    {
                        _Db.MText br = currentEntity as _Db.MText;
                        txt.Add(br);
                    }
                    else if (currentEntity is _Db.DBText)
                    {
                        _Db.DBText br      = currentEntity as _Db.DBText;
                        _Db.MText  myMtext = new _Db.MText();

                        myMtext.Contents = br.TextString;
                        myMtext.Layer    = br.Layer;
                        myMtext.Location = br.Position;
                        txt.Add(myMtext);
                    }
                    else if (currentEntity is _Db.MLeader)
                    {
                        _Db.MLeader br = currentEntity as _Db.MLeader;

                        if (br.ContentType == _Db.ContentType.MTextContent)
                        {
                            _Db.MText leaderText = br.MText;
                            leaderText.Layer = br.Layer;
                            txt.Add(leaderText);
                        }
                    }
                }
            }

            return(txt);
        }
Exemple #11
0
        private List <_Db.MText> getAllText(string layer)
        {
            List <_Db.MText> txts = new List <_Db.MText>();

            foreach (_Db.ObjectId id in _c.modelSpace)
            {
                _Db.Entity currentEntity = _c.trans.GetObject(id, _Db.OpenMode.ForWrite, false) as _Db.Entity;

                if (currentEntity == null)
                {
                    continue;
                }

                if (currentEntity is _Db.MText)
                {
                    _Db.MText mtxt = currentEntity as _Db.MText;

                    if (mtxt.Layer == layer)
                    {
                        txts.Add(mtxt);
                    }
                }
                else if (currentEntity is _Db.DBText)
                {
                    _Db.DBText dbt = currentEntity as _Db.DBText;
                    if (dbt.Layer == layer)
                    {
                        _Db.MText mtxt = new _Db.MText();
                        mtxt.Contents = dbt.TextString;
                        mtxt.Location = dbt.Position;
                        txts.Add(mtxt);
                    }
                }
                else if (currentEntity is _Db.MLeader)
                {
                    _Db.MLeader ml = currentEntity as _Db.MLeader;
                    if (ml.Layer == layer)
                    {
                        if (ml.ContentType == _Db.ContentType.MTextContent)
                        {
                            _Db.MText mtxt = ml.MText;
                            txts.Add(mtxt);
                        }
                    }
                }
            }

            return(txts);
        }
Exemple #12
0
        private void insertText(string value, _Ge.Point3d position, string layer)
        {
            _Db.BlockTableRecord btr = _c.trans.GetObject(_c.modelSpace.Id, _Db.OpenMode.ForWrite) as _Db.BlockTableRecord;

            using (_Db.DBText acText = new _Db.DBText())
            {
                acText.Layer = layer;

                acText.Position   = position;
                acText.Height     = 120;
                acText.TextString = value;

                btr.AppendEntity(acText);
                _c.trans.AddNewlyCreatedDBObject(acText, true);
            }
        }
Exemple #13
0
        public void renameText(string find, string replace)
        {
            foreach (_Db.ObjectId id in _c.modelSpace)
            {
                _Db.Entity currentEntity = _c.trans.GetObject(id, _Db.OpenMode.ForWrite, false) as _Db.Entity;

                if (currentEntity == null)
                {
                    continue;
                }
                if (currentEntity is _Db.MText)
                {
                    _Db.MText txt = currentEntity as _Db.MText;
                    txt.Contents = txt.Contents.Replace(find, replace);
                }
                if (currentEntity is _Db.DBText)
                {
                    _Db.DBText txt = currentEntity as _Db.DBText;
                    txt.TextString = txt.TextString.Replace(find, replace);
                }
            }
        }
Exemple #14
0
        // Transaction extensions

        ///<summary>
        /// Create a bounding rectangle around a piece of text (for debugging).
        ///</summary>
        ///<param name="txt">The text object around which to create a box.</param>
        public static void CreateBoundingBox(this _AcDb.Transaction tr, _AcDb.DBText txt)
        {
            var ms =
                tr.GetObject(
                    _AcDb.SymbolUtilityServices.GetBlockModelSpaceId(txt.Database),
                    _AcDb.OpenMode.ForWrite

                    ) as _AcDb.BlockTableRecord;

            if (ms != null)
            {
                var corners = txt.ExtractBounds();
                if (corners.Count >= 4)
                {
                    var doc = _AcAp.Application.DocumentManager.MdiActiveDocument;
                    if (doc == null)
                    {
                        return;
                    }
                    var ed  = doc.Editor;
                    var ucs = ed.CurrentUserCoordinateSystem;
                    var cs  = ucs.CoordinateSystem3d;
                    var pl  = new _AcDb.Polyline(4);

                    for (int i = 0; i < 4; i++)
                    {
                        pl.AddVertexAt(i, corners[i].ProjectToUcs(cs), 0, 0, 0);
                    }

                    pl.Closed = true;
                    pl.TransformBy(ucs);
                    ms.AppendEntity(pl);
                    tr.AddNewlyCreatedDBObject(pl, true);
                }
            }
        }
Exemple #15
0
        /// <summary>
        /// Створює коллекцію текстових обектів значень данних таблиці виносу внатуру меж земельної ділянки.
        /// </summary>
        /// <param name="polygon">Земельна ділянка.</param>
        /// <param name="settingTable">Налаштування таблиці.</param>
        /// <returns>
        ///  Повертає <see cref="T:AcDb.DBObjectCollection"/>, що містить текстові значення данний таблиці виносу внатуру меж земельної ділянки.
        /// </returns>
        internal static AcDb.DBObjectCollection GetDataTableStakeOutParcelPoints(LandParcel polygon, SettingTable settingTable)
        {
            List <StakeOutParcelPoint> stakeoutPoints = polygon.StakeOutParcelPoints;

            //stakeoutPoints.Sort((x, y) => y.PointStation.Name.CompareTo(x.PointStation.Name));

            AcDb.DBObjectCollection objects = new AcDb.DBObjectCollection();

            AcDb.DBText  textValue;
            AcGe.Point3d insertPoint;

            //AcGe.Point2d backPoint, stationPoint, parcelPoint;

            double heightTable = (settingTable.GetHeightCapTable() + settingTable.TextHeight) * -1;

            int index = -1;

            foreach (StakeOutParcelPoint stakeoutPoint in stakeoutPoints)
            {
                index++;
                double colWidth = 0;
                heightTable += settingTable.TextHeight * 2 * index;

                foreach (ColumnTable col in settingTable.Columns)
                {
                    colWidth += col.Width;

                    insertPoint = new AcGe.Point3d();
                    insertPoint = new AcGe.Point3d
                                  (
                        colWidth - col.Width / 2,
                        (settingTable.GetHeightCapTable() + (index + 1) * settingTable.TextHeight * 2) * -1,
                        0
                                  );

                    textValue = new AcDb.DBText();

                    textValue.Height         = settingTable.TextHeight;
                    textValue.Justify        = AcDb.AttachmentPoint.BottomCenter;
                    textValue.Position       = settingTable.BasePointDrawing.Add(insertPoint.GetAsVector());
                    textValue.AlignmentPoint = textValue.Position;

                    if (col.Format.IndexOf("Number") > -1)
                    {
                        textValue.TextString = stakeoutPoint.Name;
                    }
                    else if (col.Format.IndexOf("X") > -1)
                    {
                        textValue.TextString = stakeoutPoint.Coordinates.X.ToString("0.00");
                    }
                    else if (col.Format.IndexOf("Y") > -1)
                    {
                        textValue.TextString = stakeoutPoint.Coordinates.Y.ToString("0.00");
                    }
                    else if (col.Format.IndexOf("LengthLine") > -1)
                    {
                        textValue.TextString = stakeoutPoint.Distance.ToString("0.00");
                    }
                    else if (col.Format.IndexOf("DirAngle") > -1)
                    {
                        textValue.TextString = stakeoutPoint.DirAngleToString(AcRx.AngularUnitFormat.DegreesMinutesSeconds);
                    }
                    else if (col.Format.IndexOf("InnerAngle") > -1)
                    {
                        textValue.TextString = stakeoutPoint.LeftlAngleToString(AcRx.AngularUnitFormat.DegreesMinutesSeconds);
                    }
                    else if (col.Format.IndexOf("BasePoints_dirAngle") > -1)
                    {
                        textValue.TextString = stakeoutPoint.PointStation.Name;
                    }
                    else if (col.Format.IndexOf("BasePoints_innerAngle") > -1)
                    {
                        textValue.TextString = stakeoutPoint.PointStation.Name
                                               + " -> "
                                               + stakeoutPoint.PointOrientation.Name;
                    }
                    else
                    {
                        textValue.TextString = "None";
                    }

                    textValue.TextString = textValue.TextString.Replace(",", ".");
                    textValue.TextString = FormatAngleValue(textValue.TextString);

                    objects.Add(textValue);
                }
            }

            return(objects);
        }
Exemple #16
0
        /// <summary>
        /// Створює коллекцію текстових обектів значень данних таблиці межі земельної ділянки.
        /// </summary>
        /// <param name="polygon">Ділянка, що є вихідною для таблиці.</param>
        /// <param name="settingTable">Налаштування таблиці.</param>
        /// <returns>
        ///  Повертає <see cref="T:AcDb.DBObjectCollection"/>, що містить текстові значення данний таблиці межі земельної ділянки.
        /// </returns>

        internal static AcDb.DBObjectCollection GetDataTableBorderPolygon(LandParcel polygon, SettingTable settingTable)
        {
            AcDb.DBObjectCollection objects = new AcDb.DBObjectCollection();

            AcDb.DBText  textValue;
            AcGe.Point3d insertPoint;

            AcGe.Point2d backPoint, currentPoint, frontPoint;

            double heightTable = (settingTable.GetHeightCapTable() + settingTable.TextHeight) * -1;

            for (int index = 0; index <= polygon.Points.Count; index++)//(Point2d point in polygon.Points)
            {
                double colWidth = 0;
                heightTable += settingTable.TextHeight * 2 * index;

                if (index == 0)
                {
                    backPoint    = polygon.Points.ToArray()[polygon.Points.Count - 1];
                    currentPoint = polygon.Points.ToArray()[index];
                    frontPoint   = polygon.Points.ToArray()[index + 1];
                }
                else if (index == polygon.Points.Count - 1)
                {
                    backPoint    = polygon.Points.ToArray()[index - 1];
                    currentPoint = polygon.Points.ToArray()[index];
                    frontPoint   = polygon.Points.ToArray()[0];
                }
                else if (index == polygon.Points.Count)
                {
                    backPoint    = polygon.Points.ToArray()[index - 1];
                    currentPoint = polygon.Points.ToArray()[0];
                    frontPoint   = polygon.Points.ToArray()[1];
                }
                else
                {
                    backPoint    = polygon.Points.ToArray()[index - 1];
                    currentPoint = polygon.Points.ToArray()[index];
                    frontPoint   = polygon.Points.ToArray()[index + 1];
                }

                foreach (ColumnTable col in settingTable.Columns)
                {
                    colWidth += col.Width;

                    insertPoint = new AcGe.Point3d();
                    insertPoint = new AcGe.Point3d(colWidth - col.Width / 2, (settingTable.GetHeightCapTable() + (index + 1) * settingTable.TextHeight * 2) * -1, 0);

                    textValue = new AcDb.DBText();

                    textValue.Height         = settingTable.TextHeight;
                    textValue.Justify        = AcDb.AttachmentPoint.BottomCenter;
                    textValue.Position       = settingTable.BasePointDrawing.Add(insertPoint.GetAsVector());
                    textValue.AlignmentPoint = textValue.Position;

                    if (col.Format.IndexOf("Number") > -1)
                    {
                        if (index == polygon.Points.Count)
                        {
                            textValue.TextString = "1";
                        }
                        else
                        {
                            textValue.TextString = Math.Abs(index + 1).ToString();
                        }
                    }
                    else if (col.Format.IndexOf("X") > -1)
                    {
                        textValue.TextString = currentPoint.X.ToString("0.00");
                    }
                    else if (col.Format.IndexOf("Y") > -1)
                    {
                        textValue.TextString = currentPoint.Y.ToString("0.00");
                    }
                    else if (col.Format.IndexOf("LengthLine") > -1)
                    {
                        if (index < polygon.Points.Count)
                        {
                            textValue.Position       = textValue.Position.Add(new AcGe.Vector3d(0, settingTable.TextHeight * -1, 0));
                            textValue.AlignmentPoint = textValue.Position;
                            textValue.TextString     = currentPoint.GetDistanceTo(frontPoint).ToString("0.00");
                        }
                    }
                    else if (col.Format.IndexOf("DirAngle") > -1)
                    {
                        if (index < polygon.Points.Count)
                        {
                            textValue.Position       = textValue.Position.Add(new AcGe.Vector3d(0, settingTable.TextHeight * -1, 0));
                            textValue.AlignmentPoint = textValue.Position;
                            double angle = ServiceGeodesy.GetDirAngle(currentPoint, frontPoint);
                            textValue.TextString = AcRx.Converter.AngleToString(angle, AcRx.AngularUnitFormat.DegreesMinutesSeconds, 3);
                        }
                    }
                    else if (col.Format.IndexOf("InnerAngle") > -1)
                    {
                        double angle = ServiceGeodesy.GetRightAngle(backPoint, currentPoint, frontPoint);
                        textValue.TextString = AcRx.Converter.AngleToString(angle, AcRx.AngularUnitFormat.DegreesMinutesSeconds, 3);
                    }
                    else
                    {
                        textValue.TextString = "None";
                    }

                    textValue.TextString = textValue.TextString.Replace(",", ".");

                    for (int i = 0; i < 10; i++)
                    {
                        textValue.TextString = textValue.TextString
                                               .Replace("°" + i.ToString() + "'", "°" + i.ToString("00") + "'");
                    }
                    for (int i = 0; i < 10; i++)
                    {
                        textValue.TextString = textValue.TextString
                                               .Replace("'" + i.ToString() + "\"", "'" + i.ToString("00") + "\"");
                    }

                    objects.Add(textValue);
                }
            }

            return(objects);
        }
Exemple #17
0
 public TextPlacementJig(AcDb.DBText oText)
     : base((AcDb.Entity)oText)
 {
     _angle   = oText.Rotation;
     _txtSize = oText.Height;
 }
Exemple #18
0
        // DBText extensions



        ///<summary>
        /// Gets the bounds of a DBText object.
        ///</summary>
        ///<param name="fac">Optional multiplier to increase/reduce buffer.</param>
        ///<returns>A collection of points defining the text's extents.</returns>
        public static _AcGe.Point3dCollection ExtractBounds(
            this _AcDb.DBText txt, double fac = 1.0
            )
        {
            var pts = new _AcGe.Point3dCollection();

            if (txt.Bounds.HasValue && txt.Visible)
            {
                // Create a straight version of the text object
                // and copy across all the relevant properties
                // (stopped copying AlignmentPoint, as it would
                // sometimes cause an eNotApplicable error)
                // We'll create the text at the WCS origin
                // with no rotation, so it's easier to use its
                // extents

                var txt2 = new _AcDb.DBText();

                txt2.Normal   = _AcGe.Vector3d.ZAxis;
                txt2.Position = _AcGe.Point3d.Origin;

                // Other properties are copied from the original
                txt2.TextString     = txt.TextString;
                txt2.TextStyleId    = txt.TextStyleId;
                txt2.LineWeight     = txt.LineWeight;
                txt2.Thickness      = txt2.Thickness;
                txt2.HorizontalMode = txt.HorizontalMode;
                txt2.VerticalMode   = txt.VerticalMode;
                txt2.WidthFactor    = txt.WidthFactor;
                txt2.Height         = txt.Height;
                txt2.IsMirroredInX  = txt2.IsMirroredInX;
                txt2.IsMirroredInY  = txt2.IsMirroredInY;
                txt2.Oblique        = txt.Oblique;

                // Get its bounds if it has them defined
                // (which it should, as the original did)
                if (txt2.Bounds.HasValue)
                {
                    var maxPt = txt2.Bounds.Value.MaxPoint;

                    // Only worry about this single case, for now
                    _AcGe.Matrix3d mat = _AcGe.Matrix3d.Identity;
                    if (txt.Justify == _AcDb.AttachmentPoint.MiddleCenter)
                    {
                        mat = _AcGe.Matrix3d.Displacement((_AcGe.Point3d.Origin - maxPt) * 0.5);
                    }

                    // Place all four corners of the bounding box
                    // in an array

                    double minX, minY, maxX, maxY;
                    if (txt.Justify == _AcDb.AttachmentPoint.MiddleCenter)
                    {
                        minX = -maxPt.X * 0.5 * fac;
                        maxX = maxPt.X * 0.5 * fac;
                        minY = -maxPt.Y * 0.5 * fac;
                        maxY = maxPt.Y * 0.5 * fac;
                    }
                    else
                    {
                        minX = 0;
                        minY = 0;
                        maxX = maxPt.X * fac;
                        maxY = maxPt.Y * fac;
                    }

                    var bounds =
                        new _AcGe.Point2d[] {
                        new _AcGe.Point2d(minX, minY),
                        new _AcGe.Point2d(minX, maxY),
                        new _AcGe.Point2d(maxX, maxY),
                        new _AcGe.Point2d(maxX, minY)
                    };

                    // We're going to get each point's WCS coordinates
                    // using the plane the text is on
                    var pl = new _AcGe.Plane(txt.Position, txt.Normal);

                    // Rotate each point and add its WCS location to the
                    // collection
                    foreach (_AcGe.Point2d pt in bounds)
                    {
                        pts.Add(
                            pl.EvaluatePoint(
                                pt.RotateBy(txt.Rotation, _AcGe.Point2d.Origin)
                                )
                            );
                    }
                }
            }
            return(pts);
        }