GNOME Terminal Antialiasing Saga

Previously.

On lower-DPI displays, I like to use bitmap fonts in my terminals and text editors. I was surprised to see that Gnome Terminal still antialiased and hinted my bitmap font:

Gnome terminal making stuff blurry

Here’s a close-up:

Enlargement of antialiasing

The red text is obvious, but you can also see tinges of blue and red on the white text. Not pretty.

Other platforms make it easy to get the desired behavior. Both Terminal.app and PuTTY have checkboxes to disable antialiasing and subpixel hinting. But (as anyone familiar with Gnome would expect) Gnome Terminal has no GUI setting to change this.

To solve the problem, I delved into fontconfig. My goal was to disable antialiasing for just one font. I created ~/.fonts.conf and filled it with some guesses based on docs and related Stack Overflow answers:

<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
  <match target="pattern">
    <test name="family">
      <string>ProggyTinyTTSZ</string>
    </test>
    <edit mode="assign" name="antialias">
      <bool>false</bool>
    </edit>
    <edit mode="assign" name="hinting">
     <bool>false</bool>
    </edit>
  </match>
</fontconfig>

This had no effect. I re-read some fontconfig docs and noticed that ~/.fonts.conf had been deprecated for a new config path: ~/.config/fontconfig/fonts.conf. I moved the config file. Still no change.

After reading more fontconfig docs, I found out about FC_DEBUG:

To help diagnose font and applications problems, fontconfig is built with a large amount of internal debugging left enabled. It is controlled by means of the FC_DEBUG environment variable.

Surely, debug logging would give me some clues. Naturally, this variable wasn’t just a boolean:

The value of this variable is interpreted as a number, and each bit within that value controls different debugging messages.

I tried setting FC_DEBUG to 35 (0b0100011), corresponding to verbose info for caching & matching. It turns out that verbose logging lives up to its name:

ggreer@zinc:~% FC_DEBUG=35 fc-match -v ProggyTinyTTSZ family antialias hinting file | wc -l
29771

That’s right: almost 30,000 lines of debug logs— almost as useless as no logs. I played with other values, eventually settling on FC_DEBUG=4. That generated “only” 5,000 lines and seemed to contain some useful clues.

The first thing I noticed when scouring the debug logs was that many settings were being processed after my user config. I traced this down to the order of config files in /etc/fonts/conf.d/. The rule to load user configs was in the middle, not at the last thing done. To ensure no global config was overriding my directives, I ran sudo mv 50-user.conf 99-user.conf. Debug logs then confirmed that my rules were run last.

Still, I saw blurry text.

At this point, I’d been at it for almost two hours. I was getting pretty frustrated. With nothing better coming to mind, I stared at my XML. I tediously compared it against examples in the fontconfig docs. I saw one suspicious line: I was using <match target="pattern">, while many examples used <match target="font">. I changed the target attribute from “pattern” to “font”:

<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
  <match target="font">
    <test name="family" qual="any" compare="eq">
      <string>ProggyTinyTTSZ</string>
    </test>
    <edit mode="assign" name="antialias">
      <bool>false</bool>
    </edit>
    <edit mode="assign" name="hinting">
     <bool>false</bool>
    </edit>
  </match>
</fontconfig>

…and was finally rewarded with pixel-perfect text:

Gnome terminal with correctly rendered fonts

A close-up:

Enlargement of no antialiasing

Finally!

This is yet more evidence of how ridiculously hostile Gnome is to users. I’m no novice, but it took me two hours to accomplish what takes two seconds on every other platform. What a waste.



When commenting, remember: Is it true? Is it necessary? Is it kind?


Go dark.