Retrieving the Style String for a TrueType Font

Last reviewed: November 2, 1995
Article ID: Q84132
The information in this article applies to:
  • Microsoft Windows Software Development Kit (SDK) for Windows version 3.1
  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows NT versions 3.5 and 3.51
        - Microsoft Windows 95 version 4.0
    

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 will 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 sample code below 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);


Additional reference words: 3.10 3.50 4.00 95
KBCategory: kbgraphic
KBSubcategory: GdiTt


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: November 2, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.