Find the height and width of a text string in pixels (in VFP)

Two simple methods for finding the dimensions of a given piece of text.

By Dan Macleod

In Visual FoxPro, you sometimes need to programmatically determine the height and width of a text string. You would typically do that if you want to dynamically resize a container so that the text fits snugly inside it.

There are a couple of ways you can go about it.

The TextWidth and TextHeight methods

The first option is to use the TextWidth and TextHeight methods. These are methods of a form (including _SCREEN). They return the width and height respectively of a specified text string, based on the form's current font settings.

To use the methods, you simply pass the relevant text as a parameter:

? _SCREEN.TextWidth("Hello World")  
? _SCREEN.TextHeight("Hello World")  

Both methods work with multi-line text. If the text contains carriage returns (ASCII 13), TextWidth returns the width of the longest line. If the text contains line feeds (ASCII 10), TextHeight returns the total height of all the lines.

TXTWIDTH() and FONTMETRIC()

The above methods are fine if the text happens to be in the same font, font size and style as its parent form. More often, you will want to specify the font settings yourself. One way to do that would be to change the form's settings just before you call the methods, and change them back again just afterwards. But that's messy.

A better approach is to use the TXTWIDTH() function. This returns the width of string for any specified font, font size and style. In this context, the "style" is a set of letters that say whether the font is bold, italic, shadowed, outline, or whatever. So "BI" means bold italic, for instance (see the VFP Help for all the options).

Here's an example:

? TXTWIDTH("Hello World", "Verdana", 10, "BI")  

Just to complicate the issue, the width returned by TXTWIDTH() is expressed, not in pixels but in foxels. What's a foxel? It's the average width of a character in a given font, size and style.

So to get the required width in pixels, you need to multiply the figure returned by TXTWIDTH() by the average character width for the font, size and style. To determine that average character width, use FONTMETRIC(), passing 6 as its first parameter.

Here then is a complete function that will return the width in pixels for any character string, in a specified font, size and style:

FUNCTION GetTextSize

* Determines the width in pixels of a given text string, based on 
* a given font, point size and font style.

* Parameters: text string, font name, size in points, font style in
* format used by FONTMETRIC() (e.g. "B" for bold, "BI" for bold italic;
* defaults to normal).	

LPARAMETERS tcString, tcFont, tnSize, tcStyle

LOCAL lnTextWidth, lnAvCharWidth

IF EMPTY(tcStyle)
	tcStyle = ""
ENDIF 
	
lnTextWidth = TXTWIDTH(tcString, tcFont, tnSize, tcStyle)
lnAvCharWidth = FONTMETRIC(6, tcFont, tnSize, tcStyle)

RETURN lnTextWidth * lnAvCharWidth

Unfortunately, TXTWIDTH() doesn't work with multi-line text. Any CRs or LFs in the string are treated as if they were printable characters, with a specific width of their own. The total width of the string will be that of all the characters, regardless of how many lines they occupy.

What about the height?

To find the height of a text string for a given font, size and style, simply call FONTMETRIC(), passing 1 as the first parameter. If the text contains multiple lines, multiply the value returned by FONTMETRIC() by the number of lines.

And that's all there is to it. As you can easy, finding the size of a text string is fairly easy, whichever of the two methods you use.

March 2012

Please note: The information given on this site has been carefully checked and is believed to be correct, but no legal liability can be accepted for its use. Do not use code, components or techniques unless you are satisfied that they will work correctly with your sites or applications.

If you found this article useful, please tell your friends: