January 22nd 2018

linux, fonts

Fonts on Linux, Chapter One: Changing Default and Fallback Fonts with Fontconfig


I want an easy way to map the default Sans, Sans-Serif and Monospace fonts to fonts of my choice. I have seen posts on the internet where this is achieved by editing $XDG_CONFIG_HOME/.config/fontconfig/fonts.conf:

<!-- Generic name aliasing -->
<alias>
    <family>sans-serif</family>
    <prefer>
        <family>Noto Sans</family>
    </prefer>
</alias>
<alias>
    <family>serif</family>
    <prefer>
        <family>Noto Serif</family>
    </prefer>
</alias>
<alias>
    <family>monospace</family>
    <prefer>
        <family>xos4 Terminus</family>
    </prefer>
</alias>

But it didn't work!

fc-match sans
DejaVuSans.ttf: "DejaVu Sans" "Book"
fc-match anything
DejaVuSans.ttf: "DejaVu Sans" "Book"

Long story short, I have a customized setup in /etc/fonts because after infinality died, I applied this gist. Testing the waters by starting any fontconfig-using application with FC_DEBUG=1024 application:

Loading config file from /etc/fonts/fonts.conf
Scanning config dir /etc/fonts/conf.d
Loading config file from /etc/fonts/conf.d/10-hinting-slight.conf
Loading config file from /etc/fonts/conf.d/10-sub-pixel-rgb.conf
Loading config file from /etc/fonts/conf.d/11-lcdfilter-default.conf
Loading config file from /etc/fonts/conf.d/20-unhint-small-dejavu-sans-mono.conf
Loading config file from /etc/fonts/conf.d/20-unhint-small-dejavu-sans.conf
Loading config file from /etc/fonts/conf.d/20-unhint-small-dejavu-serif.conf
Loading config file from /etc/fonts/conf.d/20-unhint-small-vera.conf
Loading config file from /home/mus/.config/fontconfig/fonts.conf
Loading config file from /etc/fonts/conf.d/30-infinality-aliases.conf
Loading config file from /etc/fonts/conf.d/30-metric-aliases.conf
Loading config file from /etc/fonts/conf.d/30-urw-aliases.conf
Loading config file from /etc/fonts/conf.d/30-win32-aliases.conf
Loading config file from /etc/fonts/conf.d/31-cantarell.conf
Loading config file from /etc/fonts/conf.d/40-nonlatin.conf
Loading config file from /etc/fonts/conf.d/45-generic.conf
Loading config file from /etc/fonts/conf.d/45-latin.conf
Loading config file from /etc/fonts/conf.d/49-sansserif.conf
Loading config file from /etc/fonts/conf.d/50-user.conf    <====== !!!!!
Loading config file from /etc/fonts/conf.d/51-local.conf
Loading config file from /etc/fonts/conf.d/57-dejavu-sans-mono.conf
Loading config file from /etc/fonts/conf.d/57-dejavu-sans.conf
Loading config file from /etc/fonts/conf.d/57-dejavu-serif.conf
Loading config file from /etc/fonts/conf.d/60-generic.conf
Loading config file from /etc/fonts/conf.d/60-latin.conf
Loading config file from /etc/fonts/conf.d/65-fonts-persian.conf
Loading config file from /etc/fonts/conf.d/65-nonlatin.conf
Loading config file from /etc/fonts/conf.d/69-unifont.conf
Loading config file from /etc/fonts/conf.d/75-yes-terminus.conf
Loading config file from /etc/fonts/conf.d/80-delicious.conf
Loading config file from /etc/fonts/conf.d/81-ubuntu.conf
Loading config file from /etc/fonts/conf.d/90-synthetic.conf

I see that 50-user.conf is being applied after 30-infinality-aliases.conf. And in fontconfig, first has highest prioriy, not last. So:

sudo su -
cd /etc/fonts/conf.d
# these are just the symlinks, the actual config files are still in ../conf.avail.d
rm 10-scale-bitmap-fonts.conf # "off topic", but while I was at it I removed it.
rm 50-user.conf
cd ../conf.avail
# raising the priority of user configuration
cp 50-user.conf 21-user.conf
cd ../conf.d
ln -s ../21-user.conf

No system files were harmed in the process.

That's it, now it works:

fc-match sans
NotoSans-Regular.ttc: "Noto Sans" "Regular"
fc-match mono
ter-x12n.pcf.gz: "xos4 Terminus" "Regular"

Now I can set all my applications (GTK, tint2, openbox, conky...) to use "Sans" and "monospace" and all customization will happen through fontconfig from now on (though some applications might reject the excellent Terminus bitmap font and choose a "better" scalable font instead).

Continue to Chapter Two