SUMMARY
Windows version 3.1 introduces the concept of a font style. In
previous versions of Windows, a font could have bold, italic,
underline, and strikeout properties, which were supported by
corresponding members of the
LOGFONT and
TEXTMETRIC structures.
Windows 3.1 continues to support these properties, however, it also
supports the concept of a style name for TrueType fonts.
Windows use of style names can be demonstrated by the ChooseFont
dialog box in the common dialog boxes dynamic-link library
(COMMDLG.DLL). The ChooseFont dialog box contains two list boxes named
Font and Font Style. The Font list box contains a list of all face
names and the Font Style list box contains a list of font styles for
the currently selected face. For example, if any non-TrueType font
(such as MS Sans Serif) is selected, the following styles appear
in the style list box:
Regular
Bold
Italic
Bold Italic
TrueType fonts may have these or more elaborate styles. For example,
the "Lucida Sans" face includes the following style names:
Regular
Italic
Demibold Roman
Demibold Italic
MORE INFORMATION
As part of the TrueType support, the
GetOutlineTextMetrics function can be
used to retrieve metric information for TrueType fonts, including the style
name.
GetOutlineTextMetrics is prototyped as follows:
DWORD GetOutlineTextMetrics(HDC hdc, UINT cbData,
LPOUTLINETEXTMETRIC lpotm);
The hdc parameter identifies the device context.
GetOutlineTextMetrics
retrieves the metric information for the font currently selected into
the specified device context. For
GetOutlineTextMetrics to succeed,
the font must be a TrueType font. The sample code given below shows
how to synthesize the style name for a non-TrueType font.
The cbData parameter specifies the size, in bytes, of the buffer in
which information is returned.
The lpotm parameter points to an
OUTLINETEXTMETRIC structure. If this
parameter is NULL, the function returns the size of the buffer
required for the retrieved metric information.
The
OUTLINETEXTMETRIC structure contains most of the font metric
information provided with the TrueType format. The relative parts of
the structure are listed below:
typedef struct tagOUTLINETEXTMETRIC {
.
.
.
PSTR otmpFamilyName;
PSTR otmpFaceName;
PSTR otmpStyleName;
PSTR otmpFullName;
} OUTLINETEXTMETRIC;
While these four members of the
OUTLINETEXTMETRIC structure are
defined as near pointers to strings (PSTR), they are actually offsets
into the structure from the beginning of the structure. Because the
length of these strings is not defined, an application must allocate
space for them above and beyond the space allocated for the
OUTLINETEXTMETRIC structure itself. The following sample code demonstrates this. It also demonstrates using
GetOutlineTextMetrics in an application that will also work with Windows 3.0.
#include <windows.h>
#include <windowsx.h>
.
.
.
HFONT hFont;
LPOUTLINETEXTMETRIC potm;
TEXTMETRIC tm;
int cbBuffer;
hFont = CreateFont( ..... );
hFont = SelectObject(hDC, hFont);
/*
* Call the GetTextMetrics function to determine whether or not the
* font is a TrueType font.
*/
GetTextMetrics(hDC, &tm);
/*
* GetOutlineTextMetrics is a function implemented in Windows 3.1
* and later. Assume fWin30 was determined by calling GetVersion.
*/
if (!fWin30 && tm.tmPitchAndFamily & TMPF_TRUETYPE)
{
WORD (WINAPI *lpfnGOTM)(HDC, UINT, LPOUTLINETEXTMETRIC);
/*
* GetOutlineTextMetrics is exported from
* GDI.EXE at ordinal #308
*/
lpfnGOTM = GetProcAddress(GetModuleHandle("GDI"),
MAKEINTRESOURCE(308));
/*
* Call GOTM with NULL to retrieve the size of the buffer.
*/
cbBuffer = (*lpfnGOTM)(hDC, NULL, NULL);
if (cbBuffer == 0)
{
/* GetOutlineTextMetrics failed! */
hFont = SelectObject(hDC, hFont);
DeleteObject(hFont);
return FALSE;
}
/*
* Allocate the memory for the OUTLINETEXTMETRIC structure plus
* the strings.
*/
potm = (LPOUTLINETEXTMETRIC)GlobalAllocPtr(GHND, cbBuffer);
if (potm)
{
potm->otmSize = cbBuffer;
/*
* Call GOTM with the pointer to the buffer. It will
* fill in the buffer.
*/
if (!(*lpfnGOTM)(hDC, cbBuffer, potm))
{
/* GetOutlineTextMetrics failed! */
hFont = SelectObject(hDC, hFont);
DeleteObject(hFont);
return FALSE;
}
/*
* Do something useful with the string buffers. NOTE: To access
* the string buffers, the otmp???Name members are used as
* OFFSETS into the buffer. They *ARE NOT* pointers themselves.
*/
OutputDebugString((LPSTR)potm + (UINT)potm->otmpFamilyName);
OutputDebugString((LPSTR)potm + (UINT)potm->otmpFaceName);
OutputDebugString((LPSTR)potm + (UINT)potm->otmpStyleName);
OutputDebugString((LPSTR)potm + (UINT)potm->otmpFullName);
/* Don't forget to free the memory! */
GlobalFreePtr(potm);
}
else
{
/* GlobalAllocPtr failed */
hFont = SelectObject(hDC, hFont);
DeleteObject(hFont);
return FALSE;
}
}
else
{
/*
* It was not a TrueType font, or Windows 3.0 is running.
*/
LOGFONT lf;
char szStyle[LF_FACESIZE];
LPSTR p;
GetObject(hFont, sizeof(LOGFONT), &lf);
/*
* Fabricate a style string. Important note! The strings
* "Italic", "Bold", and "Regular" are only valid in English. On
* versions of Windows localized for other countries, these
* strings will differ.
*/
szStyle[0] = '\0';
if (lf.lfWeight >= FW_BOLD)
lstrcpy(szStyle, "Bold ");
/*
* If it's "Bold Italic," concatenate.
*/
p = szStyle + lstrlen(szStyle);
if (lf.lfItalic)
lstrcpy(p, "Italic");
if (!lstrlen(szStyle))
lstrcpy(szStyle, "Regular");
/*
* szStyle now holds what is equivalent to the otmpStyleName
* member.
*/
OutputDebugString(szStyle);
}
hFont = SelectObject(hDC, hFont);
DeleteObject(hFont);