bumbler
December 19th, 2003, 00:13
Tweaking System Font Registry
Ed Hurst
17 December 2003

================================================== ======================

You got some really nice TrueType fonts (TTFs), and you install them on
your FOSS box. For some reason, they aren't properly grouped so that a
particular font is missing its italic or bold version. Instead, the
italic or bold version is listed as a separate font. Because of the way
the font was read and installed, your system registers the wrong
information.

Can it be fixed? Of course! That's what Open Source is all about. No,
it does not mean having to rewrite the code for your font installer.
However, it may mean something that seems at first almost as arcane as
writing code. Since my previous articles make it clear I am quite far
from being any sort of coder (okay, I do XHTML by hand), you can rest
assured the fix is within the reach of non-geeks. I've done it, and it
works fine. It's not because I am any kind of font guru; it's a simple
matter of persistence and good fortune that I discoverd this info.

First, a little theory behind the whole thing. TTFs are binary files,
unlike some Type1 fonts. There was a time when the X server required
special help reading TTFs. Within the file is some header information
that is read by your installer. In those other OSs whence we get most
of our TrueType fonts, this is all worked out automatically based on
some proprietary assumptions. Makers of these TTFs encode their fonts
for that system. Our FOSS installers simply read what's there, and it
may not follow our much older standards.

Most fonts come in groups of four: normal, italic, bold, and
bold-italic. A complete display/printing font will have all four. A
notorious exception is Tahoma, but that's another story. Some free TTFs
come with only one style because they are largely decorative in the
first place. We are focused here on using the standard fonts that fall
into rather high use patters for printing and webpage display. When
there is trouble, it is usually a matter of the italic versions
(meaning slanted forward, also called "oblique") are recognized, but
the bold version is read as a separate font. The naming convention
between regular and bold faces is not always followed precisely. You
end up with two pairs of similar fonts, with similar names, but not
properly registered as all one font. Most often, this is reported with
some Corel TTFs.

There are two places where this information appears, and it is in plain
text, and easy to change. One is in the AFM (Adobe Font Metric) files
that are created for each font so that Ghostscript, and other print
utilities, can decide how to use them. The other place is the fonts.dir
and fonts.scale files in each directory, which are used by the X server
in deciding how to display the fonts. In theory, the
fonts.dir/fonts.scale files are built from the AFMs.

Let's go to where these things are found. Open Source OSs all tend to
keep them in a standard location:

/usr/X11R6/lib/X11/fonts/

with the TTF folder taking any number of various names. On my current
system it's called "truetype". Move into your TTF folder and look
around. You would likely see at least a few AFM files.

Take at look at any randomly chosen AFM. Each font contains a set of
"glyphs" -- a list of characters that have been created using the
particular style of the font. Fonts with an extensive set of glyphs are
quite large, with a single set of font files together taking up 5MB of
space. In the age of 32-bit computing, it has become possible for just
about every language in use to have their peculiar alphabet included in
the display capabilities of system fonts, and in a few printer fonts.
Thus, you hear talk of "UTF-8" and "Unicode" display issues. Very few
fonts are truly Unicode, but anything in the range of 3000 glyphs or
more comes as close as you are likely to find.

When these fonts are processed for printing, the first step is to
create an AFM file that lists whatever glyphs are available. Every
glyph is placed within a standard character cell, and it must be
located based on where it falls within that cell. You can't simply put
your apostrophe on the lower left-hand corner, or no one would consider
it an apostrophe, but would think it were a comma or something. The AFM
will describe the location of the glyph by citing a standard reference
in numbers. When you open an AFM in a text viewer or editor, you'll see
those numbers. Fortunately, this particular standard is seldom flouted.

That explains what you see at below the header information. What we are
going to fix is in that header. Here's what I see in "georgia.afm" --

StartFontMetrics 2.0
Comment kfontinst iso8859-1
FontName Georgia
FullName Georgia
FamilyName Georgia
Weight Medium
Notice Created with kfontinst v0.11

If we are to have trouble, it will be in the lines where the naming
appears, lines 3-5. We also add line 6 as an area of concern. In this
case, because there is uniformity, there's really no problem. When we
compare this with the AFM for the bold version, we see --

FontName Georgia-Bold
FullName Georgia Bold
FamilyName Georgia
Weight Bold

Notice that everything matches neatly. The line beginning with
"FontName" is simply a record of what's in the font header itself. It
may have all sorts of information run together in a single string.
That's usually not an issue for us. It's the other three lines where we
can run into trouble. When these lines do not follow a consistent
pattern for each of the four styles of a single font, they will be
improperly read for printing and for display. The pattern for this is:

Family Bold Italic

In general, the family name can be almost anything, including spaces
between several term, but it must be consistent with each of the four
AFMs. "Bold" only if it is so, and "Italic" comes last if it is so.
Obviously, the "FamilyName" line should be just that, and consistent
with the line above, but without the "Bold" or "Italic" designation,
and the same across all four versions. For most fonts, the "Weight"
will be "Medium" or "Bold" as appropriate.

