Administering Fonts 

http://www.linux-mag.com/2000-02/guru_01.html http://www.linux-mag.com/cgi-bin/printer.pl?issue=2000-02&article=guru

by Aleen Frisch

One of the most obvious and painful imperfections of Linux systems is the X Window System's cumbersome font-handling facilities. The chief reason that fonts cause so much difficulty — or at least inconvenience — is that there is no unified font manager in this environment. Instead, most applications have their own unique font-handling methods and each one must be configured individually.

This month, I'll describe how X handles fonts and how to add Adobe Type 1 fonts to your system. Next month, I'll explain how to install TrueType fonts and how office applications handle fonts. What's the difference between Type 1 and TrueType fonts? Read on.

Font Basics 

Font names such as Times and Helvetica actually refer to font families containing a number of different typefaces, such as regular Times, italic Times, bold Times, bold italic Times, and so on. There are two formats for font files: bitmap and outline. Bitmap fonts store the information about the characters in a font as bitmap images, while outline fonts define the characters in a font as a series of lines and curves, comprising in this way mathematical representations of the component characters.

From a practical point of view, the main difference between these two font types is scalability. Outline fonts can be scaled up or down any arbitrary amount and look equally good at all sizes. In contrast, bitmap fonts do not scale well, becoming extremely jagged and primitive as they get larger. These effects become increasingly significant as resolution increases. For example, on a computer screen whose resolution is 72 dpi, both types of fonts tend to look reasonably good. However, on a laser printer whose resolution is typically 300 dpi or higher, the difference between these font types becomes very obvious. For these reasons, outline fonts are generally preferred over bitmap fonts.

To further complicate matters, there are two competing formats for outline fonts: Adobe Type 1 and TrueType. The chief technical difference between them consists of the kinds of curves used to represent the characters: Bezier curves and b-splines, respectively. The other major difference between the two formats is price, with Type 1 fonts generally being significantly more expensive than TrueType fonts.

All of these different types of fonts are generally present on Linux systems. The most important formats are listed in Table One, along with their corresponding file extensions.

Table One: Common Font File Formats

Format Bitmap/Outline Extension
Portable Compiled Font Bitmap .PCF.gz
Speedo Bitmap .spd
Ghostscript font Outline .gsf
Type 1 Outline .pfa, .pfb, .afm
TrueType Outline .ttf

The PCF fonts are bitmap fonts (generally stored in compressed format) that come as part of the XFree86 system. They are located in directories under /usr/lib/X11/fonts. The Speedofonts were donated to the X Window System by Bitstream and are located in the same place.

The Ghostscript fonts are Type 1 fonts (using a slight variation in format). In addition there may be Type 1 and/or TrueType fonts present on the system.

Type 1 fonts consist of multiple files. The .pfa and .pfb files contain the actual font outline representation in ASCII and binary format respectively, and the .afm file contains font metrics information in ASCII format. Type 1 fonts on Linux systems generally use the binary .pfb files probably because they are smaller in size, but .pfa files may also be used. The corresponding .afm file is also required in order to print.

The X Window System uses an arcane naming convention for referring to fonts. It goes like this:

-foundry-family-weight-
  slant-stretch-style-
  pixel-points-xres-yres-
  spacing-avgwidth-
  registry-encoding

Here is how it would look for a font in the Octavian family:

-monotype-octavian mt-
  medium-i-normal-
  0-0-0-0-p-0-iso8859-1

The foundry is the organization (often a commercial entity) that provided or sold the font, Monotype in our example. The family indicates the overall grouping of typefaces to which this particular item belongs (for example, Times or Helvetica). Our example is from the Octavian MT family. weight is a keyword indicating the relative darkness of this typeface with respect to other family members (medium, bold, light, black, and so on). slant is a single character indicating whether this typeface is upright (r for roman, i for italic, or o for oblique). stretch is a keyword indicating whether the typeface is expanded or compressed with respect to normal lettering (normal, condensed, expanded, and so on). style indicates any additional typographic style information relevant to this typeface (e.g., expert, ornaments, oldstylefigures, etc.). The example typeface is Octavian Italic (not bold, not condensed/expanded, and no additional style designation).

