From c722ffec03d3e0832bf693469c07ee6ba71509c7 Mon Sep 17 00:00:00 2001 From: tasn Date: Wed, 4 May 2011 08:27:19 +0000 Subject: [PATCH] Evas font-engine: Moved non-draw related from font_draw.c to font_main.c git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@59180 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/engines/common/evas_font_draw.c | 327 ------------------------------- src/lib/engines/common/evas_font_main.c | 329 ++++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+), 327 deletions(-) diff --git a/src/lib/engines/common/evas_font_draw.c b/src/lib/engines/common/evas_font_draw.c index 515c702..3c9573e 100644 --- a/src/lib/engines/common/evas_font_draw.c +++ b/src/lib/engines/common/evas_font_draw.c @@ -7,8 +7,6 @@ #include "evas_font_ot.h" -#include FT_OUTLINE_H - #define WORD_CACHE_MAXLEN 50 /* How many to cache */ #define WORD_CACHE_NWORDS 40 @@ -74,331 +72,6 @@ evas_common_font_draw_finish(void) } #endif -static void -_fash_int2_free(Fash_Int_Map2 *fash) -{ - int i; - - for (i = 0; i < 256; i++) if (fash->bucket[i]) free(fash->bucket[i]); - free(fash); -} - -static void -_fash_int_free(Fash_Int *fash) -{ - int i; - - for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_int2_free(fash->bucket[i]); - free(fash); -} - -static Fash_Int * -_fash_int_new(void) -{ - Fash_Int *fash = calloc(1, sizeof(Fash_Int)); - fash->freeme = _fash_int_free; - return fash; -} - -static Fash_Item_Index_Map * -_fash_int_find(Fash_Int *fash, int item) -{ - int grp, maj, min; - - // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) - grp = (item >> 16) & 0xff; - maj = (item >> 8) & 0xff; - min = item & 0xff; - if (!fash->bucket[grp]) return NULL; - if (!fash->bucket[grp]->bucket[maj]) return NULL; - return &(fash->bucket[grp]->bucket[maj]->item[min]); -} - -static void -_fash_int_add(Fash_Int *fash, int item, RGBA_Font_Int *fint, int index) -{ - int grp, maj, min; - - // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) - grp = (item >> 16) & 0xff; - maj = (item >> 8) & 0xff; - min = item & 0xff; - if (!fash->bucket[grp]) - fash->bucket[grp] = calloc(1, sizeof(Fash_Int_Map2)); - EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]); - if (!fash->bucket[grp]->bucket[maj]) - fash->bucket[grp]->bucket[maj] = calloc(1, sizeof(Fash_Int_Map)); - EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]); - fash->bucket[grp]->bucket[maj]->item[min].fint = fint; - fash->bucket[grp]->bucket[maj]->item[min].index = index; -} - -static void -_fash_gl2_free(Fash_Glyph_Map2 *fash) -{ - int i; - - for (i = 0; i < 256; i++) if (fash->bucket[i]) free(fash->bucket[i]); - free(fash); -} - -static void -_fash_gl_free(Fash_Glyph *fash) -{ - int i; - - for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_gl2_free(fash->bucket[i]); - free(fash); -} - -static Fash_Glyph * -_fash_gl_new(void) -{ - Fash_Glyph *fash = calloc(1, sizeof(Fash_Glyph)); - fash->freeme = _fash_gl_free; - return fash; -} - -static RGBA_Font_Glyph * -_fash_gl_find(Fash_Glyph *fash, int item) -{ - int grp, maj, min; - - // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) - grp = (item >> 16) & 0xff; - maj = (item >> 8) & 0xff; - min = item & 0xff; - if (!fash->bucket[grp]) return NULL; - if (!fash->bucket[grp]->bucket[maj]) return NULL; - return fash->bucket[grp]->bucket[maj]->item[min]; -} - -static void -_fash_gl_add(Fash_Glyph *fash, int item, RGBA_Font_Glyph *glyph) -{ - int grp, maj, min; - - // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) - grp = (item >> 16) & 0xff; - maj = (item >> 8) & 0xff; - min = item & 0xff; - if (!fash->bucket[grp]) - fash->bucket[grp] = calloc(1, sizeof(Fash_Glyph_Map2)); - EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]); - if (!fash->bucket[grp]->bucket[maj]) - fash->bucket[grp]->bucket[maj] = calloc(1, sizeof(Fash_Glyph_Map)); - EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]); - fash->bucket[grp]->bucket[maj]->item[min] = glyph; -} - -EAPI RGBA_Font_Glyph * -evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index) -{ - RGBA_Font_Glyph *fg; - FT_UInt hindex; - FT_Error error; - int size; - const FT_Int32 hintflags[3] = - { FT_LOAD_NO_HINTING, FT_LOAD_FORCE_AUTOHINT, FT_LOAD_NO_AUTOHINT }; - static FT_Matrix transform = {0x10000, 0x05000, 0x0000, 0x10000}; // about 12 degree. - - evas_common_font_int_promote(fi); - if (fi->fash) - { - fg = _fash_gl_find(fi->fash, index); - if (fg == (void *)(-1)) return NULL; - else if (fg) return fg; - } - - hindex = index + (fi->hinting * 500000000); - -// fg = eina_hash_find(fi->glyphs, &hindex); -// if (fg) return fg; - - evas_common_font_int_reload(fi); - FTLOCK(); - error = FT_Load_Glyph(fi->src->ft.face, index, - FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP | - hintflags[fi->hinting]); - FTUNLOCK(); - if (error) - { - if (!fi->fash) fi->fash = _fash_gl_new(); - if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1)); - return NULL; - } - - /* Transform the outline of Glyph according to runtime_rend. */ - if (fi->runtime_rend & FONT_REND_ITALIC) - FT_Outline_Transform(&fi->src->ft.face->glyph->outline, &transform); - /* Embolden the outline of Glyph according to rundtime_rend. */ - if (fi->runtime_rend & FONT_REND_BOLD) - FT_Outline_Embolden(&fi->src->ft.face->glyph->outline, - (fi->src->ft.face->size->metrics.x_ppem * 5 * 64) / 100); - - fg = malloc(sizeof(struct _RGBA_Font_Glyph)); - if (!fg) return NULL; - memset(fg, 0, (sizeof(struct _RGBA_Font_Glyph))); - - FTLOCK(); - error = FT_Get_Glyph(fi->src->ft.face->glyph, &(fg->glyph)); - FTUNLOCK(); - if (error) - { - free(fg); - if (!fi->fash) fi->fash = _fash_gl_new(); - if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1)); - return NULL; - } - if (fg->glyph->format != FT_GLYPH_FORMAT_BITMAP) - { - FTLOCK(); - error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1); - if (error) - { - FT_Done_Glyph(fg->glyph); - FTUNLOCK(); - free(fg); - if (!fi->fash) fi->fash = _fash_gl_new(); - if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1)); - return NULL; - } - FTUNLOCK(); - } - fg->glyph_out = (FT_BitmapGlyph)fg->glyph; - fg->index = hindex; - fg->fi = fi; - - if (!fi->fash) fi->fash = _fash_gl_new(); - if (fi->fash) _fash_gl_add(fi->fash, index, fg); - /* This '+ 200' is just an estimation of how much memory freetype will use - * on it's size. This value is not really used anywhere in code - it's - * only for statistics. */ - size = sizeof(RGBA_Font_Glyph) + sizeof(Eina_List) + - (fg->glyph_out->bitmap.width * fg->glyph_out->bitmap.rows) + 200; - fi->usage += size; - if (fi->inuse) evas_common_font_int_use_increase(size); - -// eina_hash_direct_add(fi->glyphs, &fg->index, fg); - return fg; -} - -typedef struct _Font_Char_Index Font_Char_Index; -struct _Font_Char_Index -{ - FT_UInt index; - Eina_Unicode gl; -}; - -EAPI FT_UInt -evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl) -{ - Font_Char_Index result; - //FT_UInt ret; - -#ifdef HAVE_PTHREAD -/// pthread_mutex_lock(&fi->ft_mutex); -#endif - -// result = eina_hash_find(fi->indexes, &gl); -// if (result) goto on_correct; -// -// result = malloc(sizeof (Font_Char_Index)); -// if (!result) -// { -//#ifdef HAVE_PTHREAD -// pthread_mutex_unlock(&fi->ft_mutex); -//#endif -// return FT_Get_Char_Index(fi->src->ft.face, gl); -// } - - evas_common_font_int_reload(fi); - FTLOCK(); - result.index = FT_Get_Char_Index(fi->src->ft.face, gl); - FTUNLOCK(); - result.gl = gl; - -// eina_hash_direct_add(fi->indexes, &result->gl, result); -// -// on_correct: -#ifdef HAVE_PTHREAD -// pthread_mutex_unlock(&fi->ft_mutex); -#endif - return result.index; -} - -EAPI int -evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, Eina_Unicode gl) -{ - Eina_List *l; - - if (fn->fash) - { - Fash_Item_Index_Map *fm = _fash_int_find(fn->fash, gl); - if (fm) - { - if (fm->fint) - { - *fi_ret = fm->fint; - return fm->index; - } - else if (fm->index == -1) return 0; - } - } - - for (l = fn->fonts; l; l = l->next) - { - RGBA_Font_Int *fi; - int index; - - fi = l->data; - -#if 0 /* FIXME: charmap user is disabled and use a deprecated data type. */ -/* - if (fi->src->charmap) // Charmap loaded, FI/FS blank - { - index = evas_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_array_hash_free(fi->src->charmap); - fi->src->charmap = NULL; - - *fi_ret = fi; - return index; - } - } - else -*/ -#endif - if (!fi->src->ft.face) /* Charmap not loaded, FI/FS blank */ - { - evas_common_font_int_reload(fi); - } - if (fi->src->ft.face) - { - index = evas_common_get_char_index(fi, gl); - if (index != 0) - { - if (!fi->ft.size) - evas_common_font_int_load_complete(fi); - if (!fn->fash) fn->fash = _fash_int_new(); - if (fn->fash) _fash_int_add(fn->fash, gl, fi, index); - *fi_ret = fi; - return index; - } - else - { - if (!fn->fash) fn->fash = _fash_int_new(); - if (fn->fash) _fash_int_add(fn->fash, gl, NULL, -1); - } - } - } - return 0; -} - /* * BiDi handling: We receive the shaped string + other props from text_props, * we need to reorder it so we'll have the visual string (the way we draw) diff --git a/src/lib/engines/common/evas_font_main.c b/src/lib/engines/common/evas_font_main.c index 821ab6e..159b0a9 100644 --- a/src/lib/engines/common/evas_font_main.c +++ b/src/lib/engines/common/evas_font_main.c @@ -3,6 +3,8 @@ #include "evas_font_private.h" +#include FT_OUTLINE_H + FT_Library evas_ft_lib = 0; static int initialised = 0; @@ -209,3 +211,330 @@ evas_common_font_get_line_advance(RGBA_Font *fn) // return ret; } +/* Set of common functions that are used in a couple of places. */ + +static void +_fash_int2_free(Fash_Int_Map2 *fash) +{ + int i; + + for (i = 0; i < 256; i++) if (fash->bucket[i]) free(fash->bucket[i]); + free(fash); +} + +static void +_fash_int_free(Fash_Int *fash) +{ + int i; + + for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_int2_free(fash->bucket[i]); + free(fash); +} + +static Fash_Int * +_fash_int_new(void) +{ + Fash_Int *fash = calloc(1, sizeof(Fash_Int)); + fash->freeme = _fash_int_free; + return fash; +} + +static Fash_Item_Index_Map * +_fash_int_find(Fash_Int *fash, int item) +{ + int grp, maj, min; + + // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) + grp = (item >> 16) & 0xff; + maj = (item >> 8) & 0xff; + min = item & 0xff; + if (!fash->bucket[grp]) return NULL; + if (!fash->bucket[grp]->bucket[maj]) return NULL; + return &(fash->bucket[grp]->bucket[maj]->item[min]); +} + +static void +_fash_int_add(Fash_Int *fash, int item, RGBA_Font_Int *fint, int index) +{ + int grp, maj, min; + + // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) + grp = (item >> 16) & 0xff; + maj = (item >> 8) & 0xff; + min = item & 0xff; + if (!fash->bucket[grp]) + fash->bucket[grp] = calloc(1, sizeof(Fash_Int_Map2)); + EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]); + if (!fash->bucket[grp]->bucket[maj]) + fash->bucket[grp]->bucket[maj] = calloc(1, sizeof(Fash_Int_Map)); + EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]); + fash->bucket[grp]->bucket[maj]->item[min].fint = fint; + fash->bucket[grp]->bucket[maj]->item[min].index = index; +} + +static void +_fash_gl2_free(Fash_Glyph_Map2 *fash) +{ + int i; + + for (i = 0; i < 256; i++) if (fash->bucket[i]) free(fash->bucket[i]); + free(fash); +} + +static void +_fash_gl_free(Fash_Glyph *fash) +{ + int i; + + for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_gl2_free(fash->bucket[i]); + free(fash); +} + +static Fash_Glyph * +_fash_gl_new(void) +{ + Fash_Glyph *fash = calloc(1, sizeof(Fash_Glyph)); + fash->freeme = _fash_gl_free; + return fash; +} + +static RGBA_Font_Glyph * +_fash_gl_find(Fash_Glyph *fash, int item) +{ + int grp, maj, min; + + // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) + grp = (item >> 16) & 0xff; + maj = (item >> 8) & 0xff; + min = item & 0xff; + if (!fash->bucket[grp]) return NULL; + if (!fash->bucket[grp]->bucket[maj]) return NULL; + return fash->bucket[grp]->bucket[maj]->item[min]; +} + +static void +_fash_gl_add(Fash_Glyph *fash, int item, RGBA_Font_Glyph *glyph) +{ + int grp, maj, min; + + // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) + grp = (item >> 16) & 0xff; + maj = (item >> 8) & 0xff; + min = item & 0xff; + if (!fash->bucket[grp]) + fash->bucket[grp] = calloc(1, sizeof(Fash_Glyph_Map2)); + EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]); + if (!fash->bucket[grp]->bucket[maj]) + fash->bucket[grp]->bucket[maj] = calloc(1, sizeof(Fash_Glyph_Map)); + EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]); + fash->bucket[grp]->bucket[maj]->item[min] = glyph; +} + +EAPI RGBA_Font_Glyph * +evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index) +{ + RGBA_Font_Glyph *fg; + FT_UInt hindex; + FT_Error error; + int size; + const FT_Int32 hintflags[3] = + { FT_LOAD_NO_HINTING, FT_LOAD_FORCE_AUTOHINT, FT_LOAD_NO_AUTOHINT }; + static FT_Matrix transform = {0x10000, 0x05000, 0x0000, 0x10000}; // about 12 degree. + + evas_common_font_int_promote(fi); + if (fi->fash) + { + fg = _fash_gl_find(fi->fash, index); + if (fg == (void *)(-1)) return NULL; + else if (fg) return fg; + } + + hindex = index + (fi->hinting * 500000000); + +// fg = eina_hash_find(fi->glyphs, &hindex); +// if (fg) return fg; + + evas_common_font_int_reload(fi); + FTLOCK(); + error = FT_Load_Glyph(fi->src->ft.face, index, + FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP | + hintflags[fi->hinting]); + FTUNLOCK(); + if (error) + { + if (!fi->fash) fi->fash = _fash_gl_new(); + if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1)); + return NULL; + } + + /* Transform the outline of Glyph according to runtime_rend. */ + if (fi->runtime_rend & FONT_REND_ITALIC) + FT_Outline_Transform(&fi->src->ft.face->glyph->outline, &transform); + /* Embolden the outline of Glyph according to rundtime_rend. */ + if (fi->runtime_rend & FONT_REND_BOLD) + FT_Outline_Embolden(&fi->src->ft.face->glyph->outline, + (fi->src->ft.face->size->metrics.x_ppem * 5 * 64) / 100); + + fg = malloc(sizeof(struct _RGBA_Font_Glyph)); + if (!fg) return NULL; + memset(fg, 0, (sizeof(struct _RGBA_Font_Glyph))); + + FTLOCK(); + error = FT_Get_Glyph(fi->src->ft.face->glyph, &(fg->glyph)); + FTUNLOCK(); + if (error) + { + free(fg); + if (!fi->fash) fi->fash = _fash_gl_new(); + if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1)); + return NULL; + } + if (fg->glyph->format != FT_GLYPH_FORMAT_BITMAP) + { + FTLOCK(); + error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1); + if (error) + { + FT_Done_Glyph(fg->glyph); + FTUNLOCK(); + free(fg); + if (!fi->fash) fi->fash = _fash_gl_new(); + if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1)); + return NULL; + } + FTUNLOCK(); + } + fg->glyph_out = (FT_BitmapGlyph)fg->glyph; + fg->index = hindex; + fg->fi = fi; + + if (!fi->fash) fi->fash = _fash_gl_new(); + if (fi->fash) _fash_gl_add(fi->fash, index, fg); + /* This '+ 200' is just an estimation of how much memory freetype will use + * on it's size. This value is not really used anywhere in code - it's + * only for statistics. */ + size = sizeof(RGBA_Font_Glyph) + sizeof(Eina_List) + + (fg->glyph_out->bitmap.width * fg->glyph_out->bitmap.rows) + 200; + fi->usage += size; + if (fi->inuse) evas_common_font_int_use_increase(size); + +// eina_hash_direct_add(fi->glyphs, &fg->index, fg); + return fg; +} + +typedef struct _Font_Char_Index Font_Char_Index; +struct _Font_Char_Index +{ + FT_UInt index; + Eina_Unicode gl; +}; + +EAPI FT_UInt +evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl) +{ + Font_Char_Index result; + //FT_UInt ret; + +#ifdef HAVE_PTHREAD +/// pthread_mutex_lock(&fi->ft_mutex); +#endif + +// result = eina_hash_find(fi->indexes, &gl); +// if (result) goto on_correct; +// +// result = malloc(sizeof (Font_Char_Index)); +// if (!result) +// { +//#ifdef HAVE_PTHREAD +// pthread_mutex_unlock(&fi->ft_mutex); +//#endif +// return FT_Get_Char_Index(fi->src->ft.face, gl); +// } + + evas_common_font_int_reload(fi); + FTLOCK(); + result.index = FT_Get_Char_Index(fi->src->ft.face, gl); + FTUNLOCK(); + result.gl = gl; + +// eina_hash_direct_add(fi->indexes, &result->gl, result); +// +// on_correct: +#ifdef HAVE_PTHREAD +// pthread_mutex_unlock(&fi->ft_mutex); +#endif + return result.index; +} + +EAPI int +evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, Eina_Unicode gl) +{ + Eina_List *l; + + if (fn->fash) + { + Fash_Item_Index_Map *fm = _fash_int_find(fn->fash, gl); + if (fm) + { + if (fm->fint) + { + *fi_ret = fm->fint; + return fm->index; + } + else if (fm->index == -1) return 0; + } + } + + for (l = fn->fonts; l; l = l->next) + { + RGBA_Font_Int *fi; + int index; + + fi = l->data; + +#if 0 /* FIXME: charmap user is disabled and use a deprecated data type. */ +/* + if (fi->src->charmap) // Charmap loaded, FI/FS blank + { + index = evas_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_array_hash_free(fi->src->charmap); + fi->src->charmap = NULL; + + *fi_ret = fi; + return index; + } + } + else +*/ +#endif + if (!fi->src->ft.face) /* Charmap not loaded, FI/FS blank */ + { + evas_common_font_int_reload(fi); + } + if (fi->src->ft.face) + { + index = evas_common_get_char_index(fi, gl); + if (index != 0) + { + if (!fi->ft.size) + evas_common_font_int_load_complete(fi); + if (!fn->fash) fn->fash = _fash_int_new(); + if (fn->fash) _fash_int_add(fn->fash, gl, fi, index); + *fi_ret = fi; + return index; + } + else + { + if (!fn->fash) fn->fash = _fash_int_new(); + if (fn->fash) _fash_int_add(fn->fash, gl, NULL, -1); + } + } + } + return 0; +} + -- 2.7.4