font_dirs = NULL;
#ifdef HAVE_FONTCONFIG
- fc_init--;
- if (fc_init == 0) FcFini();
+/* this is bad i got a:
+ * fccache.c:512: FcCacheFini: Assertion fcCacheChains[i] == ((void *)0)' failed.
+ *
+ * all i can do for now is shut this puppy down. butthat breaks, so disable
+ * it as in reality - there is little reason to care about the memory not
+ * being freed etc.
+ *
+ * fc_init--;
+ * if (fc_init == 0) FcFini();
+ */
#endif
}
#include "evas_intl_utils.h" /*defines INTERNATIONAL_SUPPORT if possible */
+static void
+_fash_int_free(Fash_Int *fash)
+{
+ int i;
+
+ for (i = 0; i < 256; i++) if (fash->bucket[i]) 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 maj, min;
+
+ item &= 0xffff; // fixme: to do > 65k
+ maj = (item >> 8) & 0xff;
+ min = item & 0xff;
+ if (!fash->bucket[maj]) return NULL;
+ return &(fash->bucket[maj]->item[min]);
+}
+
+static void
+_fash_int_add(Fash_Int *fash, int item, RGBA_Font_Int *fint, int index)
+{
+ int maj, min;
+
+ item &= 0xffff; // fixme: to do > 65k
+ maj = (item >> 8) & 0xff;
+ min = item & 0xff;
+ if (!fash->bucket[maj])
+ fash->bucket[maj] = calloc(1, sizeof(Fash_Int_Map));
+ fash->bucket[maj]->item[min].fint = fint;
+ fash->bucket[maj]->item[min].index = index;
+}
+
+
+
+
+
+static void
+_fash_gl_free(Fash_Glyph *fash)
+{
+ int i;
+
+ for (i = 0; i < 256; i++) if (fash->bucket[i]) 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 maj, min;
+
+ item &= 0xffff; // fixme: to do > 65k
+ maj = (item >> 8) & 0xff;
+ min = item & 0xff;
+ if (!fash->bucket[maj]) return NULL;
+ return fash->bucket[maj]->item[min];
+}
+
+static void
+_fash_gl_add(Fash_Glyph *fash, int item, RGBA_Font_Glyph *glyph)
+{
+ int maj, min;
+
+ item &= 0xffff; // fixme: to do > 65k
+ maj = (item >> 8) & 0xff;
+ min = item & 0xff;
+ if (!fash->bucket[maj])
+ fash->bucket[maj] = calloc(1, sizeof(Fash_Int_Map));
+ fash->bucket[maj]->item[min] = glyph;
+}
+
+
+
+
+
EAPI RGBA_Font_Glyph *
evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index)
{
const FT_Int32 hintflags[3] =
{ FT_LOAD_NO_HINTING, FT_LOAD_FORCE_AUTOHINT, FT_LOAD_NO_AUTOHINT };
+ 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;
+
+// fg = eina_hash_find(fi->glyphs, &hindex);
+// if (fg) return fg;
// error = FT_Load_Glyph(fi->src->ft.face, index, FT_LOAD_NO_BITMAP);
error = FT_Load_Glyph(fi->src->ft.face, index,
FT_LOAD_RENDER | hintflags[fi->hinting]);
- if (error) return NULL;
+ if (error)
+ {
+ if (!fi->fash) fi->fash = _fash_gl_new();
+ if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1));
+ return NULL;
+ }
fg = malloc(sizeof(struct _RGBA_Font_Glyph));
if (!fg) return NULL;
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)
{
FT_Done_Glyph(fg->glyph);
free(fg);
+ if (!fi->fash) fi->fash = _fash_gl_new();
+ if (fi->fash) _fash_gl_add(fi->fash, index, (void *)(-1));
return NULL;
}
}
fg->index = hindex;
fg->fi = fi;
+
+ if (!fi->fash) fi->fash = _fash_gl_new();
+ if (fi->fash) _fash_gl_add(fi->fash, index, fg);
- eina_hash_direct_add(fi->glyphs, &fg->index, fg);
+// eina_hash_direct_add(fi->glyphs, &fg->index, fg);
return fg;
}
static FT_UInt
_evas_common_get_char_index(RGBA_Font_Int* fi, int gl)
{
- Font_Char_Index *result;
-
-#ifdef HAVE_PTHREAD
- pthread_mutex_lock(&fi->ft_mutex);
-#endif
-
- result = eina_hash_find(fi->indexes, &gl);
- if (result) goto on_correct;
+ Font_Char_Index result;
- result = malloc(sizeof (Font_Char_Index));
- if (!result)
- {
#ifdef HAVE_PTHREAD
- pthread_mutex_unlock(&fi->ft_mutex);
+/// pthread_mutex_lock(&fi->ft_mutex);
#endif
- return FT_Get_Char_Index(fi->src->ft.face, gl);
- }
-
- result->index = FT_Get_Char_Index(fi->src->ft.face, gl);
- result->gl = gl;
- eina_hash_direct_add(fi->indexes, &result->gl, result);
-
- on_correct:
+// 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);
+// }
+
+ result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
+ result.gl = gl;
+
+// eina_hash_direct_add(fi->indexes, &result->gl, result);
+//
+// on_correct:
#ifdef HAVE_PTHREAD
- pthread_mutex_unlock(&fi->ft_mutex);
+// pthread_mutex_unlock(&fi->ft_mutex);
#endif
- return result->index;
+ return result.index;
}
EAPI int
{
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;
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 */
+/*
+ if (fi->src->charmap) // Charmap loaded, FI/FS blank
{
index = evas_array_hash_search(fi->src->charmap, gl);
if (index != 0)
}
}
else
+*/
#endif
- if (!fi->src->ft.face) /* Charmap not loaded, FI/FS blank */
+ if (!fi->src->ft.face) /* Charmap not loaded, FI/FS blank */
{
if (evas_common_font_source_load_complete(fi->src))
return 0;
#if 0 /* FIXME: disable this. this can eat a LOT of memory and in my tests with expedite at any rate shows no visible improvements */
+/*
index = FT_Get_Char_Index(fi->src->ft.face, gl);
if (index == 0)
{
- /* Load Hash */
+ // Load Hash
FT_ULong charcode;
FT_UInt gindex;
charcode = FT_Get_Next_Char(fi->src->ft.face, charcode, &gindex);
}
- /* Free face */
+ // Free face
FT_Done_Face(fi->src->ft.face);
fi->src->ft.face = NULL;
}
*fi_ret = fi;
return index;
}
+ */
#endif
}
else /* Charmap not loaded, FS loaded */
{
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;
if (gl == 0) break;
index = evas_common_font_glyph_search(fn, &fi, gl);
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
/* hmmm kerning means i can't sanely do my own cached metric tables! */
/* grrr - this means font face sharing is kinda... not an option if */
/* you want performance */
}
else
#endif
-
{
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
if (ext_h <= 0) return;
LKL(fn->lock);
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op);
{
FT_Done_Face(fs->ft.face);
#if 0 /* FIXME: Disable as it is only used by dead code using deprecated datatype. */
- if (fs->charmap) evas_array_hash_free(fs->charmap);
+// if (fs->charmap) evas_array_hash_free(fs->charmap);
#endif
if (fs->name) eina_stringshare_del(fs->name);
free(fs);
evas_common_font_int_modify_cache_by(fi, -1);
- eina_hash_foreach(fi->glyphs, font_flush_free_glyph_cb, NULL);
- eina_hash_free(fi->glyphs);
+// eina_hash_foreach(fi->glyphs, font_flush_free_glyph_cb, NULL);
+// eina_hash_free(fi->glyphs);
- eina_hash_free(fi->kerning);
- eina_hash_free(fi->indexes);
+// eina_hash_free(fi->kerning);
+// eina_hash_free(fi->indexes);
#ifdef HAVE_PTHREAD
pthread_mutex_destroy(&fi->ft_mutex);
if (fi->references == 0)
fonts_lru = eina_list_remove(fonts_lru, fi);
+ if (fi->fash) fi->fash->freeme(fi->fash);
free(fi);
}
_evas_common_font_int_cache_init(RGBA_Font_Int *fi)
{
/* Add some font kerning cache. */
- fi->indexes = eina_hash_new(NULL,
- EINA_KEY_CMP(_evas_common_font_int_cmp),
- EINA_KEY_HASH(eina_hash_int32),
- free, 3);
- fi->kerning = eina_hash_new(NULL,
- EINA_KEY_CMP(_evas_common_font_double_int_cmp),
- EINA_KEY_HASH(_evas_common_font_double_int_hash),
- free, 3);
+// fi->indexes = eina_hash_new(NULL,
+// EINA_KEY_CMP(_evas_common_font_int_cmp),
+// EINA_KEY_HASH(eina_hash_int32),
+// free, 3);
+// fi->kerning = eina_hash_new(NULL,
+// EINA_KEY_CMP(_evas_common_font_double_int_cmp),
+// EINA_KEY_HASH(_evas_common_font_double_int_hash),
+// free, 3);
#ifdef HAVE_PTHREAD
pthread_mutex_init(&fi->ft_mutex, NULL);
#endif
evas_common_font_int_load_init(RGBA_Font_Int *fi)
{
fi->ft.size = NULL;
- fi->glyphs = eina_hash_new(NULL,
- EINA_KEY_CMP(_evas_common_font_int_cmp),
- EINA_KEY_HASH(eina_hash_int32),
- NULL,
- 6);
+// fi->glyphs = eina_hash_new(NULL,
+// EINA_KEY_CMP(_evas_common_font_int_cmp),
+// EINA_KEY_HASH(eina_hash_int32),
+// NULL,
+// 6);
fi->usage = 0;
fi->references = 1;
/* couldn't choose the size anyway... what now? */
}
}
- fi->src->current_size = fi->size;
+ fi->src->current_size = 0;
fi->max_h = 0;
Eina_List *l;
RGBA_Font_Int *fi;
- if (!fn)
- return;
+ if (!fn) return;
fn->references--;
if (fn->references > 0) return;
EINA_LIST_FOREACH(fn->fonts, l, fi)
}
evas_common_font_flush();
eina_list_free(fn->fonts);
+ if (fn->fash) fn->fash->freeme(fn->fash);
LKD(fn->lock);
free(fn);
}
{
int sz_hash = 0;
- if (fi->glyphs) sz_hash = eina_hash_population(fi->glyphs);
- eina_hash_foreach(fi->glyphs, font_modify_cache_cb, &dir);
+// if (fi->glyphs) sz_hash = eina_hash_population(fi->glyphs);
+// eina_hash_foreach(fi->glyphs, font_modify_cache_cb, &dir);
font_cache_usage += dir * (sizeof(RGBA_Font) + sz_hash +
sizeof(FT_FaceRec) + 16384); /* fudge values */
}
int ret;
RGBA_Font_Int *fi;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
fi = fn->fonts->data;
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
val = (int)fi->src->ft.face->size->metrics.ascender;
if (fi->src->ft.face->units_per_EM == 0)
return val;
int ret;
RGBA_Font_Int *fi;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
fi = fn->fonts->data;
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
val = -(int)fi->src->ft.face->size->metrics.descender;
if (fi->src->ft.face->units_per_EM == 0)
return val;
int ret;
RGBA_Font_Int *fi;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
fi = fn->fonts->data;
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
val = (int)fi->src->ft.face->bbox.yMax;
if (fi->src->ft.face->units_per_EM == 0)
return val;
int ret;
RGBA_Font_Int *fi;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
fi = fn->fonts->data;
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
val = -(int)fi->src->ft.face->bbox.yMin;
if (fi->src->ft.face->units_per_EM == 0)
return val;
int ret;
RGBA_Font_Int *fi;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
fi = fn->fonts->data;
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
val = (int)fi->src->ft.face->size->metrics.height;
if (fi->src->ft.face->units_per_EM == 0)
return val;
#include "evas_common.h"
-
#include "evas_intl_utils.h" /*defines INTERNATIONAL_SUPPORT if possible */
EAPI int
int key[2];
int error = 1;
- key[0] = prev;
- key[1] = index;
+// return 0;
+// key[0] = prev;
+// key[1] = index;
#ifdef HAVE_PTHREAD
- pthread_mutex_lock(&fi->ft_mutex);
+// pthread_mutex_lock(&fi->ft_mutex);
#endif
- result = eina_hash_find(fi->kerning, key);
- if (result)
- {
- *kerning = result[2];
- goto on_correct;
- }
+// result = eina_hash_find(fi->kerning, key);
+// if (result)
+// {
+// *kerning = result[2];
+// goto on_correct;
+// }
/* NOTE: ft2 seems to have a bug. and sometimes returns bizarre
* values to kern by - given same font, same size and same
key[0], key[1],
ft_kerning_default, &delta) == 0)
{
- int *push;
+// int *push;
*kerning = delta.x >> 6;
- push = malloc(sizeof (int) * 3);
- if (!push) return 1;
+// push = malloc(sizeof (int) * 3);
+// if (!push) return 1;
- push[0] = key[0];
- push[1] = key[1];
- push[2] = *kerning;
+// push[0] = key[0];
+// push[1] = key[1];
+// push[2] = *kerning;
- eina_hash_direct_add(fi->kerning, push, push);
+// eina_hash_direct_add(fi->kerning, push, push);
goto on_correct;
}
on_correct:
#ifdef HAVE_PTHREAD
- pthread_mutex_unlock(&fi->ft_mutex);
+// pthread_mutex_unlock(&fi->ft_mutex);
#endif
return error;
}
pen_x = 0;
pen_y = 0;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
prev_index = 0;
for (chr = 0; text[chr];)
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) break;
index = evas_common_font_glyph_search(fn, &fi, gl);
- /* hmmm kerning means i can't sanely do my own cached metric tables! */
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
+ /* hmmm kerning means i can't sanely do my own cached metric tables! */
/* grrr - this means font face sharing is kinda... not an option if */
/* you want performance */
kern = 0;
if (!text[0]) return 0;
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) return 0;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
index = evas_common_font_glyph_search(fn, &fi, gl);
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
fg = evas_common_font_int_cache_glyph_get(fi, index);
if (!fg) return 0;
/*
start_x = 0;
pen_x = 0;
pen_y = 0;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
prev_index = 0;
for (chr = 0; text[chr];)
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) break;
index = evas_common_font_glyph_search(fn, &fi, gl);
- /* hmmm kerning means i can't sanely do my own cached metric tables! */
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
+ /* hmmm kerning means i can't sanely do my own cached metric tables! */
/* grrr - this means font face sharing is kinda... not an option if */
/* you want performance */
if ((use_kerning) && (prev_index) && (index) &&
pen_x = 0;
pen_y = 0;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
prev_index = 0;
prev_chr_end = 0;
pen_x = 0;
pen_y = 0;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
prev_index = 0;
prev_chr_end = 0;
pen_x = 0;
pen_y = 0;
- evas_common_font_size_use(fn);
+// evas_common_font_size_use(fn);
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
prev_index = 0;
prev_chr_end = 0;
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) break;
index = evas_common_font_glyph_search(fn, &fi, gl);
+ if (fi->src->current_size != fi->size)
+ {
+ FT_Activate_Size(fi->ft.size);
+ fi->src->current_size = fi->size;
+ }
kern = 0;
/* hmmm kerning means i can't sanely do my own cached metric tables! */
/* grrr - this means font face sharing is kinda... not an option if */
int x, y;
};
+// for fonts...
+/////
+typedef struct _Fash_Item_Index_Map Fash_Item_Index_Map;
+typedef struct _Fash_Int_Map Fash_Int_Map;
+typedef struct _Fash_Int Fash_Int;
+struct _Fash_Item_Index_Map
+{
+ RGBA_Font_Int *fint;
+ int index;
+};
+struct _Fash_Int_Map
+{
+ Fash_Item_Index_Map item[256];
+};
+struct _Fash_Int
+{
+ Fash_Int_Map *bucket[256];
+ void (*freeme) (Fash_Int *fash);
+};
+
+/////
+typedef struct _Fash_Glyph_Map Fash_Glyph_Map;
+typedef struct _Fash_Glyph Fash_Glyph;
+struct _Fash_Glyph_Map
+{
+ RGBA_Font_Glyph *item[256];
+};
+struct _Fash_Glyph
+{
+ Fash_Glyph_Map *bucket[256];
+ void (*freeme) (Fash_Glyph *fash);
+};
+/////
+
struct _RGBA_Font
{
Eina_List *fonts;
Font_Hint_Flags hinting;
int references;
+ Fash_Int *fash;
+ unsigned char sizeok : 1;
LK(lock);
};
FT_Size size;
} ft;
- Eina_Hash *glyphs;
+// Eina_Hash *glyphs;
LK(ft_mutex);
Eina_Hash *kerning;
- Eina_Hash *indexes;
+// Eina_Hash *indexes;
int usage;
Font_Hint_Flags hinting;
int references;
+ Fash_Glyph *fash;
+ unsigned char sizeok : 1;
};
struct _RGBA_Font_Source
void *data;
int data_size;
int current_size;
-#if 0 /* FIXME: charmap user is disabled and use a deprecated data type. */
- Evas_Array_Hash *charmap;
-#endif
-
+
struct {
int orig_upem;
FT_Face face;