After a few years of exclusively using Linux as my main OS I recently had to start using macOS again because of work. One of the things I dislike about macOS is the way it renders Persian/Arabic out of the box. The default font on macOS does not include any Persian glyphs so the job somehow falls onto Arial which does include the glyphs, albeit incredibly ugly ones:

This problem also exists on Linux but thanks to fontconfig it is incredibly easy to change the default font for rendering Persian text. You can check out my dotfiles to see how I configure fontconfig to use my preferred Persian, Vazirmatn, system-wide.

Things are not so easy on macOS. I found some references to a DefaultFontFallbacks.plist file which, as the name suggests, specified the fallback font for language glyphs that are not included in the system font. This sounded like exactly what I needed but Apple seems to have removed it in recent versions of macOS (Catalina onwards).

I then thought about creating my custom font which would be mostly the default masOS font with the extra Persian glyphs from Vazirmatn injected in. There is already a script to do this in Vazirmatn repo to combine it with the Roboto font. However, even if I did make this font, changing the default font in macOS did not seem trivial. I came across TinkerTool which lets you do it easily but apparently it is only effective for native macOS programs and only if the developer has added support for font preference.

So I conceded to at least fixing things in two places where I spend most of my time: the terminal and the browser.

I use Kitty as my terminal emulator and luckily I didn’t have to do much. Kitty has excellent font support and lets you map unicode ranges to specific fonts so my config just transferred over from Linux:

symbol_map U+0600-U+06FF,U+200C-U+200E,U+2010-U+2011,U+204F,U+2E41,U+FB50-U+FDFF,U+FE80-U+FEFC Vazir Code

In the browser, I wanted to apply custom CSS to all websites in a way that wouldn’t override the their carefully chosen fonts. I ended up using CSS’s unicode-range to redefine Arial to use Vazirmatn for Persian/Arabic glyphs:

@font-face {
    font-family:'Arial';
    src: local('Vazirmatn');
    unicode-range: U+0600-06FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE80-FEFC;
}
@font-face {
    font-family:'Arial';
    src: local("Arial");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

I dropped this in Firefox’s userContent.css but sadly it was not picked up. According to this old thread it is due to the CSS spec and the order in which @font-faces are defined. I was however able to add it to Stylus extension and it’s been working great: