Use same algorithm for checking if cell can be rendered everywhere
This commit is contained in:
Kovid Goyal
2024-06-30 15:01:05 +05:30
parent 642dbc6f64
commit 66034d54fb
5 changed files with 21 additions and 25 deletions

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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);
}