Fix problem with fonts that cant load completely

* fix reference counting for font_int(s)
 * properly backout if face doesnt load correctly, this way we dont end up
   using the face again
 * put some comments about fudged font cache


SVN revision: 29863
This commit is contained in:
Stafford Mitchell Horne 2007-05-05 10:30:11 +00:00
parent d783212329
commit f0c58de312
2 changed files with 37 additions and 9 deletions

View File

@ -158,6 +158,7 @@ evas_font_load(Evas *evas, const char *name, const char *source, int size)
} }
} }
} }
for (l = fonts_zero; l; l = l->next) for (l = fonts_zero; l; l = l->next)
{ {
fd = l->data; fd = l->data;
@ -330,8 +331,8 @@ evas_font_load(Evas *evas, const char *name, const char *source, int size)
FcPatternGet(set->fonts[i], FC_FILE, 0, &filename); FcPatternGet(set->fonts[i], FC_FILE, 0, &filename);
if (font) if (font)
evas->engine.func->font_add(evas->engine.data.output, font, (char *)filename.u.s, size); evas->engine.func->font_add(evas->engine.data.output, font, (char *)filename.u.s, size);
else else
font = evas->engine.func->font_load(evas->engine.data.output, (char *)filename.u.s, size); font = evas->engine.func->font_load(evas->engine.data.output, (char *)filename.u.s, size);
} }
@ -350,6 +351,7 @@ evas_font_load(Evas *evas, const char *name, const char *source, int size)
fd->ref = 1; fd->ref = 1;
fonts_cache = evas_list_prepend(fonts_cache, fd); fonts_cache = evas_list_prepend(fonts_cache, fd);
} }
if (font) if (font)
evas->engine.func->font_hinting_set(evas->engine.data.output, font, evas->engine.func->font_hinting_set(evas->engine.data.output, font,
evas->hinting); evas->hinting);

View File

@ -69,11 +69,20 @@ evas_common_font_source_load_complete(RGBA_Font_Source *fs)
int error; int error;
error = FT_New_Face(evas_ft_lib, fs->file, 0, &(fs->ft.face)); error = FT_New_Face(evas_ft_lib, fs->file, 0, &(fs->ft.face));
if (error) return error; if (error)
{
fs->ft.face = NULL;
return error;
}
error = FT_Select_Charmap(fs->ft.face, ft_encoding_unicode); error = FT_Select_Charmap(fs->ft.face, ft_encoding_unicode);
if (error) return error; if (error)
{
FT_Done_Face(fs->ft.face);
fs->ft.face = NULL;
return error;
}
fs->ft.orig_upem = fs->ft.face->units_per_EM; fs->ft.orig_upem = fs->ft.face->units_per_EM;
return error; return error;
} }
@ -123,6 +132,7 @@ evas_common_font_size_use(RGBA_Font *fn)
RGBA_Font_Int *fi; RGBA_Font_Int *fi;
fi = l->data; fi = l->data;
if (fi->src->current_size != fi->size) if (fi->src->current_size != fi->size)
{ {
FT_Activate_Size(fi->ft.size); FT_Activate_Size(fi->ft.size);
@ -278,6 +288,7 @@ evas_common_font_load(const char *name, int size)
fi = evas_common_font_int_load(name, size); fi = evas_common_font_int_load(name, size);
if (!fi) return NULL; if (!fi) return NULL;
/* First font, complete load */ /* First font, complete load */
if (!fi->ft.size) if (!fi->ft.size)
{ {
@ -285,9 +296,12 @@ evas_common_font_load(const char *name, int size)
{ {
if (evas_common_font_source_load_complete(fi->src)) if (evas_common_font_source_load_complete(fi->src))
{ {
fonts = evas_object_list_remove(fonts, fi); fi->references--;
evas_common_font_source_free(fi->src); if (fi->references == 0)
free(fi); {
evas_common_font_int_modify_cache_by(fi, 1);
evas_common_font_flush();
}
return NULL; return NULL;
} }
} }
@ -297,7 +311,12 @@ evas_common_font_load(const char *name, int size)
fn = calloc(1, sizeof(RGBA_Font)); fn = calloc(1, sizeof(RGBA_Font));
if (!fn) if (!fn)
{ {
free(fi); fi->references--;
if (fi->references == 0)
{
evas_common_font_int_modify_cache_by(fi, 1);
evas_common_font_flush();
}
return NULL; return NULL;
} }
fn->fonts = evas_list_append(fn->fonts, fi); fn->fonts = evas_list_append(fn->fonts, fi);
@ -472,6 +491,10 @@ font_modify_cache_cb(Evas_Hash *hash, const char *key, void *data, void *fdata)
key = 0; key = 0;
} }
/* when the fi->references == 0 we increase this instead of really deleting
* we then check if the cache_useage size is larger than allowed
* !If the cache is NOT too large we dont delete font_int
* !If the cache is too large we really delete font_int */
EAPI void EAPI void
evas_common_font_int_modify_cache_by(RGBA_Font_Int *fi, int dir) evas_common_font_int_modify_cache_by(RGBA_Font_Int *fi, int dir)
{ {
@ -519,6 +542,9 @@ font_flush_free_glyph_cb(Evas_Hash *hash, const char *key, void *data, void *fda
fdata = 0; fdata = 0;
} }
/* We run this when the cache gets larger than allowed size
* We check cache size each time a fi->references goes to 0
* PERFORMS: Find font_int(s) with references == 0 and delete them */
EAPI void EAPI void
evas_common_font_flush_last(void) evas_common_font_flush_last(void)
{ {