pango falls back to another font if the glyphs are present in the selected font
Linux Fedora 36, pango-1.50.8-1.fc36.x86_64, gtk3-3.24.34-1.fc36.x86_64, gnome-shell-42.3.1-1.fc36.x86_64.
Make sure following fonts are installed in the system:
- google-noto-emoji-fonts-20211102-1.fc36.noarch
- google-noto-emoji-color-fonts-20211102-1.fc36.noarch
- gdouros-symbola-fonts-10.24-10.fc36.noarch
Download and install locally "Iosevka Fixed SS09" font:
$ mkdir ~/.local/share/fonts/iosevka
$ cd ~/.local/share/fonts/iosevka
$ wget https://github.com/be5invis/Iosevka/releases/download/v15.6.0/ttf-iosevka-fixed-ss09-15.6.0.zip
$ unzip ttf-iosevka-fixed-ss09-15.6.0.zip iosevka-fixed-ss09-regular.ttf
# The font archive includes 54 fonts, extracting just one font file is enough for test purposes.
$ fc-cache -r .
Verify that the font contains the glyph for U+23E9 BLACK RIGHT-POINTING DOUBLE TRIANGLE
:
- Run gucharmap.
- Select "Iosevka Fixed SS09" from the drop-down list.
- View → Show only glyphs from this font, make sure checkbox is marked.
- Press Ctrl+F and search for
U+23E9
.
Remember the glyph: it is relatively small double-triangle, because "Iosevka Fixed SS09" is strictly monospace font, so any glyph must fit into one char cell.
Now View → Show only glyphs from this font and clear the checkbox. As we know, the glyph is present in the font, but the glyph is replaced with a glyph from another font.
The same effect may be reproduced with small C program:
$ cat test.c
#include <gtk/gtk.h>
static void on_app_activate(GApplication *app, gpointer data) {
GtkWidget *window = gtk_application_window_new(GTK_APPLICATION(app));
GtkWidget *lbl = gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(lbl),
"<span font_family=\"Iosevka Fixed SS09\" size=\"80000\" fallback=\"false\">\u23E9</span>"
);
gtk_container_add(GTK_CONTAINER(window), lbl);
gtk_widget_show_all(GTK_WIDGET(window));
}
int main(int argc, char *argv[]) {
GtkApplication *app = gtk_application_new(
"org.gtkmm.example.HelloApp",
G_APPLICATION_FLAGS_NONE
);
g_signal_connect(app, "activate", G_CALLBACK(on_app_activate), NULL);
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
$ gcc $(pkg-config --cflags --libs gtk+-3.0) test.c
$ ./a.out
Note: <span ... fallback="false">
works as expected, the double-triangle arrow is rendered correctly, black and relatively small, this is for sure a glyph from "Iosevka Fixed SS09" font:
Now edit the source code and replace <span ... fallback="false">
with <span ... fallback="true">
, rebuild and re-run the program:
$ sed -i -e 's/false/true/' test.c
$ gcc $(pkg-config --cflags --libs gtk+-3.0) test.c
$ ./a.out
Bang! Instead of the glyph from "Iosevka" now you see a glyph from another font (I guess it is from "Noto Color Emoji"):
Why does Pango decide to falls back to "Noto Color Emoji", if the specified "Iosevka Fixed SS09" has the glyph for U+23E8
?
"Iosevka Fixed SS09" is strictly monospace font, especially designed to be used in plain text editors and terminal emulators to maintain column alignment, because every glyph fits char cell. "Iosevka Fixed SS09" has a lot of glyphs, but Pango ignores them and use glyphs from another font which do not fit into char cell and breaks column alignment. A lot of programs affected: plain text editors geany, gnome-text-editor, gnome-builder, gvim, pluma, mousepad, leafpad; terminal emulators gnome-terminal, tilix.
Test program: test.c