Font oddities: DejaVu Sans Mono, hinting, GNOME, and Evolution
Here's a fun yak shave I had this morning!
I started out running pylint on fedfind and finding several cases where it said my hanging indents were off. When I looked at the column count instead of eyeballing them, indeed they were - but when I matched the column count, it didn't look right at all.
After scratching my head for a bit, I figured it out. gedit bolds certain things when doing syntax highlighting. I've been using Droid Sans Mono as my monospace font. That doesn't have a bold version, so fontconfig asks freetype to generate one artificially. When freetype generates a bold version of a font, it doesn't match the glyph widths.
I'm not the first person to notice this.
There are various ways I could deal with this, but I'm not a huge font geek so the first thing I thought was 'eh, I'll just change fonts'. I looked through the list for ones which have matching glyph widths when bolded, and found that Liberation Mono and DejaVu Sans Mono seem to fit the bill. I don't really like Liberation much, and DejaVu Sans Mono is the Fedora default, so I figured I'd go with that.
Then I remembered one of the things that caused me to switch away from it in the first place: it seemed like when I used it, my monospace text in Evolution looked completely different from anything else. So dramatically different I thought it was some kind of bug causing the wrong font to be used.
After poking around at it for a bit, though, it turns out it's subtler than that. With Fedora's font libraries, at 96dpi, at 11 point size, DejaVu Sans Mono looks drastically different with 'medium' hinting compared to how it looks with 'slight' hinting. Here's medium:
And here's slight:
Crazy, huh? After fiddling around with settings for a bit, I figured I was seeing slight hinting in gedit and GNOME Terminal and Firefox, but medium hinting in Evolution. From there it was but a short leap to figure out that...Evolution doesn't respect GNOME's font configuration.
I was tweaking the settings in GNOME Tweak Tool's Fonts pane. You can set the desired hinting and antialiasing configuration here, as well as default font faces and sizes. I don't know the details of what this is actually setting and how exactly GNOME applies it to applications, but it seems like just about everything picked it up...except Evolution. Fedora's default setting is medium, but I much prefer slight; medium distorts things too much for me. (There's an obvious bug where the dot on the lower-case 'i' character in the Ubuntu font doesn't match with the stem, for instance). So I'd been setting it to Slight. All along, I'd been seeing different hinting in Evolution to everything else, but it just happens it wasn't totally obvious for anything but the monospace font.
As it happens, once I figured out what was going on, I knew the way to force Evolution to use slight hinting too: configure it at the fontconfig level. I created a file /etc/fonts/conf.d/99-happyassassin-slight-hint.conf
(following my personal convention of putting 'happyassassin' in every site config file, and numbering it 99 so all the rules which disable hinting entirely for specific fonts override it) with this content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE fontconfig SYSTEM "../fonts.dtd">
<fontconfig>
<!-- /etc/fonts/conf.d/99-happyassassin-medium-hint-dejavu-sans-mono.conf
Use slight hinting for all (except overridden later).
-->
<match target="font">
<edit name="hintstyle">
<const>hintslight</const>
</edit>
</match>
</fontconfig>
and boom, now Evolution uses slight hinting too. All my fonts look consistent between Evo and everything else, and I can use DejaVu Sans Mono without being irritated by the discrepancy.
There's just one problem remaining...I actually kinda like how DejaVu Sans Mono looks with medium hinting! (though honestly, the look with 'slight' seems truer to the font in general; it's just a bit tall for my liking). But I haven't yet figured out a way to make the system use medium hinting just for that font, but slight for everything else. You can express it in fontconfig configuration, but I think GNOME's setting seems to be a universal one that overrides the fontconfig one, so doing so has no effect as the GNOME value overrides it for most apps (the ones that respect GNOME's setting). I haven't checked into that in detail, though, so I may be off the mark there too.
So after all that I can get back to re-indenting my code. :)
Edit: Here's an alternative 'fix': create a font config file (mine's /etc/fonts/conf.d/99-happyassassin-disable-mono-bold.conf
) with this content:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
Disable artificial bold for fixed-width fonts
-->
<match target="font">
<!-- don't embolden fixed-width, as it changes the width -->
<test name="spacing" compare="eq">
<const>mono</const>
</test>
<edit name="embolden" mode="assign">
<bool>false</bool>
</edit>
</match>
</fontconfig>
I believe this may not affect apps that use Xft directly, but it at least fixes it for most apps. This disables the synthetic emboldening feature for fixed-width fonts. In a way it's 'cleaner' to adjust 90-synthetic.conf
to not apply to fixed-width fonts, but the problem with that is it'll get overridden when your distro updates fontconfig. I have submitted a patch to 90-synthetic.conf
upstream for discussion.
Comments
Like I said specifically for DejaVu Sans Mono I actually prefer the medium rendering. But nothing else looks better with medium, to me. DejaVu Sans regular (not mono) doesn't look anything like the mono font with medium hinting. If everything looked like DSM with medium, that'd be one thing, but nope.