Особенности примитивов TEXT и ATTRIB*
С точки зрения программирования достаточно большой интерес представляют примитивы TEXT, MTEXT и ATT* (соответственно однострочные и многострочные тексты и атрибуты - как описания, так и вхождения). Я бы хотел рассмотреть такую достаточно забавную штуку, как точка вставки текста.
Для упрощения понимания работать будем в пространстве модели, в мировой системе координат. Все эксперименты провожу в AutoCAD 2008 Eng + SP.
Сделаем "от балды" однострочный текст и выполним (entget (entlast)):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | _$ (entget (entlast)) '((0 . "TEXT") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (100 . "AcDbText") (10 1.46689e+008 8.45653e+007 0.0) (40 . 2.5) (1 . "qwerty") (50 . 0.0) (41 . 0.7) (51 . 0.0) (7 . "SPDS") (71 . 0) (72 . 0) (11 0.0 0.0 0.0) (100 . "AcDbText") (73 . 0) ) _$ |
Некритичные для построения данные опущены. За компанию - и дамп объекта снимем:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | _$ (vlax-dump-object (vlax-ename->vla-object (entlast))) ; IAcadText: AutoCAD Text Interface ; Property values: ; Alignment = 0 ; Application (RO) = #<VLA-OBJECT IAcadApplication 00d74d3c> ; Backward = 0 ; Document (RO) = #<VLA-OBJECT IAcadDocument 359c1910> ; Handle (RO) = "77064F" ; HasExtensionDictionary (RO) = 0 ; Height = 2.5 ; InsertionPoint = (1.46689e+008 8.45653e+007 0.0) ; Layer = "СТЕНЫ НАРУЖНЫЕ" ; Linetype = "ByLayer" ; LinetypeScale = 400.0 ; Lineweight = -1 ; Material = "ByLayer" ; Normal = (0.0 0.0 1.0) ; ObjectName (RO) = "AcDbText" ; ObliqueAngle = 0.0 ; PlotStyleName = "ByLayer" ; Rotation = 0.0 ; ScaleFactor = 0.7 ; StyleName = "SPDS" ; TextAlignmentPoint = (0.0 0.0 0.0) ; TextGenerationFlag = 0 ; TextString = "qwerty" ; Thickness = 0.0 ; UpsideDown = 0 ; Visible = -1 T _$ |
Обратите внимание - InsertionPoint (для DXF - 10 группа) имеет значения, отличные от 0. А вот TextAlignmentPoint (DXF 11) - наоборот. Выравнивание текста - по умолчанию, то есть как бы BottomLeft. Не затрагивая поворота, попробуем (вручную!) поменять выравнивание, например, на MiddleCenter:
DXF | ActiveX | ||||
|
|
Как видно, изменилось (в AutoCAD 2008) только TextAlignmentPoint (DXF 11). В версии 2005, например, по ходу дела еще менялась и InsertionPoint (DXF 10). Как дело обстоит, например, в 2010 или 2011 - проверить сейчас не могу. Но! Если заменить программно выравнивание текста, то автоматически заменяться ни TextAlignmentPoint, ни InsertionPoint не будут. Задача по их изменению ложится на программиста.
А если еще учесть вариант, что иногда приходится создавать / модифицировать объекты, располагающиеся не в мировой системе координат, задача становится совсем интересной.
Объекты атрибутов (по крайней мере, однострочных) в этом отношении практически полностью аналогичны однострочным текстам.
Теперь попробуем разобраться с многострочным текстом. Точно так же, создаем многострочный текст в любом месте чертежа (выравнивание - TopLeft):
DXF | ActiveX | ||||
|
|
Обратите внимание - в свойствах многострочного текста установлена ширина, равная 0. Ну и меняем, например, опять же - на MiddleCenter:
DXF | ActiveX | ||||
|
|
Достаточно внимательно посмотреть на последние 2 таблицы, и будет видно, что точка вставки InsertionPoint (DXF 10) меняется сама. Если необходимо "оставить многострочный текст как было", то положение новой точки вставки придется вычислять.
Основой таких вычислений будет середина описанного вокруг многострочного текста прямоугольника. Первое телодвижение у меня было - использовать функцию (textbox), благо она позволит заодно и вычислить смещения верхней и нижней границ текста. Да вот беда, textbbox напрочь отказывается обрабатывать хоть сколько-нибудь сложные многострочные тексты. Пришлось использовать метод GetBoundningBox...
P.S. Здесь я не рассматривал варианты изменения нормали объектов, а также обработки объектов, лежащих в немировой системой координат.
Добавлю: можно использовать не vla-GetBoundingBox, а acet-ent-geomextents либо acet-geom-textbox (идет в составе ExpressTools). В качестве аргументов в acet-geom-textbox передается ename-указатель на примитив и точность, с которой вычиляются координаты (насколько я понимаю).