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:
parent
1d905fc19b
commit
88edaa2e02
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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 = \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue