2006-10-08 06:00:26 -07:00
|
|
|
/*
|
|
|
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
|
|
|
*/
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
#include "evas_common.h"
|
2006-04-08 19:36:03 -07:00
|
|
|
#include "evas_private.h"
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2004-01-15 06:58:03 -08:00
|
|
|
extern FT_Library evas_ft_lib;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
|
|
|
static int font_cache_usage = 0;
|
|
|
|
static int font_cache = 0;
|
2008-10-17 04:23:18 -07:00
|
|
|
static Eina_Inlist * fonts_src = NULL;
|
|
|
|
static Eina_Inlist * fonts = NULL;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
static Evas_Bool font_modify_cache_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata);
|
|
|
|
static Evas_Bool font_flush_free_glyph_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata);
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font_Source *
|
2004-01-22 18:14:45 -08:00
|
|
|
evas_common_font_source_memory_load(const char *name, const void *data, int data_size)
|
|
|
|
{
|
2005-11-30 00:45:20 -08:00
|
|
|
int error;
|
2004-01-22 18:14:45 -08:00
|
|
|
RGBA_Font_Source *fs;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-11-30 00:45:20 -08:00
|
|
|
fs = calloc(1, sizeof(RGBA_Font_Source) + data_size);
|
2004-01-22 18:14:45 -08:00
|
|
|
if (!fs) return NULL;
|
2005-11-30 00:45:20 -08:00
|
|
|
fs->data = ((unsigned char *)fs) + sizeof(RGBA_Font_Source);
|
2005-12-01 19:15:08 -08:00
|
|
|
fs->data_size = data_size;
|
2004-01-22 21:58:34 -08:00
|
|
|
fs->current_size = 0;
|
2004-01-22 18:14:45 -08:00
|
|
|
memcpy(fs->data, data, data_size);
|
|
|
|
error = FT_New_Memory_Face(evas_ft_lib, fs->data, fs->data_size, 0, &(fs->ft.face));
|
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
free(fs);
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-10-15 07:38:34 -07:00
|
|
|
fs->name = eina_stringshare_add(name);
|
2005-12-01 19:15:08 -08:00
|
|
|
fs->file = NULL;
|
2004-01-26 00:21:00 -08:00
|
|
|
error = FT_Select_Charmap(fs->ft.face, ft_encoding_unicode);
|
|
|
|
fs->ft.orig_upem = fs->ft.face->units_per_EM;
|
2004-01-22 18:14:45 -08:00
|
|
|
fs->references = 1;
|
2008-10-17 04:23:18 -07:00
|
|
|
fonts_src = eina_inlist_prepend(fonts_src, EINA_INLIST_GET(fs));
|
2004-01-22 18:14:45 -08:00
|
|
|
return fs;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font_Source *
|
2004-01-22 18:14:45 -08:00
|
|
|
evas_common_font_source_load(const char *name)
|
|
|
|
{
|
|
|
|
RGBA_Font_Source *fs;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-11-30 00:45:20 -08:00
|
|
|
fs = calloc(1, sizeof(RGBA_Font_Source));
|
2004-01-22 18:14:45 -08:00
|
|
|
if (!fs) return NULL;
|
2004-01-22 21:58:34 -08:00
|
|
|
fs->data = NULL;
|
|
|
|
fs->data_size = 0;
|
|
|
|
fs->current_size = 0;
|
2006-04-08 17:02:47 -07:00
|
|
|
fs->ft.face = NULL;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2008-10-15 07:38:34 -07:00
|
|
|
fs->name = eina_stringshare_add(name);
|
2005-12-01 19:15:08 -08:00
|
|
|
fs->file = fs->name;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2006-04-08 17:02:47 -07:00
|
|
|
fs->ft.orig_upem = 0;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2004-01-22 18:14:45 -08:00
|
|
|
fs->references = 1;
|
2008-10-17 04:23:18 -07:00
|
|
|
fonts_src = eina_inlist_prepend(fonts_src, EINA_INLIST_GET(fs));
|
2004-01-22 18:14:45 -08:00
|
|
|
return fs;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI int
|
2006-04-08 17:02:47 -07:00
|
|
|
evas_common_font_source_load_complete(RGBA_Font_Source *fs)
|
|
|
|
{
|
|
|
|
int error;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
|
|
|
error = FT_New_Face(evas_ft_lib, fs->file, 0, &(fs->ft.face));
|
|
|
|
if (error)
|
2007-05-05 03:30:11 -07:00
|
|
|
{
|
|
|
|
fs->ft.face = NULL;
|
|
|
|
return error;
|
|
|
|
}
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2006-04-08 17:02:47 -07:00
|
|
|
error = FT_Select_Charmap(fs->ft.face, ft_encoding_unicode);
|
2008-07-10 11:12:45 -07:00
|
|
|
if (error)
|
2007-05-05 03:30:11 -07:00
|
|
|
{
|
|
|
|
FT_Done_Face(fs->ft.face);
|
|
|
|
fs->ft.face = NULL;
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2006-04-08 17:02:47 -07:00
|
|
|
fs->ft.orig_upem = fs->ft.face->units_per_EM;
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font_Source *
|
2004-01-22 18:14:45 -08:00
|
|
|
evas_common_font_source_find(const char *name)
|
|
|
|
{
|
2008-10-20 05:36:48 -07:00
|
|
|
RGBA_Font_Source *fs;
|
2004-01-23 03:03:07 -08:00
|
|
|
|
2004-01-22 18:14:45 -08:00
|
|
|
if (!name) return NULL;
|
2008-10-21 05:19:57 -07:00
|
|
|
EINA_INLIST_FOREACH(fonts_src, fs)
|
2004-01-22 18:14:45 -08:00
|
|
|
{
|
|
|
|
if ((fs->name) && (!strcmp(name, fs->name)))
|
|
|
|
{
|
2005-05-21 19:49:50 -07:00
|
|
|
fs->references++;
|
2008-10-17 04:23:18 -07:00
|
|
|
fonts_src = eina_inlist_demote(fonts_src, EINA_INLIST_GET(fs));
|
2004-01-22 18:14:45 -08:00
|
|
|
return fs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2004-01-22 18:14:45 -08:00
|
|
|
evas_common_font_source_free(RGBA_Font_Source *fs)
|
|
|
|
{
|
|
|
|
fs->references--;
|
|
|
|
if (fs->references > 0) return;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-10-17 04:23:18 -07:00
|
|
|
fonts_src = eina_inlist_remove(fonts_src, EINA_INLIST_GET(fs));
|
2004-01-22 18:14:45 -08:00
|
|
|
FT_Done_Face(fs->ft.face);
|
2008-07-10 11:12:45 -07:00
|
|
|
if (fs->charmap) evas_array_hash_free(fs->charmap);
|
2008-10-15 07:38:34 -07:00
|
|
|
if (fs->name) eina_stringshare_del(fs->name);
|
2004-01-22 18:14:45 -08:00
|
|
|
free(fs);
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2004-01-22 18:14:45 -08:00
|
|
|
evas_common_font_size_use(RGBA_Font *fn)
|
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
for (l = fn->fonts; l; l = l->next)
|
|
|
|
{
|
|
|
|
RGBA_Font_Int *fi;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi = l->data;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2005-03-20 09:14:41 -08:00
|
|
|
if (fi->src->current_size != fi->size)
|
|
|
|
{
|
|
|
|
FT_Activate_Size(fi->ft.size);
|
|
|
|
fi->src->current_size = fi->size;
|
|
|
|
}
|
2005-03-20 07:57:55 -08:00
|
|
|
}
|
2004-01-22 18:14:45 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font_Int *
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_int_memory_load(const char *name, int size, const void *data, int data_size)
|
2004-01-22 18:14:45 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
RGBA_Font_Int *fi;
|
2004-01-22 18:14:45 -08:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi = evas_common_font_int_find(name, size);
|
|
|
|
if (fi) return fi;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
|
|
|
fi = calloc(1, sizeof(RGBA_Font_Int));
|
2005-03-20 07:57:55 -08:00
|
|
|
if (!fi) return NULL;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi->src = evas_common_font_source_find(name);
|
2008-07-10 11:12:45 -07:00
|
|
|
if (!fi->src)
|
2006-04-08 17:02:47 -07:00
|
|
|
fi->src = evas_common_font_source_memory_load(name, data, data_size);
|
2004-01-22 18:14:45 -08:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
if (!fi->src)
|
2004-01-22 18:14:45 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
free(fi);
|
2004-01-22 18:14:45 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi->size = size;
|
2004-01-22 18:14:45 -08:00
|
|
|
|
2006-04-08 19:36:03 -07:00
|
|
|
fi = evas_common_font_int_load_init(fi);
|
|
|
|
evas_common_font_int_load_complete(fi);
|
|
|
|
|
|
|
|
return fi;
|
2004-01-22 18:14:45 -08:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font_Int *
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_int_load(const char *name, int size)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
RGBA_Font_Int *fi;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi = evas_common_font_int_find(name, size);
|
|
|
|
if (fi) return fi;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2005-05-21 19:49:50 -07:00
|
|
|
fi = calloc(1, sizeof(RGBA_Font_Int));
|
2005-03-20 07:57:55 -08:00
|
|
|
if (!fi) return NULL;
|
2005-01-31 01:32:31 -08:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi->src = evas_common_font_source_find(name);
|
2006-04-08 19:36:03 -07:00
|
|
|
if (!fi->src && evas_file_path_is_file(name))
|
2005-11-25 21:24:25 -08:00
|
|
|
fi->src = evas_common_font_source_load(name);
|
2004-01-22 18:14:45 -08:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
if (!fi->src)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
free(fi);
|
2002-11-08 00:02:15 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi->size = size;
|
2004-01-22 18:14:45 -08:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
return evas_common_font_int_load_init(fi);
|
2004-01-22 18:14:45 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font_Int *
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_int_load_init(RGBA_Font_Int *fi)
|
2006-04-08 17:02:47 -07:00
|
|
|
{
|
2006-04-08 19:36:03 -07:00
|
|
|
fi->ft.size = NULL;
|
2008-12-09 09:56:31 -08:00
|
|
|
fi->glyphs = eina_hash_int32_new(NULL);
|
2006-04-08 17:02:47 -07:00
|
|
|
fi->usage = 0;
|
|
|
|
fi->references = 1;
|
2008-10-17 04:23:18 -07:00
|
|
|
fonts = eina_inlist_prepend(fonts, EINA_INLIST_GET(fi));
|
2008-12-09 09:56:31 -08:00
|
|
|
|
2006-04-08 17:02:47 -07:00
|
|
|
return fi;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font_Int *
|
2006-04-08 17:02:47 -07:00
|
|
|
evas_common_font_int_load_complete(RGBA_Font_Int *fi)
|
2004-01-22 18:14:45 -08:00
|
|
|
{
|
|
|
|
int error;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
error = FT_New_Size(fi->src->ft.face, &(fi->ft.size));
|
2004-01-26 00:21:00 -08:00
|
|
|
if (!error)
|
2004-01-25 19:31:40 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
FT_Activate_Size(fi->ft.size);
|
2004-01-25 19:31:40 -08:00
|
|
|
}
|
2005-03-20 07:57:55 -08:00
|
|
|
fi->real_size = fi->size * 64;
|
|
|
|
error = FT_Set_Char_Size(fi->src->ft.face, 0, fi->real_size, 75, 75);
|
2002-11-08 00:02:15 -08:00
|
|
|
if (error)
|
2004-01-22 18:14:45 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
fi->real_size = fi->size;
|
|
|
|
error = FT_Set_Pixel_Sizes(fi->src->ft.face, 0, fi->real_size);
|
2004-01-22 18:14:45 -08:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int chosen_size = 0;
|
|
|
|
int chosen_width = 0;
|
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
for (i = 0; i < fi->src->ft.face->num_fixed_sizes; i++)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
int s;
|
|
|
|
int d, cd;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
s = fi->src->ft.face->available_sizes[i].height;
|
|
|
|
cd = chosen_size - fi->size;
|
2002-11-08 00:02:15 -08:00
|
|
|
if (cd < 0) cd = -cd;
|
2005-03-20 07:57:55 -08:00
|
|
|
d = s - fi->size;
|
2002-11-08 00:02:15 -08:00
|
|
|
if (d < 0) d = -d;
|
|
|
|
if (d < cd)
|
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
chosen_width = fi->src->ft.face->available_sizes[i].width;
|
2002-11-08 00:02:15 -08:00
|
|
|
chosen_size = s;
|
|
|
|
}
|
|
|
|
if (d == 0) break;
|
|
|
|
}
|
2005-03-20 07:57:55 -08:00
|
|
|
fi->real_size = chosen_size;
|
|
|
|
error = FT_Set_Pixel_Sizes(fi->src->ft.face, chosen_width, fi->real_size);
|
2002-11-08 00:02:15 -08:00
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
/* couldn't choose the size anyway... what now? */
|
|
|
|
}
|
|
|
|
}
|
2005-03-20 07:57:55 -08:00
|
|
|
fi->src->current_size = fi->size;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
return fi;
|
|
|
|
}
|
2008-07-16 13:46:47 -07:00
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font *
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_memory_load(const char *name, int size, const void *data, int data_size)
|
|
|
|
{
|
|
|
|
RGBA_Font *fn;
|
|
|
|
RGBA_Font_Int *fi;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi = evas_common_font_int_memory_load(name, size, data, data_size);
|
|
|
|
if (!fi) return NULL;
|
|
|
|
fn = calloc(1, sizeof(RGBA_Font));
|
2005-08-26 01:00:49 -07:00
|
|
|
if (!fn)
|
2006-02-27 06:03:27 -08:00
|
|
|
{
|
|
|
|
free(fi);
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-10-21 09:31:05 -07:00
|
|
|
fn->fonts = eina_list_append(fn->fonts, fi);
|
2006-02-27 06:03:27 -08:00
|
|
|
fn->hinting = FONT_BYTECODE_HINT;
|
|
|
|
fi->hinting = fn->hinting;
|
2006-11-13 15:23:44 -08:00
|
|
|
fn->references = 1;
|
|
|
|
LKI(fn->lock);
|
2002-11-08 00:02:15 -08:00
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font *
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_load(const char *name, int size)
|
|
|
|
{
|
|
|
|
RGBA_Font *fn;
|
|
|
|
RGBA_Font_Int *fi;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi = evas_common_font_int_load(name, size);
|
|
|
|
if (!fi) return NULL;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
|
|
|
/* First font, complete load */
|
2006-04-08 17:02:47 -07:00
|
|
|
if (!fi->ft.size)
|
|
|
|
{
|
|
|
|
if (!fi->src->ft.face)
|
|
|
|
{
|
|
|
|
if (evas_common_font_source_load_complete(fi->src))
|
|
|
|
{
|
2007-05-05 03:30:11 -07:00
|
|
|
fi->references--;
|
|
|
|
if (fi->references == 0)
|
|
|
|
{
|
|
|
|
evas_common_font_int_modify_cache_by(fi, 1);
|
|
|
|
evas_common_font_flush();
|
|
|
|
}
|
2006-04-08 17:02:47 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
evas_common_font_int_load_complete(fi);
|
|
|
|
}
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fn = calloc(1, sizeof(RGBA_Font));
|
2005-08-26 01:00:49 -07:00
|
|
|
if (!fn)
|
2006-02-27 06:03:27 -08:00
|
|
|
{
|
2008-07-10 11:12:45 -07:00
|
|
|
fi->references--;
|
|
|
|
if (fi->references == 0)
|
2007-05-05 03:30:11 -07:00
|
|
|
{
|
|
|
|
evas_common_font_int_modify_cache_by(fi, 1);
|
|
|
|
evas_common_font_flush();
|
|
|
|
}
|
2006-02-27 06:03:27 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-10-21 09:31:05 -07:00
|
|
|
fn->fonts = eina_list_append(fn->fonts, fi);
|
2006-02-27 06:03:27 -08:00
|
|
|
fn->hinting = FONT_BYTECODE_HINT;
|
|
|
|
fi->hinting = fn->hinting;
|
2006-11-13 15:23:44 -08:00
|
|
|
fn->references = 1;
|
|
|
|
LKI(fn->lock);
|
2005-03-20 07:57:55 -08:00
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font *
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_add(RGBA_Font *fn, const char *name, int size)
|
|
|
|
{
|
|
|
|
RGBA_Font_Int *fi;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-08-26 01:00:49 -07:00
|
|
|
if (!fn)
|
|
|
|
return NULL;
|
2005-03-20 07:57:55 -08:00
|
|
|
fi = evas_common_font_int_load(name, size);
|
|
|
|
if (fi)
|
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
fn->fonts = eina_list_append(fn->fonts, fi);
|
2006-02-27 07:40:46 -08:00
|
|
|
fi->hinting = fn->hinting;
|
2005-03-20 08:41:49 -08:00
|
|
|
return fn;
|
2005-03-20 07:57:55 -08:00
|
|
|
}
|
2005-03-20 08:41:49 -08:00
|
|
|
return NULL;
|
2005-03-20 07:57:55 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font *
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_memory_add(RGBA_Font *fn, const char *name, int size, const void *data, int data_size)
|
|
|
|
{
|
|
|
|
RGBA_Font_Int *fi;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-08-26 01:00:49 -07:00
|
|
|
if (!fn)
|
|
|
|
return NULL;
|
2005-03-20 07:57:55 -08:00
|
|
|
fi = evas_common_font_int_memory_load(name, size, data, data_size);
|
|
|
|
if (fi)
|
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
fn->fonts = eina_list_append(fn->fonts, fi);
|
2006-02-27 07:40:46 -08:00
|
|
|
fi->hinting = fn->hinting;
|
2005-03-20 08:41:49 -08:00
|
|
|
return fn;
|
2005-03-20 07:57:55 -08:00
|
|
|
}
|
2005-03-20 08:41:49 -08:00
|
|
|
return NULL;
|
2005-03-20 07:57:55 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_font_free(RGBA_Font *fn)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
2008-12-09 09:56:31 -08:00
|
|
|
RGBA_Font_Int *fi;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-08-26 01:00:49 -07:00
|
|
|
if (!fn)
|
|
|
|
return;
|
2006-11-13 15:23:44 -08:00
|
|
|
fn->references--;
|
|
|
|
if (fn->references > 0) return;
|
2008-12-09 09:56:31 -08:00
|
|
|
EINA_LIST_FOREACH(fn->fonts, l, fi)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
fi->references--;
|
|
|
|
if (fi->references == 0)
|
|
|
|
{
|
|
|
|
evas_common_font_int_modify_cache_by(fi, 1);
|
|
|
|
evas_common_font_flush();
|
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2008-10-21 09:31:05 -07:00
|
|
|
eina_list_free(fn->fonts);
|
2006-11-13 15:23:44 -08:00
|
|
|
LKD(fn->lock);
|
2005-03-20 07:57:55 -08:00
|
|
|
free(fn);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2006-02-27 06:03:27 -08:00
|
|
|
evas_common_font_hinting_set(RGBA_Font *fn, Font_Hint_Flags hinting)
|
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
2008-12-09 09:56:31 -08:00
|
|
|
RGBA_Font_Int *fi;
|
2008-07-10 11:12:45 -07:00
|
|
|
|
2006-02-27 06:03:27 -08:00
|
|
|
if (!fn)
|
|
|
|
return;
|
|
|
|
fn->hinting = hinting;
|
2008-12-09 09:56:31 -08:00
|
|
|
EINA_LIST_FOREACH(fn->fonts, l, fi)
|
|
|
|
fi->hinting = fn->hinting;
|
2006-02-27 06:03:27 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI Evas_Bool
|
2006-02-27 06:03:27 -08:00
|
|
|
evas_common_hinting_available(Font_Hint_Flags hinting)
|
|
|
|
{
|
2006-10-08 06:00:26 -07:00
|
|
|
switch (hinting)
|
2006-02-27 06:03:27 -08:00
|
|
|
{
|
2006-10-08 06:00:26 -07:00
|
|
|
case FONT_NO_HINT:
|
|
|
|
case FONT_AUTO_HINT:
|
|
|
|
/* these two hinting modes are always available */
|
|
|
|
return 1;
|
|
|
|
case FONT_BYTECODE_HINT:
|
|
|
|
/* Only use the bytecode interpreter if support for the _patented_
|
|
|
|
* algorithms is available because the free bytecode
|
|
|
|
* interpreter's results are too crappy.
|
|
|
|
*
|
|
|
|
* On freetyp 2.2+, we can ask the library about support for
|
|
|
|
* the patented interpreter. On older versions, we need to use
|
|
|
|
* macros to check for it.
|
|
|
|
*/
|
|
|
|
#if FREETYPE_MINOR >= 2
|
|
|
|
return FT_Get_TrueType_Engine_Type(evas_ft_lib) >=
|
|
|
|
FT_TRUETYPE_ENGINE_TYPE_PATENTED;
|
2006-02-27 06:03:27 -08:00
|
|
|
#else
|
2006-10-08 06:58:58 -07:00
|
|
|
/* we may not rely on TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
|
|
|
* here to find out whether it's supported.
|
|
|
|
*
|
|
|
|
* so, assume it is. o_O
|
|
|
|
*/
|
2006-10-08 06:00:26 -07:00
|
|
|
return 1;
|
2006-02-27 06:03:27 -08:00
|
|
|
#endif
|
|
|
|
}
|
2006-10-08 06:00:26 -07:00
|
|
|
|
|
|
|
/* shouldn't get here - need to add another case statement */
|
2006-02-27 06:03:27 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font *
|
2006-02-27 07:40:46 -08:00
|
|
|
evas_common_font_memory_hinting_load(const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting)
|
|
|
|
{
|
|
|
|
RGBA_Font *fn;
|
|
|
|
|
|
|
|
fn = evas_common_font_memory_load(name, size, data, data_size);
|
|
|
|
if (fn) evas_common_font_hinting_set(fn, hinting);
|
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font *
|
2006-02-27 07:40:46 -08:00
|
|
|
evas_common_font_hinting_load(const char *name, int size, Font_Hint_Flags hinting)
|
|
|
|
{
|
|
|
|
RGBA_Font *fn;
|
|
|
|
|
|
|
|
fn = evas_common_font_load(name, size);
|
|
|
|
if (fn) evas_common_font_hinting_set(fn, hinting);
|
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font *
|
2006-02-27 07:40:46 -08:00
|
|
|
evas_common_font_hinting_add(RGBA_Font *fn, const char *name, int size, Font_Hint_Flags hinting)
|
|
|
|
{
|
|
|
|
fn = evas_common_font_add(fn, name, size);
|
|
|
|
if (fn) evas_common_font_hinting_set(fn, hinting);
|
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font *
|
2006-02-27 07:40:46 -08:00
|
|
|
evas_common_font_memory_hinting_add(RGBA_Font *fn, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting)
|
|
|
|
{
|
|
|
|
fn = evas_common_font_memory_add(fn, name, size, data, data_size);
|
|
|
|
if (fn) evas_common_font_hinting_set(fn, hinting);
|
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
static Eina_Bool
|
|
|
|
font_modify_cache_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
int *dir;
|
|
|
|
RGBA_Font_Glyph *fg;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
|
|
|
fg = data;
|
2002-11-08 00:02:15 -08:00
|
|
|
dir = fdata;
|
2005-05-21 19:49:50 -07:00
|
|
|
font_cache_usage += (*dir) *
|
2002-11-08 00:02:15 -08:00
|
|
|
((fg->glyph_out->bitmap.width * fg->glyph_out->bitmap.rows) +
|
2008-10-21 09:31:05 -07:00
|
|
|
sizeof(RGBA_Font_Glyph) + sizeof(Eina_List) + 400); /* fudge values */
|
2002-11-08 00:02:15 -08:00
|
|
|
return 1;
|
|
|
|
hash = 0;
|
|
|
|
key = 0;
|
|
|
|
}
|
|
|
|
|
2007-05-05 03:30:11 -07:00
|
|
|
/* when the fi->references == 0 we increase this instead of really deleting
|
2008-07-10 11:12:45 -07:00
|
|
|
* we then check if the cache_useage size is larger than allowed
|
|
|
|
* !If the cache is NOT too large we dont delete font_int
|
2007-05-05 03:30:11 -07:00
|
|
|
* !If the cache is too large we really delete font_int */
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_int_modify_cache_by(RGBA_Font_Int *fi, int dir)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2004-01-22 18:14:45 -08:00
|
|
|
int sz_hash = 0;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
if (fi->glyphs) sz_hash = eina_hash_population(fi->glyphs);
|
|
|
|
eina_hash_foreach(fi->glyphs, font_modify_cache_cb, &dir);
|
2004-01-22 18:14:45 -08:00
|
|
|
font_cache_usage += dir * (sizeof(RGBA_Font) + sz_hash +
|
2002-11-08 00:02:15 -08:00
|
|
|
sizeof(FT_FaceRec) + 16384); /* fudge values */
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI int
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_font_cache_get(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
return font_cache;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_font_cache_set(int size)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
font_cache = size;
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_font_flush();
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_font_flush(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
if (font_cache_usage < font_cache) return;
|
2002-11-13 21:38:10 -08:00
|
|
|
while (font_cache_usage > font_cache) evas_common_font_flush_last();
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
static Eina_Bool
|
|
|
|
font_flush_free_glyph_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
RGBA_Font_Glyph *fg;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
fg = data;
|
|
|
|
FT_Done_Glyph(fg->glyph);
|
2003-09-08 22:51:03 -07:00
|
|
|
/* extension calls */
|
|
|
|
if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat);
|
2002-11-08 00:02:15 -08:00
|
|
|
free(fg);
|
|
|
|
return 1;
|
|
|
|
hash = 0;
|
|
|
|
key = 0;
|
|
|
|
fdata = 0;
|
|
|
|
}
|
|
|
|
|
2007-05-05 03:30:11 -07:00
|
|
|
/* 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 */
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_font_flush_last(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2008-10-20 05:36:48 -07:00
|
|
|
RGBA_Font_Int *fi_tmp;
|
2005-03-20 07:57:55 -08:00
|
|
|
RGBA_Font_Int *fi = NULL;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-10-21 05:19:57 -07:00
|
|
|
EINA_INLIST_FOREACH(fonts, fi_tmp)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
if (fi_tmp->references == 0) fi = fi_tmp;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-03-20 07:57:55 -08:00
|
|
|
if (!fi) return;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
FT_Done_Size(fi->ft.size);
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-10-17 04:23:18 -07:00
|
|
|
fonts = eina_inlist_remove(fonts, EINA_INLIST_GET(fi));
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_int_modify_cache_by(fi, -1);
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
eina_hash_foreach(fi->glyphs, font_flush_free_glyph_cb, NULL);
|
|
|
|
eina_hash_free(fi->glyphs);
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_source_free(fi->src);
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
free(fi);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font_Int *
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_int_find(const char *name, int size)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2008-10-20 05:36:48 -07:00
|
|
|
RGBA_Font_Int *fi;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-10-21 05:19:57 -07:00
|
|
|
EINA_INLIST_FOREACH(fonts, fi)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
if ((fi->size == size) && (!strcmp(name, fi->src->name)))
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-03-20 07:57:55 -08:00
|
|
|
if (fi->references == 0) evas_common_font_int_modify_cache_by(fi, -1);
|
|
|
|
fi->references++;
|
2008-10-17 04:23:18 -07:00
|
|
|
fonts = eina_inlist_promote(fonts, EINA_INLIST_GET(fi));
|
2005-03-20 07:57:55 -08:00
|
|
|
return fi;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|