Fonts R Us!
OS/2 2.1 comes with support for, and provides a selection of, both image (bitmap) fonts and Adobe type 1 outline fonts. In this article, we look at some of the considerations that you should make when using these fonts in a Presentation Manager application. We will take an overall look at the issues of dealing with fonts and explain some of the most commonly used terminology.
Contents
Plan Ahead!
Before adding font support to an application, stop and consider what type of application you are producing. You must decide whether the application is a screen-only application or if it will support other devices such as printers and plotters. This decision will affect the way that you write font-handling code in your application. Also, if your application demands WYSIWYG (what-you-see-is-what-you-get) support, then it should be using the outline fonts, which are much more flexible than image fonts.
System Image vs. Outline Fonts - Which to Use?
The image fonts that come as part of the OS/2 system should, ideally, only be used for displaying text on the screen. They consist of a set of fixed point sizes that are not scaleable and, thus, have limited flexibility. Image fonts cannot be sheared, sized, and rotated in the way that outline fonts can. For applications that just want to write to the screen they might be ideal; however, outline fonts are far better suited for more general uses.
The outline fonts, on the other hand. are far more flexible and can be used in a wide variety of ways. You can use them effectively both on the screen and hardcopy devices because they can be sized accurately with graphics, such that words and pictures appear in the same scale. In addition, they have more flexible uses such as producing outlines, constructing fills, using paths, and constructing clip paths. Outline fonts also can be transformed just like any other graphical primitives; they can be accurately rotated, scaled, and sheared.
Some General Font and Typeface Terminology
When discussing fonts, and typefaces in general, it is useful to define some of the common terminology. This terminology is not unique to the computer industry; almost all of the basic font-related terminology comes from the printing and typesetting world. You can open almost any book in the art section of your local bookstore that deals with typesetting and find a good explanation of the basic terms. In fact, I would recommend people new to working with fonts do just that.
The Font Metrics Structure
Given this diagram, we can look at the font metrics (FONTMETRICS) structure as used by the GpiQueryFonts function. This structure definition can be found in the OS2DEF.H header file that is part of the Developer's Toolkit for OS/2. As you can see, this structure contains all of the relevant information, or metrics. about a particular font.
typedef struct _FONTMETRICS /* fm */ { CHAR szFamilyname[FACESIZE]; CHAR szFacename[FACESIZE]; USHORT idRegistry; USHORT usCodePage; LONG lEmHeight; LONG lXHeight; LONG lMaxAscender; LONG lMaxDescender; LONG lLowerCaseAscent; LONG lLowerCaseDescent; LONG lInternalLeading; LONG lExternalLeading; LONG lAveCharWidth; LONG lMaxCharInc; LONG lEmInc; LONG lMaxBaselineExt; SHORT sCharSlope; SHORT sInlineDir; SHORT sCharRot; USHORT usWeightClass; USHORT usWidthClass; SHORT sXDeviceRes; SHORT sYDeviceRes; SHORT sFirstChar; SHORT sLastChar; SHORT sDefaultChar; SHORT sBreakChar; SHORT sNominalPointSize; SHORT sMinimumPointSize; SHORT sMaximumPointSize; USHORT fsType; USHORT fsDefn; USHORT fsSelection; USHORT fsCapabilities; LONG lSubscriptXSize; LONG lSubscriptYSize; LONG lSubscriptXOffset; LONG lSubscriptYOffset; LONG lSuperscriptXSize; LONG lSuperscriptYSize; LONG lSuperscriptXOffset; LONG lSuperscriptYOffset; LONG lUnderscoreSize; LONG lUnderscorePosition; LONG lStrikeoutSize; LONG lStrikeoutPosition; SHORT sKerningPairs; SHORT sFamilyClass; LONG lMatch; LONG FamilyNameAtom; LONG FaceNameAtom; PANOSE panose; } FONTMETRICS;
Figure 1. Font Metrics
So, What Fonts Do I Have?
To determine the fonts that currently are loaded in the system, an application can call the GpiQueryFonts function. Use this function to query how many fonts are available and to retrieve the metrics for some, or all, of these fonts. The function, MyQueryFonts, calculates how many fonts are loaded in the system, allocates space to store the font metrics, and retrieves the metrics. An application can query information about just the public (that is, system-wide) fonts or private fonts (that is, local to the application) or both. Do this by using one or both of the QF_PUBLIC and QF_PRIVATE flags on the call.
VOID MyQueryFonts( HWND hwnd ) { LONG lNum; LONG lRem; LONG lReq=0; PFONTMETRICS pfm; HPS hps; // Get a presentation space for the window provided hps = WinGetPS( hwnd ); // Query how many fonts are available to us at this time lNum = GpiQueryFonts( hps , QF_PUBLIC | QF_PRIVATE , NULL , &lReq , 0L , NULL ); // Allocate space to store the fontmetrics structures pfm = (PFONTMETRICS) malloc( sizeof(FONTMETRICS) *lNum ); // Now query the metrics structures lRem = GpiQueryFonts( hps , QF_PUBLIC | QF_PRIVATE , NULL , &lNum , sizeof(FONTMETRICS) , pfm ); // Free resources free( pfm ); WinReleasePS( hps ); }
Sample Code 1. My Query Fonts function
Having queried the list of available fonts, the application can present the user with a list and have them choose a font to use for a particular task. However, as the following section indicates, OS/2 provides a standard dialog interface for choosing fonts that all applications should use. This lets each program offer a consistent interface for selecting fonts. More importantly than using the metric information to generate lists of the available fonts in the system, applications can use the information in the FONTMETRICS structure to calculate such things as line and character spacing.
Another Structure
The font attributes (FATTRS) structure as used by the GpiCreateLogFont and the WinFontDlg functions display the font selection dialog. The FATTRS structure also is defined in the OS2DEF.H header file.
typedef struct _FATTRS /* fat */ { USHORT usRecordLength; USHORT fsSelection; LONG lMatch; CHAR szFacename[FACESIZE]; USHORT idRegistry; USHORT usCodePage; LONG lMaxBaselineExt; LONG lAveCharWidth; USHORT fsType; USHORT fsFontUse; } FATTRS;
Figure 2. The Font Attributes structure
A Consistent Dialog
Offering a list of fonts to choose from is something that many Presentation Manager applications must do. Rather than have each application programmer invent a new set of dialogs for doing this, we provide a standard interface as part of the base system. Use the WinFontDlg function to display the dialog. Although can be a very complex function (at first look), it is actually very flexible. The best way to get familiar with the power offered by the font dialog is to experiment with it in your applications.
However, at a minimum, the function DisplayFontDialog shows how to set up a call to WinFontDlg having specified only a few of the many parameters that are available. The WinFontDlg call expects to receive a FONTDLG structure as one of its parameters. This is a large structure; therefore, only those parts of the structure needed in the example are filled in by the DisplayFontDlg function.
typedef struct _FONTDLG /* fntdlg */ { ULONG cbSize; /* sizeof(FONTDLG) */ HPS hpsScreen; /* Screen presentation space */ HPS hpsPrinter; /* Printer presentation space */ PSZ pszTitle; /* Application supplied title */ PSZ pszPreview; /* String to print in preview wndw */ PSZ pszPtSizeList; /* Application provided size list */ PFNWP pfnDlgProc; /* Dialog subclass procedure */ PSZ pszFamilyname; /* Family name of font */ FIXED fxPointSize; /* Point size the user selected */ ULONG fl; /* FNTS_* flags - dialog styles */ ULONG flFlags; /* FNTF_* state flags */ ULONG flType; /* Font type option bits */ ULONG flTypeMask; /* Mask of which font types to use */ ULONG flStyle; /* The selected style bits */ ULONG flStyleMask; /* Mask of which style bits to use */ LONG clrFore; /* Selected foreground color */ LONG clrBack; /* Selected background color */ ULONG ulUser; /* Blank field for application */ LONG lReturn; /* Return Value of the Dialog */ LONG lSRC; /* System return code. */ LONG lEmHeight; /* Em height of the current font */ LONG lXHeight; /* X height of the current font */ LONG lExternalLeading; /* External Leading of font */ HMODULE hMod; /* Module to load custom template */ FATTRS fAttrs; /* Font attribute structure */ SHORT sNominalPointSize; /* Nominal Point Size of font */ USHORT usWeight; /* The boldness of the font */ USHORT usWidth; /* The width of the font */ SHORT x; /* X coordinate of the dialog */ SHORT y; /* Y coordinate of the dialog */ USHORT usDlgId; /* ID of a custom dialog template */ USHORT usFamilyBufLen; /* Length of family buffer provided*/ USHORT usReserved; /* reserved */ } FONTDLG;
Figure 3. The Font Dialog structure All of the flags and the FONTDLG structure are defined in the PMSTDDLG.H header file, which is part of the Developer's Toolkit for OS/2 2.1. The following function displays the font dialog:
VOID DisplayFontDlg( HWND hwnd ) { HPS hps; FONTDLG fd; // Set the title the dialog will use CHAR pszTitle[17] = "Font Dialog Test"; // Reserve storage for the fonts name CHAR pszFamilyName[FACESIZE] = "\0"; // Initialize the font dialog structure. memset( &fd, 0, sizeof( FONTDLG )); hps = WinGetPS( hwnd ); fd.hpsScreen = hps; fd.cbSize = sizeof( FONTDLG ); fd.pszFamilyname = pszFamilyName ; fd.pszTitle = pszTitle; fd.usFamilyBufLen = FACESIZE; fd.fxPointSize = (FIXED)0; fd.clrFore = CLR_BLACK; fd.clrBack = CLR_WHITE; fd.pszPreview = "Sample Text"; fd.fl = FNTS_CENTER; WinFontDlg( HWND_DESKTOP, hwnd, &fd ); WinReleasePS( hps ); }
Sample Code 2. The DisplayFontDlg() function
Upon return from a call to WinFontDlg, the fAttrs field of the font dialog structure contains the font attributes for the font that was selected by the user. These attributes, then, can be passed to the GpiCreateLogFont function to create a logical font representing the font chosen by the user.
Creating a Logical Font and Displaying Text
Having established the font attributes structure for the font that we wish to display text in, before we can actually display the text, create a logical font for the selected font and establish that font as the current character set for our presentation s pace. The function CreateFontAndDisplayIt creates a logical font, using the fAttrs structure returned from the call to WinFontDlg and displays the string "Hello!" using that font.
VOID CreateFontAndDisplayIt( HWND hwnd, PFATTRS pfAttrs ) { #define MYCHARSET 99L HPS hps = WinGetPS( hwnd ); SIZEF box; // Create a logical font for the FATTRS passed in. Use MYCHARSET as // the character set number for this logical font. GpiCreateLogFont( hps, NULL, MYCHARSET, pfAttrs ); // Select MYCHARSET as the current one for thhis Presentation Space GpiSetCharSet( hps, MYCHARSET ); // If the user had slected an outline font then, as a rough approximation // set the character box to the maximum baseline extent so that the text // will be roughly in the size requested. Note that bitmap fonts are of // size and we don't have to explicitly size them. Note this is an inaccurate // sizing algorithm. if ( pfAttrs->fsFontUse & FATTR_FONTUSE_OUTLINE ) { box.cx = box.cy = pfAttrs->lMaxBaselineExt << 16; GpiSetCharBox( hps, &box ); } // Draw a text string at the current position, using our new logical font GpiCharString( hps, 6L, "Hello!" ); WinReleasePS( hps ); }
Sample Code 3. A function to create a font, then display it.
If the Font Fits...
The CreateFontAndDisplayIt function uses a somewhat inaccurate calculation to approximate the size that the character box should be set to if the user selects an outline font. For much more exact sizing of an outline font for display on a specific device, you can use the following algorithm:
- Choose the point size required
- Apply the following formula:
- pt = selected point size
- dev = device graphics resolution in pels per meter
- mi = 0.0254 (meters/inch)
- ip = 0.9961/72 (inches/point)
- character box = pt * dev * mi * ip
Then, use the GpiSetCharBox function to set the character box accordingly.
The formula uses the following basic rules from the typesetting world:
- 12 points = 1 pica
- 6 picas = 1 inch (actually 0.9961 inches)
- 72 points = 1 inch
- 1 inch = 2.54 cm
- 1 inch = 0.0254 m
And, That's Not All!
In this article, we have only touched on some of the many features that OS/2 Presentation Manager provides for manipulating and displaying text characters in different fonts. As always, the best way to get familiar with these interfaces is to try them out in your own programs. Complete sample programs can be found on your accompanying Developer Connection for OS/2 CD-ROM.
In a future article, we will look at some more complex ways to use fonts in your applications.
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation