2011-08-06

How to set up nicely hinted default fonts on Linux

This blog post explains how to set up a per-user default font configuration under Linux (tested on Ubuntu Lucid), which contains easy-to-read fonts in small sizes and properly hinted rendering.

Install the Microsoft core fonts (e.g. Times New Roman, Arial, Courier New), using the following command (without the $ sign):

$ sudo apt-get install msttcorefonts

Create (or overwrite) the file ~/.fonts.conf with the following contents:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>

<!-- Accept bitmap fonts -->
  <selectfont>
    <acceptfont>
    <pattern>
      <patelt name="scalable"><bool>false</bool></patelt>
    </pattern>
    </acceptfont>
  </selectfont>

<!--  Enable proper hinting (medium) and disable subpixel rendering (rgba=none)
      for the Microsoft Core fonts (msttcorefonts) with high quality hints.
  --> 
  <match target="font">
    <test name="family"><string>Andale mono</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Arial</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Arial Black</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Comic Sans MS</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Courier New</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Georgia</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Impact</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Times New Roman</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Trebouchet MS</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Verdana</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>Webdings</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>

<!--  Just a safe bet: enable proper hinting for the DejaVu font family.
      Bitstream Vera is not shipped on Ubuntu Lucid anymore (but there was a
      package on Ubuntu Hardy).
  --> 
  <match target="font">
    <test name="family"><string>DejaVu Sans</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>DejaVu Sans Mono</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>DejaVu Sans,DejaVu Sans Condensed</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>DejaVu Sans Condensed</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>DejaVu Sans,DejaVu Sans Light</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>DejaVu Sans Light</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>DejaVu Serif</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>DejaVu Serif,DejaVu Serif Condensed</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>
  <match target="font">
    <test name="family"><string>DejaVu Serif Condensed</string></test>
    <test name="pixelsize" compare="more"><double>7.5</double></test>
    <edit name="hinting"><bool>true</bool></edit>
    <edit name="hintstyle"><const>hintmedium</const></edit>
    <edit name="rgba"><const>none</const></edit>
  </match>

<!-- Set font family preferences for Firefox. Chrome seems to ignore these.
     Please note that /etc/fonts/conf.d/60-latin.conf has more defaults, which
     we don't have to repeat here.
  -->
  <alias><family>serif</family><prefer>
    <family>Times New Roman</family>
  </prefer></alias>
  <alias><family>sans-serif</family><prefer>
    <family>Arial</family>
  </prefer></alias>
  <alias><family>monospace</family><prefer>
    <family>DejaVu Sans Mono</family>
  </prefer></alias>
</fontconfig>

The hintmedium setting above is especially important, because it turns on the proper hinting for Times New Roman etc., which makes these fonts easy to read at small sizes. The default is slight hinting (instead of medium), which is wrong, and it remains wrong (because of a bug) even if you select it at System / Preferences / Appearance / Fonts / Details / Hinting / Medium. The proper way to get the medium hinting is to write a ~/.fonts.conf file, as above.

After changing ~/.fonts.conf log out and back in, or restart all applications for the changes to take effect.

Google Chrome doesn't pay attention to the default fonts specified in ~/.fonts.conf. In Chrome, visit chrome://settings/fonts, and change the defaults to:

  • Standard Font: Times New Roman
  • Serif Font: Times New Roman
  • Sans Serif Font: Arial
  • Fixed-Width Font: DejaVu Sans Mono

You may want to change the window title and dialog box fonts as well. You can do that in System / Preferences / Appearance / Fonts. See this blog post for some crisp (i.e. non-antialiased), small font size defaults. Don't forget to install the FixedSC and Helxetica fonts first, as documented there.