Fixing My Missing Degree Celsius Symbol

For years OpenWeather has been my favorite GNOME extension for quick and beautiful weather information. However today when I looked at my top bar again for weather, I had the impression as if something is missing:

And this is what it used to be like:

My degree Celsius symbol is missing!

Finding the culprit

The first thing I thought was, is this specific to OpenWeather? And I was surprised to find out that when I googled “degree Celsius symbol”, the °C as U+00B0 ° degree sign plus U+0043 C latin capital letter c is present, while ℃ as U+2103 ℃ degree celsius is simply empty. However a <span> with font-family: serif on Wikipedia showed the symbol correctly, so this must be a font/fontconfig issue.

And I lessed my own fontconfig configuration with /etc/fonts/local.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<match>
<test name="family"><string>sans-serif</string></test>
<edit name="family" mode="prepend" binding="strong">
<string>WenQuanYi Micro Hei</string>
<string>WenQuanYi Zen Hei</string>
<string>WenQuanYi Bitmap Song</string>
<string>DejaVu Sans</string>
<string>Noto Color Emoji</string>
</edit>
</match>
<match>
<test name="family"><string>serif</string></test>
<edit name="family" mode="prepend" binding="strong">
<string>DejaVu Serif</string>
<string>WenQuanYi Bitmap Song</string>
<string>WenQuanYi Zen Hei Sharp</string>
<string>AR PL UMing CN</string>
<string>AR PL UMing TW</string>
<string>AR PL New Sung</string>
<string>Noto Color Emoji</string>
</edit>
</match>
<match>
<test name="family"><string>monospace</string></test>
<edit name="family" mode="prepend" binding="strong">
<string>WenQuanYi Micro Hei Mono</string>
<string>WenQuanYi Zen Hei Mono</string>
<string>WenQuanYi Bitmap Song</string>
<string>DejaVu Sans Mono</string>
<string>Noto Color Emoji</string>
</edit>
</match>
</fontconfig>

So the different order of font families in sans-serif and serif might be the issue. I googled a while for finding out the font selected by fontconfig for a glyph, and found an article suggesting the use of FC_DEBUG and pango-view:

1
FC_DEBUG=4 pango-view -q --font='<YOUR_FONT_FAMILY>' -t '<YOUR_CHARACTER>' 2>&1 | grep -o 'family:"[^"]\+' | cut -c 10- | tail -n 1

The latter part basically filters out the last printed family name from the tedious debug output. And when I run this for my degree Celsius symbol (), I found:

What’s wrong with WenQuanYi Micro Hei? I’ve been using it for years, and now it’s giving me nothing for degree Celsius symbol? And why did fontconfig ever choose it seemed to have no such glyph?

Confused by this I opened my wqy-microhei.ttc with FontForge, and was again surprised to find out that my WenQuanYi Micro Hei is providing an empty glyph (instead of nothing) for certain codepoints!

This is crazy, and I’m left wondering how my degree Celsius symbol ever worked in the past few years.

Finding the way to fix it

There must be some configuration that allow me to blacklist certain glyphs in a font. And after another round of digging around, I found some interesting results.

The first one is a bug on fontconfig Bugzilla which requested such support back in 2006 and was marked fixed in 2011. Feeling excited, I scrolled down and found a single line of comment from the dev:

This is fixed in master with target=scan charset editing.

After all the hard work, why didn’t he or she celebrate the moment of closing this bug with a more detailed explanation, or at least a helpful pointer? Even after reading though man fonts-conf, I found nothing describing how I can edit the charset of a font family. After all, the <charset> element says it must contain one or more integer, however the whole charset normally contains a huge amount of hexadecimal integers.

So I searched harder and found another answer on StackOverflow. It suggested an undocumented way of configuration that’s mentioned somewhere in a RedHat bug thread, which was its only appearance on the whole Internet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<match target="scan">
<test name="family" compare="not_eq">
<string>VL Gothic</string>
</test>
<edit name="charset" mode="assign">
<minus>
<name>charset</name>
<range>
<int>0x0021</int>
<int>0x00FF</int>
</range>
</minus>
</edit>
</match>

This is just what i wanted! So I happily applied this to my mischievous WenQuanYi Micro Hei, changing the compare to "eq" and setting the range to include 0x2103 (My precious degree Celsius symbol). Finally, sudo fc-cache -f && fc-cache -f! [sigh of relief]

Nope.

This could have worked, in some time of the history, but is not working for now, on my latest Arch Linux installation.

No.

But wait. I did saw something mentioning, we have a <charset> element and it must contain some integers? So I started to coin my own solution (You should also do the same for WenQuanYi Micro Hei Mono):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<match target="scan">
<test name="family">
<string>WenQuanYi Micro Hei</string>
</test>
<edit name="charset">
<minus>
<name>charset</name>
<charset>
<int>0x2103</int>
<int>0x2109</int>
<int>0x212B</int>
<int>0x2164</int>
<int>0x2169</int>
</charset>
</minus>
</edit>
</match>

sudo fc-cache -f && fc-cache -f, pango-view again to confirm, and Alt+F2 r to restart my GNOME shell. It worked! After all these hours, my degree Celsius symbol is back and alive again!

A final note

The above solution is only a workaround, and to actually fix this, The Wenquanyi Micro Hei font itself should be patched. In fact this was what I first tried when I surprisingly found out those empty glyphs.

However, when I went to wenq.org, there latest update was posted in late 2011 (We are in 2018 now), and their forum is giving me a blank page with certain resources returning 404. Their SourceForge issue tracker is also unattended for years with that notorious hangul advance bug still open. Sadly, the whole project seems dead. So I decided to work around instead of fixing this.

And one sentence I encountered during my search kept lingering in my mind:

When you gaze long into fontconfig, fontconfig also gazes into you.

Update: With another link on their official website, I was able to find their real bug tracker and this bug, and a similar bug. The dev said it’s fixed, but maybe some recent fontconfig or freetype changes brought it back. Maybe some day I should fork it and try to actually fix these bugs.

And according to the dev’s comment, those glyphs existed in Droid Sans Fallback, so a proper fix to my configuration should also include adding Droid Sans Fallback to the sans-serif and monospace families, right below the WenQuanYi Micro Hei entry.