forked from external/yambar
font: cache loaded fonts
Instantiating a new font is expensive, both in CPU and memory. Mitigate by adding a cache. On a hit, instead of instantiating a new font, clone the one from the cache. Remember, cloning is basically just a ref counter bump.
This commit is contained in:
parent
fae2e5cb18
commit
7525ae99eb
1 changed files with 18 additions and 0 deletions
18
font.c
18
font.c
|
@ -10,12 +10,15 @@
|
||||||
#define LOG_MODULE "font"
|
#define LOG_MODULE "font"
|
||||||
#define LOG_ENABLE_DBG 0
|
#define LOG_ENABLE_DBG 0
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "tllist.h"
|
||||||
|
|
||||||
struct font {
|
struct font {
|
||||||
char *name;
|
char *name;
|
||||||
cairo_scaled_font_t *scaled_font;
|
cairo_scaled_font_t *scaled_font;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static tll(const struct font *) cache = tll_init();
|
||||||
|
|
||||||
static void __attribute__((constructor))
|
static void __attribute__((constructor))
|
||||||
init(void)
|
init(void)
|
||||||
{
|
{
|
||||||
|
@ -37,11 +40,18 @@ static void __attribute__((destructor))
|
||||||
fini(void)
|
fini(void)
|
||||||
{
|
{
|
||||||
FcFini();
|
FcFini();
|
||||||
|
assert(tll_length(cache) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct font *
|
struct font *
|
||||||
font_new(const char *name)
|
font_new(const char *name)
|
||||||
{
|
{
|
||||||
|
/* Check if font have already been loaded */
|
||||||
|
tll_foreach(cache, it) {
|
||||||
|
if (strcmp(name, it->item->name) == 0)
|
||||||
|
return font_clone(it->item);
|
||||||
|
}
|
||||||
|
|
||||||
FcPattern *pattern = FcNameParse((const unsigned char *)name);
|
FcPattern *pattern = FcNameParse((const unsigned char *)name);
|
||||||
if (pattern == NULL) {
|
if (pattern == NULL) {
|
||||||
LOG_ERR("%s: failed to lookup font", name);
|
LOG_ERR("%s: failed to lookup font", name);
|
||||||
|
@ -104,6 +114,7 @@ font_new(const char *name)
|
||||||
font->name = strdup(name);
|
font->name = strdup(name);
|
||||||
font->scaled_font = scaled_font;
|
font->scaled_font = scaled_font;
|
||||||
|
|
||||||
|
tll_push_back(cache, font);
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +135,13 @@ font_destroy(struct font *font)
|
||||||
if (font == NULL)
|
if (font == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
tll_foreach(cache, it) {
|
||||||
|
if (it->item == font) {
|
||||||
|
tll_remove(cache, it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cairo_scaled_font_destroy(font->scaled_font);
|
cairo_scaled_font_destroy(font->scaled_font);
|
||||||
free(font->name);
|
free(font->name);
|
||||||
free(font);
|
free(font);
|
||||||
|
|
Loading…
Add table
Reference in a new issue