2.13.7 Selecting Fonts with GDI

GDI maintains a collection of fonts from different typefaces. In addition to this collection, some devices maintain a collection of hardware fonts in their ROM. GDI lets you describe a font and then selects the closest matching available font from your description.

GDI requires you to describe the font you want to use to create text. The font you describe is a logical font (it may or may not actually exist). GDI compares this logical font to the available physical fonts and selects the closest match.

The process of selecting the physical font that bears the closest resemblance to the specified logical font is known as font mapping. GDI also maintains a font table. Each entry in the font table describes a physical font and its attributes. Included in each entry is a pointer to a corresponding font resource. Figure 2.19 shows a font table that contains fonts X, Y, and Z:

Font-Mapping Scheme

GDI cannot guarantee that a physical font exists that exactly matches a requested logical font, so GDI attempts to pick a font that has the fewest differences from the requested logical font. Since fonts have many different attributes, the GDI font mapper assigns penalties to physical fonts whose characteristics do not match the characteristics of the specified logical font. The physical font with the fewest penalties assigned is the one that GDI selects.

To begin the mapping, GDI transforms the requested height and width of the logical font to device units. This transformation depends on the current mapping mode and window and viewport extents. GDI then asks the device to realize the physical font. A device can realize a font if it can create it or a font very close to it.

If the device can realized a physical font, GDI compares this font with its own set of fonts. If GDI has a font that more closely matches the logical font, GDI uses it. But if the device signals that it can take device-realized fonts only, GDI uses the realized font.

If the device cannot realize a font, GDI searches its own fonts for a match.

To determine how good a match a given physical font is to the requested logical font, the mapper takes the logical font and compares it one attribute at a time with each physical font in the system.

Table 2.5 lists the characteristics that are penalized by GDI's font mapper. The characteristics are grouped according to penalty weights, with the heaviest penalty assigned to the CharSet characteristic and the lightest penalty assigned to the Weight, Slant, Underline, and StrikeOut characteristics.

Table 2.5 Font-Mapping Characteristics

Characteristic Penalty Scheme
Penalty
Weight
CharSet If the character set does not match, the candidate font is penalized heavily. Fonts with the wrong character set are very rarely selected as the physical font. There is no default character set. This means a logical font must always specify the desired set. 4
Pitch The wrong pitch is penalized heavily. If the requested pitch is fixed, a wrong pitch is assessed a greater penalty since an application that handles fixed pitches may not be able to handle variable-pitch fonts. 3
Family If the font families do not match, the candidate font is penalized heavily. If a default font family is requested, no penalties are assessed. 3
FaceName If the font typeface names do not match, the candidate font is penalized heavily. If a default font facename is requested, no penalties are assessed. 3
Height The wrong height is penalized. GDI always chooses or synthesizes a shorter font if the exact height is not available. GDI can synthesize a font by expanding a font's character bitmaps by an integer multiple. GDI will expand a font up to eight times. If a default height is requested, GDI arbitrarily searches for a twelve-point font. 2
Width The wrong width is penalized. GDI always chooses or synthesizes a narrower font if the exact width is not available. If a default width is requested, GDI assesses a penalty for any difference between the aspect ratio of the device and the aspect ratio of the font. The mapper can give unexpected results if there are no fonts for the given aspect ratio. 2

Table 2.5 Font-Mapping Characteristics (continued)

Characteristic Penalty Scheme
Penalty
Weight
Weight Although GDI can synthesize bold, an actual bold font is preferred. The mapper penalizes for synthesizing. 1
Slant Although GDI can synthesize italics, an actual italic font is preferred. The mapper penalizes for synthesizing. 1
Underline Although GDI can synthesize underlining, an actual underline font is preferred. The mapper penalizes for synthesizing. 1
StrikeOut Although GDI can synthesize strikeouts, an actual strikeout font is preferred. The mapper penalizes for synthesizing. 1

If GDI synthesizes a font, the mapper assesses a penalty that depends on the number of times the font was replicated. Furthermore, a penalty is added if the font was synthesized in both directions and the synthesizing was uneven, that is, if the font was stretched more in one direction than the other.

When the mapper has compared all the fonts in the system, it picks the one with the smallest penalty. The application should retrieve the metrics of the font to find out the characteristics of the font it received.

The penalty weights listed in Table 2.5 are the default penalties used by GDI.

Example of Font Selection

For the purpose of this example, assume that the system font table lists only the three fonts shown in Figure 2.19, “A GDI Font Table,” fonts X, Y, and Z. Suppose you need to use a specific font, font Q, to create text on an output device. You will need to describe font Q so that GDI can choose the physical font (X, Y, or Z) that bears the closest resemblance to Q.

To describe font Q, you use the CreateFont or CreateFontIndirect GDI function. These functions create a logical font which is a description of the desired physical font.

Use the SelectObject function to select the physical font that most closely matches logical font Q. (The SelectObject function requires that you pass a handle to font Q.) Once a call to the SelectObject function occurs, GDI will initiate the selection process.

Table 2.6 shows the physical fonts in the font table and the penalties that GDI assigns to each as it tries to find a font that will match font Q. The left column shows the font attributes that GDI compares; the second column gives the attributes of font Q, the desired font. The attributes of fonts X, Y, and Z—the fonts that are actually in the system font table—are followed by the penalty values that GDI gives to each one. The bottom row of the table gives the penalty totals for each font:

Table 2.6 Sample Font Selection Ratings

             
Desired   Available Fonts/Penalty Score        
Attributes Q X   Y   Z,  
             
CharSet ANSI OEM 4 OEM 4 ANSI 0
Pitch Fixed Variable 3 Fixed 0 Variable 3
Family Roman Modern 3 Roman 0 Modern 3
FaceName Tms Rmn Pica 3 Tms Rmn 0 Elite 3
Height 8 10 2 10 2 8 0
Width 4 6 2 6 2 4 0
Slant None None 0 None 0 None 0
Underline None None 0 None 0 None 0
StrikeOut None None 0 None 0 None 0
          ,  
Penalty Total   17   8   9  
          ,  

The penalty totals show that font Y has the lowest penalty score and therefore resembles font Q most closely. In this example, GDI would select font Y as the physical font on the output device.