18.4.9 Creating Customized Fonts

GDI keeps a system font table containing all the fonts that applications can use. GDI chooses a font from this table when an application calls the CreateFont or CreateFontIndirect function. There can be up to 253 entries in the system font table.

A font resource is a group of individual fonts representing characters in a given character set that have various combinations of heights, widths, and pitches. Applications can load font resources and add the fonts in the resource to the system font table by using the AddFontResource function. After a font resource has been added, the application can use the individual fonts in the resource. In other words, the CreateFont function takes the fonts into account when it tries to match a physical font with the specified logical font. (Fonts in the system font table are never directly accessible to an application. They are available only through the CreateFontIndirect and CreateFont functions, which return handles of the fonts, not memory addresses.)

An application can add a font resource to the system font table by using the AddFontResource function. To remove a font resource, an application can use the RemoveFontResource function.

Whenever an application adds or removes a font resource, it should inform all other applications of the change by sending a WM_FONTCHANGE message to them. An application can use the following call to the SendMessage function to send the message to all windows:

SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);

An application can use the GetProfileString function to retrieve a list of any fonts the user has used Control Panel to install. The application would use GetProfileString to search the [Fonts] section of the WIN.INI file.

An application can create font resources by creating font files and adding them as resources to a font resource file. To create a font resource file, an application should follow these steps:

1.Create the font files.

2.Create a resource-definition file for the font.

3.Create a dummy code module.

4.Create a module-definition file that describes the fonts and the devices that use the fonts.

5.Compile and link the sources.

A font resource file is an empty Windows dynamic-link library; it contains no code or data, but does contain resources. An application can add a font file to an empty library, along with such resources as icons, cursors, and menus, by using Microsoft Windows Resource Compiler (RC).

18.4.9.1 Creating Font Files

An application can create raster font files by using Microsoft Windows Font Editor (FONTEDIT.EXE), as described in Microsoft Windows Programming Tools. (Font Editor cannot be used to generate vector or TrueType fonts.) The application can use any number, size, and type of font files in a font resource. In most cases, enough fonts should be included to reasonably satisfy most logical-font requests for the target device.

GDI can scale device-independent raster fonts by 1 to 8 times vertically and 1 to 5 times horizontally. GDI can also simulate bold, underlined, strikeout, and italic fonts. Font designers may choose to allow GDI to synthesize some sizes and properties of a font, rather than providing separate font files.

Font Editor modifies existing .FNT files; it cannot create font files from scratch. The Microsoft Windows 3.1 Software Development Kit (SDK) includes two .FNT files that font designers can load into Font Editor, modify, and save as customized fonts. The file named ATRM1111.FNT is a fixed-width font. The file named VGASYS.FNT is a variable-width font.

The Save As dialog box in Font Editor includes two File Format radio buttons. Font files saved in Font Editor 3.0 format can be used only in 386 enhanced mode. Font files saved in Font Editor 2.0 format can be used in all modes.

18.4.9.2 Creating the Resource-Definition File for a Font

An application can add resources to a font file by adding one or more FONT statements to the resource-definition file. The resource-definition file can add .FNT files to a Windows library, a device driver, or a resource-only file that contains only icons, cursor, fonts, and other resources. Because font resources are available to all applications, they should not be added to application modules.

The FONT statement has the following form:

number FONT filename

One statement is required for each font file to be placed in the resource. The number must be unique, because it is used to identify the font later. The following is a typical resource-definition file for a font resource:

1  FONT FNTFIL01.FNT
2  FONT FNTFIL02.FNT
3  FONT FNTFIL03.FNT
4  FONT FNTFIL04.FNT
5  FONT FNTFIL05.FNT
6  FONT FNTFIL06.FNT

You can add fonts to modules that contain other resources by adding them to the existing resource-definition file. An application can have icon, menu, cursor, and dialog box definitions in the resource-definition file, as well as FONT statements.

18.4.9.3 Creating a Dummy Code Module

A dummy code module provides the object file from which the font resource file is made. A developer can create the dummy code module by using the assembler and the Cmacros. The module's source file could look like this

TITLE   FONTRES - Stub file to build a .FON resource file

.xlist
include cmacros.inc
.list
sBegin CODE
db 0
sEnd   CODE
end

Microsoft Segmented Executable Linker LINK version 4 allows empty code segments, but LINK versions 5.12 and later does not. The inclusion of “db 0” between sBegin and sEnd in the preceding example prevents an empty code segment.

