diff --git a/kitty/fonts.h b/kitty/fonts.h index 6a92aa761..d43a53401 100644 --- a/kitty/fonts.h +++ b/kitty/fonts.h @@ -25,3 +25,4 @@ void sprite_tracker_set_limits(size_t max_texture_size, size_t max_array_len); void sprite_tracker_set_layout(unsigned int cell_width, unsigned int cell_height); typedef void (*free_extra_data_func)(void*); PyObject* ft_face_from_data(const uint8_t* data, size_t sz, void *extra_data, free_extra_data_func fed, PyObject *path, int hinting, int hintstyle, float size_in_pts, float xdpi, float ydpi); +PyObject* ft_face_from_path_and_psname(const char* path, const char* psname, void *extra_data, free_extra_data_func fed, int hinting, int hintstyle, float size_in_pts, float xdpi, float ydpi); diff --git a/kitty/freetype.c b/kitty/freetype.c index 0261be443..9ea90a0cb 100644 --- a/kitty/freetype.c +++ b/kitty/freetype.c @@ -133,9 +133,39 @@ ft_face_from_data(const uint8_t* data, size_t sz, void *extra_data, free_extra_d if (ans == NULL) return NULL; int error = FT_New_Memory_Face(library, data, sz, 0, &ans->face); if(error) { set_freetype_error("Failed to load memory face, with error:", error); Py_CLEAR(ans); return NULL; } + if (!init_ft_face(ans, path, hinting, hintstyle, size_in_pts, xdpi, ydpi)) Py_CLEAR(ans); ans->extra_data = extra_data; ans->free_extra_data = fed; - if (!init_ft_face(ans, path, hinting, hintstyle, size_in_pts, xdpi, ydpi)) Py_CLEAR(ans); + return (PyObject*)ans; +} + +static inline bool +load_from_path_and_psname(const char *path, const char* psname, FT_Face ans) { + int error, num_faces, index = 0; + error = FT_New_Face(library, path, index, &ans); + if (error) { set_freetype_error("False to load face, with error:", error); return false; } + num_faces = ans->num_faces; + if (num_faces < 2) return true; + do { + if (strcmp(FT_Get_Postscript_Name(ans), psname) == 0) return true; + FT_Done_Face(ans); + error = FT_New_Face(library, path, ++index, &ans); + if (error) continue; + } while(index < num_faces); + PyErr_Format(PyExc_ValueError, "No face matching the postscript name: %s found in: %s", psname, path); + return false; +} + +PyObject* +ft_face_from_path_and_psname(const char* path, const char* psname, void *extra_data, free_extra_data_func fed, int hinting, int hintstyle, float size_in_pts, float xdpi, float ydpi) { + Face *ans = (Face*)Face_Type.tp_alloc(&Face_Type, 0); + if (!load_from_path_and_psname(path, psname, ans->face)) { Py_CLEAR(ans); return NULL; } + PyObject *p = PyUnicode_FromString(path); + if (p == NULL) { Py_CLEAR(ans); return NULL; } + if (!init_ft_face(ans, p, hinting, hintstyle, size_in_pts, xdpi, ydpi)) Py_CLEAR(ans); + ans->extra_data = extra_data; + ans->free_extra_data = fed; + Py_DECREF(p); return (PyObject*)ans; }