mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-06-25 02:17:03 +00:00
macOS: When CoreText fails to find a fallback font for a character in the first Private Use Unicode Area, preferentially use the NERD font, if available, for it
Fixes #6043
This commit is contained in:
parent
f3d9ad3244
commit
e646596c5b
2 changed files with 30 additions and 19 deletions
|
|
@ -56,6 +56,9 @@ Detailed list of changes
|
|||
|
||||
- macOS: Fix text rendered with fallback fonts not respecting bold/italic styling (:disc:`7241`)
|
||||
|
||||
- macOS: When CoreText fails to find a fallback font for a character in the first Private Use Unicode Area, preferentially use the NERD font, if available, for it (:iss:`6043`)
|
||||
|
||||
|
||||
0.33.0 [2024-03-12]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -184,12 +184,17 @@ glyph_id_for_codepoint_ctfont(CTFontRef ct_font, char_type ch) {
|
|||
return glyphs[0];
|
||||
}
|
||||
|
||||
static bool
|
||||
cf_string_equals(CFStringRef a, CFStringRef b) { return CFStringCompare(a, b, 0) == kCFCompareEqualTo; }
|
||||
|
||||
#define LAST_RESORT_FONT_NAME "LastResort"
|
||||
|
||||
static bool
|
||||
is_last_resort_font(CTFontRef new_font) {
|
||||
CFStringRef name = CTFontCopyPostScriptName(new_font);
|
||||
CFComparisonResult cr = CFStringCompare(name, CFSTR("LastResort"), 0);
|
||||
bool ans = cf_string_equals(name, CFSTR(LAST_RESORT_FONT_NAME));
|
||||
CFRelease(name);
|
||||
return cr == kCFCompareEqualTo;
|
||||
return ans;
|
||||
}
|
||||
|
||||
static CTFontRef
|
||||
|
|
@ -197,26 +202,29 @@ manually_search_fallback_fonts(CTFontRef current_font, CPUCell *cell) {
|
|||
CFArrayRef fonts = CTFontCollectionCreateMatchingFontDescriptors(all_fonts_collection());
|
||||
CTFontRef ans = NULL;
|
||||
const CFIndex count = CFArrayGetCount(fonts);
|
||||
char_type ch = cell->ch ? cell->ch : ' ';
|
||||
bool in_first_pua = 0xe000 <= ch && ch <= 0xf8ff;
|
||||
// preferentially load from NERD fonts
|
||||
for (CFIndex i = 0; i < count; i++) {
|
||||
CTFontDescriptorRef descriptor = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i);
|
||||
CFStringRef name = CTFontDescriptorCopyAttribute(descriptor, kCTFontNameAttribute);
|
||||
bool is_last_resort_font = cf_string_equals(name, CFSTR(LAST_RESORT_FONT_NAME));
|
||||
bool is_nerd_font = cf_string_equals(name, CFSTR("SymbolsNFM"));
|
||||
CFRelease(name);
|
||||
if (is_last_resort_font) continue;
|
||||
CTFontRef new_font = CTFontCreateWithFontDescriptor(descriptor, CTFontGetSize(current_font), NULL);
|
||||
if (new_font) {
|
||||
if (!is_last_resort_font(new_font)) {
|
||||
char_type ch = cell->ch ? cell->ch : ' ';
|
||||
bool found = true;
|
||||
if (!glyph_id_for_codepoint_ctfont(new_font, ch)) found = false;
|
||||
for (unsigned i = 0; i < arraysz(cell->cc_idx) && cell->cc_idx[i] && found; i++) {
|
||||
ch = codepoint_for_mark(cell->cc_idx[i]);
|
||||
if (!glyph_id_for_codepoint_ctfont(new_font, ch)) found = false;
|
||||
}
|
||||
if (found) {
|
||||
ans = new_font;
|
||||
if (global_state.debug_font_fallback) fprintf(stderr, "Manually found fallback font.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
CFRelease(new_font);
|
||||
bool found = true;
|
||||
if (!glyph_id_for_codepoint_ctfont(new_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(new_font, cch)) found = false;
|
||||
}
|
||||
if (found) {
|
||||
// preferentially use NERD font for glyphs in first PUA
|
||||
if (!ans || is_nerd_font) { if (ans) CFRelease(ans); ans = new_font; CFRetain(ans); }
|
||||
if (is_nerd_font || !in_first_pua) break;
|
||||
}
|
||||
CFRelease(new_font);
|
||||
}
|
||||
CFRelease(fonts);
|
||||
return ans;
|
||||
|
|
@ -241,7 +249,7 @@ find_substitute_face(CFStringRef str, CTFontRef old_font, CPUCell *cpu_cell) {
|
|||
new_font = manually_search_fallback_fonts(old_font, cpu_cell);
|
||||
if (new_font) return new_font;
|
||||
}
|
||||
PyErr_Format(PyExc_ValueError, "Failed to find fallback CTFont other than the LastResort font for: %s", [(NSString *)str UTF8String]);
|
||||
PyErr_Format(PyExc_ValueError, "Failed to find fallback CTFont other than the %s font for: %s", LAST_RESORT_FONT_NAME, [(NSString *)str UTF8String]);
|
||||
return NULL;
|
||||
}
|
||||
return new_font;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue