Как найти ограничивающую рамку элемента TEXT из файла AutoCAD DXF

Боюсь, это один из тех вопросов, на которые нет простого ответа.

У меня есть чертежи AutoCAD в формате ASCII DXF. Я сканирую их на наличие текстовых элементов. Мне нужно вычислить координаты вершин ограничительной рамки для каждого текстового элемента. (На случай, если кто-то использует другую терминологию, для меня ограничительная рамка — это гипотетический прямоугольник, который можно нарисовать так, чтобы текст точно помещался внутри прямоугольника)

Это очень сложно, учитывая, что каждый элемент может иметь разный шрифт, разный стиль текста, разный масштаб, разную ориентацию, поворот и т.д.

Я получаю исходную точку и точку выравнивания (если есть) из записи объекта TEXT в файле DXF. Я также могу получить коэффициенты масштабирования вращения и высоты из того же места. Но я особенно зациклен на том, как получить ширину, поскольку каждый символ имеет разную ширину, и может быть любое количество разных шрифтов. Если бы это было программирование для Windows, я бы использовал функции Windows API для получения метрик об используемом шрифте, но Autocad, похоже, не имеет аналогии с этим.

Кто-нибудь знает, как это сделать?


person Josh    schedule 02.08.2015    source источник
comment
Можете дать ссылку на файл примера?   -  person Ognyan Dimitrov    schedule 03.08.2015


Ответы (2)


Если используются шрифты TTF, вы можете использовать Windows API для определения ширины конкретной строки текста. Если это SHX, это сложнее. Вы должны найти способ читать файлы .shx, чтобы вычислить ширину каждого символа. Вот описание файлов SHP, которые скомпилированы в SHX: -7f42.htm,topicNumber=d0e400463" rel="nofollow">http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%202010%20User%20Documentation/index.html?url=WS73099cc142f4875513fb5cd10c4aa30d6b-7f42.htm42.htm ,topicNumber=d0e400463

Обратное проектирование этих файлов может быть утомительным и считаться незаконным, например, если вы живете в США.

Вы также можете создать плагин AutoCAD (используя ObjectARX или другой API) для вычисления ширины каждого символа и сохранения этой ширины в большой таблице. Затем вам придется искать в этой таблице, чтобы вычислить ширину конкретной строки.

Существуют также версии основных файлов SHX в формате True Type (думаю, они устанавливаются вместе с Inventor).

Обратите внимание, что для ширины существует масштабный коэффициент (код 41), а объекты MTEXT могут содержать коды форматирования...

person Maxence    schedule 03.08.2015
comment
Добавляя к ответу @maxence, вы можете сделать это в AutoCAD с помощью плагина, и вам не нужно, чтобы AutoCAD был установлен на компьютере, просто используйте веб-службу ввода-вывода AutoCAD (загрузите DXF с пользовательским .NET, который вычисляет ограничивающую рамку , затем загрузите результат). - person Augusto Goncalves; 03.08.2015

Эта подпрограмма изменяет вставки текста таким образом, что позиция текста остается нарисованной, что также обеспечивает искомую функциональность.

Function TEXT_align(entity As AcadEntity, opt As String) As AcadEntity
Set TEXT_align = Nothing

Dim MTEXT As AcadMText
Dim TTEXT As ACADTEXT
Dim ATTRIB As AcadAttribute

Dim Dest_min As Variant
Dim Dest_max As Variant
Dim Source_min As Variant
Dim Source_max As Variant

Call entity.GetBoundingBox(Source_min, Source_max)

Select Case LCase(entity.objectname)
    Case "acdbtext"
        Set TTEXT = entity
        Select Case UCase(opt)

            Case "TL": TTEXT.alignment = acAlignmentTopLeft
            Case "TC": TTEXT.alignment = acAlignmentTopCenter
            Case "TR": TTEXT.alignment = acAlignmentTopRight
            Case "ML": TTEXT.alignment = acAlignmentMiddleLeft
            Case "MC": TTEXT.alignment = acAlignmentMiddleCenter
            Case "MR": TTEXT.alignment = acAlignmentMiddleRight
            Case "BL": TTEXT.alignment = acAlignmentBottomLeft
            Case "BC": TTEXT.alignment = acAlignmentBottomCenter
            Case "BR": TTEXT.alignment = acAlignmentBottomRight
        End Select
    Case "acdbmtext"

        Set MTEXT = entity

        Select Case UCase(opt)
            Case "TL": MTEXT.ATTACHMENTPOINT = acAttachmentPointTopLeft
            Case "TC": MTEXT.ATTACHMENTPOINT = acAttachmentPointTopCenter
            Case "TR": MTEXT.ATTACHMENTPOINT = acAttachmentPointTopRight
            Case "ML": MTEXT.ATTACHMENTPOINT = acAttachmentPointMiddleLeft
            Case "MC": MTEXT.ATTACHMENTPOINT = acAttachmentPointMiddleCenter
            Case "MR": MTEXT.ATTACHMENTPOINT = acAttachmentPointMiddleRight
            Case "BL": MTEXT.ATTACHMENTPOINT = acAttachmentPointBottomLeft
            Case "BC": MTEXT.ATTACHMENTPOINT = acAttachmentPointBottomCenter
            Case "BR": MTEXT.ATTACHMENTPOINT = acAttachmentPointBottomRight
        End Select
    Case "acdbattributedefinition"
        Set ATTRIB = entity

        Select Case UCase(opt)
            Case "TL": ATTRIB.alignment = acAlignmentTopLeft
            Case "TC": ATTRIB.alignment = acAlignmentTopCenter
            Case "TR": ATTRIB.alignment = acAlignmentTopRight
            Case "ML": ATTRIB.alignment = acAlignmentMiddleLeft
            Case "MC": ATTRIB.alignment = acAlignmentMiddleCenter
            Case "MR": ATTRIB.alignment = acAlignmentMiddleRight
            Case "BL": ATTRIB.alignment = acAlignmentBottomLeft
            Case "BC": ATTRIB.alignment = acAlignmentBottomCenter
            Case "BR": ATTRIB.alignment = acAlignmentBottomRight
        End Select
    Case Else
        Exit Function
End Select

Call entity.GetBoundingBox(Dest_min, Dest_max)

entity.MOVE Dest_min, Source_min

End Function
person Thomas Ludewig    schedule 21.01.2019