Add font charmap caching

* TODO: store cache on disc, for faster cache loading (this requires EET to support arrays)


SVN revision: 22294
This commit is contained in:
Stafford Mitchell Horne 2006-04-22 11:08:01 +00:00
parent 1d905fc19b
commit 88edaa2e02
7 changed files with 188 additions and 15 deletions

View File

@ -616,7 +616,7 @@ object_text_font_cache_dir_add(char *dir)
Evas_Font_Alias *fa;
/* skip comments */
if ((fdef[0] == '!') || (fdef[0] == '#')) continue;
if ((fname[0] == '!') || (fname[0] == '#')) continue;
fa = calloc(1, sizeof(Evas_Font_Alias));
if (fa)
{

View File

@ -403,7 +403,7 @@ evas_hash_free(Evas_Hash *hash)
*
* This function goes through every entry in the hash table @p hash and calls
* the function @p func on each member. The function should NOT modify the
* hash table contents if it reeturns 1. IF the hash table contents are
* hash table contents if it returns 1. IF the hash table contents are
* modified by this function or the function wishes to stop processing it must
* return 0, otherwise return 1 to keep processing.
*

View File

@ -53,6 +53,7 @@ evas_scale_sample.c \
evas_scale_smooth.c \
evas_tiler.c \
evas_regionbuf.c \
evas_array_hash.c \
evas_blend_ops.h
EXTRA_DIST = \

View File

@ -0,0 +1,114 @@
#include "evas_common.h"
#define EAH_BUCKETS 256
#define EAH_HASH(key) \
( key % EAH_BUCKETS )
typedef struct _Evas_Array_Hash_El Evas_Array_Hash_El;
struct _Evas_Array_Hash
{
Evas_Array_Hash_El *buckets[EAH_BUCKETS];
};
struct _Evas_Array_Hash_El
{
int data_max;
int data_count;
int *data;
};
/*
These functions provide an interface for a simple hash. The hash
is and array of int array pointers. Right now that hash size is 256.
The hash size is static. The key and data are ints.
Keys must be added in ascending order because the search function
assumes that the hash buckets are sorted.
*/
Evas_Array_Hash *
evas_common_array_hash_new(void)
{
Evas_Array_Hash *hash;
hash = calloc(1, sizeof(Evas_Array_Hash));
return hash;
}
void
evas_common_array_hash_free(Evas_Array_Hash *hash)
{
int i;
for (i = 0; i < EAH_BUCKETS; i++)
{
if (hash->buckets[i])
{
free(hash->buckets[i]->data);
free(hash->buckets[i]);
}
}
free(hash);
}
void
evas_common_array_hash_add(Evas_Array_Hash *hash, int key, int data)
{
int hash_val;
Evas_Array_Hash_El *el;
hash_val = EAH_HASH(key);
el = hash->buckets[hash_val];
if (!el)
{
el = malloc(sizeof(Evas_Array_Hash_El));
el->data_max = 1 << 5;
el->data = malloc(sizeof(int) * el->data_max);
el->data_count = 0;
hash->buckets[hash_val] = el;
}
else if (el->data_count == el->data_max)
{
el->data_max = el->data_max << 1;
el->data = realloc(el->data, sizeof(int) * el->data_max);
}
el->data[el->data_count++] = key;
el->data[el->data_count++] = data;
}
int
evas_common_array_hash_search(Evas_Array_Hash *hash, int key)
{
int hash_val;
Evas_Array_Hash_El *el;
int low, high, i, val;
hash_val = EAH_HASH(key);
el = hash->buckets[hash_val];
if (!el)
return 0;
/* Binary Search the bucket for key */
low = 0;
high = ( el->data_count / 2 ) - 1;
while ( high >= low )
{
i = (high + low) / 2;
val = el->data[i << 1];
if (val == key)
return el->data[(i << 1) + 1];
else if (val > key)
high = i - 1;
else
low = i + 1;
}
return 0;
}

View File

@ -62,20 +62,67 @@ evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl)
{
RGBA_Font_Int *fi;
int index;
fi = l->data;
if (!fi->ft.size)
if (fi->src->charmap) /* Charmap loaded, FI/FS blank */
{
if (!fi->src->ft.face)
evas_common_font_source_load_complete(fi->src);
evas_common_font_int_load_complete(fi);
index = evas_common_array_hash_search(fi->src->charmap, gl);
if (index != 0)
{
evas_common_font_source_load_complete(fi->src);
evas_common_font_int_load_complete(fi);
evas_common_array_hash_free(fi->src->charmap);
fi->src->charmap = NULL;
*fi_ret = fi;
return index;
}
}
index = FT_Get_Char_Index(fi->src->ft.face, gl);
if (index != 0)
else if (!fi->src->ft.face) /* Charmap not loaded, FI/FS blank */
{
*fi_ret = fi;
return index;
if (evas_common_font_source_load_complete(fi->src));
return 0;
index = FT_Get_Char_Index(fi->src->ft.face, gl);
if (index == 0)
{
/* Load Hash */
FT_ULong charcode;
FT_UInt gindex;
fi->src->charmap = evas_common_array_hash_new();
charcode = FT_Get_First_Char(fi->src->ft.face, &gindex );
while ( gindex != 0 )
{
evas_common_array_hash_add(fi->src->charmap, charcode, gindex);
charcode = FT_Get_Next_Char(fi->src->ft.face, charcode, &gindex );
}
/* Free face */
FT_Done_Face(fi->src->ft.face);
fi->src->ft.face = NULL;
}
else
{
evas_common_font_int_load_complete(fi);
*fi_ret = fi;
return index;
}
}
else /* Charmap not loaded, FS loaded */
{
index = FT_Get_Char_Index(fi->src->ft.face, gl);
if (index != 0)
{
if (!fi->ft.size)
evas_common_font_int_load_complete(fi);
*fi_ret = fi;
return index;
}
}
}
return 0;

