forked from enlightenment/efl
* evas_font_dir: reduce use of FcFontSort by using cache as much as possible.
This reduce in EWeather the time spend in FcFontSort from 25% of the startup time to 1% with a small memory footprint increase. SVN revision: 44444
This commit is contained in:
parent
576d5f7091
commit
0ccf619ba0
|
@ -31,6 +31,11 @@ struct _Fndat
|
||||||
int size;
|
int size;
|
||||||
void *font;
|
void *font;
|
||||||
int ref;
|
int ref;
|
||||||
|
|
||||||
|
#ifdef HAVE_FONTCONFIG
|
||||||
|
FcFontSet *set;
|
||||||
|
FcPattern *p_nm;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* private methods for font dir cache */
|
/* private methods for font dir cache */
|
||||||
|
@ -51,15 +56,16 @@ static int fc_init = 0;
|
||||||
void
|
void
|
||||||
evas_font_dir_cache_free(void)
|
evas_font_dir_cache_free(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_FONTCONFIG
|
|
||||||
fc_init--;
|
|
||||||
if (fc_init == 0) FcFini();
|
|
||||||
#endif
|
|
||||||
if (!font_dirs) return;
|
if (!font_dirs) return;
|
||||||
|
|
||||||
eina_hash_foreach(font_dirs, font_cache_dir_free, NULL);
|
eina_hash_foreach(font_dirs, font_cache_dir_free, NULL);
|
||||||
eina_hash_free(font_dirs);
|
eina_hash_free(font_dirs);
|
||||||
font_dirs = NULL;
|
font_dirs = NULL;
|
||||||
|
|
||||||
|
#ifdef HAVE_FONTCONFIG
|
||||||
|
fc_init--;
|
||||||
|
if (fc_init == 0) FcFini();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -124,6 +130,8 @@ evas_fonts_zero_free(Evas *evas)
|
||||||
if (fd->name) eina_stringshare_del(fd->name);
|
if (fd->name) eina_stringshare_del(fd->name);
|
||||||
if (fd->source) eina_stringshare_del(fd->source);
|
if (fd->source) eina_stringshare_del(fd->source);
|
||||||
evas->engine.func->font_free(evas->engine.data.output, fd->font);
|
evas->engine.func->font_free(evas->engine.data.output, fd->font);
|
||||||
|
if (fd->set) FcFontSetDestroy(fd->set);
|
||||||
|
if (fd->p_nm) FcPatternDestroy(fd->p_nm);
|
||||||
free(fd);
|
free(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,6 +152,8 @@ evas_fonts_zero_presure(Evas *evas)
|
||||||
if (fd->name) eina_stringshare_del(fd->name);
|
if (fd->name) eina_stringshare_del(fd->name);
|
||||||
if (fd->source) eina_stringshare_del(fd->source);
|
if (fd->source) eina_stringshare_del(fd->source);
|
||||||
evas->engine.func->font_free(evas->engine.data.output, fd->font);
|
evas->engine.func->font_free(evas->engine.data.output, fd->font);
|
||||||
|
if (fd->set) FcFontSetDestroy(fd->set);
|
||||||
|
if (fd->p_nm) FcPatternDestroy(fd->p_nm);
|
||||||
free(fd);
|
free(fd);
|
||||||
|
|
||||||
if (eina_list_count(fonts_zero) < 5) break;
|
if (eina_list_count(fonts_zero) < 5) break;
|
||||||
|
@ -180,6 +190,8 @@ evas_font_free(Evas *evas, void *font)
|
||||||
if (fd->name) eina_stringshare_del(fd->name);
|
if (fd->name) eina_stringshare_del(fd->name);
|
||||||
if (fd->source) eina_stringshare_del(fd->source);
|
if (fd->source) eina_stringshare_del(fd->source);
|
||||||
evas->engine.func->font_free(evas->engine.data.output, fd->font);
|
evas->engine.func->font_free(evas->engine.data.output, fd->font);
|
||||||
|
if (fd->set) FcFontSetDestroy(fd->set);
|
||||||
|
if (fd->p_nm) FcPatternDestroy(fd->p_nm);
|
||||||
free(fd);
|
free(fd);
|
||||||
|
|
||||||
if (eina_list_count(fonts_zero) < 43) break;
|
if (eina_list_count(fonts_zero) < 43) break;
|
||||||
|
@ -202,9 +214,36 @@ evas_font_init(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
evas_load_fontconfig(Evas *evas, FcFontSet *set, int size)
|
||||||
|
{
|
||||||
|
void *font = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Do loading for all in family */
|
||||||
|
for (i = 0; i < set->nfont; i++)
|
||||||
|
{
|
||||||
|
FcValue filename;
|
||||||
|
|
||||||
|
FcPatternGet(set->fonts[i], FC_FILE, 0, &filename);
|
||||||
|
|
||||||
|
if (font)
|
||||||
|
evas->engine.func->font_add(evas->engine.data.output, font, (char *)filename.u.s, size);
|
||||||
|
else
|
||||||
|
font = evas->engine.func->font_load(evas->engine.data.output, (char *)filename.u.s, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
evas_font_load(Evas *evas, const char *name, const char *source, int size)
|
evas_font_load(Evas *evas, const char *name, const char *source, int size)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_FONTCONFIG
|
||||||
|
FcPattern *p_nm = NULL;
|
||||||
|
FcFontSet *set = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
void *font = NULL;
|
void *font = NULL;
|
||||||
Eina_List *fonts, *l;
|
Eina_List *fonts, *l;
|
||||||
Fndat *fd;
|
Fndat *fd;
|
||||||
|
@ -228,6 +267,11 @@ evas_font_load(Evas *evas, const char *name, const char *source, int size)
|
||||||
fd->ref++;
|
fd->ref++;
|
||||||
return fd->font;
|
return fd->font;
|
||||||
}
|
}
|
||||||
|
else if (fd->set && fd->p_nm)
|
||||||
|
{
|
||||||
|
font = evas_load_fontconfig(evas, fd->set, size);
|
||||||
|
goto on_find;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,6 +290,11 @@ evas_font_load(Evas *evas, const char *name, const char *source, int size)
|
||||||
fd->ref++;
|
fd->ref++;
|
||||||
return fd->font;
|
return fd->font;
|
||||||
}
|
}
|
||||||
|
else if (fd->set && fd->p_nm)
|
||||||
|
{
|
||||||
|
font = evas_load_fontconfig(evas, fd->set, size);
|
||||||
|
goto on_find;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,10 +430,7 @@ evas_font_load(Evas *evas, const char *name, const char *source, int size)
|
||||||
#ifdef HAVE_FONTCONFIG
|
#ifdef HAVE_FONTCONFIG
|
||||||
if (!font) /* Search using fontconfig */
|
if (!font) /* Search using fontconfig */
|
||||||
{
|
{
|
||||||
FcPattern *p_nm = NULL;
|
|
||||||
FcFontSet *set;
|
|
||||||
FcResult res;
|
FcResult res;
|
||||||
int i;
|
|
||||||
|
|
||||||
p_nm = FcNameParse((FcChar8 *)name);
|
p_nm = FcNameParse((FcChar8 *)name);
|
||||||
FcConfigSubstitute(NULL, p_nm, FcMatchPattern);
|
FcConfigSubstitute(NULL, p_nm, FcMatchPattern);
|
||||||
|
@ -395,28 +441,15 @@ evas_font_load(Evas *evas, const char *name, const char *source, int size)
|
||||||
if (!set)
|
if (!set)
|
||||||
{
|
{
|
||||||
ERR("No fontconfig font matches '%s'. It was the last resource, no font found!", name);
|
ERR("No fontconfig font matches '%s'. It was the last resource, no font found!", name);
|
||||||
goto fc_end;
|
FcPatternDestroy(p_nm);
|
||||||
|
p_nm = NULL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Do loading for all in family */
|
font = evas_load_fontconfig(evas, set, size);
|
||||||
for (i = 0; i < set->nfont; i++)
|
|
||||||
{
|
|
||||||
FcValue filename;
|
|
||||||
|
|
||||||
FcPatternGet(set->fonts[i], FC_FILE, 0, &filename);
|
|
||||||
|
|
||||||
if (font)
|
|
||||||
evas->engine.func->font_add(evas->engine.data.output, font, (char *)filename.u.s, size);
|
|
||||||
else
|
|
||||||
font = evas->engine.func->font_load(evas->engine.data.output, (char *)filename.u.s, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
FcFontSetDestroy(set);
|
|
||||||
fc_end:
|
|
||||||
FcPatternDestroy(p_nm);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
on_find:
|
||||||
fd = calloc(1, sizeof(Fndat));
|
fd = calloc(1, sizeof(Fndat));
|
||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
|
@ -426,6 +459,10 @@ evas_font_load(Evas *evas, const char *name, const char *source, int size)
|
||||||
fd->font = font;
|
fd->font = font;
|
||||||
fd->ref = 1;
|
fd->ref = 1;
|
||||||
fonts_cache = eina_list_prepend(fonts_cache, fd);
|
fonts_cache = eina_list_prepend(fonts_cache, fd);
|
||||||
|
#ifdef HAVE_FONTCONFIG
|
||||||
|
fd->set = set;
|
||||||
|
fd->p_nm = p_nm;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (font)
|
if (font)
|
||||||
|
|
Loading…
Reference in New Issue