The remaining fields specify the default point size (points), the body size in pixels at that point size (pixels), the typeface's default horizontal and vertical resolution (xres and yres), its spacing class (one of m for monospace or fixed width, c for character cell, and p for proportional), a measure of the average width of the glyphs in the font (avgwidth), and the character set used for coding the font (registry and encoding). Most of the numeric fields tend to be set to zero for outline fonts — as they are in my example — indicating that the font's default value should be used. The three remaining fields are generally set to the values shown in the example as well.

In most instances, you'll never need to construct one of these names by hand. Instead, you can use utilities that create them for you automatically for various contexts. However, if you ever do need to generate one yourself, you can find all the essential information by running the strings command on the binary font file and looking at the information displayed at the beginning of its output. (If you have an ASCII font file, you can look at that file's contents directly.)

For more general information about fonts, consult the FAQ from the comp. fonts newsgroup. (Version 2.1.5, dated August 1996, is the most recent.) For a complete explanation of X font-naming conventions, see "X Logical Font Description Conventions," which is included among the general X documentation. For additional information about TrueType fonts, consult the TrueType HowTo. (Sources for all of these are listed in the sidebar on pg. 56.)

Managing Fonts Under X 

As I noted previously, the fonts that come with the X Window System conventionally reside under /usr/lib/X11/ fonts. However, when an application needs a font to display on the screen, it checks the current font path to find it. In older versions of XFree86, the default font path is defined in the XFree86Config configuration file (generally located in /etc/X11, with several links to other places) via FontPath lines in the Files section (see Listing One).

Example 1. Listing One: Defining the Default Font Path in XFree86Config

Section "Files"
RgbPath         "/usr/X11R6/lib/X11/rgb"
FontPath        "/usr/X11R6/lib/X11/fonts/misc"
FontPath        "/usr/X11R6/lib/X11/fonts/75dpi"
 ...
EndSection

Each successive FontPath entry adds an additional directory to the font path.

On more recent systems, these lines have been replaced by one like this:

FontPath "tcp/localhost:7100"

This indicates that a font server is in use, listening for font requests on TCP port 7100 on the local machine. Additional FontPath entries may again be present, specifying either local directories or ports on other computers. The introduction of the font server in X11R5 made life easier since it allowed files to be shared between systems. Note that on some systems running Red Hat Linux, the entry appears as follows:

FontPath "unix/:-1"

This format refers to the Red Hat-modified version of the X font server from which networking capabilities have been removed. The font server process actually runs the xfs program.

Regardless of how the default font path is configured, users can always modify it via the xset command's fp option. For example, the first command below adds the directory /more/fonts/ type1 to the beginning of the font path, and the second restores the font path to its default:

$ xset +fp /more/fonts/type1
$ xset fp

The latter is very useful after running applications such as StarOffice and Applixware, both of which fiddle with the font path when they run and don't bother to clean up after themselves when they exit. The command xset q will display the current font path and other information about the current X session.

t1utils is a useful package for manipulating Type 1 fonts. It contains commands for converting between .pfa and .pfb files (t1ascii and t1binary). In addition, the t1lib package includes the type1afm utility, which you use if you want to print with a font that you have somehow acquired as a lone .pfa or .pfb file (generally under somewhat shady circumstances). Note that .afm files produced by type1afm differ from those provided by the manufacturer. Unfortunately, I'm not enough of a typography expert to know if the differences are significant are not.

Administering Type 1 fonts for screen display is quite straightforward. However, printing introduces a few new wrinkles. In order to be printed, Type 1 fonts must be rendered (technically, rasterized). Under X, this is usually handled by the Ghostscript facility, so in order to print successfully, Ghostscript needs to know about any new fonts.

Ghostscript font configuration occurs via its Fontmap configuration file, located in the /usr/share/ghostscript/5.10 directory on my Red Hat system. See some sample entries from the file in Listing Two.

Example 2. Listing Two: Ghostscript Configuration in the Font Map File

