1. Win32 Font Metrics
- Posted by "Cuny, David" <David.Cuny at DSS.CA.GOV> Feb 25, 1999
- 504 views
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. -- David Cuny -- begin code -- global constant xGetCharABCWidths = linkFunc(gdi32, "GetCharABCWidthsA", {C_POINTER, C_LONG, C_LONG, C_POINTER}, C_POINTER ) -- Type ABC global constant abcA = allot( Integer ), abcB = allot( Integer ), abcC = allot( Integer ), SIZEOF_ABC = allotted_size() global function getFontCharSize( integer id ) sequence widths atom hdc, result, abc, ptr -- get the device context hdc = getDC( id ) -- set the font putFontIntoHDC( hdc, id ) -- array of chars 1-255 abc = allocate_struct( SIZEOF_TEXTMETRIC * 255 ) -- fill with zeros widths = repeat( 0, 255 ) -- get ABC structures for chars 1 through 255 if not c_func( xGetCharABCWidths, { hdc, 1, 255, abc } ) then warnErr( "GetCharABCWidths in getFontCharSize failed." ) else -- starting char to retrieve ptr = abc -- retrieve values for i = 1 to 255 do -- width is sum of spacing widths[i] = ( fetch( ptr, abcA ) + fetch( ptr, abcB ) + fetch( ptr, abcC ) ) * xScale -- advance to next char ptr += SIZEOF_ABC end for end if -- cleanup: replace the font replaceObject( hdc, DefaultFontID, ForProgram ) -- cleanup: release the device context releaseDC( id ) -- cleanup: free the structure free( abc ) return widths end function -- end code --
2. Re: Win32 Font Metrics
- Posted by Bernie Ryan <bwryan at PCOM.NET> Feb 25, 1999
- 460 views
- Last edited Feb 26, 1999
David - David Cuny -- begin code -- ---- global constant xGetCharABCWidths = linkFunc(gdi32, ----- "GetCharABCWidthsA", ----- {C_POINTER, C_LONG, C_LONG, C_POINTER}, C_POINTER ) You are using two different names in your function ? There are large number of functions in GDI32.dll Some are used for fixed fonts. This is how you get TRUE FONT INFORMATION -- SYNTAX IS BOOL GetCharABCWidths( hdc, uFirstChar, uLastChar, lpabc ) ----- Parameter --------- Type ----------- Description ---------- hdc HDC Device Context ( handle ) uFirstChar UNIT First character in character range ( unsigned integer ) uFirstChar UNIT Last character in character range ( unsigned integer ) lpabc LPABC Pointer to ABC data structure to receive the character widths --------------------------------------------------------------------------- Discription: The GETCharABCWidths function retrieves the character widths of the characters for the current font in the range from uFirstChar to uFirstChar. lpabc points to a data structure of the type ABC that receives the character widths. typedef struct _ABC { short abcA; short abcB; short abcC; } ABC; The abcA part of structure contains the distance that is added to the current position before drawing the character glyph. The abcB part of structure contains the the drawn portion of the character glyph. The abcC part of structure contains the white space on the right side of the character glyph. ------------------------------------------------------------------- -- Type ABCglobal constant abcA = allot( Integer ), abcB = allot( Integer ), abcC = allot( Integer ), SIZEOF_ABC = allotted_size()
3. Re: Win32 Font Metrics
- Posted by Bernie Ryan <bwryan at PCOM.NET> Feb 25, 1999
- 476 views
- Last edited Feb 26, 1999
SORRY correcting some typing errors This is how you get TRUETYPE FONT INFORMATION -- SYNTAX IS BOOL GetCharABCWidths( hdc, uFirstChar, uLastChar, lpabc ) ----- Parameter --------- Type ----------- Description ---------- hdc HDC Device Context ( handle ) uFirstChar UNIT First character in character range ( unsigned integer ) uLastChar UNIT Last character in character range ( unsigned integer ) lpabc LPABC Pointer to ABC data structure to receive the character widths --------------------------------------------------------------------------- Discription: The GETCharABCWidths function retrieves the character widths of the characters for the current font in the range from uFirstChar to uLastChar. lpabc points to a data structure of the type ABC that receives the character widths. Bernie
4. Re: Win32 Font Metrics
- Posted by Daniel Berstein <daber at PAIR.COM> Feb 25, 1999
- 496 views
- Last edited Feb 26, 1999
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]