More recent systems often do not create an AFM, because good modern
word processors (for example) will present their files for printing to
the Ghostscript interpreter as a single, page-filling graphic. However,
you will still find the fonts listed in the fonts.dir and fonts.scale.
Now here I take issue with a couple of Linux distros that act as if no
font is processed directly by the X server, but that all fonts
naturally pass through the Xft engine. That's not too bad if you run
only KDE 3.x or Gnome 2.x, or every application has an interface drawn
by Qt3 or Gtk2. As it happens, there are still a large number of
applications built on other interface libraries, chief among them
Tkl/Tk, Gtk1, and plain old Xlibs. None of these use the Xft engine,
but render directly from the X server itself. Worse, only a handful of
Type1 fonts and the TTFs are set up to render through Xft on some
systems. That keeps you from seeing other fonts in at all in KDE or
Gnome.

It's not as if Xft can't render these other fonts; it can indeed. Feel
free to edit your fonts.conf file (usually at /etc/fonts/fonts.conf)
and your XftConfig (if you have one, it's usually two directories
above, where you find the fonts folder: /usr/X11R6/lib/X11/XftConfig).
Just pay attention to the format near the top of each file and make
sure all the font paths are listed for the fonts you want to use in
your KDE and Gnome apps. Then go to each directory and make sure that
fonts.dir is a copy of fonts.scale. You'll probably have to run the
command:

fc-cache

to make them available to Xft.

Take a look at your XF86Config:

less /etc/X11/XF86Config

and you will see that right near the top is a list of font paths. In
order for the X server to process fonts directly for these other
interfaces, each of these font directories included in your listing of
font paths must have a properly formatted fonts.dir and fonts.scale.
These two files have identical formats, by the way. If you make a copy
of your fonts.dir and name it fonts.scale, the job is done. It's this
fonts.scale that is needed by X to render the fonts.

Since we are already in the TTFs directory, take a look at the
fonts.scale file there. Several modern Linux distros make it blank, so
go ahead and make a copy of fonts.dir. If you have time, run down where
it is in your system that are the instructions to blank that file and
turn that feature off. Each OS that does this does it differently, and
you'll have to get help from someone who knows that distro (for SUSE
see my tutorials at http://webs.tconline.net/softedges/linux/).

In this file is a catalog of the fonts, matching the name of the file
itself with description of the font in a standard format. Here's the
entry for our Georgia normal font on my system:

georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-adobe-standard
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso10646-1
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso8859-1
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso8859-10
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso8859-13
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso8859-15
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso8859-2
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso8859-3
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso8859-4
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso8859-5
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-iso8859-9
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-koi8-e
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-koi8-r
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-koi8-ru
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-koi8-u
georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-microsoft-cp1252

The font name comes first on each line, and *must* be exactly the same
as the name of the file itself, and capitalized the same, if
applicable. Notice that the same file is listed several times, and each
line is different only at the end. That's a reference to an encoding
scheme. Some applications ask for the font to be displayed according
the "adobe-standard" which excludes a large number of glyphs. The next
listing is the fancy encoding term for Unicode. That's included for
programs that request the font with all the glyphs available. The
others you can learn about by reading up on font encodings for foreign
languages.

What matters for us here is that this same collection of encodings is
listed in this file for each of the four versions of Georgia. If we
compare the lines for the adobe-standard encoding for each of the
files, we see:

georgia.ttf -microsoft-Georgia-medium-r-normal--0-0-0-0-p-0-adobe-standard
georgiai.ttf -microsoft-Georgia-medium-o-normal--0-0-0-0-p-0-adobe-standard
georgiab.ttf -microsoft-Georgia-bold-r-normal--0-0-0-0-p-0-adobe-standard
georgiaz.ttf -microsoft-Georgia-bold-o-normal--0-0-0-0-p-0-adobe-standard

Notice that each of them looks the same for the most part. The file name
is followed by:

- the foundry: the name of the company that created the font
- the font family: the name of the basic font face itself
- the weight: whether it is medium or bold
- the slant: a single letter indicating upright (r) or slanted (i or o)
- the width: it might be normal, compressed, demi, wide, etc.

Chances are your problem fonts will have something different for that
second item. Whatever you have decided is your standard for the AFMs is
what you want to make these match. You must edit each line wherever
that font occurs so that every reference to that font file is the same.
Also, if you notice that your font files are not properly described by
the width and slant, you have to change them to match reality. Most
errors are a matter of listing your bold versions as medium.

Naturally you will want to make a backup copy of your fonts.scale and
fonts.dir (remember you have to edit both to match) before editing, so
that you can recover the original. I usually make a copy in the same
directory and change the name a bit:

cp fonts.dir bak.fonts.dir

Advanced editors will allow you to change multiple lines if you are
careful to identify the pattern to find and replace, so that it doesn't
change something that is okay as is. Let's pretend for a moment there
is some confusion on my system because I included a font called
"MumblesBlk" that is supposed to go with my other "Mumbles Block" font
files. So my fonts.dir/scale lists the bold font as if it were a
separate family. To prevent having to edit each line by hand, I can
tell it to search for something that matches only the lines I want to
change by including enough of the line to prevent changing other
"Mumbles" listings.

Find: mumbkb.ttf -microstuff-MumblesBlk-medium-

Replace with: mumbkb.ttf -microstuff-Mumbles Block-bold-

This protects the listings for the font file "mumbbk.ttf" which is
"Mumble Black" -- a very heavy font for headings. It gives the "Mumbles
Block Bold" the proper display instructions to be treated as a member
of the "Mumbles Block" family, but with the bold weight.

Once you've made these corrections, you can test it by restarting the X
server -- usually just logging out of the current session and then
logging back in.