How to handle CJK variants for unified characters

Hi all! I’ve got a GTK app called Hantracker, meant to test you on your knowledge of Chinese characters. It’s inspired by a discontinued feature from Kanji Koohii.

I’d like to figure out the best way to allow the user to select their font from within the app. While I could rely on the OS or the user to supply the correct font, it would be better if I could dynamically switch the font within the app.

What would be the best way to do this?

For example, let’s say I want to test myself on a list of Simplified Chinese characters. If my current font is “Noto Sans CJK KR”, it should be able to find “Noto Sans CJK SC” assuming it’s on my system.

In order to load a specific font, you will need to use Pango API, like pango_font_map_add_font_file(), pointing at the file name, if you’re shipping it with your application.

Alternatively, if the font is installed in the system, you can use a PangoAttrFontDesc attribute, and assign it to a GtkLabel using gtk_label_set_attributes().

Ok, that makes sense. I may want to ship fallback fonts just in case the user doesn’t have them.

Do attributes cascade to child widgets? I was excited to see that Gtk.Widgets will inherit the font_map from their parent in the docs.


Now as for filtering out which fonts a particular language supports. Can Pango do this? It seems like the only solution is to use fontconfig like the example in the rust docs for fontconfig.

Example (sorry, can't post more than 3 links)
use fontconfig::{Fontconfig, Pattern};

let fc = Fontconfig::new().expect("unable to init Fontconfig");

// Find fonts that support japanese
let fonts = fontconfig::list_fonts(&Pattern::new(&fc), None);
let ja_fonts: Vec<_> = fonts
    .iter()
    .filter(|p| p.lang_set().map_or(false, |mut langs| langs.any(|l| l == "ja")))
    .collect();

My only concern with that solution is that it is not cross-platform.

Edit:

I found Pango.font.get_languages, however it’s currently unsupported in Rust. I could do FFI, but there’s no point. It’s not cross platform anyway, so I’d have to roll my own solution for darwin and win32.

Edit 2:

I implemented this myself using fontconfig and I couldn’t filter out fonts based on their intended language. So it’s probably not worth writing heuristics to figure out which is the best font to use for a particular language.

Thank you for your help @ebassi.