Fix a memory leak when changing font sizes

had forgotten to free unused font groups
This commit is contained in:
Kovid Goyal 2020-09-18 07:40:30 +05:30
parent f8a80ccf5f
commit ca6010789e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 38 additions and 35 deletions

View File

@ -59,6 +59,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- Fix a regression that broke the ``move_window_to_top`` action (:pull:`2953`)
- Fix a memory leak when changing font sizes
0.18.3 [2020-08-11]
-------------------

View File

@ -130,12 +130,48 @@ font_group_is_unused(FontGroup *fg) {
return true;
}
void
free_maps(Font *font) {
#define free_a_map(type, attr) {\
type *s, *t; \
for (size_t i = 0; i < sizeof(font->attr)/sizeof(font->attr[0]); i++) { \
s = font->attr[i].next; \
while (s) { \
t = s; \
s = s->next; \
free(t); \
} \
}\
memset(font->attr, 0, sizeof(font->attr)); \
}
free_a_map(SpritePosition, sprite_map);
free_a_map(SpecialGlyphCache, special_glyph_cache);
#undef free_a_map
}
static inline void
del_font(Font *f) {
Py_CLEAR(f->face);
free(f->ffs_hb_features); f->ffs_hb_features = NULL;
free_maps(f);
f->bold = false; f->italic = false;
}
static inline void
del_font_group(FontGroup *fg) {
free(fg->canvas); fg->canvas = NULL;
fg->sprite_map = free_sprite_map(fg->sprite_map);
for (size_t i = 0; i < fg->fonts_count; i++) del_font(fg->fonts + i);
free(fg->fonts); fg->fonts = NULL;
}
static inline void
trim_unused_font_groups(void) {
save_window_font_groups();
size_t i = 0;
while (i < num_font_groups) {
if (font_group_is_unused(font_groups + i)) {
del_font_group(font_groups + i);
size_t num_to_right = (--num_font_groups) - i;
if (!num_to_right) break;
memmove(font_groups + i, font_groups + 1 + i, num_to_right * sizeof(FontGroup));
@ -282,25 +318,6 @@ sprite_tracker_current_layout(FONTS_DATA_HANDLE data, unsigned int *x, unsigned
*x = fg->sprite_tracker.xnum; *y = fg->sprite_tracker.ynum; *z = fg->sprite_tracker.z;
}
void
free_maps(Font *font) {
#define free_a_map(type, attr) {\
type *s, *t; \
for (size_t i = 0; i < sizeof(font->attr)/sizeof(font->attr[0]); i++) { \
s = font->attr[i].next; \
while (s) { \
t = s; \
s = s->next; \
free(t); \
} \
}\
memset(font->attr, 0, sizeof(font->attr)); \
}
free_a_map(SpritePosition, sprite_map);
free_a_map(SpecialGlyphCache, special_glyph_cache);
#undef free_a_map
}
void
clear_sprite_map(Font *font) {
#define CLEAR(s) s->filled = false; s->rendered = false; s->colored = false; s->glyph = 0; zero_at_ptr(&s->extra_glyphs); s->x = 0; s->y = 0; s->z = 0; s->ligature_index = 0;
@ -384,22 +401,6 @@ init_font(Font *f, PyObject *face, bool bold, bool italic, bool emoji_presentati
return true;
}
static inline void
del_font(Font *f) {
Py_CLEAR(f->face);
free(f->ffs_hb_features); f->ffs_hb_features = NULL;
free_maps(f);
f->bold = false; f->italic = false;
}
static inline void
del_font_group(FontGroup *fg) {
free(fg->canvas); fg->canvas = NULL;
fg->sprite_map = free_sprite_map(fg->sprite_map);
for (size_t i = 0; i < fg->fonts_count; i++) del_font(fg->fonts + i);
free(fg->fonts); fg->fonts = NULL;
}
static inline void
free_font_groups(void) {
if (font_groups) {