Protesilaos Stavrou
Philosopher. Polymath.

Fonts and their configs

Prot's Dots For Debian - Book index

Typography is essential to a good computing experience. I would even argue that type is the irreducible factor of a computer’s user interface. But let’s keep things in focus: good fonts are essential to a setup that strongly emphasises the use of a text terminal.

My opinionated font-related settings are stored in my dotfiles’ “fontconfig” directory (stow package). These take precedence over system-wide defaults that are defined in /etc/fonts/.

~/cpdfd $ tree -aF fontconfig/
fontconfig/
└── .config/
	└── fontconfig/
		├── conf.d/
		│   ├── 10-hinting-full.conf
		│   ├── 10-sub-pixel-rgb.conf
		│   ├── 11-lcdfilter-default.conf
		│   ├── 20-unhint-small-hack.conf
		│   ├── 45-generic.conf
		│   ├── 45-latin.conf
		│   ├── 50-enable-terminus.conf
		│   ├── 60-generic.conf
		│   ├── 60-latin.conf
		│   ├── 80-condensed-large-dejavu.conf
		│   └── README
		└── fonts.conf

3 directories, 12 files

The fonts.conf includes basic rules for adding emoji character support to all generic font family definitions: serif, sans-serif, monospace.

Inside conf.d we find the important rules (sorry, I do not really care about emoji). Some file names will suggest what each rule is about. For example, 50-enable-terminus.conf overrides the default settings that disable fixed-size typefaces (bitmap fonts).

The file 20-unhint-small-hack.conf applies to the “Hack” typeface. It concerns small point sizes. This rule serves mostly as an example, but also because that family is my preferred choice of monospaced font. You can copy and then edit the rule to match whatever typeface fails to display properly at certain point sizes.

On the other end, 80-condensed-large-dejavu.conf will substitute the default DejaVu fonts for Serif and Sans with their condensed equivalents. This makes either DejaVu variant better as a fallback font for UI elements and long form texts, because it removes the rivers of white space that run through its widely-spaced letter forms.

The file names that start with “45” attribute a generic family to each typeface. For example, I assign “Hack” to the “monospace” group.

While the “60-*” rules concern the priority of font selection. Here is a snippet of XML that I will explain:

<alias>
	<family>sans-serif</family>
	<prefer>
		<family>Roboto</family>
		<family>Noto Sans</family>
		<family>Liberation Sans</family>
	</prefer>
	<default>
		<family>DejaVu Sans</family>
	</default>
</alias>

When selecting the fontconfig alias “sans-serif” (or just “Sans”), the actual typeface is, in order of priority from top to bottom: Roboto, Noto Sans, Liberation Sans. If none of these are installed or available, then DejaVu Sans shall be used instead.

As already discussed in the chapter about installing core packages, these are the fonts I use and consider solid defaults:

sudo apt install fonts-firacode fonts-hack fonts-roboto fonts-dejavu fonts-dejavu-extra fonts-noto-color-emoji fonts-symbola xfonts-terminus

Note that fonts-symbola is mostly required to display symbols in terminals that have trouble with ambiguous characters.

Modifying the font configurations

My settings are tailored to my hardware and aesthetic preferences. I strongly encourage you to spend some time inside my conf.d to get a sense of how things work. For more, run man fonts-conf. Settings provided by Debian, are stored at /usr/share/fontconfig/conf.d/, while the applicable rules are defined in /etc/fonts/conf.d/.

Graphical applications read the configuration files that are specific to their toolkit. I only have GTK apps, so we get these files:

~/cpdfd $ tree -aF gtk
gtk
├── .config/
│   ├── gtk-3.0/
│   │   └── settings.ini
# Irrelevant files
├── .gtkrc-2.0
# More files that do not concern fonts

You only need to check .gtkrc-2.0 and the GTK3 settings.ini. The default typeface is the fontconfig alias “sans” at 10 point size. If you have followed the instructions in the chapter about installing core packages, “Sans” or “Sans-serif” should stand for “Roboto” (package is fonts-roboto).

The panel (top bar) only supports bitmap fonts, as explained in the chapter about the top panel. It is configured to use Terminus (xfonts-terminus) else fall back to whatever the “fixed” typeface is.

The notification daemon—dunst—uses “Sans-10”, in large part because its configuration file is static and cannot run shell logic. A sans-serif font is the safest default. Besides, notifications can display a big chunk of text, where a monospaced font will make the notification’s box expand out of proportion. We want them to be discreet.

All the above notwithstanding, you should know that not all applications out there will faithfully follow your rules. For example, Flatpak apps will use their own settings because they do not read from the user’s font configurations. Graphical tools that are launched with escalated privileges will read from the root user’s configs. And so on.

What makes a good choice of font

Some closing notes on the criteria that determine the choice of my default typefaces: Hack and Roboto.

  • Good unicode coverage. Support extended latin and greek glyphs at minimum.
  • Have at least two weights: regular and bold. Ideally, also support true italics, or at least oblique forms with some effort put into them, rather than some procedurally generated slanted variant of the regular letters.
  • Be legible at small point sizes. Do not create rivers of white space that flow through the text at larger sizes.
  • Have good typographic colour. In other words, do not have too thin letter forms. Typefaces that are too thin are harder to read, make colours less distinct from each other, while they tend to create a certain “halo effect” around letter forms when using them against a light backdrop.
  • Do not have a very high x-height. I need to easily tell apart miniscules from majuscules.
  • Do not rely too much on serifs and fine details. Such letters can become the standard when our displays have a pixel density that is at least as good as printed text. Until then, they can be hard to read in certain conditions.
  • For monospaced fonts: all vaguely similar glyphs should be easy to tell apart, such as 0, o, O, i, I, l, L 1, s, 5
  • Be available in Debian’s main archives. Comply with Debian’s Free Software Guidelines.

All this can be summarised as “do not be frivolous; be frugal, be accessible, and get the job done”.

ANNEX on Xterm fonts

You will notice that I recommend installing fonts-firacode. This is the typeface I use inside my terminal emulator (Xterm), because it has excellent support for box-drawing capabilities, which is particularly important for tmux.

Xterm has a very rare bug that you will only encounter if you use Greek letters and only with certain font and point size combinations. I have submitted a detailed report on the Greek pi (π) and box-drawing bug.

The bug notwithstanding, I have made sure that my .Xresources includes the necessary settings that work around this problem. As such, “Hack” and “DejaVu Sans Mono” will cope just fine with all typography-related requirements inside of Xterm.