mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-23 16:58:09 +02:00
Allow storing arbitrary data on FreeType Face objects
This commit is contained in:
@@ -23,3 +23,5 @@ bool render_glyphs_in_cells(PyObject *f, bool bold, bool italic, hb_glyph_info_t
|
|||||||
void render_line(Line *line);
|
void render_line(Line *line);
|
||||||
void sprite_tracker_set_limits(size_t max_texture_size, size_t max_array_len);
|
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);
|
void sprite_tracker_set_layout(unsigned int cell_width, unsigned int cell_height);
|
||||||
|
|
||||||
|
typedef void (*free_extra_data_func)(void*);
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ typedef struct {
|
|||||||
FT_UInt xdpi, ydpi;
|
FT_UInt xdpi, ydpi;
|
||||||
PyObject *path;
|
PyObject *path;
|
||||||
hb_font_t *harfbuzz_font;
|
hb_font_t *harfbuzz_font;
|
||||||
|
void *extra_data;
|
||||||
|
free_extra_data_func free_extra_data;
|
||||||
} Face;
|
} Face;
|
||||||
|
|
||||||
static PyObject* FreeType_Exception = NULL;
|
static PyObject* FreeType_Exception = NULL;
|
||||||
@@ -107,6 +109,24 @@ get_load_flags(int hinting, int hintstyle, int base) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
init_ft_face(Face *self, PyObject *path, int hinting, int hintstyle, float size_in_pts, float xdpi, float ydpi) {
|
||||||
|
#define CPY(n) self->n = self->face->n;
|
||||||
|
CPY(units_per_EM); CPY(ascender); CPY(descender); CPY(height); CPY(max_advance_width); CPY(max_advance_height); CPY(underline_position); CPY(underline_thickness);
|
||||||
|
#undef CPY
|
||||||
|
self->is_scalable = FT_IS_SCALABLE(self->face);
|
||||||
|
self->hinting = hinting; self->hintstyle = hintstyle;
|
||||||
|
if (!set_size_for_face((PyObject*)self, size_in_pts, xdpi, ydpi)) return false;
|
||||||
|
self->harfbuzz_font = hb_ft_font_create(self->face, NULL);
|
||||||
|
if (self->harfbuzz_font == NULL) { PyErr_NoMemory(); return false; }
|
||||||
|
hb_ft_font_set_load_flags(self->harfbuzz_font, get_load_flags(self->hinting, self->hintstyle, FT_LOAD_DEFAULT));
|
||||||
|
|
||||||
|
self->path = path;
|
||||||
|
Py_INCREF(self->path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
||||||
Face *self;
|
Face *self;
|
||||||
@@ -118,19 +138,9 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
|||||||
|
|
||||||
self = (Face *)type->tp_alloc(type, 0);
|
self = (Face *)type->tp_alloc(type, 0);
|
||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
self->path = PyTuple_GET_ITEM(args, 0);
|
|
||||||
Py_INCREF(self->path);
|
|
||||||
error = FT_New_Face(library, path, index, &(self->face));
|
error = FT_New_Face(library, path, index, &(self->face));
|
||||||
if(error) { set_freetype_error("Failed to load face, with error:", error); Py_CLEAR(self); return NULL; }
|
if(error) { set_freetype_error("Failed to load face, with error:", error); Py_CLEAR(self); return NULL; }
|
||||||
#define CPY(n) self->n = self->face->n;
|
if (!init_ft_face(self, PyTuple_GET_ITEM(args, 0), hinting, hintstyle, size_in_pts, xdpi, ydpi)) { Py_CLEAR(self); return NULL; }
|
||||||
CPY(units_per_EM); CPY(ascender); CPY(descender); CPY(height); CPY(max_advance_width); CPY(max_advance_height); CPY(underline_position); CPY(underline_thickness);
|
|
||||||
#undef CPY
|
|
||||||
self->is_scalable = FT_IS_SCALABLE(self->face);
|
|
||||||
self->hinting = hinting; self->hintstyle = hintstyle;
|
|
||||||
if (!set_size_for_face((PyObject*)self, size_in_pts, xdpi, ydpi)) { Py_CLEAR(self); return NULL; }
|
|
||||||
self->harfbuzz_font = hb_ft_font_create(self->face, NULL);
|
|
||||||
if (self->harfbuzz_font == NULL) { Py_CLEAR(self); return PyErr_NoMemory(); }
|
|
||||||
hb_ft_font_set_load_flags(self->harfbuzz_font, get_load_flags(self->hinting, self->hintstyle, FT_LOAD_DEFAULT));
|
|
||||||
}
|
}
|
||||||
return (PyObject*)self;
|
return (PyObject*)self;
|
||||||
}
|
}
|
||||||
@@ -139,6 +149,7 @@ static void
|
|||||||
dealloc(Face* self) {
|
dealloc(Face* self) {
|
||||||
if (self->harfbuzz_font) hb_font_destroy(self->harfbuzz_font);
|
if (self->harfbuzz_font) hb_font_destroy(self->harfbuzz_font);
|
||||||
if (self->face) FT_Done_Face(self->face);
|
if (self->face) FT_Done_Face(self->face);
|
||||||
|
if (self->extra_data && self->free_extra_data) self->free_extra_data(self->extra_data);
|
||||||
Py_CLEAR(self->path);
|
Py_CLEAR(self->path);
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
}
|
}
|
||||||
@@ -347,8 +358,6 @@ PyTypeObject Face_Type = {
|
|||||||
.tp_repr = (reprfunc)repr,
|
.tp_repr = (reprfunc)repr,
|
||||||
};
|
};
|
||||||
|
|
||||||
INIT_TYPE(Face)
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_freetype() {
|
free_freetype() {
|
||||||
FT_Done_FreeType(library);
|
FT_Done_FreeType(library);
|
||||||
@@ -356,6 +365,9 @@ free_freetype() {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
init_freetype_library(PyObject *m) {
|
init_freetype_library(PyObject *m) {
|
||||||
|
if (PyType_Ready(&Face_Type) < 0) return 0;
|
||||||
|
if (PyModule_AddObject(m, "Face", (PyObject *)&Face_Type) != 0) return 0;
|
||||||
|
Py_INCREF(&Face_Type);
|
||||||
FreeType_Exception = PyErr_NewException("fast_data_types.FreeTypeError", NULL, NULL);
|
FreeType_Exception = PyErr_NewException("fast_data_types.FreeTypeError", NULL, NULL);
|
||||||
if (FreeType_Exception == NULL) return false;
|
if (FreeType_Exception == NULL) return false;
|
||||||
if (PyModule_AddObject(m, "FreeTypeError", FreeType_Exception) != 0) return false;
|
if (PyModule_AddObject(m, "FreeTypeError", FreeType_Exception) != 0) return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user