Re: Win32 Font Metrics
- Posted by Daniel Berstein <daber at PAIR.COM> Feb 25, 1999
- 495 views
At 08:16 PM 25-02-1999 , you wrote: >Has anyone got Win32 code that returns the width of font characters? > >I've written a routine (included at the end of this note), but I'm not sure >what the problem with it is... The values returned from the function are >suspicious, and I suspect that I in addition I have to scale the values by >converting logical units to physical units. > >In the Win95 book, Petzold leaves this out. He "cheats" by using the average >character size. I need the character metrics so I can calculate the length >of a string, and be able to display justified text. > >Even a pointer to some C or VB code that does this would be a great help. > >Thanks. Take a look to GetTextExtentPoint32 in gdi32.dll it may be the answer :) Syntax: BOOL GetTextExtentPoint32( HDC DC, LPCTSTR Str, int Count, LPSIZE Size ); Description: This function retrieves the width and height of the string pointed by the Str parameter, in logical units. The width and height are based on the attributes of the string currently selected into the device context identified by the DC parameter. The clipping region of the specified device context does not affect the computed dimensions. In instances where a string containing kerning pairs is output to a device supporting character kerning, the dimernsions returned by this function may not match the sum of the individual character dimensions in the string. Parameters: DC: A handle to the device context whose currently selected font is used to determine the string's width and height. Str: A pointer to a string whose width and height are to be retrieved. This does not have to be a null-terminated string, as the Count parameter specifies the string length. Count: Specifies the number of characters in the string pointed to by the Str parameter. Size: A pointer to a SIZE structure that recieves the width and height of the specified string based on the attributes of the font selected into the specified device context. Return value: If the function succeeds, it return TRUE; otherwise it returns FALSE. To get extended error information, call the GetLastError function. The SIZE structure is as follows: typedef struct tagSIZE { LONG cx; LONG cy; } SIZE; The SIZE structure specifies the width and height of a rectangle. cx: Specifies the rectangle's width. cy: Specifies the rectangle's height. Here is an untested attemp (I assume your GDI functions, never have looked at them): [please wait for the beep... beeeep!] global constant xGetTextExtentPoint32 = linkFunc(gdi32, "GetTextExtentPoint32", -- Maybe need 'A' extension? {C_POINTER, C_POINTER, C_INT, C_POINTER}, C_INT ) global function getFontTextSize( integer id, sequence str ) sequence size atom hdc, pstr, psize size = {0,0} -- Allocate LPSTRZ pstr = allocate_string(str) if not pstr then warnErr( "allocate_string in getFontTextSize failed." ) return size end if -- Allocate SIZE structure psize = allocate(8) if not psize then warnErr( "allocate in getFontTextSize failed." ) free(pstr) return size end if -- get the device context hdc = getDC( id ) -- set the font putFontIntoHDC( hdc, id ) -- Get text dimensions if not c_func( xGetTextExtentPoint32, { hdc, pstr, length(str), psize } ) then warnErr( "GetTextExtentPoint32 in getFontTextSize failed." ) size = peek4s({psize, 2}) end if -- Cleanup replaceObject( hdc, DefaultFontID, ForProgram ) releaseDC( id ) free( psize ) free( pstr ) -- Return {cx,cy} sequence return size end function [tut, tut, tut...] The returned dimensions are in logical units. Use the LPtoDP API function to convert them to device units. Hope this helps. Regards, Daniel Berstein [daber at pair.com]