Index: src/lib/include/evas_common.h =================================================================== RCS file: /cvs/e/e17/libs/evas/src/lib/include/evas_common.h,v retrieving revision 1.80 diff -u -r1.80 evas_common.h --- src/lib/include/evas_common.h 6 May 2007 11:29:37 -0000 1.80 +++ src/lib/include/evas_common.h 6 Jun 2007 21:55:06 -0000 @@ -480,6 +480,7 @@ Font_Hint_Flags hinting; int references; + Evas_Hash *kerning_cache; }; struct _RGBA_Font_Source @@ -960,6 +961,7 @@ EAPI void evas_common_font_flush (void); EAPI void evas_common_font_flush_last (void); EAPI RGBA_Font_Int *evas_common_font_int_find (const char *name, int size); +EAPI int evas_common_font_query_kerning (RGBA_Font_Int *fi, int prev_index, int index); EAPI int evas_common_font_glyph_search (RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl); EAPI void evas_common_font_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text); EAPI RGBA_Font_Glyph *evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index); Index: src/lib/engines/common/evas_font_draw.c =================================================================== RCS file: /cvs/e/e17/libs/evas/src/lib/engines/common/evas_font_draw.c,v retrieving revision 1.31 diff -u -r1.31 evas_font_draw.c --- src/lib/engines/common/evas_font_draw.c 15 Nov 2006 16:44:34 -0000 1.31 +++ src/lib/engines/common/evas_font_draw.c 6 Jun 2007 21:55:06 -0000 @@ -1,5 +1,68 @@ #include "evas_common.h" +#define KERN_KEY_LEN 32 + +const char *hex_table = "0123456789ABCDEF"; + +/* + * This function stores a reversed string version of the passed integer. + * Reversing the string increases the likelihood of the strings differing + * earlier on comparisons. + * Must be called with a buffer of at least 9 bytes. + */ +static inline void +evas_common_font_query_kerning_key(char *buffer, int index) +{ + buffer[0] = hex_table[((index << 28) >> 28)]; + buffer[1] = hex_table[((index << 24) >> 28)]; + buffer[2] = hex_table[((index << 20) >> 28)]; + buffer[3] = hex_table[((index << 16) >> 28)]; + buffer[4] = hex_table[((index << 12) >> 28)]; + buffer[5] = hex_table[((index << 8) >> 28)]; + buffer[6] = hex_table[((index << 4) >> 28)]; + buffer[7] = hex_table[((index ) >> 28)]; + buffer[8] = '\0'; +} + +EAPI int +evas_common_font_query_kerning(RGBA_Font_Int *fi, int prev_index, int index) +{ + int found; + char kern_key[KERN_KEY_LEN]; + int kern = 0; + + /* Don't check for the font supporting kerning here, the calling function + * should have already done so outside of the loop */ + + // snprintf(kern_key, KERN_KEY_LEN, "%d %d", prev_index, index); + evas_common_font_query_kerning_key(kern_key, prev_index); + kern_key[8] = ' '; + evas_common_font_query_kerning_key(&(kern_key[9]), prev_index); + + found = (int)evas_hash_find(fi->kerning_cache, kern_key); + + if (!found) + { + FT_Vector delta; + + if (FT_Get_Kerning(fi->src->ft.face, prev_index, index, + ft_kerning_default, &delta) == 0) + { + found = delta.x >> 6; + } + if (!found) found = -1; + fi->kerning_cache = evas_hash_add(fi->kerning_cache, kern_key, (void *)found); + } + + if (found < 0) + { + found = 0; + } + kern = found; + + return kern; +} + EAPI RGBA_Font_Glyph * evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index) { @@ -197,11 +260,7 @@ if ((use_kerning) && (prev_index) && (index) && (pface == fi->src->ft.face)) { - FT_Vector delta; - - if (FT_Get_Kerning(fi->src->ft.face, prev_index, index, - ft_kerning_default, &delta) == 0) - pen_x += delta.x >> 6; + pen_x += evas_common_font_query_kerning(fi, prev_index, index); } pface = fi->src->ft.face; fg = evas_common_font_int_cache_glyph_get(fi, index); Index: src/lib/engines/common/evas_font_load.c =================================================================== RCS file: /cvs/e/e17/libs/evas/src/lib/engines/common/evas_font_load.c,v retrieving revision 1.41 diff -u -r1.41 evas_font_load.c --- src/lib/engines/common/evas_font_load.c 5 May 2007 10:30:11 -0000 1.41 +++ src/lib/engines/common/evas_font_load.c 6 Jun 2007 21:55:06 -0000 @@ -569,6 +569,7 @@ evas_hash_free(fi->glyphs); evas_common_font_source_free(fi->src); + evas_hash_free(fi->kerning_cache); free(fi); } Index: src/lib/engines/common/evas_font_query.c =================================================================== RCS file: /cvs/e/e17/libs/evas/src/lib/engines/common/evas_font_query.c,v retrieving revision 1.21 diff -u -r1.21 evas_font_query.c --- src/lib/engines/common/evas_font_query.c 8 Oct 2006 12:43:31 -0000 1.21 +++ src/lib/engines/common/evas_font_query.c 6 Jun 2007 21:55:06 -0000 @@ -39,14 +39,7 @@ if ((use_kerning) && (prev_index) && (index) && (pface == fi->src->ft.face)) { - FT_Vector delta; - - if (FT_Get_Kerning(fi->src->ft.face, prev_index, index, - ft_kerning_default, &delta) == 0) - { - kern = delta.x >> 6; - pen_x += kern; - } + pen_x += evas_common_font_query_kerning(fi, prev_index, index); } pface = fi->src->ft.face; fg = evas_common_font_int_cache_glyph_get(fi, index); @@ -134,11 +127,7 @@ if ((use_kerning) && (prev_index) && (index) && (pface == fi->src->ft.face)) { - FT_Vector delta; - - if (FT_Get_Kerning(fi->src->ft.face, prev_index, index, - ft_kerning_default, &delta) == 0) - pen_x += delta.x >> 6; + pen_x += evas_common_font_query_kerning(fi, prev_index, index); } pface = fi->src->ft.face; fg = evas_common_font_int_cache_glyph_get(fi, index); @@ -197,14 +186,7 @@ if ((use_kerning) && (prev_index) && (index) && (pface == fi->src->ft.face)) { - FT_Vector delta; - - if (FT_Get_Kerning(fi->src->ft.face, prev_index, index, - ft_kerning_default, &delta) == 0) - { - kern = delta.x >> 6; - pen_x += kern; - } + pen_x += evas_common_font_query_kerning(fi, prev_index, index); } pface = fi->src->ft.face; fg = evas_common_font_int_cache_glyph_get(fi, index); @@ -283,14 +265,7 @@ if ((use_kerning) && (prev_index) && (index) && (pface == fi->src->ft.face)) { - FT_Vector delta; - - if (FT_Get_Kerning(fi->src->ft.face, prev_index, index, - ft_kerning_default, &delta) == 0) - { - kern = delta.x >> 6; - pen_x += kern; - } + pen_x += evas_common_font_query_kerning(fi, prev_index, index); } pface = fi->src->ft.face; fg = evas_common_font_int_cache_glyph_get(fi, index);