Josh
Josh

Reputation: 189

How to find the bounding box of a TEXT element from AutoCAD DXF file

I fear this is one of those questions with no simple answer.

I have AutoCAD drawings in ASCII DXF format. I am scanning them for text elements. I need to calculate the coordinates of the vertices of the bounding box for each text element. (In case anyone is using different terminology, to me a bounding box is a hypothetical rectangle that could be drawn such that the text exactly fits inside the rectangle)

This is very complicated considering that each element may have a different font, different text style, different scale, different orientation, rotation, etc.

I get the origin point and alignment point (if any) from the TEXT entity entry in the DXF file. I can also get the rotation and height scale factors from the same place. But I am particularly stuck on how to get the width since each character is a different width and there could be any number of different fonts. If this was windows programming I would use windows API functions to get metrics about the font being used, but autocad does not seem to have any analogy to this.

Anyone know how to do that?

Upvotes: 2

Views: 2255

Answers (2)

Thomas Ludewig
Thomas Ludewig

Reputation: 725

This routine changes text insertations in such a way that the text position remains as drawn, which delivers also the functionality you are looking for.

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

Upvotes: 0

Maxence
Maxence

Reputation: 13329

If the fonts used are TTF, you can use Windows API to find the width of a particular line of text. If it is SHX one, it's more difficult. You have to find a way to read .shx files, in order to compute the width of each character. Here is the description of SHP files, which are compiled into SHX : http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%202010%20User%20Documentation/index.html?url=WS73099cc142f4875513fb5cd10c4aa30d6b-7f42.htm,topicNumber=d0e400463

Reverse engineering of these files can be tedious and be considered illegal if you're living in the US for example.

You can also make an AutoCAD plugin (using ObjectARX or another API) to compute the width of each character and store these widths in a big table. You will then have to lookup into this table to compute the width of a particular string.

There is also True Type versions of the main SHX files (they are installed with Inventor I think).

Note that there is a scale factor (code 41) on the width and MTEXT entities can contains formatting codes...

Upvotes: 1

Related Questions