#include "evas_font_ot.h"
-#include FT_OUTLINE_H
-
#define WORD_CACHE_MAXLEN 50
/* How many to cache */
#define WORD_CACHE_NWORDS 40
}
#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)
#include "evas_font_private.h"
+#include FT_OUTLINE_H
+
FT_Library evas_ft_lib = 0;
static int initialised = 0;
// 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;
+}
+