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>monospace</family>
	<prefer>
		<family>Hack</family>
		<family>Monoid</family>
	</prefer>
	<default>
		<family>DejaVu Sans Mono</family>
	</default>
</alias>

When selecting the fontconfig alias “Monospace”, the actual typeface is, in order of priority from top to bottom: Hack, Monoid. If none of these are installed or available, then “DejaVu Sans Mono” 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-hack fonts-roboto fonts-dejavu fonts-dejavu-extra fonts-noto-color-emoji xfonts-terminus 

Honourable mentions:

fonts-monoid fonts-firacode

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 script that sets up MATE Terminal, own_script_mate_terminal_setup, uses conditional logic to determine which typeface to use at its optimal point size. If Hack is available, then it is defined as the default at size 10. Else the script checks for Monoid and defines it at 9pt. Otherwise defaults to the generic “Monospace” alias at 10 point size. This should give you the DejaVu Sans Mono typeface. All this is done in an effort to use each typeface at its optimal point size.

Similar logic applies to the custom UI font which is used in my various dmenu implementations. This is my_custom_ui_font.sh which is included in my dotfiles at bin/.local/share/.

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. Letters with fine details can become the standard when our displays have a pixel density that is at least good as printed text.
  • 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”.