Wrap an X11 Bitmap Font with fonttosfnt

fonttosfnt wraps an old X11 bitmap font in a TrueType-compatible sfnt container, so software that expects modern font files can actually load it. The examples use fonttosfnt from Debian package xfonts-utils version 1:7.7+6build3; the installed manual identifies the utility itself as version 1.0.4.

Allow about ten minutes. You need a readable PCF or BDF bitmap font, a writable destination directory and the xfonts-utils package. The conversion itself is an ordinary unprivileged job: skip sudo unless the input or destination permissions genuinely demand it.

1. Check the installed command and choose an input

Confirm which executable your shell will run, then pick a real bitmap font. This example uses a compressed PCF file already installed with the X11 fonts:

$ command -v fonttosfnt
/usr/bin/fonttosfnt
$ dpkg-query -W -f='${Package} ${Version}\n' xfonts-utils
xfonts-utils 1:7.7+6build3
$ test -r /usr/share/fonts/X11/misc/8x13-ISO8859-4.pcf.gz && echo readable
readable

The input position accepts one font or a whole set of bitmap fonts. Keep the path quoted if it contains spaces or shell metacharacters. The program only reads the font; it never modifies it.

Checkpoint: if your font lives elsewhere, replace /path/to/input.pcf in the commands below with its exact path. Do not guess a filename from a font family name: check it first with test -r or ls -l.

2. Create a wrapper without overwriting anything

Use -o to name a new output file. The -- marker makes it explicit that what follows is an input, even if a filename happens to start with a hyphen:

$ fonttosfnt -o /tmp/8x13.ttf -- /usr/share/fonts/X11/misc/8x13-ISO8859-4.pcf.gz
$ printf 'exit status: %s\n' "$?"
exit status: 0

A successful exit status only means the command wrote the requested output; it does not by itself prove another program can use the font. The output is binary, so do not inspect it in a text editor.

Safety warning: -o will happily replace an existing file. Use a fresh path while testing. If you must replace a font already in use, write to a temporary name, validate it, then make a deliberate backup before you mv it into place; fonttosfnt has no built-in recovery for an overwritten file.

3. Verify the sfnt output

Use file to inspect the result and confirm it is not empty:

$ file /tmp/8x13.ttf
/tmp/8x13.ttf: TrueType Font data, 13 tables, 1st "EBDT", 8 names, Microsoft, language 0x409, Public domain font.  Share and enjoy.Misc FixedRegularMisc Fixed X.Org bitmap size 8x13Misc Fixe
$ test -s /tmp/8x13.ttf && echo output-present
output-present

The exact wording from file varies between versions; what matters is that it identifies TrueType font data and the file has non-zero size. The wrapper still carries the original bitmap glyph data underneath: this is not a way to turn a bitmap font into smooth outline glyphs.

If Fontconfig is installed, ask it to read the generated file too:

$ fc-scan --format='%{family}\n%{style}\n' /tmp/8x13.ttf
Misc Fixed
Regular

This is a read-only check. If fc-scan is not installed, the file check above is enough; just try the font in the application that needs it next.

4. Convert several bitmap fonts into one file

Pass more than one input after the options when you need a set of bitmap fonts wrapped together. Make sure the inputs are actually compatible with what you intend to use:

$ fonttosfnt -o /tmp/misc-fixed.ttf -- \
    /usr/share/fonts/X11/misc/8x13-ISO8859-4.pcf.gz \
    /usr/share/fonts/X11/misc/8x13-ISO8859-5.pcf.gz
$ file /tmp/misc-fixed.ttf
/tmp/misc-fixed.ttf: TrueType Font data, 13 tables, 1st "EBDT", 8 names, Microsoft, language 0x409, Public domain font.  Share and enjoy.Misc FixedRegularMisc Fixed X.Org bitmap size 8x13Misc Fixe

Adding files does not automatically make an arbitrary collection coherent. Check the encodings and pixel sizes first, then verify the resulting family in the application that will actually consume it.

5. Choose the compatibility trade-offs

The default output favours compactness while keeping the data most FreeType users need. These options change the wrapper, never the source glyphs:

Create a separate comparison file rather than overwriting the first result:

$ fonttosfnt -c -b -o /tmp/8x13-compat.ttf -- /usr/share/fonts/X11/misc/8x13-ISO8859-4.pcf.gz
$ ls -lh /tmp/8x13.ttf /tmp/8x13-compat.ttf
-rw-r--r-- 1 user user 5.1K ... /tmp/8x13.ttf
-rw-r--r-- 1 user user 5.5K ... /tmp/8x13-compat.ttf

Those sizes are representative, not fixed promises. Compare the files on your own machine and test whichever one you actually plan to deploy.

6. Handle scalable glyphs and metrics carefully

Bitmap fonts need wrapper metadata for software that expects scalable tables. -g n picks the scalable glyph strategy: 0 writes none, 1 writes only the undefined glyph, and 2, the default, writes blank glyphs for a sufficiently high range. The manual warns that 0 confuses most current software, while 1 is technically recommended but triggers a bug in current FreeType versions. Treat this as a compatibility decision, not a routine size tweak.

-m n picks scalable metrics. The default, 1, writes full metrics for one glyph and left sidebearings for the rest; 0 writes no scalable metrics, and 2 writes metrics for every glyph at a larger size. Start with the defaults unless the consuming software gives you a specific reason to try another mode.

Use a distinct output for any experiment, and verify each result:

$ fonttosfnt -g 1 -m 1 -o /tmp/8x13-g1.ttf -- /usr/share/fonts/X11/misc/8x13-ISO8859-4.pcf.gz
$ file /tmp/8x13-g1.ttf
/tmp/8x13-g1.ttf: TrueType Font data, 13 tables, 1st "EBDT", 8 names, Microsoft, language 0x409, Public domain font.  Share and enjoy.Misc FixedRegularMisc Fixed X.Org bitmap size 8x13Misc Fixe

Keep the default -g 2 when FreeType compatibility matters more than file size. If a consumer rejects the wrapper, compare a default build against one carefully documented alternative rather than changing several options at once.

7. Diagnose the common failures

A missing or unreadable input fails before any useful output appears:

$ fonttosfnt -o /tmp/missing.ttf -- /tmp/no-such-font.pcf
Couldn't open face /tmp/no-such-font.pcf.
$ printf 'exit status: %s\n' "$?"
exit status: 1

Check the path and permissions with ls -l and test -r. If the output path sits in a protected directory, write to one you own and copy the finished file through your normal deployment process; do not solve an input typo with elevated privileges.

If the command succeeds but the consuming application rejects the result, verify the output with file and fc-scan first, then test the default wrapper before touching -g, -m, encoding or alignment. Keep the original PCF or BDF file until the replacement has actually been accepted by the target application.

Done means