1. Win32 Font Metrics
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
-
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
-
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
-
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]