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.
This commit is contained in:
Daniel Eklöf 2019-08-13 20:41:21 +02:00
parent c2451e2a80
commit 8035bbfbdb
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

6
font.c
View file

@ -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);