From 8035bbfbdbd7412799ec06f6bb2fe1f74d450d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 13 Aug 2019 20:41:21 +0200 Subject: [PATCH] font: handle invalid glyphs correctly *All* glyphs are cached. But we never set the 'wc' member of failed glyphs, causing a later cache lookup of the same glyph miss in the cache, and thus re-generate yet another glyph (that is inserted into the cache). I.e. if the same (invalid) glyph is rendered over and over again, we'll end up growing the cache indefinitely. Fix by setting the 'wc' member of invalid glyphs. This causes a cache lookup to hit. But, we must also check the glyphs validity, and return NULL if the glyph isn't valid. Finally, when destroying a font, skip invalid glyphs, since they have no resources that needs to be freed. --- font.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/font.c b/font.c index c5fd2629..7ea22f41 100644 --- a/font.c +++ b/font.c @@ -433,6 +433,7 @@ glyph_for_wchar(struct font *font, wchar_t wc, struct glyph *glyph) err: *glyph = (struct glyph){ + .wc = wc, .valid = false, }; return false; @@ -451,7 +452,7 @@ font_glyph_for_wc(struct font *font, wchar_t wc) tll_foreach(*hash_entry, it) { if (it->item.wc == wc) { mtx_unlock(&font->lock); - return &it->item; + return it->item.valid ? &it->item : NULL; } } } @@ -499,6 +500,9 @@ font_destroy(struct font *font) continue; tll_foreach(*font->cache[i], it) { + if (!it->item.valid) + continue; + cairo_surface_flush(it->item.surf); void *image = cairo_image_surface_get_data(it->item.surf);