Fixing Xterm font warnings

Introduction

Running xterm (or other programs that call xterm, e.g. cssh) generates the following error messages:

damson$ xterm
xterm: cannot load font "-Misc-Fixed-medium-R-*-*-13-120-75-75-C-120-ISO10646-1"
xterm: cannot load font "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1"
damson$

Pressing CTRL-MOUSEBUTTONR (i.e. hold down CTRL and press the right mouse button) and selecting any font size there will result in a new error message and that font size becoming greyed out.

Notes on what I tried and what finally worked are presented below in the hope it helps googlers!

Experimentation

Firstly, since I had not modified any settings that I thought were relevant, I checked Google and the Debian bug tracking system. I found many descriptions of this problem and many solutions (e.g. here, here and here). But none of them worked for me.

Secondly, I installed a lot of font packages in the hope that they would provide the missing fonts. I installed the following:

damson$ dpkg -l | grep font | sed -nr 's/^ii *([^ ]*font[^ ]*).*/\1/p'
fluid-soundfont-gm
fontconfig
fontconfig-config
fonts-adf-oldania
fonts-dejavu-core
fonts-freefont-otf
fonts-freefont-ttf
fonts-lmodern
fonts-opensymbol
gsfonts
gsfonts-x11
libfontconfig1:amd64
libfontconfig1:i386
libfontenc1:amd64
libxfont2:amd64
texlive-fonts-extra
texlive-fonts-recommended
ttf-mscorefonts-installer
xfonts-100dpi
xfonts-75dpi
xfonts-encodings
xfonts-scalable
xfonts-utils
damson$

and I told xorg to refresh its font caches (using a command suggested at one one of those links above):

damson$ fc-cache -fv; xset fp rehash
/usr/share/fonts: caching, new cache contents: 0 fonts, 6 dirs
/usr/share/fonts/X11: caching, new cache contents: 0 fonts, 6 dirs
/usr/share/fonts/X11/100dpi: caching, new cache contents: 358 fonts, 0 dirs
...
/var/cache/fontconfig: not cleaning unwritable cache directory
/home/alexis/.cache/fontconfig: cleaning cache directory
/home/alexis/.fontconfig: not cleaning non-existent cache directory
fc-cache: succeeded
damson$

But xterm still produced the warnings.

Thirdly, despite believing that I had not modified any settings that I thought were relevant, I checked anyway:

damson$ xrdb -query
*customization: -color
XScreenSaver.newLoginCommand: dm-tool switch-to-greeter
Xcursor.size: 16
Xcursor.theme: default
Xcursor.theme_core: 1
Xft.antialias: 1
Xft.hintstyle: hintnone
Xft.lcdfilter: lcdnone
Xft.rgba: none
damson$

Fourthy, I checked if the xterm package itself was somehow configured to use the fonts in the warning messages:

damson$ only_files() { while read X; do [ -f "$X" ] && echo "$X"; done; }
damson$ dpkg -L xterm | grep etc | only_files | \
        xargs grep -i 'misc-fixed-medium.*120.*iso10646'
/etc/X11/app-defaults/UXTerm:*VT100.font: -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1
/etc/X11/app-defaults/UXTerm:*VT100.font4: -misc-fixed-medium-r-normal--13-120-75-75-c-80-iso10646-1
/etc/X11/app-defaults/UXTerm:*VT100.font5: -misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1
/etc/X11/app-defaults/XTerm:*VT100.utf8Fonts.font: -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1
/etc/X11/app-defaults/XTerm:*VT100.utf8Fonts.font4: -misc-fixed-medium-r-normal--13-120-75-75-c-80-iso10646-1
/etc/X11/app-defaults/XTerm:*VT100.utf8Fonts.font5: -misc-fixed-medium-r-normal--18-120-100-100-c-90-iso10646-1
damson$

The first output line there is interesting: it matches one of the fonts that xterm complains about but is a setting for the uxterm command, not for the xterm command. (In fact, uxterm is a thin wrapper around xterm but using a different X resource class set.)

Fifthly, I started playing with the settings on the various CTRL-MOUSEBUTTON* menus. Enabling TrueType Fonts fixes the problem! There is a no direct option to do this from the command line but it can be done using command-line-specified X resources:

xterm -xrm 'XTerm*renderFont: true'

But that also doesn’t work and also greys out the ‘TrueType Fonts’ in that menu. The man page kind of explains this:

renderFont (class RenderFont)
 
If xterm is built with the Xft library, this controls whether the faceName 
resource is used. The default is “default”.
...
true    startup using the TrueType font specified by the faceName and 
        faceSize resource settings. If there is no value for faceName, 
        disable the feature and use the normal (bitmap) font.

I.e. attempting to enable TrueType fonts without also specifying some other resources will actually disable TrueType fonts!

The simplest solution is hinted to in the man page:

faceName (class FaceName)
 
Specify the pattern for scalable fonts selected from the FreeType library if 
support for that library was compiled into xterm. There is no default value.
...
However (even though xfd accepts a “-fa” option to denote FreeType fonts), 
xfontsel has not been similarly extended. As a workaround, you may try

    fc-list :scalable=true:spacing=mono: family

On my machine (with the fonts that I have installed) that command reports this:

damson$ fc-list :scalable=true:spacing=mono: family
Andale Mono
DejaVu Sans Mono
Courier 10 Pitch
Nimbus Mono L
Courier
Courier New
FreeMono
damson$

To work out which was the best of those, I ran:

fc-list :scalable=true:spacing=mono: family | while read FONTNAME; do 
    xterm -title "$FONTNAME" \
        -xrm "XTerm*faceName: $FONTNAME" \
        -xrm "XTerm*InitialFont: 4" & 
done

(XTerm*InitialFont: 4 is the equivalent of selecting Medium from the CTRL-MOUSEBUTTOMR menu.)

I decided that ‘DejaVu Sans Mono’ looked best.

Solution

To make the setting permanent within my login session I ran:

echo 'XTerm*faceName: DejaVu Sans Mono' | xrdb -merge

To make the setting permanent across login sessions depends on what your X session type is and what the associated system config files do. In my own case, with my X session type set to ‘Xsession’, I just needed to add the setting the ~/.Xdefaults file and add the loading of that file into my X session startup script (~/.xsession):

echo 'XTerm*faceName: DejaVu Sans Mono' >> ~/.Xdefaults

and to insert in ~/.xsession at a suitable point:

damson$ cat ~/.xsession
#!/bin/bash
...
xrdb -merge ~/.Xdefaults
...
exec xfce4-session
damson$

I could test whether ~/.Xdefaults exists before trying to load it but it’s not really worth it: the resulting error message …

xrdb: No such file or directory
xrdb: can't open file '/home/alexis/.Xdefaults'

… is redirected to ~/.xsession-errors.

See also