mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-06 09:15:57 +02:00
Use builtin NERD font for symbol_map if no system NERD font is available
This commit is contained in:
@@ -640,7 +640,18 @@ cell_metrics(PyObject *s, unsigned int* cell_width, unsigned int* cell_height, u
|
||||
|
||||
PyObject*
|
||||
face_from_descriptor(PyObject *descriptor, FONTS_DATA_HANDLE fg) {
|
||||
RAII_CoreFoundation(CTFontDescriptorRef, desc, font_descriptor_from_python(descriptor));
|
||||
RAII_CoreFoundation(CTFontDescriptorRef, desc, NULL);
|
||||
if (builtin_nerd_font_descriptor) {
|
||||
PyObject *psname = PyDict_GetItemString(descriptor, "postscript_name");
|
||||
if (psname && PyUnicode_CompareWithASCIIString(psname, "SymbolsNFM") == 0) {
|
||||
RAII_PyObject(path, get_path_for_font_descriptor(builtin_nerd_font_descriptor));
|
||||
PyObject *dpath = PyDict_GetItemString(descriptor, "path");
|
||||
if (dpath && PyUnicode_Compare(path, dpath) == 0) {
|
||||
desc = builtin_nerd_font_descriptor; CFRetain(desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!desc) desc = font_descriptor_from_python(descriptor);
|
||||
if (!desc) return NULL;
|
||||
RAII_CoreFoundation(CTFontRef, font, CTFontCreateWithFontDescriptor(desc, fg ? scaled_point_sz(fg) : 12, NULL));
|
||||
if (!font) { PyErr_SetString(PyExc_ValueError, "Failed to create CTFont object"); return NULL; }
|
||||
@@ -672,8 +683,7 @@ new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kw) {
|
||||
|
||||
PyObject*
|
||||
specialize_font_descriptor(PyObject *base_descriptor, double font_sz_in_pts UNUSED, double dpi_x UNUSED, double dpi_y UNUSED) {
|
||||
Py_INCREF(base_descriptor);
|
||||
return base_descriptor;
|
||||
return PyDict_Copy(base_descriptor);
|
||||
}
|
||||
|
||||
struct RenderBuffers {
|
||||
@@ -1135,7 +1145,7 @@ set_builtin_nerd_font(PyObject UNUSED *self, PyObject *pypath) {
|
||||
if (builtin_nerd_font_descriptor) CFRelease(builtin_nerd_font_descriptor);
|
||||
builtin_nerd_font_descriptor = CFArrayGetValueAtIndex(descriptors, 0);
|
||||
CFRetain(builtin_nerd_font_descriptor);
|
||||
Py_RETURN_NONE;
|
||||
return font_descriptor_to_python(builtin_nerd_font_descriptor);
|
||||
}
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
|
||||
@@ -426,7 +426,7 @@ def fc_match_postscript_name(
|
||||
|
||||
|
||||
def add_font_file(path: str) -> bool: ...
|
||||
def set_builtin_nerd_font(path: str) -> None: ...
|
||||
def set_builtin_nerd_font(path: str) -> Union[CoreTextFont, FontConfigPattern]: ...
|
||||
|
||||
|
||||
class FeatureData(TypedDict):
|
||||
|
||||
@@ -426,6 +426,12 @@ specialize_font_descriptor(PyObject *base_descriptor, double font_sz_in_pts, dou
|
||||
AP(FcPatternAddDouble, FC_DPI, (dpi_x + dpi_y) / 2.0, "dpi");
|
||||
ans = _fc_match(pat);
|
||||
FcPatternDestroy(pat); pat = NULL;
|
||||
if (!ans) return NULL;
|
||||
// fontconfig returns a completely random font if the base descriptor
|
||||
// points to a font that fontconfig hasnt indexed, for example the builting
|
||||
// NERD font
|
||||
PyObject *new_path = PyDict_GetItemString(ans, "path");
|
||||
if (!new_path || PyObject_RichCompareBool(p, new_path, Py_EQ) != 1) { Py_CLEAR(ans); ans = PyDict_Copy(base_descriptor); if (!ans) return NULL; }
|
||||
|
||||
if (face_idx > 0) {
|
||||
// For some reason FcFontMatch sets the index to zero, so manually restore it.
|
||||
@@ -538,6 +544,7 @@ set_builtin_nerd_font(PyObject UNUSED *self, PyObject *pypath) {
|
||||
copy(hinting); copy(hint_style);
|
||||
#undef copy
|
||||
if (PyDict_SetItemString(builtin_nerd_font.descriptor, "path", pypath) != 0) goto end;
|
||||
if (PyDict_SetItemString(builtin_nerd_font.descriptor, "index", PyLong_FromLong(0)) != 0) goto end;
|
||||
}
|
||||
end:
|
||||
if (pat) FcPatternDestroy(pat);
|
||||
@@ -546,7 +553,8 @@ end:
|
||||
Py_CLEAR(builtin_nerd_font.descriptor);
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(builtin_nerd_font.descriptor);
|
||||
return builtin_nerd_font.descriptor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ from kitty.types import _T
|
||||
from kitty.typing import CoreTextFont, FontConfigPattern
|
||||
from kitty.utils import log_error
|
||||
|
||||
from . import family_name_to_key
|
||||
from .common import get_font_files
|
||||
|
||||
if is_macos:
|
||||
@@ -40,6 +41,7 @@ else:
|
||||
|
||||
FontObject = Union[CoreTextFont, FontConfigPattern]
|
||||
current_faces: List[Tuple[FontObject, bool, bool]] = []
|
||||
builtin_nerd_font_descriptor: Optional[FontObject] = None
|
||||
|
||||
|
||||
def font_for_family(family: str) -> Tuple[FontObject, bool, bool]:
|
||||
@@ -145,6 +147,10 @@ def create_symbol_map(opts: Options) -> Tuple[Tuple[int, int, int], ...]:
|
||||
for family in val.values():
|
||||
if family not in family_map:
|
||||
font, bold, italic = font_for_family(family)
|
||||
fkey = family_name_to_key(family)
|
||||
if fkey in ('symbolsnfm', 'symbols nerd font mono') and font['postscript_name'] != 'SymbolsNFM' and builtin_nerd_font_descriptor:
|
||||
font = builtin_nerd_font_descriptor
|
||||
bold = italic = False
|
||||
family_map[family] = count
|
||||
count += 1
|
||||
current_faces.append((font, bold, italic))
|
||||
@@ -172,8 +178,8 @@ def dump_font_debug() -> None:
|
||||
log_error(' ' + s.identify_for_debug())
|
||||
|
||||
|
||||
def set_font_family(opts: Optional[Options] = None, override_font_size: Optional[float] = None) -> None:
|
||||
global current_faces
|
||||
def set_font_family(opts: Optional[Options] = None, override_font_size: Optional[float] = None, add_builtin_nerd_font: bool = False) -> None:
|
||||
global current_faces, builtin_nerd_font_descriptor
|
||||
opts = opts or defaults
|
||||
sz = override_font_size or opts.font_size
|
||||
font_map = get_font_files(opts)
|
||||
@@ -185,6 +191,12 @@ def set_font_family(opts: Optional[Options] = None, override_font_size: Optional
|
||||
indices[k] = len(current_faces)
|
||||
current_faces.append((font_map[k], 'b' in k, 'i' in k))
|
||||
before = len(current_faces)
|
||||
if add_builtin_nerd_font:
|
||||
builtin_nerd_font_path = os.path.join(fonts_dir, 'SymbolsNerdFontMono-Regular.ttf')
|
||||
if os.path.exists(builtin_nerd_font_path):
|
||||
builtin_nerd_font_descriptor = set_builtin_nerd_font(builtin_nerd_font_path)
|
||||
else:
|
||||
log_error(f'No builtin NERD font found in {fonts_dir}')
|
||||
sm = create_symbol_map(opts)
|
||||
ns = create_narrow_symbols(opts)
|
||||
num_symbol_fonts = len(current_faces) - before
|
||||
@@ -195,15 +207,6 @@ def set_font_family(opts: Optional[Options] = None, override_font_size: Optional
|
||||
)
|
||||
|
||||
|
||||
def add_application_fonts() -> None:
|
||||
for font in ('SymbolsNerdFontMono-Regular.ttf',):
|
||||
path = os.path.join(fonts_dir, font)
|
||||
if os.path.exists(path):
|
||||
set_builtin_nerd_font(path)
|
||||
else:
|
||||
log_error(f'No builtin NERD font found in {fonts_dir}')
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
CBufType = ctypes.Array[ctypes.c_ubyte]
|
||||
else:
|
||||
|
||||
@@ -44,7 +44,7 @@ from .fast_data_types import (
|
||||
set_options,
|
||||
)
|
||||
from .fonts.box_drawing import set_scale
|
||||
from .fonts.render import add_application_fonts, dump_font_debug, set_font_family
|
||||
from .fonts.render import dump_font_debug, set_font_family
|
||||
from .options.types import Options
|
||||
from .options.utils import DELETE_ENV_VAR
|
||||
from .os_window_size import edge_spacing, initial_window_size_func
|
||||
@@ -248,8 +248,7 @@ class AppRunner:
|
||||
set_scale(opts.box_drawing_scale)
|
||||
set_options(opts, is_wayland(), args.debug_rendering, args.debug_font_fallback)
|
||||
try:
|
||||
set_font_family(opts)
|
||||
add_application_fonts()
|
||||
set_font_family(opts, add_builtin_nerd_font=True)
|
||||
_run_app(opts, args, bad_lines, talk_fd)
|
||||
finally:
|
||||
set_options(None)
|
||||
|
||||
Reference in New Issue
Block a user