From 11ee317884a562e41a2ed2b6c667153fba16d393 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 20 Dec 2017 10:40:23 +0530 Subject: [PATCH] Fix some emoji glyphs not colored on Linux Linux has a plethora of fonts that contain some emoji glyphs. If one of those fonts is used as a fallback font for a non-emoji character, it also gets used for emojis -- leading to non-colored emoji. Fix by making sure the first fallback font is a dedicated emoji font. --- kitty/fonts.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/kitty/fonts.c b/kitty/fonts.c index f98cc4ea4..5e5036a76 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -1,4 +1,5 @@ /* + * vim:fileencoding=utf-8 * fonts.c * Copyright (C) 2017 Kovid Goyal * @@ -331,20 +332,11 @@ has_cell_text(Font *self, Cell *cell) { return true; } + static inline ssize_t -fallback_font(Cell *cell) { - bool bold = (cell->attrs >> BOLD_SHIFT) & 1; - bool italic = (cell->attrs >> ITALIC_SHIFT) & 1; - ssize_t f; - - for (size_t i = 0, j = fonts.first_fallback_font_idx; i < fonts.fallback_fonts_count; i++, j++) { - Font *ff = fonts.fonts +j; - if (ff->bold == bold && ff->italic == italic && has_cell_text(ff, cell)) { - return j; - } - } - +load_fallback_font(Cell *cell, bool bold, bool italic) { if (fonts.fallback_fonts_count > 100) { fprintf(stderr, "Too many fallback fonts\n"); return MISSING_FONT; } + ssize_t f; if (bold) f = fonts.italic_font_idx > 0 ? fonts.bi_font_idx : fonts.bold_font_idx; else f = italic ? fonts.italic_font_idx : fonts.medium_font_idx; @@ -365,6 +357,31 @@ fallback_font(Cell *cell) { return ans; } + +static inline ssize_t +fallback_font(Cell *cell) { + bool bold = (cell->attrs >> BOLD_SHIFT) & 1; + bool italic = (cell->attrs >> ITALIC_SHIFT) & 1; + + // Load the emoji fallback font first as on Linux there are a bunch of + // non-color fonts that provide some emoji glyphs. + if (fonts.fallback_fonts_count < 1) { + Cell c = {0}; + c.ch = 0x1f648; // 🙈 + load_fallback_font(&c, false, false); + } + + // Check if one of the existing fallback fonts has this text + for (size_t i = 0, j = fonts.first_fallback_font_idx; i < fonts.fallback_fonts_count; i++, j++) { + Font *ff = fonts.fonts +j; + if (ff->bold == bold && ff->italic == italic && has_cell_text(ff, cell)) { + return j; + } + } + + return load_fallback_font(cell, bold, italic); +} + static inline ssize_t in_symbol_maps(char_type ch) { for (size_t i = 0; i < fonts.symbol_maps_count; i++) {