diff --git a/kitty/core_text.m b/kitty/core_text.m index 0df9708a6..385624d61 100644 --- a/kitty/core_text.m +++ b/kitty/core_text.m @@ -323,17 +323,8 @@ static CTFontRef nerd_font(CGFloat sz) { return _nerd_font_descriptor ? CTFontCreateWithFontDescriptor(_nerd_font_descriptor, sz, NULL) : NULL; } -static bool -font_can_render_cell(CTFontRef font, CPUCell *cell) { - char_type ch = cell->ch ? cell->ch : ' '; - bool found = true; - if (!glyph_id_for_codepoint_ctfont(font, ch)) found = false; - for (unsigned i = 0; i < arraysz(cell->cc_idx) && cell->cc_idx[i] && found; i++) { - char_type cch = codepoint_for_mark(cell->cc_idx[i]); - if (!glyph_id_for_codepoint_ctfont(font, cch)) found = false; - } - return found; -} +static bool ctfont_has_codepoint(const void *ctfont, char_type cp) { return glyph_id_for_codepoint_ctfont(ctfont, cp) > 0; } +static bool font_can_render_cell(CTFontRef font, CPUCell *cell) { return has_cell_text(ctfont_has_codepoint, font, cell, false); } static CTFontRef manually_search_fallback_fonts(CTFontRef current_font, CPUCell *cell) { @@ -417,6 +408,8 @@ apply_styles_to_fallback_font(CTFontRef original_fallback_font, bool bold, bool return original_fallback_font; } +static bool face_has_codepoint(const void *face, char_type ch) { return glyph_id_for_codepoint(face, ch) > 0; } + PyObject* create_fallback_face(PyObject *base_face, CPUCell* cell, bool bold, bool italic, bool emoji_presentation, FONTS_DATA_HANDLE fg) { CTFace *self = (CTFace*)base_face; @@ -451,7 +444,7 @@ create_fallback_face(PyObject *base_face, CPUCell* cell, bool bold, bool italic, } if (!ans) { ans = (PyObject*)ct_face(new_font, NULL); - if (ans && !has_cell_text(ans, cell, global_state.debug_font_fallback)) { + if (ans && !has_cell_text(face_has_codepoint, ans, cell, global_state.debug_font_fallback)) { Py_CLEAR(ans); Py_RETURN_NONE; } @@ -460,8 +453,8 @@ create_fallback_face(PyObject *base_face, CPUCell* cell, bool bold, bool italic, } unsigned int -glyph_id_for_codepoint(PyObject *s, char_type ch) { - CTFace *self = (CTFace*)s; +glyph_id_for_codepoint(const PyObject *s, char_type ch) { + const CTFace *self = (CTFace*)s; return glyph_id_for_codepoint_ctfont(self->ct_font, ch); } diff --git a/kitty/fontconfig.c b/kitty/fontconfig.c index 3ac1518e9..152c0bee7 100644 --- a/kitty/fontconfig.c +++ b/kitty/fontconfig.c @@ -466,6 +466,8 @@ end: return ok; } +static bool face_has_codepoint(const void *face, char_type cp) { return glyph_id_for_codepoint(face, cp) > 0; } + PyObject* create_fallback_face(PyObject UNUSED *base_face, CPUCell* cell, bool bold, bool italic, bool emoji_presentation, FONTS_DATA_HANDLE fg) { ensure_initialized(); @@ -490,7 +492,7 @@ create_fallback_face(PyObject UNUSED *base_face, CPUCell* cell, bool bold, bool } end: if (pat != NULL) FcPatternDestroy(pat); - if (ans && !has_cell_text(ans, cell, global_state.debug_font_fallback)) { + if (ans && !has_cell_text(face_has_codepoint, ans, cell, global_state.debug_font_fallback)) { Py_CLEAR(ans); Py_RETURN_NONE; } diff --git a/kitty/fonts.c b/kitty/fonts.c index 499c765b2..fd218be5e 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -464,7 +464,7 @@ calc_cell_metrics(FontGroup *fg) { } static bool -face_has_codepoint(PyObject* face, char_type cp) { +face_has_codepoint(const PyObject* face, char_type cp) { return glyph_id_for_codepoint(face, cp) > 0; } @@ -474,8 +474,8 @@ has_emoji_presentation(CPUCell *cpu_cell, GPUCell *gpu_cell) { } bool -has_cell_text(PyObject *face, const CPUCell *cell, bool do_debug) { - if (!face_has_codepoint(face, cell->ch)) goto not_found; +has_cell_text(bool(*has_codepoint)(const void*, char_type ch), const void* face, const CPUCell *cell, bool do_debug) { + if (!has_codepoint(face, cell->ch)) goto not_found; char_type combining_chars[arraysz(cell->cc_idx)]; unsigned num_cc = 0; for (unsigned i = 0; i < arraysz(cell->cc_idx) && cell->cc_idx[i]; i++) { @@ -484,13 +484,13 @@ has_cell_text(PyObject *face, const CPUCell *cell, bool do_debug) { } if (num_cc == 0) return true; if (num_cc == 1) { - if (face_has_codepoint(face, combining_chars[0])) return true; + if (has_codepoint(face, combining_chars[0])) return true; char_type ch = 0; if (hb_unicode_compose(hb_unicode_funcs_get_default(), cell->ch, combining_chars[0], &ch) && face_has_codepoint(face, ch)) return true; goto not_found; } for (unsigned i = 0; i < num_cc; i++) { - if (!face_has_codepoint(face, combining_chars[i])) goto not_found; + if (!has_codepoint(face, combining_chars[i])) goto not_found; } return true; not_found: @@ -500,7 +500,7 @@ not_found: for (unsigned i = 0; i < arraysz(cell->cc_idx) && cell->cc_idx[i]; i++) { debug("U+%x ", codepoint_for_mark(cell->cc_idx[i])); } - debug("is "); PyObject_Print(face, stderr, 0); + debug("is "); PyObject_Print((PyObject*)face, stderr, 0); debug(" but it does not actually contain glyphs for that text\n"); } return false; @@ -638,7 +638,7 @@ START_ALLOW_CASE_RANGE ans = fg->bi_font_idx; break; } if (ans < 0) ans = fg->medium_font_idx; - if (!*is_emoji_presentation && has_cell_text((fg->fonts + ans)->face, cpu_cell, false)) { *is_main_font = true; return ans; } + if (!*is_emoji_presentation && has_cell_text((bool(*)(const void*, char_type))face_has_codepoint, (fg->fonts + ans)->face, cpu_cell, false)) { *is_main_font = true; return ans; } return fallback_font(fg, cpu_cell, gpu_cell); } END_ALLOW_CASE_RANGE diff --git a/kitty/fonts.h b/kitty/fonts.h index 665fc8d24..36674ee0d 100644 --- a/kitty/fonts.h +++ b/kitty/fonts.h @@ -33,7 +33,7 @@ typedef struct ParsedFontFeature { // API that font backends need to implement -unsigned int glyph_id_for_codepoint(PyObject *, char_type); +unsigned int glyph_id_for_codepoint(const PyObject *, char_type); int get_glyph_width(PyObject *, glyph_index); bool is_glyph_empty(PyObject *, glyph_index); hb_font_t* harfbuzz_font_for_face(PyObject*); @@ -72,7 +72,8 @@ FontFeatures* features_for_face(PyObject *); bool create_features_for_face(const char* psname, PyObject *features, FontFeatures* output); PyObject* font_features_as_dict(const FontFeatures *font_features); -bool has_cell_text(PyObject *face, const CPUCell *c, bool do_debug); +bool +has_cell_text(bool(*has_codepoint)(const void*, char_type ch), const void* face, const CPUCell *cell, bool do_debug); static inline void right_shift_canvas(pixel *canvas, size_t width, size_t height, size_t amt) { diff --git a/kitty/freetype.c b/kitty/freetype.c index b03f75141..394c0dbec 100644 --- a/kitty/freetype.c +++ b/kitty/freetype.c @@ -412,7 +412,7 @@ cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, u } unsigned int -glyph_id_for_codepoint(PyObject *s, char_type cp) { +glyph_id_for_codepoint(const PyObject *s, char_type cp) { return FT_Get_Char_Index(((Face*)s)->face, cp); }