Extract PostScript Font Metrics with printafm
printafm pulls an Adobe Font Metrics (AFM) file out of an installed PostScript font, something an old typesetting pipeline quietly depends on. This covers finding a usable font name, generating the file without clobbering an old one, and checking the result actually has the markers it should. The examples use printafm from Ghostscript 10.02.1, package version 10.02.1~dfsg1-0ubuntu7.9.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell, the ghostscript package, and an installed Type 1 PostScript font. Apart from writing the output file, this is a read-only inspection, so it normally needs no elevated privileges.
1. Check the installed command
Confirm which script will run and record the Ghostscript version. These are ordinary read-only checks:
$ command -v printafm
/usr/bin/printafm
$ dpkg-query -W -f='${Package} ${Version}\n' ghostscript
ghostscript 10.02.1~dfsg1-0ubuntu7.9
$ gs --version
10.02.1
The exact package suffix is distribution-specific; what matters for this guide is the Ghostscript release, since the local printafm(1) manpage was revised for version 10.02.1. The wrapper invokes Ghostscript in quiet, non-display mode and sends the AFM text to standard output.
Checkpoint
If command -v printafm prints nothing, install or enable Ghostscript through your normal package process before continuing. Do not copy a script from another machine just to make the command appear.
2. Find a font name that Ghostscript can use
printafm takes exactly one argument, fontname. It does not take a directory and it will not pick a default font for you. Start by locating a local Type 1 font file:
$ find /usr/share/fonts -type f \( -iname '*.pfb' -o -iname '*.pfa' \) | head -n 5
/usr/share/fonts/X11/Type1/NimbusSansNarrow-Bold.pfb
/usr/share/fonts/X11/Type1/c0611bt_.pfb
/usr/share/fonts/X11/Type1/URWBookman-Light.pfb
/usr/share/fonts/X11/Type1/D050000L.pfb
/usr/share/fonts/X11/Type1/URWBookman-DemiItalic.pfb
Use the font's PostScript name for the first example, NimbusSansNarrow-Bold, rather than the .pfb pathname. Ghostscript's font lookup resolves that name on this installation. Font names are case-sensitive in practice, and the name embedded in a filename is not always the internal PostScript name, so do not guess when a lookup fails.
An empty result from that search means your machine has no Type 1 fonts in that directory: check the font package and its install locations. A TrueType or OpenType font is not automatically a valid input here just because some other program can render it.
3. Generate an AFM file without overwriting an old one
AFM output goes to standard output. Redirect it to a new pathname so the diagnostic stream stays visible in the terminal:
$ printafm NimbusSansNarrow-Bold > NimbusSansNarrow-Bold.afm
$ printf 'exit status: %s\n' "$?"
exit status: 0
Safety boundary
The redirection operator creates the file before the program even starts, and truncates an existing file with the same name. That is the main destructive trap in this workflow. If the destination already holds useful metrics, choose a new name first, or make a backup:
$ cp --preserve=all NimbusSansNarrow-Bold.afm NimbusSansNarrow-Bold.afm.bak
$ printafm NimbusSansNarrow-Bold > NimbusSansNarrow-Bold.afm.new
$ mv NimbusSansNarrow-Bold.afm.new NimbusSansNarrow-Bold.afm
That last command only replaces the old file once generation has succeeded. If generation fails, remove the incomplete .new file and keep the original. Deleting the backup later is irreversible, so only do that once you have checked the replacement.
Checkpoint
The command should produce no normal terminal output, since the AFM text went to the file. A zero exit status means Ghostscript completed; it is still worth checking the file content next.
4. Verify the AFM structure
An AFM file is plain text. Inspect its opening records and closing marker:
$ sed -n '1,16p' NimbusSansNarrow-Bold.afm
StartFontMetrics 2.0
FontName NimbusSansNarrow-Bold
ItalicAngle 0.0
Weight Bold
Notice (URW)++,Copyright 2014 by (URW)++ Design & Development
IsFixedPitch false
Version 1.00
Copyright Copyright (URW)++,Copyright 2014 by (URW)++ Design & Development
UnderlineThickness 50
FamilyName Nimbus Sans Narrow
FullName Nimbus Sans Narrow Bold
UnderlinePosition -100
FontBBox -144 -307 1000 1094
StartCharMetrics 854
C 32 ; WX 228 ; N space ; B 228 0 228 0 ;
$ tail -n 3 NimbusSansNarrow-Bold.afm
EndCharMetrics
EndFontMetrics
Exact metadata and character count depend on the font you chose. Check the markers rather than comparing every line against this example:
$ grep -E '^(StartFontMetrics|FontName|StartCharMetrics|EndCharMetrics|EndFontMetrics)' NimbusSansNarrow-Bold.afm
StartFontMetrics 2.0
FontName NimbusSansNarrow-Bold
StartCharMetrics 854
EndCharMetrics
EndFontMetrics
If the file is empty or lacks EndFontMetrics, treat the run as failed, even if a later script happens to accept the partial file. Keep the source font installed and rerun with its correct PostScript name.
Common traps
No argument given. Running the command bare prints usage instead of picking a default font:
$ printafm
Usage: printafm fontname
Guessed font name. A wrong name produces a Ghostscript error and a non-zero status. Capture the diagnostic in a temporary file while you test:
$ printafm NOT_A_REAL_FONT > /tmp/printafm-test.afm 2> /tmp/printafm-test.err
$ status=$?
$ printf 'exit status: %s\n' "$status"
exit status: 1
$ sed -n '1,8p' /tmp/printafm-test.err
Wording can vary with the Ghostscript build; the useful evidence is a non-zero status and an error naming the unresolved font or PostScript problem. Do not reach for sudo to fix a font lookup failure: elevated privileges do not invent a font name, and running as root can leave the generated file owned by root instead of you.
Once you have finished with a temporary diagnostic, remove it if it holds nothing you need; it is not part of the AFM workflow. No service restart, font-cache rebuild or system configuration change is needed to pull metrics out of a font Ghostscript can already resolve.
Done means
- Version checked.
printafmand its Ghostscript package version were confirmed. - Real font name used. One actual PostScript font name was supplied, not a default.
- Output path chosen deliberately. The AFM text was redirected somewhere on purpose.
- Structure verified. The output has matching
StartFontMetricsandEndFontMetricsmarkers. - Old file protected. An existing metrics file was never at risk of silent truncation, or can be restored from backup.
- No privilege or config changes. Nothing elevated or persistent was required.