Two Wrongs

Variable Width Unicode Fallback Fonts in Emacs

Variable Width Unicode Fallback Fonts in Emacs

I haven’t talked about it here before, but it is important to me that all my applications are capable of rendering symbols in a typographically pleasing way. This is nearly impossible to accomplish without the use of fallback fonts, which is what any well-designed program11 Going by this requirement, almost no terminal emulators are well designed. For a while there, I honestly thought that iTerm2 on the Mac OS X was the only terminal emulator that did font fallback cleanly. I have since found one or two terminal emulators for Linux that also do it well. does when it wants to show a symbol that is missing in the current font: it picks an alternative font to use for the missing symbol – hopefully one that blends in well with the rest of the type.

For a while now, I have used just the basic built-in stuff in Emacs to deal with that. In other words,

;; Set my main variable-width font
(set-fontset-font "fontset-startup" 'unicode
    (font-spec :name "Linux Libertine O" :size 16.0))

;; Use variable-width symbol font as a fallback
(set-fontset-font "fontset-default" 'unicode
    (font-spec :name "Symbola" :size 16.0))

This is okay, but not ideal. My main problem is that for some specific ranges of characters22 Specifically, box drawing characters., I want a fixed-width font. The set-fontset-font stuff doesn’t easily let me do that unless I split my main font into a bunch of sub-ranges.

Eventually, I gave in and decided to try to use the unicode-fonts package. What it doesn’t say in the readme is that it expects Emacs to use a fixed-width font. All default fallbacks are configured with fixed-width fonts in mind.

That is ugly, so I came up with a crude solution that will have to suffice for the time being.

(use-package unicode-fonts :init
  (use-package persistent-soft :config
    (unicode-fonts-setup))
  :config
  (setq unicode-fonts-overrides-mapping
    (append '((#x0000 #xffff ("Linux Libertine O" "Symbola")))
            unicode-fonts-overrides-mapping)))

This simply overrides all default mappings for the entire basic multilingual plane33 The basic multilingual plane (the bmp, to use jargon) are the 16 bits that “ought to be enough for anybody”. Turns out human languages are so complex that we can’t even number all the symbols they use with 16 bits. No wonder some hypothesise that our brain really evolved to deal with language, and anything else it can do is just a side effect of that … with just the two choices of my main font or my fallback font. So far, that seems to do a fairly good job.

The difference from the previous solution, is that now I can simply add more overrides for certain characters, and unicode-fonts will take care of calculating how all other ranges must be adjusted.

Neat!