Haven Rock XML and
open source software
for down-to-earth
business solutions

havenrock.com whole Web
Developer Resources

Virtual Fonts for Book Typesetting

Describes a method for assembling virtual fonts for traditional English text typesetting, where ff-ligatures and old-style numerals are provided by auxiliary fonts. The specific procedures here are for using the FontSite 500 collection with the ConTeXt macro package, but may serve as a helpful example for anyone trying to understand TeX virtual fonts. There is also a downloadable set of example files, including a Python script I used to automatically generate virtual fonts.

  1. Introduction
  2. Preliminaries
  3. Creating a VPL file
    1. Preparation
    2. Editing the VPL
    3. Generating the new virtual font
    4. A helpful Python script
  4. Completing the installation
  5. Problems
  6. Download examples
  7. Related links


Fine typesetting in the English language has traditionally used ff-ligatures and old-style figures (i.e. numerals that are shaped like lowercase letters, with small bodies, ascenders and descenders). These elements are widely considered to improve readability, and they certainly lend an air of elegance to the composition.

Standard digital fonts usually lack these glyphs, but quality vendors will often provide them in auxiliary fonts. The FontSite 500 collection, for example, has a number of families with expert fonts that include the missing ligatures. Some families also include fonts that provide old-style figures along with small capitals (which I will refer to as 'small-caps fonts').

The TeX virtual font mechanism allows you to perform a variety of useful tricks, including combining glyphs from several base fonts into a single virtual font. Although making such a composite font is not particularly difficult, it is hard to find documentation on how to do it; moreover, none of the documentation I have seen gives specific examples. This tip is my attempt to remedy the situation. I describe the procedure I followed to create virtual "book fonts" of several Type 1 font families in the FontSite 500 collection, for use with the ConTeXt macro package.


The Type 1 directory in the FontSite 500 collection is full of subdirectory and file names that are intended to be "user-friendly," but are awkward or unusable for TeX and the font utilities we will be using. So your first step should be to copy the families you want to use onto your hard disk, changing directory names to all lower-case with no spaces, and changing the font file names to lower-case.

If you are using the fonts with ConTeXt, you will probably want to install them with texfont. Although you could create your virtual fonts "from scratch" and install them manually, texfont makes the process much easier by installing fonts files automatically, naming them according to consistent conventions, and generating appropriate map files. So, rather than trying to reinvent the whole process, I recommend performing a complete texfont installation, then modifying it manually to incorporate new virtual fonts.

Assuming your font families are all in subdirectories of a single directory (which contains nothing else at this point), the following command (in a Unix-like shell environment) will install them:

      $ for fam in *; do
      > texfont --ve=fontsite --co=$fam --so=$fam --ma --in --virtual --expert
      > done

Note that the family (AKA 'collection') name for ConTeXt is the same as that of the directory containing the fonts. This is part of the reason for renaming the directories.

Creating a VPL file

This section describes in detail how to create a virtual font that takes most glyphs from one standard Type 1 font, but adds ligatures from an "expert" font, and old-style numerals from another related font. If you need to perform other manipulations you will probably want to consult the VPtoVF manual, which describes the VPL file format. If you don't have the manual, I have written another tip that describes how to obtain it.

In this example, we will be working with the Bergamo font family (a Bembo look-alike). Assuming you have converted the font names to lowercase, but otherwise left them alone, the file names for the medium Roman will be bergamo_ plus extensions (.afm, .pfb, etc.). The corresponding expert and small-caps fonts are named berge___ and bergsc__, respectively. When you install these fonts with texfont, the TFM and VF file names for the standard and small-caps fonts will be prefixed with texnansi-, reflecting the default encoding chosen by texfont. The expert font has no prefix, since it has a font-specific encoding.


The source code for a TeX virtual font is contained in a VPL (Virtual Property List) file. Creating a VPL from scratch would be quite an undertaking, but fortunately there is no need to do that. We can assemble our VPL mostly from pieces of other VPLs that we will generate.

First, generate a VPL file for the main font. Assuming the font has already been installed, you can use vftovp to generate this file, with the following syntax:

vftovp <vfname> <tfmname> <vplname>

You need to give the full paths of the VF and TFM files; on most systems you should be able to use kpsewhich to look them up. For example:

vftovp `kpsewhich texnansi-bergamo.vf` \ `kpsewhich texnansi-bergamo.tfm` texnansi-bergamo.vpl

The output of this command can be used as the VPL for your new virtual font, though you may want to save a copy before editing in case you introduce errors.

