Certain font faces aren't working

I recently upgraded to Anki 2.1.26 from 2.0, on Windows 10.

I’m using a Chinese font face called “AR Mingti Medium B5S” for one of my decks which uses simplified character glyphs for traditional character codepoints.

In Anki 2.0, if I select “AR Mingti Medium B5S” from the font selection dropdown in the “Fields” dialog, it displays just fine in the editor. And if I use font-family: "AR Mingti Medium B5S" in the card CSS then it works properly there too.

But in Anki 2.1 this doesn’t work, both the card and the editor render with a fallback font instead. If I look at the font details in Windows, it turns out that the font family is actually just “AR Mingti B5S”, and using this in the CSS makes it work again. I assume this is actually the more correct/standard behaviour (because you usually specify weight and similar stuff with other CSS properties, and the browser/webview automatically chooses which specific face to render with based on that).

However in the fields dialog I can still only select “AR Mingti Medium B5S”, and it just renders in the default fallback font (SimSun I believe). This also applies to “Add field” dialog in the template editor, which as a result will insert “AR Mingti Medium B5S” into the inline style (which as I said doesn’t work).

It’s not just this font I’m using either, any other family will have all its individual faces listed separately in the dropdown. But not all faces display the issue, e.g. if I select “Noto Sans CJK SC Regular” or “Noto Sans CJK SC Medium” it will work, in both the editor and on the cards (even though the font family is simply “Noto Sans CJK SC”), but “Noto Sans CJK SC Bold” won’t.

This is unfortunately caused by different parts of the GUI toolkit not being consistent. As a workaround, you could make a small add-on to replace the incorrect (old) font name with the one that the webview expects to get the font working correctly in the editor:

def change_name(font):
  return font.replace("oldname", "newname")

from aqt import gui_hooks

Yeah I did a little more digging/debugging and it seems that Qt is just weird. When you retrieve the “family” here, it doesn’t actually get the family at all, just returns the name of the individual font. According to the QFont docs:

The corresponding “get” functions, e.g. family(), pointSize(), etc., return the values that were set, even though the values used may differ. The actual values are available from a QFontInfo object.

That sounded promising, but when I used QFontInfo in the debug console it just returned the same thing. I’m thinking it may have been an intentional design decision for some unknown reason. So it doesn’t seem like there’s any (non-hacky) way currently to fix it from this angle. Maybe there needs to be a request to Qt to add a “realFamily” getter.

On the other side of things is the WebEngine behaviour. It will happily render the specified font with font-family: "Noto Sans CJK SC Medium" but not font-family: "Noto Sans CJK SC Bold" (even though it does in Anki 2.0). Specifying:

font-family: "Noto Sans CJK SC";
font-weight: bold;

will use the bold variant as expected though, so it’s not as if there are glyphs missing or something. I thought maybe specifying:

font-family: "Noto Sans CJK SC Bold";
font-weight: bold; // Or some other weight

might work (maybe it didn’t want to use the font when the weight is default), but it doesn’t, no matter what weight you choose.

Actually Chrome does the same thing, and WebEngine uses Chromium, so this is clearly an upstream thing. I don’t know if there’s any chance of this behaviour changing/being fixed.

Found a filed (and closed) issue here: https://bugreports.qt.io/browse/QTBUG-56398

They said that WebEngine behaviour matches spec and suggested just using manual string manipulation to account for QFont’s behaviour :confused:

1 Like

Some more research led to me to this commit which landed in Qt 5.15: https://codereview.qt-project.org/c/qt/qtbase/+/283096

So I tried Anki 2.1.28-alpha3 because it uses that version of Qt: the font selection dropdown has less individual variants/faces because they’ve presumably been properly merged into their respective families (whose names will work in CSS). But that’s still not the case for others, including my examples “Noto Sans CJK SC Bold” and “AR Mingti Medium B5S”, they stay separate and have the same behaviour as before.

Don’t know if that’s useful info at all but I thought I might as well add it.

I’m done obsessing though, at this point the addon suggestion seems like the easiest path for me personally.