The developer can assemble this source file by using the masm command. The object file that will be created will contain no code and no data, but it can be linked to an empty Windows library to which the font resources can be added.

Developers who build font files using version 6.0 of Microsoft Macro Assembler (ML) should use version 5.3 of the CMACROS.INC file (included with ML) instead of version 5.2 of the file, which is included with the SDK.

18.4.9.4 Creating a Module-Definition File

The module-definition file for the font resource must contain a LIBRARY statement that defines the resource name, a DESCRIPTION statement that describes the font resource characteristics, and a DATA statement. The module-definition file for a font resource should look like this:

LIBRARY FONTRES

DESCRIPTION 'FONTRES 133,96,72 : System, Terminal (Set #3)'

EXETYPE WINDOWS

STUB 'WINSTUB.EXE'
DATA NONE

The DESCRIPTION statement provides device-specific information about the font that is used to match a font with a given screen or printer. The following are the three possible formats for the DESCRIPTION statement in a font resource. In each case, the first characters in the description must be a single quote and the name of the library module (FONTRES):

DESCRIPTION 'FONTRES Aspect, LogPixelsX, LogPixelsY: Cmt' DESCRIPTION 'FONTRES CONTINUOUSSCALING: Cmt' DESCRIPTION 'FONTRES DEVICESPECIFIC DeviceTypeGroup: Cmt'

The first format specifies a font that was designed for a specific aspect ratio and logical pixel width and height, and can be used with any device having the same aspect and logical pixel dimensions. Aspect is the value (100*AspectY)/AspectX rounded to an integer. The AspectX, AspectY, LogPixelsX, and LogPixelsY values are the same as the values given in the corresponding device's GDIINFO structure (values that are accessible by using the GetDeviceCaps function). You can specify more than one set of Aspect, LogPixelsX, and LogPixelsY values. The Cmt value is a comment. The following statements are examples:

DESCRIPTION 'FONTRES 133,96,72: System, Terminal (Set #3)'
DESCRIPTION 'FONTRES 200,96,48; 133,96,72; 83,60,72; 167,120,72: \
    MS Sans Serif'

The second format specifies a continuous scaling font. This typically corresponds to vector fonts that can be drawn to any size and that do not depend on the aspect or logical pixel width of the output device. The following statement is an example:

DESCRIPTION 'FONTRES CONTINUOUSSCALING : Modern, Roman, Script'

The third format specifies a font that is specific to a particular device or group of devices. The DeviceTypeGroup can be DISPLAY or a list of device-type names—the same names an application might specify as the second parameter in a call to the CreateDC function. Following is an example of the third format:

DESCRIPTION 'FONTRES DISPLAY: HP 7470 plotters'
DESCRIPTION 'FONTRES DEVICESPECIFIC HP 7470A, HP 7475A: \
    HP 7470 plotters'

Note:

The maximum length of a DESCRIPTION line is 127 characters. Because GDI is capable of synthesizing attributes, such as bold, italic, and underline, the font designer need not create separate .FNT files for fonts with these attributes. Windows may use other fonts that do not correspond to the user's screen aspect ratio. These are generic raster fonts that are intended for output devices such as bitmap printers, which rely on the display driver to draw text.

18.4.9.5 Compiling and Linking a Font Resource File

The following makefile lists the commands required to compile and link a font resource file:

fontres.obj: fontres.asm
    masm fontres;

fontres.exe: fontres.def fontres.obj fontres.rc fontres.exe \
                fntfil01.fnt fntfil02.fnt fntfil03.fnt \
                fntfil04.fnt fntfil05.fnt fntfil06.fnt
    link fontres.obj, fontres.exe, NUL, /nod, fontres.def
    rc fontres.rc
    rename fontres.exe custom.fon

By convention, all raster font resource files have the .FON filename extension. The last line in the makefile renames the executable file to CUSTOM.FON.

18.4.9.6 Adding TrueType Fonts

Because Windows cannot directly interpret the native TrueType font file format, a file that mimics the standard .FON file (called a .FOT file) is required to make internal bookkeeping and enumeration easier. The CreateScalableFontResource function produces a .FOT file that points to the TrueType font file. Once this .FOT file is produced, Windows applications can use TrueType fonts transparently by using the AddFontResource and RemoveFontResource functions. Applications could also use the CreateScalableFontResource function to install special fonts for logos, icons, and other graphics.