2008-07-10 11:08:18 -07:00
|
|
|
/*
|
|
|
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
|
|
|
*/
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
#include "evas_common.h"
|
2008-07-21 09:10:48 -07:00
|
|
|
#include "evas_blend_private.h"
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Font_Glyph *
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
RGBA_Font_Glyph *fg;
|
2006-02-28 19:48:03 -08:00
|
|
|
FT_UInt hindex;
|
2002-11-08 00:02:15 -08:00
|
|
|
FT_Error error;
|
2006-02-28 19:48:03 -08:00
|
|
|
const FT_Int32 hintflags[3] =
|
|
|
|
{ FT_LOAD_NO_HINTING, FT_LOAD_FORCE_AUTOHINT, FT_LOAD_NO_AUTOHINT };
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2006-02-28 19:48:03 -08:00
|
|
|
hindex = index + (fi->hinting * 500000000);
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
fg = eina_hash_find(fi->glyphs, &hindex);
|
2002-11-08 00:02:15 -08:00
|
|
|
if (fg) return fg;
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2005-04-29 19:30:24 -07:00
|
|
|
// error = FT_Load_Glyph(fi->src->ft.face, index, FT_LOAD_NO_BITMAP);
|
2006-02-28 19:48:03 -08:00
|
|
|
error = FT_Load_Glyph(fi->src->ft.face, index,
|
|
|
|
FT_LOAD_RENDER | hintflags[fi->hinting]);
|
2002-11-08 00:02:15 -08:00
|
|
|
if (error) return NULL;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
fg = malloc(sizeof(struct _RGBA_Font_Glyph));
|
|
|
|
if (!fg) return NULL;
|
|
|
|
memset(fg, 0, (sizeof(struct _RGBA_Font_Glyph)));
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
error = FT_Get_Glyph(fi->src->ft.face->glyph, &(fg->glyph));
|
2005-05-21 19:49:50 -07:00
|
|
|
if (error)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
free(fg);
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-08-25 04:54:17 -07:00
|
|
|
if (fg->glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2007-08-26 01:21:57 -07:00
|
|
|
error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1);
|
2005-05-21 19:49:50 -07:00
|
|
|
if (error)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
FT_Done_Glyph(fg->glyph);
|
|
|
|
free(fg);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fg->glyph_out = (FT_BitmapGlyph)fg->glyph;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2008-12-09 09:56:31 -08:00
|
|
|
eina_hash_add(fi->glyphs, &hindex, fg);
|
2002-11-08 00:02:15 -08:00
|
|
|
return fg;
|
|
|
|
}
|
|
|
|
|
2009-02-10 07:53:17 -08:00
|
|
|
typedef struct _Font_Char_Index Font_Char_Index;
|
|
|
|
struct _Font_Char_Index
|
|
|
|
{
|
|
|
|
FT_UInt index;
|
|
|
|
int gl;
|
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
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);
|
|
|
|
#endif
|
|
|
|
return result->index;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI int
|
2005-03-20 07:57:55 -08:00
|
|
|
evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl)
|
|
|
|
{
|
2008-10-21 09:31:05 -07:00
|
|
|
Eina_List *l;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
for (l = fn->fonts; l; l = l->next)
|
|
|
|
{
|
|
|
|
RGBA_Font_Int *fi;
|
|
|
|
int index;
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2005-03-20 07:57:55 -08:00
|
|
|
fi = l->data;
|
2006-04-22 04:08:01 -07:00
|
|
|
|
|
|
|
if (fi->src->charmap) /* Charmap loaded, FI/FS blank */
|
2006-04-08 17:02:47 -07:00
|
|
|
{
|
2008-07-10 11:08:18 -07:00
|
|
|
index = evas_array_hash_search(fi->src->charmap, gl);
|
2006-04-22 04:08:01 -07:00
|
|
|
if (index != 0)
|
|
|
|
{
|
|
|
|
evas_common_font_source_load_complete(fi->src);
|
|
|
|
evas_common_font_int_load_complete(fi);
|
|
|
|
|
2008-07-10 11:12:45 -07:00
|
|
|
evas_array_hash_free(fi->src->charmap);
|
2006-04-22 04:08:01 -07:00
|
|
|
fi->src->charmap = NULL;
|
|
|
|
|
|
|
|
*fi_ret = fi;
|
2008-07-10 11:08:18 -07:00
|
|
|
return index;
|
2006-04-22 04:08:01 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!fi->src->ft.face) /* Charmap not loaded, FI/FS blank */
|
|
|
|
{
|
2006-08-12 07:46:15 -07:00
|
|
|
if (evas_common_font_source_load_complete(fi->src))
|
2006-04-22 04:08:01 -07:00
|
|
|
return 0;
|
2007-08-08 16:41:31 -07:00
|
|
|
#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 */
|
2006-04-22 04:08:01 -07:00
|
|
|
index = FT_Get_Char_Index(fi->src->ft.face, gl);
|
|
|
|
if (index == 0)
|
|
|
|
{
|
|
|
|
/* Load Hash */
|
|
|
|
FT_ULong charcode;
|
|
|
|
FT_UInt gindex;
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2008-07-10 14:14:44 -07:00
|
|
|
fi->src->charmap = evas_array_hash_new();
|
2007-08-08 16:41:31 -07:00
|
|
|
charcode = FT_Get_First_Char(fi->src->ft.face, &gindex);
|
|
|
|
while (gindex != 0)
|
2006-04-22 04:08:01 -07:00
|
|
|
{
|
2008-07-10 14:14:44 -07:00
|
|
|
evas_array_hash_add(fi->src->charmap, charcode, gindex);
|
2007-08-08 16:41:31 -07:00
|
|
|
charcode = FT_Get_Next_Char(fi->src->ft.face, charcode, &gindex);
|
2006-04-22 04:08:01 -07:00
|
|
|
}
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2006-04-22 04:08:01 -07:00
|
|
|
/* Free face */
|
|
|
|
FT_Done_Face(fi->src->ft.face);
|
|
|
|
fi->src->ft.face = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
evas_common_font_int_load_complete(fi);
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2006-04-22 04:08:01 -07:00
|
|
|
*fi_ret = fi;
|
|
|
|
return index;
|
|
|
|
}
|
2008-07-10 11:08:18 -07:00
|
|
|
#endif
|
2006-04-08 17:02:47 -07:00
|
|
|
}
|
2006-04-22 04:08:01 -07:00
|
|
|
else /* Charmap not loaded, FS loaded */
|
2005-03-20 07:57:55 -08:00
|
|
|
{
|
2009-02-10 07:53:17 -08:00
|
|
|
index = _evas_common_get_char_index(fi, gl);
|
2006-04-22 04:08:01 -07:00
|
|
|
if (index != 0)
|
|
|
|
{
|
2008-07-10 11:08:18 -07:00
|
|
|
if (!fi->ft.size)
|
|
|
|
evas_common_font_int_load_complete(fi);
|
|
|
|
|
2006-04-22 04:08:01 -07:00
|
|
|
*fi_ret = fi;
|
|
|
|
return index;
|
|
|
|
}
|
2005-03-20 07:57:55 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-02-20 19:13:49 -08:00
|
|
|
static void
|
|
|
|
evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text,
|
|
|
|
RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w, int ext_h, RGBA_Font_Int *fi,
|
2009-02-25 15:18:15 -08:00
|
|
|
int im_w, int im_h __UNUSED__, int use_kerning
|
2009-02-20 19:13:49 -08:00
|
|
|
)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
int pen_x, pen_y;
|
|
|
|
int chr;
|
2009-02-20 19:13:49 -08:00
|
|
|
FT_Face pface = NULL;
|
2002-11-08 00:02:15 -08:00
|
|
|
FT_UInt prev_index;
|
|
|
|
DATA32 *im;
|
2003-09-10 07:33:39 -07:00
|
|
|
int c;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2006-10-08 05:43:31 -07:00
|
|
|
pen_x = x;
|
|
|
|
pen_y = y;
|
2002-11-08 00:02:15 -08:00
|
|
|
prev_index = 0;
|
2009-02-20 19:13:49 -08:00
|
|
|
im = dst->image.data;
|
2003-09-10 07:33:39 -07:00
|
|
|
for (c = 0, chr = 0; text[chr];)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
FT_UInt index;
|
|
|
|
RGBA_Font_Glyph *fg;
|
|
|
|
int chr_x, chr_y;
|
2009-02-10 07:53:17 -08:00
|
|
|
int gl, kern;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-13 21:38:10 -08:00
|
|
|
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
|
2002-11-08 00:02:15 -08:00
|
|
|
if (gl == 0) break;
|
2005-03-20 07:57:55 -08:00
|
|
|
index = evas_common_font_glyph_search(fn, &fi, gl);
|
2004-01-23 03:03:07 -08:00
|
|
|
/* 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 */
|
2005-04-27 21:57:12 -07:00
|
|
|
if ((use_kerning) && (prev_index) && (index) &&
|
|
|
|
(pface == fi->src->ft.face))
|
2009-02-10 07:53:17 -08:00
|
|
|
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
|
|
|
|
pen_x += kern;
|
|
|
|
|
2005-04-27 21:57:12 -07:00
|
|
|
pface = fi->src->ft.face;
|
2005-03-20 07:57:55 -08:00
|
|
|
fg = evas_common_font_int_cache_glyph_get(fi, index);
|
2002-11-08 00:02:15 -08:00
|
|
|
if (!fg) continue;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2005-10-02 08:15:44 -07:00
|
|
|
if (dc->font_ext.func.gl_new)
|
2003-09-08 22:51:03 -07:00
|
|
|
{
|
|
|
|
/* extension calls */
|
|
|
|
fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg);
|
|
|
|
fg->ext_dat_free = dc->font_ext.func.gl_free;
|
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2006-10-08 05:43:31 -07:00
|
|
|
chr_x = (pen_x + (fg->glyph_out->left));
|
|
|
|
chr_y = (pen_y + (fg->glyph_out->top));
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
if (chr_x < (ext_x + ext_w))
|
|
|
|
{
|
|
|
|
DATA8 *data;
|
|
|
|
int i, j, w, h;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
data = fg->glyph_out->bitmap.buffer;
|
|
|
|
j = fg->glyph_out->bitmap.pitch;
|
|
|
|
w = fg->glyph_out->bitmap.width;
|
2003-01-08 23:41:22 -08:00
|
|
|
if (j < w) j = w;
|
2002-11-08 00:02:15 -08:00
|
|
|
h = fg->glyph_out->bitmap.rows;
|
2008-07-10 11:08:18 -07:00
|
|
|
/*
|
2005-09-05 01:01:15 -07:00
|
|
|
if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)
|
|
|
|
&& (fg->glyph_out->bitmap.num_grays == 256)
|
|
|
|
)
|
|
|
|
*/
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2003-06-04 19:59:19 -07:00
|
|
|
if ((j > 0) && (chr_x + w > ext_x))
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2006-04-16 18:57:11 -07:00
|
|
|
if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2003-09-08 22:51:03 -07:00
|
|
|
/* ext glyph draw */
|
2005-05-21 19:49:50 -07:00
|
|
|
dc->font_ext.func.gl_draw(dc->font_ext.data,
|
2005-10-02 08:15:44 -07:00
|
|
|
(void *)dst,
|
2005-05-21 19:49:50 -07:00
|
|
|
dc, fg,
|
|
|
|
chr_x,
|
2003-09-08 22:51:03 -07:00
|
|
|
y - (chr_y - y)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-11-16 05:17:27 -08:00
|
|
|
if ((fg->glyph_out->bitmap.num_grays == 256) &&
|
|
|
|
(fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-09-05 01:01:15 -07:00
|
|
|
for (i = 0; i < h; i++)
|
2003-06-04 19:59:19 -07:00
|
|
|
{
|
2005-09-05 01:01:15 -07:00
|
|
|
int dx, dy;
|
|
|
|
int in_x, in_w;
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2005-09-05 01:01:15 -07:00
|
|
|
in_x = 0;
|
|
|
|
in_w = 0;
|
|
|
|
dx = chr_x;
|
|
|
|
dy = y - (chr_y - i - y);
|
2006-11-15 08:44:34 -08:00
|
|
|
#ifdef EVAS_SLI
|
|
|
|
if (((dy) % dc->sli.h) == dc->sli.y)
|
|
|
|
#endif
|
2003-09-08 22:51:03 -07:00
|
|
|
{
|
2006-11-15 08:44:34 -08:00
|
|
|
if ((dx < (ext_x + ext_w)) &&
|
|
|
|
(dy >= (ext_y)) &&
|
|
|
|
(dy < (ext_y + ext_h)))
|
2005-09-05 01:01:15 -07:00
|
|
|
{
|
2006-11-15 08:44:34 -08:00
|
|
|
if (dx + w > (ext_x + ext_w))
|
|
|
|
in_w += (dx + w) - (ext_x + ext_w);
|
|
|
|
if (dx < ext_x)
|
|
|
|
{
|
|
|
|
in_w += ext_x - dx;
|
|
|
|
in_x = ext_x - dx;
|
|
|
|
dx = ext_x;
|
|
|
|
}
|
|
|
|
if (in_w < w)
|
|
|
|
{
|
|
|
|
func(NULL, data + (i * j) + in_x, dc->col.col,
|
|
|
|
im + (dy * im_w) + dx, w - in_w);
|
|
|
|
}
|
2005-09-05 01:01:15 -07:00
|
|
|
}
|
2003-09-08 22:51:03 -07:00
|
|
|
}
|
2005-09-05 01:01:15 -07:00
|
|
|
}
|
|
|
|
}
|
2005-11-16 05:17:27 -08:00
|
|
|
else
|
2005-09-05 01:01:15 -07:00
|
|
|
{
|
|
|
|
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
|
|
|
|
int bi, bj;
|
|
|
|
const DATA8 bitrepl[2] = {0x0, 0xff};
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2005-11-28 07:18:01 -08:00
|
|
|
tmpbuf = alloca(w);
|
|
|
|
for (i = 0; i < h; i++)
|
2005-09-05 01:01:15 -07:00
|
|
|
{
|
2005-11-28 07:18:01 -08:00
|
|
|
int dx, dy;
|
|
|
|
int in_x, in_w, end;
|
2008-07-10 11:08:18 -07:00
|
|
|
|
2005-11-28 07:18:01 -08:00
|
|
|
in_x = 0;
|
|
|
|
in_w = 0;
|
|
|
|
dx = chr_x;
|
|
|
|
dy = y - (chr_y - i - y);
|
2006-11-15 08:44:34 -08:00
|
|
|
#ifdef EVAS_SLI
|
|
|
|
if (((dy) % dc->sli.h) == dc->sli.y)
|
|
|
|
#endif
|
2003-09-08 22:51:03 -07:00
|
|
|
{
|
2006-11-15 08:44:34 -08:00
|
|
|
tp = tmpbuf;
|
|
|
|
dp = data + (i * fg->glyph_out->bitmap.pitch);
|
|
|
|
for (bi = 0; bi < w; bi += 8)
|
2005-09-05 01:01:15 -07:00
|
|
|
{
|
2006-11-15 08:44:34 -08:00
|
|
|
bits = *dp;
|
|
|
|
if ((w - bi) < 8) end = w - bi;
|
|
|
|
else end = 8;
|
|
|
|
for (bj = 0; bj < end; bj++)
|
|
|
|
{
|
|
|
|
*tp = bitrepl[(bits >> (7 - bj)) & 0x1];
|
|
|
|
tp++;
|
|
|
|
}
|
|
|
|
dp++;
|
2005-09-05 01:01:15 -07:00
|
|
|
}
|
2006-11-15 08:44:34 -08:00
|
|
|
if ((dx < (ext_x + ext_w)) &&
|
|
|
|
(dy >= (ext_y)) &&
|
|
|
|
(dy < (ext_y + ext_h)))
|
2005-09-05 01:01:15 -07:00
|
|
|
{
|
2006-11-15 08:44:34 -08:00
|
|
|
if (dx + w > (ext_x + ext_w))
|
|
|
|
in_w += (dx + w) - (ext_x + ext_w);
|
|
|
|
if (dx < ext_x)
|
|
|
|
{
|
|
|
|
in_w += ext_x - dx;
|
|
|
|
in_x = ext_x - dx;
|
|
|
|
dx = ext_x;
|
|
|
|
}
|
|
|
|
if (in_w < w)
|
|
|
|
{
|
|
|
|
func(NULL, tmpbuf + in_x, dc->col.col,
|
|
|
|
im + (dy * im_w) + dx, w - in_w);
|
|
|
|
}
|
2005-09-05 01:01:15 -07:00
|
|
|
}
|
2003-09-08 22:51:03 -07:00
|
|
|
}
|
2003-06-04 19:59:19 -07:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
}
|
2003-09-10 07:33:39 -07:00
|
|
|
c++;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
2006-10-08 05:43:31 -07:00
|
|
|
pen_x += fg->glyph->advance.x >> 16;
|
2005-05-21 19:49:50 -07:00
|
|
|
prev_index = index;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2009-02-20 19:13:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text)
|
|
|
|
{
|
|
|
|
int ext_x, ext_y, ext_w, ext_h;
|
|
|
|
int im_w, im_h;
|
|
|
|
int use_kerning;
|
|
|
|
RGBA_Gfx_Func func;
|
|
|
|
RGBA_Font_Int *fi;
|
|
|
|
Cutout_Rects *rects;
|
|
|
|
Cutout_Rect *r;
|
|
|
|
int c, cx, cy, cw, ch;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
fi = fn->fonts->data;
|
|
|
|
|
|
|
|
im_w = dst->cache_entry.w;
|
|
|
|
im_h = dst->cache_entry.h;
|
|
|
|
|
|
|
|
ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h;
|
|
|
|
if (dc->clip.use)
|
|
|
|
{
|
|
|
|
ext_x = dc->clip.x;
|
|
|
|
ext_y = dc->clip.y;
|
|
|
|
ext_w = dc->clip.w;
|
|
|
|
ext_h = dc->clip.h;
|
|
|
|
if (ext_x < 0)
|
|
|
|
{
|
|
|
|
ext_w += ext_x;
|
|
|
|
ext_x = 0;
|
|
|
|
}
|
|
|
|
if (ext_y < 0)
|
|
|
|
{
|
|
|
|
ext_h += ext_y;
|
|
|
|
ext_y = 0;
|
|
|
|
}
|
|
|
|
if ((ext_x + ext_w) > im_w)
|
|
|
|
ext_w = im_w - ext_x;
|
|
|
|
if ((ext_y + ext_h) > im_h)
|
|
|
|
ext_h = im_h - ext_y;
|
|
|
|
}
|
|
|
|
if (ext_w <= 0) return;
|
|
|
|
if (ext_h <= 0) return;
|
|
|
|
|
|
|
|
LKL(fn->lock);
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (!dc->cutout.rects)
|
|
|
|
{
|
|
|
|
evas_common_font_draw_internal(dst, dc, fn, x, y, text,
|
|
|
|
func, ext_x, ext_y, ext_w, ext_h, fi,
|
|
|
|
im_w, im_h, use_kerning
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-02-22 23:20:21 -08:00
|
|
|
c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
|
2009-02-20 19:13:49 -08:00
|
|
|
evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
|
|
|
|
/* our clip is 0 size.. abort */
|
|
|
|
if ((dc->clip.w > 0) && (dc->clip.h > 0))
|
|
|
|
{
|
|
|
|
rects = evas_common_draw_context_apply_cutouts(dc);
|
|
|
|
for (i = 0; i < rects->active; ++i)
|
|
|
|
{
|
|
|
|
r = rects->rects + i;
|
|
|
|
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,
|
|
|
|
func, r->x, r->y, r->w, r->h, fi,
|
|
|
|
im_w, im_h, use_kerning
|
|
|
|
);
|
|
|
|
}
|
|
|
|
evas_common_draw_context_apply_clear_cutouts(rects);
|
|
|
|
}
|
2009-02-22 23:20:21 -08:00
|
|
|
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
|
2009-02-20 19:13:49 -08:00
|
|
|
}
|
2006-11-13 15:23:44 -08:00
|
|
|
LKU(fn->lock);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|