There is probably no VF file installed for the expert font, so you will need to use a different method for it. You can generate a VPL file from an AFM file using afm2tfm as follows:

afm2tfm berge___.afm -v berge.vpl

The VPL for the small-caps font may be generated by either of the two methods. As far as I know, either is fine for the current purpose.

Editing the VPL

Adding references to auxiliary fonts

Since a virtual font is based on one or more real fonts, the VPL file used to create it must refer to these fonts. This is done with MAPFONT instructions. The original VPL file is based on just the main font, so you need to add MAPFONT instructions for the expert and small-caps fonts, as illustrated below:

Adding mapfont instructions

There are just a few things to note about these definitions:

  • D 1, as in MAPFONT D 1, means the decimal integer 1. This value is used to identify the font in other instructions such as SELECTFONT.

  • FONTNAME should be the name of the font as known to TeX. Hence, the expert font here is called berge (because it has no useful TeX encoding), and the small-caps font is called texnansi-raw-bergsc.

  • FONTAT and FONTDSIZE have to do with scaling. I do not fully understand their usage, but since we are working with fonts that are designed to be used together, there is probably no need to edit these values.

Adding new ligature definitions

The next step is to add new ligature definitions to the ligature and kerning table. Each entry in the table consists of several LIG and/or KRN properties between a LABEL instruction and a STOP.

LABEL specifies the glyph to which the properties apply; for example, (LABEL C f) means "the following properties apply to the glyph for 'Character f' (which, please note, is just the position in the font normally associated with the letter f)."

Each LIG instruction gives the code of the following character in a ligature (the leading character being given by the LABEL), and then gives the code of the actual ligature glyph. So if you see ...

          (LABEL C f)
          (LIG C l O 13)

... this means that the fl ligature is represented by the glyph whose code is O 13 (octal integer 13).

The normal FontSite fonts already contain fi and fl ligatures, so we just need to add ff, ffi, and ffl. The following image shows the changes that are needed.

Adding new ligature definitions

Note that, since the file already contains a LABEL C f entry, adding the ff ligature just requires a new LIG property. Since ff was previously undefined in this font, we must create a new LABEL O 13 entry (with O 13 representing ff, in order to add the ffi and fft ligatures. We will also need to add character definitions for codes O 13, O 16, and O 17.

Do the ligatures require kerning information? I need to investigate this question further to be sure, but since there is no kerning information for the two built-in ligatures, it appears the answer is no. My guess is that for kerning ligatures, TeX simply uses the kerning information provided for the individual characters, so that, for example, fl followed by c would be kerned in the same way as l and c.

Mapping characters

Last but not least, we must provide character mappings in order to use the glyphs provided by auxiliary fonts. The general procedure for doing this is as follows:

  1. Determine the position of the desired glyph in the source font. In the case of old-style figures, this is easy, since the FontSite small-caps fonts have all glyphs in the same positions as in the normal fonts. For ligatures and other glyphs provided by expert fonts, you will need to consult a character chart provided by the vendor.

  2. For each glyph, copy all metric information from the source font VPL.

  3. Check the DESIGNUNITS property at the head of each VPL file. If they are different, you will need to adjust the metric values to conform to the scale of the main VPL. In my case, the main VPLs (generated by vftovp from fonts installed by texfont) have DESIGNUNITS=1.0, while the auxiliary VPLs (generated from the vendor AFMs by afm2tfm) have DESIGNUNITS=1000, meaning that all the imported metrics must be divided by 1000. I don't know the reason for this discrepancy, but there seems to be no way to control the DESIGNUNITS property other than editing it in the VPL file.

  4. Add a MAP instruction, including SELECTFONT and SETCHAR statements. (SELECTFONT D 2) means "take the following glyphs from font D 2 (which should be declared in a MAPFONT instruction). (SETCHAR C 0) means "use the glyph at position C 0 in the currently selected font."

The diagram below shows the process of mapping Character 0 to the old-style figure provided by the small-caps font.

Mapping characters

Mapping the ligatures is essentially the same as the above, except that you will probably need to add new character mappings rather than replacing existing ones.

Generating the new virtual font

Assuming there are no errors in your edited VPL file, the following command should do the trick:

      vptovf texnansi-bergk.vpl

After executing the above command, you should have a TFM file and a VF file, which may be placed together with the installed files for the same font family. You now have a complete virtual font, but as explained in Completing the installation, additional steps may be needed before you can use the font.

A helpful Python script

Editing a VPL file by hand is not particularly difficult, but it is tedious and error-prone. I wrote a Python script, (bookfont.py in the examples package) which automates the process described above. A word of caution is in order here: this script was designed to meet my needs, and will probably require modification if your circumstances are different from mine. In particular, it relies on font names such as those generated by recent versions of texfont, and on details of content and formatting in VPL files. Results could also be affected by peculiarities of your operating system and TeX distribution.

Before using the script, you must prepare a configuration file that specifies the families and fonts to be processed. Here is an example, again for the Bergamo family:

    {                                 [ 1 ]
    'bergamo': {                      [ 2 ]
        'psname': 'Bergamo',          [ 3 ]
        'bookfam': 'bergambk',        [ 3 ]
        'fonts': {                    [ 4 ]
            'bergamo': {              [ 5 ]
                'lig': 'berge',       [ 6 ]
                'osf': 'bergsc',      [ 7 ]
                'out': 'bergk'        [ 8 ]
            'bergi': {                [ 5 ]
                'lig': 'bergei',      [ 6 ]
                'out': 'bergki'       [ 8 ]
            'bergb': {                [ 5 ]
  1. The file should contain a nested Python dictionary.
  2. The toplevel keys are family names. The source fonts should be organized in subdirectories whose names match these family names.
  3. These items are currently unused.
  4. The value of 'fonts' is a dictionary describing the specific font names within the family. Appropriate prefixes and suffixes are added automatically by bookfont.py.
  5. The keys in the 'fonts' dictionary should match the names of the regular fonts: 'bergamo' is the medium Roman, 'bergi' is the italic, and so on.
  6. 'lig' [REQUIRED] specifies an expert font that provides ligature glyphs.
  7. 'osf' [OPTIONAL] specifies a font that provides old-style figures.
  8. 'out' [REQUIRED] specifies the name for the new virtual font.

Save the configuration file as fontmap.py (a complete sample may be found in the examples package). You can now run the script:


If all goes well, each family subdirectory should now contain VF and TFM files for your new virtual fonts. You must manually move these files to appropriate places in your TeX search path, and as usual, run mktexlsr or texhash to make them visible to the system.

Completing the installation

If you intend to use the virtual fonts with ConTeXt, you will probably wish to create typescripts for them. If you already have typescripts for the base fonts, you can copy and edit them for the new fonts. Here's an example:

  1. Copy type-bergamo.tex to type-bergambk.tex, and edit the latter as follows.
  2. Change all instances of Bergamo to BergamoBook.
  3. Change the family name, bergamo, to bergambk.
  4. Change the individual font names: bergamo to bergk, bergi to bergki, and so on.
  5. Remove the definitions for the expert fonts. This step is optional; in my case, the characters I need from the expert fonts are now incorporated into the main (virtual) fonts, so there is no reason to keep the former as separate entities.


texfont may treat some expert fonts as regular fonts, and install them with a TeXnANSI encoding. In my installation, this happened with the University Old Style family. I am not sure whether this is a bug in texfont, or in the fonts themselves. At any rate, the result is that the expert fonts are installed with the 'texnansi-' prefix, instead of the usual short names. When bookfont.py constructs a VPL file, it uses short names for all expert fonts. Thus a virtual font file will refer to uniose (University Old Style Expert), while the font name as installed is texnansi-raw-uniose. When this happens, the simplest way to make the font accessible is:

  1. Rename the offending TFM files, or symlink them: e.g. texnansi-raw-uniose.tfm to uniose.tfm.
  2. Edit all references to the misnamed fonts in map files (e.g., the texnansi-unios.map file generated by texfont).

Download examples


Related links

  • ConTeXt and pdfTeX Beginners Help Page

    Bill McClain's site has lots of good information on ConTeXt, including a section on installing FontSite 500 fonts.

  • The FontSite

    Home of the FontSite 500 CD, a large collection of good-quality fonts at an amazingly low price. Most or all of them are clones (or near imitations?) of well-known type faces.

  • Making TeX Work

    The Fonts chapter of Norman Walsh's book provides an excellent conceptual overview of how TeX uses fonts.

  • The Font Installation Guide

    Though not directly relevant to the issues discussed here, this thorough (and beautifully formatted!) book by Philipp Lehman addresses many important aspects of font installation and usage in TeX and LaTeX.

  • Pragma Advanced Document Engineering

    Home of the ConTeXt package. Rather hard to navigate, but the software and documentation here are well worth the effort.

Copyright © 2004 by Matt Gushee   ::  Last modified:  July 07, 2004