View File

@ -64,8 +64,8 @@ int
evas_common_font_source_load_complete(RGBA_Font_Source *fs)
{
int error;
error = FT_New_Face(evas_ft_lib, fs->name, 0, &(fs->ft.face));
error = FT_New_Face(evas_ft_lib, fs->file, 0, &(fs->ft.face));
if (error) return error;
error = FT_Select_Charmap(fs->ft.face, ft_encoding_unicode);
@ -105,6 +105,7 @@ evas_common_font_source_free(RGBA_Font_Source *fs)
fonts_src = evas_object_list_remove(fonts_src, fs);
FT_Done_Face(fs->ft.face);
if (fs->charmap) evas_common_array_hash_free(fs->charmap);
if (fs->name) evas_stringshare_del(fs->name);
free(fs);
}
@ -546,3 +547,4 @@ evas_common_font_int_find(const char *name, int size)
}
return NULL;
}

View File

@ -109,6 +109,9 @@ typedef struct _Convert_Pal Convert_Pal;
typedef struct _Tilebuf Tilebuf;
typedef struct _Tilebuf_Tile Tilebuf_Tile;
typedef struct _Tilebuf_Rect Tilebuf_Rect;
typedef struct _Evas_Array_Hash Evas_Array_Hash;
/*
typedef struct _Regionbuf Regionbuf;
typedef struct _Regionspan Regionspan;
@ -341,7 +344,8 @@ struct _RGBA_Font_Source
int data_size;
int current_size;
Evas_Array_Hash *charmap;
struct {
int orig_upem;
FT_Face face;
@ -965,6 +969,11 @@ Gfx_Func_Blend_Src_Dst evas_common_draw_func_copy_get (int pixe
void evas_font_dir_cache_free(void);
Evas_Array_Hash *evas_common_array_hash_new (void);
void evas_common_array_hash_free (Evas_Array_Hash *hash);
void evas_common_array_hash_add (Evas_Array_Hash *hash, int key, int data);
int evas_common_array_hash_search (Evas_Array_Hash *hash, int key);
/*****************************************************************************/
#ifdef __cplusplus