/NimbusRomNo9L-Regu (n021003l.pfb) /NimbusRomNo9L-ReguItal (n021023l.pfb)
/Times-Roman /NimbusRomNo9L-Regu /Times-Italic /NimbusRomNo9L-ReguItal ;

Each line contains three fields: a name preceded by a slash, a filename enclosed in parentheses or another name, and finally a semicolon; spaces and/or tabs separate the fields from one another. If the second field is a filename, then print requests for the correspondingly named font will use this font file. If the second field is another name (indicated by an initial slash), then the first field becomes an alias for the same typeface.

For example, the preceding entries will cause the file n021003I.pfb to be used when someone wants to print the Times Roman font.

In order to print the Octavian typeface, you need to add the following line to this file:

/OctavianMT-Italic (oci_____.pfb) ;

The type1inst utility that I mentioned earlier creates a Fontmap file within the current directory along with the fonts.dir and fonts.scale files, making it easy to add the required entries to the actual Ghostscript font-configuration file.

The filename field may contain either an absolute path or a simple filename. In the latter case, the Ghostscript font path will be searched for that file. The default path is set up when the facility is compiled and typically consists of subdirectories under /usr/share/fonts/default (e.g., ghostscript and Type1).

You can make fonts available to Ghostscript by adding them to these existing locations (and modifying the current fonts.dir and fonts.scale files accordingly), or by using a new location, which can be added to the Ghostscript path by setting the GS_LIB environment variable.

So that's it for Type 1 fonts. Next month I'll delve into TrueType fonts and show you how to configure fonts on StarOffice and Applixware.

Adding Fonts to X 

Adding fonts for use in screen display by the X Window System is very easy. For Type 1 fonts, you can do this in four steps.

  1. Create a directory to hold the new fonts (if necessary), and copy the font files there. Generally, you will need to put in both the .pfa or .pfb file and the .afm file there.
  2. Generate the required configuration files named fonts.dir and fonts.scale.(These two files are identical in the case of Type 1 fonts.) This can be done manually, or you can have a utility do it for you. Using the standard X command mkfontdir often works well for this task, and the widely available type1inst command is very reliable. (Both of them are run from within the directory holding the new fonts.) The entry in the files corresponding to the Octavian Italic typeface looks like this:

    oci_____.pfb -monotype-octavian mt-medium-i-normal-0-0-0-0-p-0-iso8859-1

    The first item is the filename dictating the Type 1 font (oci'_'.pfb in this case), and the second item is the standard X typeface designation.

  3. Add the new directory to the font path. If you are not using a font server, this is done by adding another FontPath entry to the XFree86Config file. If you are using a font server, you must edit an entry in its configuration file. The xfs font server typically stores its configuration file as /etc/X11/fs/config. You will also need to add an additional component to the catalogue list:

    catalogue = /usr/share/fonts/ISO8859-7/Type1,
           /usr/share/fonts/default/Type1,
           /usr/X11R6/lib/X11/fonts/misc,
           /usr/X11R6/lib/X11/fonts/Type1,
           /usr/X11R6/lib/X11/fonts/Speedo,
           /more/fonts/type1

    Here, I have added the /more/fonts/type directory as the final component of the catalogue . Note that the various entries are separated by commas.

    Guru gfontview Figure One: The gfontview Font Display Utility.

  4. Restart the font server and any current X session.On your typical Red Hat system, the command will look like /etc/rc.d/rc3.d/S90xfs restart.

Once this is all complete, the new fonts should be available to any application that uses the standard X font facilities. You can verify that the fonts are installed correctly using the X commands xfontsel and xfd. The GIMP application provides another very pleasant way of exploring the new fonts. xfontsel and xfd can also be useful for exploring what fonts are available on the system and displaying all the characters within a given typeface.

However, the latter job is better handled by the freely available gfontview utility, whose output is displayed in Figure One. This facility allows you to view a single character, a short string, or a palette containing every character within it. In order to build properly, gfontview requires the t1lib support, which is usually not present by default on Linux systems.

Font-Related Information and Resources 

Aleen Frisch is the author of O'Reilly & Associates Essential System Administration.