forked from enlightenment/efl
Fix issue when using word-cache: Make sure we have a 'last' word
before trying to free it, else we segfault. Fix compiler warnings wrt const vs non-const of Evas_BiDi_Props. Fix formatting and remove whitespace also. NB: The major change here is in evas_font_word_prerender wrt freeing the 'last' word of the cache. SVN revision: 53166
This commit is contained in:
parent
9910581b1c
commit
2f3b2b99e5
|
@ -10,7 +10,8 @@
|
|||
#define WORD_CACHE_NWORDS 40
|
||||
static int max_cached_words = WORD_CACHE_NWORDS;
|
||||
|
||||
struct prword {
|
||||
struct prword
|
||||
{
|
||||
EINA_INLIST;
|
||||
/* FIXME: Need to save font/size et al */
|
||||
int size;
|
||||
|
@ -25,13 +26,18 @@ struct prword {
|
|||
int baseline;
|
||||
};
|
||||
|
||||
struct cinfo {
|
||||
struct cinfo
|
||||
{
|
||||
int gl;
|
||||
FT_UInt index;
|
||||
struct { int x, y; } pos;
|
||||
struct
|
||||
{
|
||||
int x, y;
|
||||
} pos;
|
||||
int posx;
|
||||
RGBA_Font_Glyph *fg;
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
int w,h;
|
||||
int rows;
|
||||
unsigned char *data;
|
||||
|
@ -50,6 +56,7 @@ evas_common_font_draw_init(void)
|
|||
{
|
||||
char *p;
|
||||
int tmp;
|
||||
|
||||
if ((p = getenv("EVAS_WORD_CACHE_MAX_WORDS")))
|
||||
{
|
||||
tmp = strtol(p,NULL,10);
|
||||
|
@ -110,10 +117,6 @@ _fash_int_add(Fash_Int *fash, int item, RGBA_Font_Int *fint, int index)
|
|||
fash->bucket[maj]->item[min].index = index;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
_fash_gl_free(Fash_Glyph *fash)
|
||||
{
|
||||
|
@ -156,10 +159,6 @@ _fash_gl_add(Fash_Glyph *fash, int item, RGBA_Font_Glyph *glyph)
|
|||
fash->bucket[maj]->item[min] = glyph;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
EAPI RGBA_Font_Glyph *
|
||||
evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index)
|
||||
{
|
||||
|
@ -224,7 +223,6 @@ evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index)
|
|||
}
|
||||
fg->glyph_out = (FT_BitmapGlyph)fg->glyph;
|
||||
fg->index = hindex;
|
||||
|
||||
fg->fi = fi;
|
||||
|
||||
if (!fi->fash) fi->fash = _fash_gl_new();
|
||||
|
@ -380,7 +378,6 @@ evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* BiDi handling: We receive the shaped string + other props from intl_props,
|
||||
* we need to reorder it so we'll have the visual string (the way we draw)
|
||||
|
@ -402,18 +399,23 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
int c;
|
||||
int char_index = 0; /* the index of the current char */
|
||||
|
||||
|
||||
#if defined(METRIC_CACHE) || defined(WORD_CACHE)
|
||||
unsigned int len;
|
||||
|
||||
/* A fast strNlen would be nice (there is a wcsnlen strangely) */
|
||||
len = eina_unicode_strnlen(text,WORD_CACHE_MAXLEN);
|
||||
|
||||
if (len > 2 && len < WORD_CACHE_MAXLEN){
|
||||
struct prword *word = evas_font_word_prerender(dc, text, intl_props, len, fn, fi,
|
||||
use_kerning);
|
||||
if (word){
|
||||
int j,rowstart,rowend,xstart,xrun;
|
||||
if (len > 2 && len < WORD_CACHE_MAXLEN)
|
||||
{
|
||||
struct prword *word;
|
||||
|
||||
word =
|
||||
evas_font_word_prerender(dc, text, (Evas_BiDi_Props *)intl_props,
|
||||
len, fn, fi, use_kerning);
|
||||
if (word)
|
||||
{
|
||||
int j, rowstart, rowend, xstart, xrun;
|
||||
|
||||
im = dst->image.data;
|
||||
xrun = word->width;
|
||||
y -= word->baseline;
|
||||
|
@ -421,19 +423,23 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
rowstart = 0;
|
||||
rowend = word->height;
|
||||
/* Clip to extent */
|
||||
if (x + xrun > ext_x + ext_w){
|
||||
if (x + xrun > ext_x + ext_w)
|
||||
{
|
||||
xrun -= x + xrun - ext_x - ext_w;
|
||||
}
|
||||
if (x < ext_x) {
|
||||
if (x < ext_x)
|
||||
{
|
||||
int excess = ext_x - x;
|
||||
xstart = excess - 1;
|
||||
xrun -= excess;
|
||||
x = ext_x;
|
||||
}
|
||||
if (y + rowend > ext_y + ext_h){
|
||||
if (y + rowend > ext_y + ext_h)
|
||||
{
|
||||
rowend -= (y - ext_y + rowend - ext_h);
|
||||
}
|
||||
if (y < ext_y){
|
||||
if (y < ext_y)
|
||||
{
|
||||
int excess = ext_y - y;
|
||||
rowstart += excess;
|
||||
//rowend -= excess;
|
||||
|
@ -442,8 +448,10 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
|
||||
if (xrun < 1) return;
|
||||
# ifdef WORD_CACHE
|
||||
if (word->im){
|
||||
for (j = rowstart ; j < rowend ; j ++){
|
||||
if (word->im)
|
||||
{
|
||||
for (j = rowstart ; j < rowend ; j ++)
|
||||
{
|
||||
func(NULL, word->im + (word->roww * j) + xstart, dc->col.col,
|
||||
im + ((y + j) * im_w) + x, xrun);
|
||||
}
|
||||
|
@ -451,8 +459,10 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
}
|
||||
# elif defined(METRIC_CACHE)
|
||||
int ind;
|
||||
|
||||
y += word->baseline;
|
||||
for (ind = 0 ; ind < len ; ind ++){
|
||||
for (ind = 0 ; ind < len ; ind ++)
|
||||
{
|
||||
// FIXME Do we need to draw?
|
||||
struct cinfo *ci = word->cinfo + ind;
|
||||
for (j = rowstart ; j < rowend ; j ++)
|
||||
|
@ -464,8 +474,7 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
(void *)dst,
|
||||
dc, ci->fg,
|
||||
x + ci->pos.x,
|
||||
y - ci->bm.h + j
|
||||
);
|
||||
y - ci->bm.h + j);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -477,7 +486,6 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
return;
|
||||
# endif
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -499,7 +507,6 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
intl_props = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
pen_x = x;
|
||||
pen_y = y;
|
||||
last_adv = 0;
|
||||
|
@ -580,10 +587,8 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
/* ext glyph draw */
|
||||
dc->font_ext.func.gl_draw(dc->font_ext.data,
|
||||
(void *)dst,
|
||||
dc, fg,
|
||||
chr_x,
|
||||
y - (chr_y - y)
|
||||
);
|
||||
dc, fg, chr_x,
|
||||
y - (chr_y - y));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -694,7 +699,6 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
EAPI void
|
||||
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text,
|
||||
const Evas_BiDi_Props *intl_props)
|
||||
|
@ -750,8 +754,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
|
|||
{
|
||||
evas_common_font_draw_internal(dst, dc, fn, x, y, text, intl_props,
|
||||
func, ext_x, ext_y, ext_w, ext_h, fi,
|
||||
im_w, im_h, use_kerning
|
||||
);
|
||||
im_w, im_h, use_kerning);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -767,8 +770,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
|
|||
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
|
||||
evas_common_font_draw_internal(dst, dc, fn, x, y, text, intl_props,
|
||||
func, r->x, r->y, r->w, r->h, fi,
|
||||
im_w, im_h, use_kerning
|
||||
);
|
||||
im_w, im_h, use_kerning);
|
||||
}
|
||||
evas_common_draw_context_apply_clear_cutouts(rects);
|
||||
}
|
||||
|
@ -779,12 +781,12 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: Where is it freed at? */
|
||||
/* Only used if cache is on */
|
||||
#if defined(METRIC_CACHE) || defined(WORD_CACHE)
|
||||
struct prword *
|
||||
evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Evas_BiDi_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning){
|
||||
evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Evas_BiDi_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning)
|
||||
{
|
||||
int pen_x, pen_y;
|
||||
struct cinfo *metrics;
|
||||
const Eina_Unicode *text = in_text;
|
||||
|
@ -805,9 +807,9 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Eva
|
|||
if (gl) return NULL;
|
||||
# endif
|
||||
|
||||
|
||||
LKL(lock_words);
|
||||
EINA_INLIST_FOREACH(words,w){
|
||||
EINA_INLIST_FOREACH(words,w)
|
||||
{
|
||||
if (w->len == len && w->font == fn && fi->size == w->size &&
|
||||
(w->str == in_text || memcmp(w->str, in_text, len * sizeof(Eina_Unicode)) == 0)){
|
||||
words = eina_inlist_promote(words, EINA_INLIST_GET(w));
|
||||
|
@ -822,8 +824,10 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Eva
|
|||
pen_x = pen_y = 0;
|
||||
above = 0; below = 0; baseline = 0; height = 0; descent = 0;
|
||||
metrics = malloc(sizeof(struct cinfo) * len);
|
||||
|
||||
/* First pass: Work out how big */
|
||||
for (char_index = 0, c = 0, chr = 0 ; *text ; text++, char_index ++){
|
||||
for (char_index = 0, c = 0, chr = 0 ; *text ; text++, char_index ++)
|
||||
{
|
||||
struct cinfo *ci = metrics + char_index;
|
||||
ci->gl = *text;
|
||||
ci->index = evas_common_font_glyph_search(fn, &fi, ci->gl);
|
||||
|
@ -872,7 +876,8 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Eva
|
|||
pface = fi->src->ft.face;
|
||||
|
||||
LKU(fi->ft_mutex);
|
||||
if (gl){
|
||||
if (gl)
|
||||
{
|
||||
ci->fg->ext_dat =dc->font_ext.func.gl_new(dc->font_ext.data,ci->fg);
|
||||
ci->fg->ext_dat_free = dc->font_ext.func.gl_free;
|
||||
}
|
||||
|
@ -896,22 +901,25 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Eva
|
|||
width = (width & 0x7) ? width + (8 - (width & 0x7)) : width;
|
||||
|
||||
height = baseline + descent;
|
||||
if (!gl){
|
||||
if (!gl)
|
||||
{
|
||||
im = calloc(height, width);
|
||||
for (i = 0 ; i < char_index ; i ++){
|
||||
for (i = 0 ; i < char_index ; i ++)
|
||||
{
|
||||
struct cinfo *ci = metrics + i;
|
||||
for (j = 0 ; j < ci->bm.rows ; j ++){
|
||||
|
||||
for (j = 0 ; j < ci->bm.rows ; j ++)
|
||||
memcpy(im + ci->pos.x + (j + baseline - ci->bm.h) * width, ci->bm.data + j * ci->bm.w, ci->bm.w);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
else
|
||||
{
|
||||
im = NULL;
|
||||
}
|
||||
|
||||
/* Save it */
|
||||
struct prword *save;
|
||||
|
||||
|
||||
save = malloc(sizeof(struct prword));
|
||||
save->cinfo = metrics;
|
||||
save->str = eina_ustringshare_add(in_text);
|
||||
|
@ -927,19 +935,21 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, Eva
|
|||
words = eina_inlist_prepend(words, EINA_INLIST_GET(save));
|
||||
|
||||
/* Clean up if too long */
|
||||
if (eina_inlist_count(words) > max_cached_words){
|
||||
if (eina_inlist_count(words) > max_cached_words)
|
||||
{
|
||||
struct prword *last = (struct prword *)(words->last);
|
||||
|
||||
if (last)
|
||||
{
|
||||
if (last->im) free(last->im);
|
||||
if (last->cinfo) free(last->cinfo);
|
||||
eina_ustringshare_del(last->str);
|
||||
words = eina_inlist_remove(words,EINA_INLIST_GET(last));
|
||||
words = eina_inlist_remove(words, EINA_INLIST_GET(last));
|
||||
free(last);
|
||||
}
|
||||
}
|
||||
LKU(lock_words);
|
||||
|
||||
return save;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue