Snapshot.

SVN revision: 56552
This commit is contained in:
Tom Hacohen 2011-01-30 13:55:04 +00:00
parent debf4d9428
commit d6feccdebb
16 changed files with 844 additions and 1177 deletions

View File

@ -63,6 +63,7 @@ language/evas_bidi_utils.c \
language/evas_language_utils.c \ language/evas_language_utils.c \
evas_text_utils.c \ evas_text_utils.c \
evas_font_ot.c \ evas_font_ot.c \
evas_font_glyph_info.c \
evas_map_image.c \ evas_map_image.c \
evas_map_image.h evas_map_image.h
@ -105,6 +106,7 @@ language/evas_bidi_utils.h \
language/evas_language_utils.h \ language/evas_language_utils.h \
evas_text_utils.h \ evas_text_utils.h \
evas_font_ot.h \ evas_font_ot.h \
evas_font_glyph_info.h \
evas_map_image_internal.c \ evas_map_image_internal.c \
evas_map_image_core.c \ evas_map_image_core.c \
evas_map_image_loop.c evas_map_image_loop.c

View File

@ -3,190 +3,163 @@
/* Macros for text walking */ /* Macros for text walking */
/** /**
* @def EVAS_FONT_UPDATE_KERN() * @def EVAS_FONT_WALK_TEXT_INIT
* @internal * @internal
* This macro updates kern according to kerning. * This macro defines the variables that will later be used with the following
* This macro assumes the following variables exist: * macros, and by font handling functions.
* intl_props, char_index, fi, kern, index, prev_index * @see EVAS_FONT_WALK_TEXT_START
* @see EVAS_FONT_WALK_TEXT_WORK
* @see EVAS_FONT_WALK_TEXT_END
*/ */
#ifdef BIDI_SUPPORT # define EVAS_FONT_WALK_TEXT_INIT() \
#define EVAS_FONT_UPDATE_KERN(is_visual) \ int _pen_x = 0, _pen_y = 0; \
do \ size_t char_index; \
{ \ (void) _pen_y; /* Sometimes it won't be used */
/* if it's rtl, the kerning matching should be reversed, */ \
/* i.e prev index is now the index and the other way */ \
/* around. There is a slight exception when there are */ \
/* compositing chars involved.*/ \
if (intl_props && (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && \
visible && !is_visual) \
{ \
if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \
_pen_x += kern; \
} \
else \
{ \
if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \
_pen_x += kern; \
} \
} \
while (0)
#else
#define EVAS_FONT_UPDATE_KERN(is_visual) \
do \
{ \
(void) is_visual; \
if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \
_pen_x += kern; \
} \
while (0)
#endif
/** /**
* @def EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START * @def EVAS_FONT_WALK_TEXT_VISUAL_START
* @internal * @internal
* This runs through the text in visual order while updating char_index, * This runs through the text in visual order while updating char_index,
* which is the current index in the text. * which is the current index in the text.
* Does not end with a ; * Does not end with a ;
* Take a look at EVAS_FONT_WALK_DEFAULT_X_OFF and the like. * Take a look at EVAS_FONT_WALK_X_OFF and the like.
* @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT * @see EVAS_FONT_WALK_TEXT_INIT
* @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK * @see EVAS_FONT_WALK_TEXT_WORK
* @see EVAS_FONT_WALK_DEFAULT_TEXT_END * @see EVAS_FONT_WALK_TEXT_END
* @see EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START * @see EVAS_FONT_WALK_TEXT_LOGICAL_START
*/ */
#define EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() \ #define EVAS_FONT_WALK_TEXT_VISUAL_START() \
do \ do \
{ \ { \
const Eina_Unicode *_base_text; \ int visible = 1; \
int _char_index_d, _i; \ for (char_index = 0 ; char_index < text_props->len ; char_index++) \
int visible; \ {
prev_index = 0; \
_base_text = text; \ /**
for ( ; *text ; text++); \ * @def EVAS_FONT_WALK_TEXT_LOGICAL_START
_i = text - _base_text; \ * @internal
if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \ * This runs through the text in logical order while updating char_index,
* which is the current index in the text.
* Does not end with a ;
* Take a look at EVAS_FONT_WALK_X_OFF and the like.
* @see EVAS_FONT_WALK_TEXT_INIT
* @see EVAS_FONT_WALK_TEXT_WORK
* @see EVAS_FONT_WALK_TEXT_END
* @see EVAS_FONT_WALK_TEXT_VISUAL_START
*/
#ifdef BIDI_SUPPORT
#define EVAS_FONT_WALK_TEXT_LOGICAL_START() \
do \
{ \ { \
char_index = text - _base_text - 1; \ int _char_index_d, _i; \
text--; \ int visible = 1; \
_i = text_props->len; \
if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
{ \
char_index = text_props->len - 1; \
_char_index_d = -1; \ _char_index_d = -1; \
} \ } \
else \ else \
{ \ { \
char_index = 0; \ char_index = 0; \
text = _base_text; \
_char_index_d = 1; \ _char_index_d = 1; \
} \ } \
for ( ; _i > 0 ; char_index += _char_index_d, text += _char_index_d, _i--) \ for ( ; _i > 0 ; char_index += _char_index_d, _i--) \
{ \ {
FT_UInt index; \ #else
RGBA_Font_Glyph *fg; \ #define EVAS_FONT_WALK_TEXT_LOGICAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START()
int _gl, kern; \ #endif
_gl = *text; \
if (_gl == 0) break;
/**
* @def EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START
* @internal
* This runs through the text in logical order while updating char_index,
* which is the current index in the text.
* Does not end with a ;
* Take a look at EVAS_FONT_WALK_DEFAULT_X_OFF and the like.
* @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT
* @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK
* @see EVAS_FONT_WALK_DEFAULT_TEXT_END
* @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
*/
#define EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() \
do \
{ \
int visible; \
prev_index = 0; \
for (char_index = 0 ; *text ; text++, char_index++) \
{ \
FT_UInt index; \
RGBA_Font_Glyph *fg; \
int _gl, kern; \
_gl = *text; \
if (_gl == 0) break;
/*FIXME: doc */ /*FIXME: doc */
#define EVAS_FONT_WALK_DEFAULT_X_OFF (0) #ifdef OT_SUPPORT
#define EVAS_FONT_WALK_DEFAULT_Y_OFF (0) # define EVAS_FONT_WALK_X_OFF \
#define EVAS_FONT_WALK_DEFAULT_X_BEAR (fg->glyph_out->left) ((text_props->info->ot) ? \
#define EVAS_FONT_WALK_DEFAULT_Y_BEAR (fg->glyph_out->top) (EVAS_FONT_ROUND_26_6_TO_INT( \
#define _EVAS_FONT_WALK_DEFAULT_X_ADV (fg->glyph->advance.x >> 10) EVAS_FONT_OT_X_OFF_GET( \
#define EVAS_FONT_WALK_DEFAULT_X_ADV \ text_props->info->ot[char_index]))) : \
(EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_DEFAULT_X_ADV)) (0))
#define EVAS_FONT_WALK_DEFAULT_Y_ADV (0) # define EVAS_FONT_WALK_Y_OFF \
#define EVAS_FONT_WALK_DEFAULT_WIDTH (fg->glyph_out->bitmap.width) ((text_props->info->ot) ? \
#define EVAS_FONT_WALK_DEFAULT_POS (char_index) (EVAS_FONT_ROUND_26_6_TO_INT( \
#define EVAS_FONT_WALK_DEFAULT_IS_LAST \ EVAS_FONT_OT_Y_OFF_GET( \
(!text[char_index]) text_props->info->ot[char_index]))) : \
#define EVAS_FONT_WALK_DEFAULT_IS_FIRST \ (0))
# define EVAS_FONT_WALK_POS \
((text_props->info->ot) ? \
(EVAS_FONT_OT_POS_GET( \
text_props->info->ot[char_index])) : \
(char_index))
# define EVAS_FONT_WALK_POS_NEXT \
((text_props->info->ot) ? \
((!EVAS_FONT_WALK_IS_LAST) ? \
EVAS_FONT_OT_POS_GET( \
text_props->info->ot[char_index + 1]) : \
EVAS_FONT_WALK_POS \
) : \
((!EVAS_FONT_WALK_IS_LAST) ? \
(char_index + 1) : EVAS_FONT_WALK_POS))
# define EVAS_FONT_WALK_POS_PREV \
((text_props->info->ot) ? \
((char_index > 0) ? \
EVAS_FONT_OT_POS_GET( \
text_props->info->ot[char_index - 1]) : \
EVAS_FONT_WALK_POS \
) : \
((char_index > 0) ? \
(char_index - 1) : EVAS_FONT_WALK_POS))
#else
# define EVAS_FONT_WALK_X_OFF 0
# define EVAS_FONT_WALK_Y_OFF 0
# define EVAS_FONT_WALK_POS (char_index)
# define EVAS_FONT_WALK_POS_NEXT \
((!EVAS_FONT_WALK_IS_LAST) ? \
(char_index + 1) : EVAS_FONT_WALK_POS)
# define EVAS_FONT_WALK_POS_PREV \
((char_index > 0) ? \
(char_index - 1) : EVAS_FONT_WALK_POS)
#endif
#define EVAS_FONT_WALK_X_BEAR (text_props->info->glyph[char_index].x_bear)
#define EVAS_FONT_WALK_Y_BEAR (fg->glyph_out->top)
#define _EVAS_FONT_WALK_X_ADV \
(text_props->info->glyph[char_index].advance)
#define EVAS_FONT_WALK_WIDTH (text_props->info->glyph[char_index].width)
#define EVAS_FONT_WALK_X_ADV \
(EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_X_ADV))
#define EVAS_FONT_WALK_PEN_X (EVAS_FONT_ROUND_26_6_TO_INT(_pen_x))
#define EVAS_FONT_WALK_PEN_Y (EVAS_FONT_ROUND_26_6_TO_INT(_pen_y))
#define EVAS_FONT_WALK_Y_ADV (0)
#define EVAS_FONT_WALK_IS_LAST \
(char_index + 1 == text_props->len)
#define EVAS_FONT_WALK_IS_FIRST \
(!char_index) (!char_index)
#define EVAS_FONT_WALK_DEFAULT_POS_NEXT \ #define EVAS_FONT_WALK_LEN (text_props->len)
((!EVAS_FONT_WALK_DEFAULT_IS_LAST) ? \
(char_index + 1) : \
(char_index) \
)
#define EVAS_FONT_WALK_DEFAULT_POS_PREV \
((!EVAS_FONT_WALK_DEFAULT_IS_FIRST) ? \
(char_index - 1) : \
EVAS_FONT_WALK_DEFAULT_POS \
)
#define EVAS_FONT_WALK_DEFAULT_LEN (EVAS_FONT_WALK_ORIG_LEN)
/**
* @def EVAS_FONT_WALK_DEFAULT_TEXT_WORK
* @internal
* This macro actually updates the values mentioned in EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
* according to the current positing in the walk.
* @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
* @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT
* @see EVAS_FONT_WALK_DEFAULT_TEXT_END
*/
#define EVAS_FONT_WALK_DEFAULT_TEXT_WORK(is_visual) \
index = evas_common_font_glyph_search(fn, &fi, _gl); \
LKL(fi->ft_mutex); \
fg = evas_common_font_int_cache_glyph_get(fi, index); \
if (!fg) \
{ \
LKU(fi->ft_mutex); \
continue; \
} \
kern = 0; \
if (EVAS_FONT_CHARACTER_IS_INVISIBLE(_gl)) \
{ \
visible = 0; \
} \
else \
{ \
visible = 1; \
} \
/* 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) && \
(pface == fi->src->ft.face)) \
{ \
EVAS_FONT_UPDATE_KERN(is_visual); \
} \
\
pface = fi->src->ft.face; \
LKU(fi->ft_mutex); \
/** /**
* @def EVAS_FONT_WALK_DEFAULT_TEXT_END * @def EVAS_FONT_WALK_TEXT_WORK
* @internal * @internal
* Closes EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START, needs to end with a ; * This macro actually updates the values mentioned in EVAS_FONT_WALK_TEXT_VISUAL_START
* @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START * according to the current positing in the walk.
* @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT * @see EVAS_FONT_WALK_TEXT_VISUAL_START
* @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK * @see EVAS_FONT_WALK_TEXT_INIT
* @see EVAS_FONT_WALK_TEXT_END
*/ */
#define EVAS_FONT_WALK_DEFAULT_TEXT_END() \ #define EVAS_FONT_WALK_TEXT_WORK() do {} while(0);
/**
* @def EVAS_FONT_WALK_TEXT_END
* @internal
* Closes EVAS_FONT_WALK_TEXT_VISUAL_START, needs to end with a ;
* @see EVAS_FONT_WALK_TEXT_VISUAL_START
* @see EVAS_FONT_WALK_TEXT_INIT
* @see EVAS_FONT_WALK_TEXT_WORK
*/
#define EVAS_FONT_WALK_TEXT_END() \
if (visible) \ if (visible) \
{ \ { \
_pen_x += _EVAS_FONT_WALK_DEFAULT_X_ADV; \ _pen_x += _EVAS_FONT_WALK_X_ADV; \
} \ } \
prev_index = index; \
} \ } \
} \ } \
while(0) while(0)

View File

@ -49,7 +49,7 @@ struct cinfo
#if defined(METRIC_CACHE) || defined(WORD_CACHE) #if defined(METRIC_CACHE) || defined(WORD_CACHE)
LK(lock_words); // for word cache call LK(lock_words); // for word cache call
static Eina_Inlist *words = NULL; static Eina_Inlist *words = NULL;
static struct prword *evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning); static struct prword *evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *text, const Evas_Text_Props *text_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning);
#endif #endif
EAPI void EAPI void
@ -389,19 +389,20 @@ evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl)
} }
/* /*
* BiDi handling: We receive the shaped string + other props from intl_props, * 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) * we need to reorder it so we'll have the visual string (the way we draw)
* and then for kerning we have to switch the order of the kerning query (as the prev * and then for kerning we have to switch the order of the kerning query (as the prev
* is on the right, and not on the left). * is on the right, and not on the left).
*/ */
static void static void
evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *in_text, evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *in_text,
const Evas_Text_Props *intl_props, RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w, const Evas_Text_Props *text_props, RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w,
int ext_h, RGBA_Font_Int *fi, int im_w, int im_h __UNUSED__, int use_kerning int ext_h, RGBA_Font_Int *fi, int im_w, int im_h __UNUSED__, int use_kerning
) )
{ {
const Eina_Unicode *text = in_text; const Eina_Unicode *text = in_text;
DATA32 *im; DATA32 *im;
FT_Face pface = NULL;
EVAS_FONT_WALK_TEXT_INIT(); EVAS_FONT_WALK_TEXT_INIT();
#if defined(METRIC_CACHE) || defined(WORD_CACHE) #if defined(METRIC_CACHE) || defined(WORD_CACHE)
@ -415,7 +416,7 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
struct prword *word; struct prword *word;
word = word =
evas_font_word_prerender(dc, text, intl_props, evas_font_word_prerender(dc, text, text_props,
len, fn, fi, use_kerning); len, fn, fi, use_kerning);
if (word) if (word)
{ {
@ -492,6 +493,8 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
# endif # endif
} }
} }
#else
(void) use_kerning;
#endif #endif
if (fi->src->current_size != fi->size) if (fi->src->current_size != fi->size)
@ -504,14 +507,45 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
im = dst->image.data; im = dst->image.data;
#ifdef OT_SUPPORT /* Load the glyph according to the first letter of the script, preety
if (evas_common_font_ot_is_enabled() && intl_props->ot_data) * bad, but will have to do */
{ {
EVAS_FONT_WALK_OT_TEXT_VISUAL_START() /* Skip common chars */
const Eina_Unicode *tmp;
for (tmp = text ;
*tmp &&
evas_common_language_char_script_get(*tmp) ==
EVAS_SCRIPT_COMMON ;
tmp++)
;
if (!*tmp && (tmp > text)) tmp--;
evas_common_font_glyph_search(fn, &fi, *tmp);
}
EVAS_FONT_WALK_TEXT_VISUAL_START()
{ {
FT_UInt index;
RGBA_Font_Glyph *fg;
int chr_x, chr_y, chr_w; int chr_x, chr_y, chr_w;
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); index = text_props->info->glyph[char_index].index;
LKL(fi->ft_mutex);
fg = evas_common_font_int_cache_glyph_get(fi, index);
if (!fg)
{
LKU(fi->ft_mutex);
continue;
}
if (EVAS_FONT_CHARACTER_IS_INVISIBLE(text[EVAS_FONT_WALK_POS]))
{
visible = 0;
}
else
{
visible = 1;
}
pface = fi->src->ft.face;
LKU(fi->ft_mutex);
if (dc->font_ext.func.gl_new) if (dc->font_ext.func.gl_new)
{ {
@ -520,9 +554,9 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
fg->ext_dat_free = dc->font_ext.func.gl_free; fg->ext_dat_free = dc->font_ext.func.gl_free;
} }
chr_x = x + EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_OFF + EVAS_FONT_WALK_OT_X_BEAR; chr_x = x + EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
chr_y = y + EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_OT_Y_OFF + EVAS_FONT_WALK_OT_Y_BEAR; chr_y = y + EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
chr_w = EVAS_FONT_WALK_OT_WIDTH; chr_w = EVAS_FONT_WALK_WIDTH;
if (chr_x < (ext_x + ext_w)) if (chr_x < (ext_x + ext_w))
{ {
@ -651,163 +685,13 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
else else
break; break;
} }
EVAS_FONT_WALK_OT_TEXT_END(); EVAS_FONT_WALK_TEXT_END();
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
{
int chr_x, chr_y, chr_w;
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
if (dc->font_ext.func.gl_new)
{
/* 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;
}
chr_x = x + EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_OFF + EVAS_FONT_WALK_DEFAULT_X_BEAR;
chr_y = y + EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_DEFAULT_Y_OFF + EVAS_FONT_WALK_DEFAULT_Y_BEAR;
chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH;
if (chr_x < (ext_x + ext_w))
{
DATA8 *data;
int i, j, w, h;
data = fg->glyph_out->bitmap.buffer;
j = fg->glyph_out->bitmap.pitch;
w = fg->glyph_out->bitmap.width;
if (j < w) j = w;
h = fg->glyph_out->bitmap.rows;
/*
if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)
&& (fg->glyph_out->bitmap.num_grays == 256)
)
*/
{
if ((j > 0) && (chr_x + w > ext_x))
{
if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
{
/* ext glyph draw */
dc->font_ext.func.gl_draw(dc->font_ext.data,
(void *)dst,
dc, fg, chr_x,
y - (chr_y - y));
}
else
{
if ((fg->glyph_out->bitmap.num_grays == 256) &&
(fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
{
for (i = 0; i < h; i++)
{
int dx, dy;
int in_x, in_w;
in_x = 0;
in_w = 0;
dx = chr_x;
dy = y - (chr_y - i - y);
#ifdef EVAS_SLI
if (((dy) % dc->sli.h) == dc->sli.y)
#endif
{
if ((dx < (ext_x + ext_w)) &&
(dy >= (ext_y)) &&
(dy < (ext_y + ext_h)))
{
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);
}
}
}
}
}
else
{
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
int bi, bj;
const DATA8 bitrepl[2] = {0x0, 0xff};
tmpbuf = alloca(w);
for (i = 0; i < h; i++)
{
int dx, dy;
int in_x, in_w, end;
in_x = 0;
in_w = 0;
dx = chr_x;
dy = y - (chr_y - i - y);
#ifdef EVAS_SLI
if (((dy) % dc->sli.h) == dc->sli.y)
#endif
{
tp = tmpbuf;
dp = data + (i * fg->glyph_out->bitmap.pitch);
for (bi = 0; bi < w; bi += 8)
{
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++;
}
if ((dx < (ext_x + ext_w)) &&
(dy >= (ext_y)) &&
(dy < (ext_y + ext_h)))
{
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);
}
}
}
}
}
}
}
}
}
else
break;
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
evas_common_font_int_use_trim(); evas_common_font_int_use_trim();
} }
EAPI void EAPI void
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text,
const Evas_Text_Props *intl_props) const Evas_Text_Props *text_props)
{ {
int ext_x, ext_y, ext_w, ext_h; int ext_x, ext_y, ext_w, ext_h;
int im_w, im_h; int im_w, im_h;
@ -859,7 +743,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
if (!dc->cutout.rects) if (!dc->cutout.rects)
{ {
evas_common_font_draw_internal(dst, dc, fn, x, y, text, intl_props, evas_common_font_draw_internal(dst, dc, fn, x, y, text, text_props,
func, ext_x, ext_y, ext_w, ext_h, fi, func, ext_x, ext_y, ext_w, ext_h, fi,
im_w, im_h, use_kerning); im_w, im_h, use_kerning);
} }
@ -875,7 +759,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
{ {
r = rects->rects + i; r = rects->rects + i;
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); 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, evas_common_font_draw_internal(dst, dc, fn, x, y, text, text_props,
func, r->x, r->y, r->w, r->h, fi, func, r->x, r->y, r->w, r->h, fi,
im_w, im_h, use_kerning); im_w, im_h, use_kerning);
} }
@ -892,7 +776,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
/* Only used if cache is on */ /* Only used if cache is on */
#if defined(METRIC_CACHE) || defined(WORD_CACHE) #if defined(METRIC_CACHE) || defined(WORD_CACHE)
struct prword * struct prword *
evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, const Evas_Text_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, const Evas_Text_Props *text_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning)
{ {
struct cinfo *metrics; struct cinfo *metrics;
const Eina_Unicode *text = in_text; const Eina_Unicode *text = in_text;
@ -930,14 +814,14 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con
/* It's a bit hackish to use index and fg here as they are internal, /* It's a bit hackish to use index and fg here as they are internal,
* but that'll have to be good enough ATM */ * but that'll have to be good enough ATM */
#ifdef OT_SUPPORT #ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled() && intl_props->ot_data) if (evas_common_font_ot_is_enabled())
{ {
len = intl_props->ot_data->len; len = text_props->info->ot_data->len;
metrics = malloc(sizeof(struct cinfo) * len); metrics = malloc(sizeof(struct cinfo) * len);
EVAS_FONT_WALK_OT_TEXT_VISUAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START()
{ {
struct cinfo *ci = metrics + char_index; struct cinfo *ci = metrics + char_index;
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE);
/* Currently broken with invisible chars if (!visible) continue; */ /* Currently broken with invisible chars if (!visible) continue; */
ci->index = index; ci->index = index;
ci->fg = fg; ci->fg = fg;
@ -958,19 +842,19 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con
if (above > baseline) baseline = above; if (above > baseline) baseline = above;
ci->pos.x = EVAS_FONT_WALK_PEN_X + ci->fg->glyph_out->left; ci->pos.x = EVAS_FONT_WALK_PEN_X + ci->fg->glyph_out->left;
ci->pos.y = EVAS_FONT_WALK_PEN_Y + ci->fg->glyph_out->top; ci->pos.y = EVAS_FONT_WALK_PEN_Y + ci->fg->glyph_out->top;
last_delta = EVAS_FONT_WALK_OT_X_ADV - last_delta = EVAS_FONT_WALK_X_ADV -
(ci->bm.w + ci->fg->glyph_out->left); (ci->bm.w + ci->fg->glyph_out->left);
} }
EVAS_FONT_WALK_OT_TEXT_END(); EVAS_FONT_WALK_TEXT_END();
} }
else else
#endif #endif
{ {
metrics = malloc(sizeof(struct cinfo) * len); metrics = malloc(sizeof(struct cinfo) * len);
EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() EVAS_FONT_WALK_TEXT_LOGICAL_START()
{ {
struct cinfo *ci = metrics + char_index; struct cinfo *ci = metrics + char_index;
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE); EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE);
/* Currently broken with invisible chars if (!visible) continue; */ /* Currently broken with invisible chars if (!visible) continue; */
ci->index = index; ci->index = index;
ci->fg = fg; ci->fg = fg;
@ -991,10 +875,10 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con
if (above > baseline) baseline = above; if (above > baseline) baseline = above;
ci->pos.x = EVAS_FONT_WALK_PEN_X + ci->fg->glyph_out->left; ci->pos.x = EVAS_FONT_WALK_PEN_X + ci->fg->glyph_out->left;
ci->pos.y = EVAS_FONT_WALK_PEN_Y + ci->fg->glyph_out->top; ci->pos.y = EVAS_FONT_WALK_PEN_Y + ci->fg->glyph_out->top;
last_delta = EVAS_FONT_WALK_DEFAULT_X_ADV - last_delta = EVAS_FONT_WALK_X_ADV -
(ci->bm.w + ci->fg->glyph_out->left); (ci->bm.w + ci->fg->glyph_out->left);
} }
EVAS_FONT_WALK_DEFAULT_TEXT_END(); EVAS_FONT_WALK_TEXT_END();
} }
/* First loop done */ /* First loop done */

View File

@ -0,0 +1,166 @@
#include "evas_common.h"
#include "evas_font_private.h" /* for Frame-Queuing support */
#include "evas_font_ot.h"
#include "evas_font_glyph_info.h"
EAPI Eina_Bool
evas_common_font_glyph_info_create(void *_fn, const Eina_Unicode *text,
Evas_Text_Props *text_props, int len)
{
RGBA_Font *fn = (RGBA_Font *) _fn;
RGBA_Font_Int *fi;
size_t char_index;
if (text_props->info)
{
evas_common_text_props_content_unref(text_props);
}
text_props->info = calloc(1, sizeof(Evas_Text_Props_Info));
fi = fn->fonts->data;
/* evas_common_font_size_use(fn); */
evas_common_font_int_reload(fi);
if (fi->src->current_size != fi->size)
{
FTLOCK();
FT_Activate_Size(fi->ft.size);
FTUNLOCK();
fi->src->current_size = fi->size;
}
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled())
{
evas_common_font_ot_populate_text_props(fn, text, text_props, len);
/* Load the glyph according to the first letter of the script, preety
* bad, but will have to do */
{
/* Skip common chars */
const Eina_Unicode *tmp;
for (tmp = text ;
*tmp &&
evas_common_language_char_script_get(*tmp) ==
EVAS_SCRIPT_COMMON ;
tmp++)
;
if (!*tmp && (tmp > text)) tmp--;
evas_common_font_glyph_search(fn, &fi, *tmp);
}
for (char_index = 0 ; char_index < text_props->len ; char_index++)
{
FT_UInt index;
RGBA_Font_Glyph *fg;
index = text_props->info->glyph[char_index].index;
LKL(fi->ft_mutex);
fg = evas_common_font_int_cache_glyph_get(fi, index);
if (!fg)
{
LKU(fi->ft_mutex);
continue;
}
LKU(fi->ft_mutex);
text_props->info->glyph[char_index].x_bear =
fg->glyph_out->left;
text_props->info->glyph[char_index].width =
fg->glyph_out->bitmap.width;
/* text_props->info->glyph[char_index].advance =
* text_props->info->glyph[char_index].index =
* already done by the ot function */
/* FIXME add visible handling */
}
}
else
#endif
{
/* We are walking the string in visual ordering */
Eina_Bool use_kerning;
FT_UInt prev_index;
FT_Face pface = NULL;
int adv_d, i;
FTLOCK();
use_kerning = FT_HAS_KERNING(fi->src->ft.face);
FTUNLOCK();
prev_index = 0;
i = len;
text_props->info->glyph = calloc(len,
sizeof(Evas_Font_Glyph_Info));
if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
text += len - 1;
adv_d = -1;
}
else
{
adv_d = 1;
}
char_index = 0;
for ( ; i > 0 ; char_index++, text += adv_d, i--)
{
FT_UInt index;
RGBA_Font_Glyph *fg;
int _gl, kern;
_gl = *text;
if (_gl == 0) break;
index = evas_common_font_glyph_search(fn, &fi, _gl);
LKL(fi->ft_mutex);
fg = evas_common_font_int_cache_glyph_get(fi, index);
if (!fg)
{
LKU(fi->ft_mutex);
continue;
}
kern = 0;
if ((use_kerning) && (prev_index) && (index) &&
(pface == fi->src->ft.face))
{
#ifdef BIDI_SUPPORT
/* if it's rtl, the kerning matching should be reversed, */
/* i.e prev index is now the index and the other way */
/* around. There is a slight exception when there are */
/* compositing chars involved.*/
if (text_props &&
(text_props->bidi.dir != EVAS_BIDI_DIRECTION_RTL))
{
if (evas_common_font_query_kerning(fi, index, prev_index, &kern))
{
text_props->info->glyph[char_index - 1].advance +=
kern;
}
}
else
#endif
{
if (evas_common_font_query_kerning(fi, prev_index, index, &kern))
{
text_props->info->glyph[char_index - 1].advance +=
kern;
}
}
}
pface = fi->src->ft.face;
LKU(fi->ft_mutex);
text_props->info->glyph[char_index].index = index;
text_props->info->glyph[char_index].x_bear =
fg->glyph_out->left;
text_props->info->glyph[char_index].advance =
fg->glyph->advance.x >> 10;
text_props->info->glyph[char_index].width =
fg->glyph_out->bitmap.width;
prev_index = index;
}
text_props->len = len;
}
text_props->info->refcount = 1;
return EINA_TRUE;
}

View File

@ -0,0 +1,25 @@
#ifndef _EVAS_FONT_METRICS_H
# define _EVAS_FONT_METRICS_H
/* Sorted in visual order when created */
struct _Evas_Font_Glyph_Info
{
unsigned int index; /* Should conform to FT */
Evas_Coord x_bear;
#if 0
/* This one is rarely used, only in draw, in which we already get the glyph
* so it doesn't really save time. Leaving it here just so no one will
* add it thinking it was accidentally skipped */
Evas_Coord y_bear;
#endif
Evas_Coord width;
Evas_Coord advance;
};
typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info;
EAPI Eina_Bool
evas_common_font_glyph_info_create(void *_fn, const Eina_Unicode *text,
Evas_Text_Props *text_props, int len);
#endif

View File

@ -34,21 +34,22 @@ evas_common_font_ot_is_enabled(void)
#ifdef OT_SUPPORT #ifdef OT_SUPPORT
/* FIXME: doc. returns #items */ /* FIXME: doc. returns #items */
EAPI int EAPI int
evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index, int orig_len) evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index)
{ {
int i; int i;
int items; int items;
int left_bound, right_bound; int left_bound, right_bound;
size_t base_cluster = EVAS_FONT_OT_POS_GET(props->ot_data->items[char_index]); char_index += props->start;
size_t base_cluster = EVAS_FONT_OT_POS_GET(props->info->ot[char_index]);
for (i = (int) char_index ; for (i = (int) char_index ;
(i >= 0) && (i >= (int) props->start) &&
(EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ; (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
i--) i--)
; ;
left_bound = i; left_bound = i;
for (i = (int) char_index + 1; for (i = (int) char_index + 1;
(i < (int) props->ot_data->len) && (i < (int) (props->start + props->len)) &&
(EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ; (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
i++) i++)
; ;
right_bound = i; right_bound = i;
@ -60,26 +61,26 @@ evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_i
{ {
if (left_bound < 0) if (left_bound < 0)
{ {
items = orig_len - items = props->start + props->len -
props->ot_data->items[left_bound + 1].source_cluster; props->info->ot[left_bound + 1].source_cluster;
} }
else else
{ {
items = props->ot_data->items[left_bound].source_cluster - items = props->info->ot[left_bound].source_cluster -
props->ot_data->items[left_bound + 1].source_cluster; props->info->ot[left_bound + 1].source_cluster;
} }
} }
else else
{ {
if (right_bound == (int) props->ot_data->len) if (right_bound == (int) props->len)
{ {
items = orig_len - items = props->start + props->len -
props->ot_data->items[right_bound - 1].source_cluster; props->info->ot[right_bound - 1].source_cluster;
} }
else else
{ {
items = props->ot_data->items[right_bound].source_cluster - items = props->info->ot[right_bound].source_cluster -
props->ot_data->items[right_bound - 1].source_cluster; props->info->ot[right_bound - 1].source_cluster;
} }
} }
return (items > 0) ? items : 1; return (items > 0) ? items : 1;
@ -114,152 +115,6 @@ _evas_common_font_ot_shape(hb_buffer_t *buffer, RGBA_Font_Source *src)
hb_font_destroy(hb_font); hb_font_destroy(hb_font);
} }
/* Won't work in the middle of ligatures */
EAPI void
evas_common_font_ot_cutoff_text_props(Evas_Text_Props *props, int cutoff)
{
Evas_Font_OT_Data *new_data;
if ((cutoff <= 0) || (!props->ot_data) ||
(((size_t) cutoff) >= props->ot_data->len))
return;
new_data = malloc(sizeof(Evas_Font_OT_Data));
memcpy(new_data, props->ot_data, sizeof(Evas_Font_OT_Data));
new_data->refcount = 1;
new_data->len = cutoff;
new_data->items = malloc(cutoff * sizeof(Evas_Font_OT_Data_Item));
if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
memcpy(new_data->items,
props->ot_data->items + (props->ot_data->len - cutoff),
cutoff * sizeof(Evas_Font_OT_Data_Item));
}
else
{
memcpy(new_data->items,
props->ot_data->items,
cutoff * sizeof(Evas_Font_OT_Data_Item));
}
evas_common_font_ot_props_unref(props->ot_data);
props->ot_data = new_data;
}
/* Won't work in the middle of ligatures
* aissumes ext doesn't have an already init ot_data
* we assume there's at least one char in each part */
EAPI void
evas_common_font_ot_split_text_props(Evas_Text_Props *base,
Evas_Text_Props *ext, int cutoff)
{
Evas_Font_OT_Data *new_data;
int i;
if ((cutoff <= 0) || (!base->ot_data) ||
(((size_t) cutoff) >= base->ot_data->len))
return;
ext->ot_data = calloc(1, sizeof(Evas_Font_OT_Data));
ext->ot_data->refcount = 1;
ext->ot_data->len = base->ot_data->len - cutoff;
ext->ot_data->items = calloc(ext->ot_data->len,
sizeof(Evas_Font_OT_Data_Item));
new_data = malloc(sizeof(Evas_Font_OT_Data));
memcpy(new_data, base->ot_data, sizeof(Evas_Font_OT_Data));
new_data->refcount = 1;
new_data->items = malloc(cutoff * sizeof(Evas_Font_OT_Data_Item));
new_data->len = cutoff;
if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
memcpy(ext->ot_data->items, base->ot_data->items,
ext->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
memcpy(new_data->items,
base->ot_data->items + ext->ot_data->len,
cutoff * sizeof(Evas_Font_OT_Data_Item));
}
else
{
memcpy(ext->ot_data->items, base->ot_data->items + cutoff,
ext->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
memcpy(new_data->items, base->ot_data->items,
cutoff * sizeof(Evas_Font_OT_Data_Item));
}
evas_common_font_ot_props_unref(base->ot_data);
base->ot_data = new_data;
/* Adjust the offset of the clusters */
{
size_t min;
min = ext->ot_data->items[0].source_cluster;
for (i = 1 ; i < (int) ext->ot_data->len ; i++)
{
if (ext->ot_data->items[i].source_cluster < min)
{
min = ext->ot_data->items[i].source_cluster;
}
}
for (i = 0 ; i < (int) ext->ot_data->len ; i++)
{
ext->ot_data->items[i].source_cluster -= min;
}
ext->ot_data->offset = base->ot_data->offset + min;
}
}
/* Won't work in the middle of ligatures
* assumes both are init correctly and that both are from the
* same origin item, i.e both have the same script + direction.
* assume item1 is logically first */
EAPI void
evas_common_font_ot_merge_text_props(Evas_Text_Props *item1,
const Evas_Text_Props *item2)
{
Evas_Font_OT_Data *new_data;
Evas_Font_OT_Data_Item *itr; /* Itr will be used for adding back
the offsets */
size_t len;
if (!item1->ot_data || !item2->ot_data)
return;
len = item1->ot_data->len + item2->ot_data->len;
new_data = malloc(sizeof(Evas_Font_OT_Data));
memcpy(new_data, item1->ot_data, sizeof(Evas_Font_OT_Data));
new_data->refcount = 1;
new_data->items = malloc(len * sizeof(Evas_Font_OT_Data_Item));
new_data->len = len;
if (item1->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
memcpy(new_data->items, item2->ot_data->items,
item2->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
memcpy(new_data->items + item2->ot_data->len, item1->ot_data->items,
item1->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
itr = new_data->items;
}
else
{
memcpy(new_data->items, item1->ot_data->items,
item1->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
memcpy(new_data->items + item1->ot_data->len, item2->ot_data->items,
item2->ot_data->len * sizeof(Evas_Font_OT_Data_Item));
itr = new_data->items + item1->ot_data->len;
}
evas_common_font_ot_props_unref(item1->ot_data);
item1->ot_data = new_data;
/* Add back the offset of item2 to the newly created */
if (item2->ot_data->offset > 0)
{
int i;
for (i = 0 ; i < (int) item2->ot_data->len ; i++, itr++)
{
/* This must be > 0, just because this is how it works */
itr->source_cluster += item2->ot_data->offset -
item1->ot_data->offset;
}
}
}
EAPI Eina_Bool EAPI Eina_Bool
evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text, evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
Evas_Text_Props *props, int len) Evas_Text_Props *props, int len)
@ -272,12 +127,6 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
int slen; int slen;
unsigned int i; unsigned int i;
if (!evas_common_font_ot_is_enabled()) return EINA_TRUE; if (!evas_common_font_ot_is_enabled()) return EINA_TRUE;
if (props->ot_data)
{
evas_common_font_ot_props_unref(props->ot_data);
}
props->ot_data = calloc(1, sizeof(Evas_Font_OT_Data));
props->ot_data->refcount = 1;
fi = fn->fonts->data; fi = fn->fonts->data;
/* Load the font needed for this script */ /* Load the font needed for this script */
@ -323,18 +172,20 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
_evas_common_font_ot_shape(buffer, fi->src); _evas_common_font_ot_shape(buffer, fi->src);
props->ot_data->len = hb_buffer_get_length(buffer); props->len = hb_buffer_get_length(buffer);
props->ot_data->items = calloc(props->ot_data->len, props->info->ot = calloc(props->len,
sizeof(Evas_Font_OT_Data_Item)); sizeof(Evas_Font_OT_Info));
props->info->glyph = calloc(props->len,
sizeof(Evas_Font_Glyph_Info));
positions = hb_buffer_get_glyph_positions(buffer); positions = hb_buffer_get_glyph_positions(buffer);
infos = hb_buffer_get_glyph_infos(buffer); infos = hb_buffer_get_glyph_infos(buffer);
for (i = 0 ; i < props->ot_data->len ; i++) for (i = 0 ; i < props->len ; i++)
{ {
props->ot_data->items[i].index = infos[i].codepoint; props->info->ot[i].source_cluster = infos[i].cluster;
props->ot_data->items[i].source_cluster = infos[i].cluster; props->info->ot[i].x_offset = positions[i].x_offset;
props->ot_data->items[i].x_advance = positions[i].x_advance; props->info->ot[i].y_offset = positions[i].y_offset;
props->ot_data->items[i].x_offset = positions[i].x_offset; props->info->glyph[i].index = infos[i].codepoint;
props->ot_data->items[i].y_offset = positions[i].y_offset; props->info->glyph[i].advance = positions[i].x_advance;
} }
hb_buffer_destroy(buffer); hb_buffer_destroy(buffer);
@ -343,23 +194,5 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
return EINA_FALSE; return EINA_FALSE;
} }
EAPI void
evas_common_font_ot_props_ref(Evas_Font_OT_Data *data)
{
data->refcount++;
}
EAPI void
evas_common_font_ot_props_unref(Evas_Font_OT_Data *data)
{
OTLOCK();
if (--data->refcount == 0)
{
if (data->items)
free(data->items);
free(data);
}
OTUNLOCK();
}
#endif #endif

View File

@ -12,58 +12,31 @@
# ifdef OT_SUPPORT # ifdef OT_SUPPORT
# include <stdlib.h> # include <stdlib.h>
typedef struct _Evas_Font_OT_Data Evas_Font_OT_Data; typedef struct _Evas_Font_OT_Info Evas_Font_OT_Info;
typedef struct _Evas_Font_OT_Data_Item Evas_Font_OT_Data_Item;
struct _Evas_Font_OT_Data
{
int refcount;
size_t len;
Evas_Font_OT_Data_Item *items;
size_t offset; /* The offset from the start of the script segment,
this is useful when it's a split item */
};
# else # else
typedef void *Evas_Font_OT_Data; typedef void *Evas_Font_OT_Info;
# endif # endif
# include "Evas.h" # include "Evas.h"
# ifdef OT_SUPPORT # ifdef OT_SUPPORT
struct _Evas_Font_OT_Data_Item struct _Evas_Font_OT_Info
{ {
unsigned int index; /* Should conform to FT */
size_t source_cluster; size_t source_cluster;
Evas_Coord x_offset; Evas_Coord x_offset;
Evas_Coord y_offset; Evas_Coord y_offset;
Evas_Coord x_advance;
}; };
# endif # endif
# ifdef OT_SUPPORT # ifdef OT_SUPPORT
# define EVAS_FONT_OT_X_OFF_GET(a) ((a).x_offset) # define EVAS_FONT_OT_X_OFF_GET(a) ((a).x_offset)
# define EVAS_FONT_OT_Y_OFF_GET(a) ((a).y_offset) # define EVAS_FONT_OT_Y_OFF_GET(a) ((a).y_offset)
# define EVAS_FONT_OT_X_ADV_GET(a) ((a).x_advance)
//# define EVAS_FONT_OT_Y_ADV_GET(a) ((a).y_advance)
# define EVAS_FONT_OT_INDEX_GET(a) ((a).index)
# define EVAS_FONT_OT_POS_GET(a) ((a).source_cluster) # define EVAS_FONT_OT_POS_GET(a) ((a).source_cluster)
# else
# define EVAS_FONT_OT_X_OFF_GET(a) (0)
# define EVAS_FONT_OT_Y_OFF_GET(a) (0)
# define EVAS_FONT_OT_X_ADV_GET(a) (0)
//# define EVAS_FONT_OT_POS_Y_ADV_GET(a) (0)
# define EVAS_FONT_OT_INDEX_GET(a) (0) /* FIXME!!! */
# define EVAS_FONT_OT_POS_GET(a) (0) /* FIXME!!! */
# endif # endif
EAPI Eina_Bool EAPI Eina_Bool
evas_common_font_ot_is_enabled(void); evas_common_font_ot_is_enabled(void);
EAPI void
evas_common_font_ot_props_ref(Evas_Font_OT_Data *data);
EAPI void
evas_common_font_ot_props_unref(Evas_Font_OT_Data *data);
EAPI void EAPI void
evas_common_font_ot_load_face(void *_font); evas_common_font_ot_load_face(void *_font);
@ -72,7 +45,7 @@ evas_common_font_ot_unload_face(void *_font);
# include "evas_text_utils.h" # include "evas_text_utils.h"
EAPI int EAPI int
evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index, int orig_len); evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index);
EAPI Eina_Bool EAPI Eina_Bool
evas_common_font_ot_populate_text_props(void *fn, const Eina_Unicode *text, evas_common_font_ot_populate_text_props(void *fn, const Eina_Unicode *text,

View File

@ -36,7 +36,7 @@
if (!*tmp && (tmp > text)) tmp--; \ if (!*tmp && (tmp > text)) tmp--; \
evas_common_font_glyph_search(fn, &fi, *tmp); \ evas_common_font_glyph_search(fn, &fi, *tmp); \
} \ } \
for (char_index = 0 ; char_index < intl_props->ot_data->len ; char_index++) \ for (char_index = 0 ; char_index < intl_props->len ; char_index++) \
{ \ { \
FT_UInt index; \ FT_UInt index; \
RGBA_Font_Glyph *fg; \ RGBA_Font_Glyph *fg; \
@ -72,10 +72,10 @@
evas_common_font_glyph_search(fn, &fi, *tmp); \ evas_common_font_glyph_search(fn, &fi, *tmp); \
} \ } \
prev_index = 0; \ prev_index = 0; \
_i = intl_props->ot_data->len; \ _i = intl_props->len; \
if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \ if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
{ \ { \
char_index = intl_props->ot_data->len - 1; \ char_index = intl_props->len - 1; \
_char_index_d = -1; \ _char_index_d = -1; \
} \ } \
else \ else \
@ -92,39 +92,39 @@
#define EVAS_FONT_WALK_OT_X_OFF \ #define EVAS_FONT_WALK_OT_X_OFF \
(EVAS_FONT_ROUND_26_6_TO_INT( \ (EVAS_FONT_ROUND_26_6_TO_INT( \
EVAS_FONT_OT_X_OFF_GET( \ EVAS_FONT_OT_X_OFF_GET( \
intl_props->ot_data->items[char_index]))) intl_props->info->ot[char_index])))
#define EVAS_FONT_WALK_OT_Y_OFF \ #define EVAS_FONT_WALK_OT_Y_OFF \
(EVAS_FONT_ROUND_26_6_TO_INT( \ (EVAS_FONT_ROUND_26_6_TO_INT( \
EVAS_FONT_OT_Y_OFF_GET( \ EVAS_FONT_OT_Y_OFF_GET( \
intl_props->ot_data->items[char_index]))) intl_props->info->ot[char_index])))
#define EVAS_FONT_WALK_OT_X_BEAR (fg->glyph_out->left) #define EVAS_FONT_WALK_OT_X_BEAR (intl_props->info->glyph[char_index].x_bear)
#define EVAS_FONT_WALK_OT_Y_BEAR (fg->glyph_out->top) #define EVAS_FONT_WALK_OT_Y_BEAR (fg->glyph_out->top)
#define _EVAS_FONT_WALK_OT_X_ADV \ #define _EVAS_FONT_WALK_OT_X_ADV \
(EVAS_FONT_OT_X_ADV_GET( \ (intl_props->info->glyph[char_index].advance)
intl_props->ot_data->items[char_index]))
#define EVAS_FONT_WALK_OT_X_ADV \ #define EVAS_FONT_WALK_OT_X_ADV \
(EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_OT_X_ADV)) (EVAS_FONT_ROUND_26_6_TO_INT( \
#define EVAS_FONT_WALK_OT_WIDTH (fg->glyph_out->bitmap.width) _EVAS_FONT_WALK_OT_X_ADV))
#define EVAS_FONT_WALK_OT_WIDTH (intl_props->info->glyph[char_index].width)
#define EVAS_FONT_WALK_OT_POS \ #define EVAS_FONT_WALK_OT_POS \
(EVAS_FONT_OT_POS_GET( \ (EVAS_FONT_OT_POS_GET( \
intl_props->ot_data->items[char_index])) intl_props->info->ot[char_index]))
#define EVAS_FONT_WALK_OT_IS_LAST \ #define EVAS_FONT_WALK_OT_IS_LAST \
(char_index + 1 == intl_props->ot_data->len) (char_index + 1 == intl_props->len)
#define EVAS_FONT_WALK_OT_IS_FIRST \ #define EVAS_FONT_WALK_OT_IS_FIRST \
(!char_index) (!char_index)
#define EVAS_FONT_WALK_OT_POS_NEXT \ #define EVAS_FONT_WALK_OT_POS_NEXT \
((!EVAS_FONT_WALK_OT_IS_LAST) ? \ ((!EVAS_FONT_WALK_OT_IS_LAST) ? \
EVAS_FONT_OT_POS_GET( \ EVAS_FONT_OT_POS_GET( \
intl_props->ot_data->items[char_index + 1]) : \ intl_props->info->ot[char_index + 1]) : \
EVAS_FONT_WALK_OT_POS \ EVAS_FONT_WALK_OT_POS \
) )
#define EVAS_FONT_WALK_OT_POS_PREV \ #define EVAS_FONT_WALK_OT_POS_PREV \
((char_index > 0) ? \ ((char_index > 0) ? \
EVAS_FONT_OT_POS_GET( \ EVAS_FONT_OT_POS_GET( \
intl_props->ot_data->items[char_index - 1]) : \ intl_props->info->ot[char_index - 1]) : \
EVAS_FONT_WALK_OT_POS \ EVAS_FONT_WALK_OT_POS \
) )
#define EVAS_FONT_WALK_OT_LEN (intl_props->ot_data->len) #define EVAS_FONT_WALK_OT_LEN (intl_props->len)
/** /**
* @def EVAS_FONT_WALK_OT_TEXT_WORK * @def EVAS_FONT_WALK_OT_TEXT_WORK
* @internal * @internal
@ -135,7 +135,7 @@
* @see EVAS_FONT_WALK_OT_TEXT_END * @see EVAS_FONT_WALK_OT_TEXT_END
*/ */
#define EVAS_FONT_WALK_OT_TEXT_WORK(is_visual) \ #define EVAS_FONT_WALK_OT_TEXT_WORK(is_visual) \
index = EVAS_FONT_OT_INDEX_GET(intl_props->ot_data->items[char_index]); \ index = intl_props->info->glyph[char_index].index; \
LKL(fi->ft_mutex); \ LKL(fi->ft_mutex); \
fg = evas_common_font_int_cache_glyph_get(fi, index); \ fg = evas_common_font_int_cache_glyph_get(fi, index); \
if (!fg) \ if (!fg) \

View File

@ -54,26 +54,4 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi);
# endif # endif
# include "evas_font_default_walk.x" # include "evas_font_default_walk.x"
/**
* @def EVAS_FONT_WALK_TEXT_INIT
* @internal
* This macro defines the variables that will later be used with the following
* macros, and by font handling functions.
* @see EVAS_FONT_WALK_TEXT_START
* @see EVAS_FONT_WALK_TEXT_WORK
* @see EVAS_FONT_WALK_TEXT_END
*/
# define EVAS_FONT_WALK_TEXT_INIT() \
int _pen_x = 0, _pen_y = 0; \
size_t char_index; \
FT_UInt prev_index; \
FT_Face pface = NULL; \
int _len = eina_unicode_strlen(text); \
(void) _len; /* We don't have to use it */ \
(void) _pen_y; /* Sometimes it won't be used */
# define EVAS_FONT_WALK_PEN_X (EVAS_FONT_ROUND_26_6_TO_INT(_pen_x))
# define EVAS_FONT_WALK_PEN_Y (EVAS_FONT_ROUND_26_6_TO_INT(_pen_y))
#endif /* !_EVAS_FONT_PRIVATE_H */ #endif /* !_EVAS_FONT_PRIVATE_H */

View File

@ -1,6 +1,7 @@
#include "evas_common.h" #include "evas_common.h"
#include "language/evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */ #include "language/evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */
#include "evas_font_private.h" /* for Frame-Queuing support */ #include "evas_font_private.h" /* for Frame-Queuing support */
#include "evas_font_ot.h"
EAPI int EAPI int
evas_common_font_query_kerning(RGBA_Font_Int* fi, evas_common_font_query_kerning(RGBA_Font_Int* fi,
@ -104,132 +105,62 @@ evas_common_font_query_inset(RGBA_Font *fn, const Eina_Unicode *text)
return fg->glyph_out->left; return fg->glyph_out->left;
} }
/**
* @def _INIT_FI_AND_KERNINNG()
* @internal
* This macro inits fi and use_kerning.
* Assumes the following variables exist:
* fi, fn and use_kerning.
*/
#define _INIT_FI_AND_KERNING() \
do \
{ \
fi = fn->fonts->data; \
/* evas_common_font_size_use(fn); */ \
evas_common_font_int_reload(fi); \
if (fi->src->current_size != fi->size) \
{ \
FTLOCK(); \
FT_Activate_Size(fi->ft.size); \
FTUNLOCK(); \
fi->src->current_size = fi->size; \
} \
FTLOCK(); \
use_kerning = FT_HAS_KERNING(fi->src->ft.face); \
FTUNLOCK(); \
} \
while (0)
/* size of the string (width and height) in pixels /* size of the string (width and height) in pixels
* BiDi handling: We receive the shaped string + other props from intl_props, * BiDi handling: We receive the shaped string + other props from text_props,
* We only care about the size, and the size does not depend on the visual order. * We only care about the size, and the size does not depend on the visual order.
* As long as we follow the logical string and get kerning data like we should, * As long as we follow the logical string and get kerning data like we should,
* we are fine. * we are fine.
*/ */
EAPI void EAPI void
evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_props __UNUSED__, int *w, int *h) evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *text_props __UNUSED__, int *w, int *h)
{ {
int keep_width = 0; int keep_width = 0;
int prev_pen_x = 0; int prev_pen_x = 0;
int use_kerning;
RGBA_Font_Int *fi;
EVAS_FONT_WALK_TEXT_INIT(); EVAS_FONT_WALK_TEXT_INIT();
_INIT_FI_AND_KERNING();
#ifdef OT_SUPPORT EVAS_FONT_WALK_TEXT_VISUAL_START()
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{ {
EVAS_FONT_WALK_OT_TEXT_VISUAL_START() EVAS_FONT_WALK_TEXT_WORK();
{
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
if (!visible) continue; if (!visible) continue;
/* Keep the width because we'll need it for the last char */ /* Keep the width because we'll need it for the last char */
keep_width = EVAS_FONT_WALK_OT_WIDTH + EVAS_FONT_WALK_OT_X_OFF + keep_width = EVAS_FONT_WALK_WIDTH +
EVAS_FONT_WALK_OT_X_BEAR; EVAS_FONT_WALK_X_OFF +
EVAS_FONT_WALK_X_BEAR;
/* Keep the previous EVAS_FONT_WALK_PEN_X, before it's advanced in TEXT_END */ /* Keep the previous EVAS_FONT_WALK_PEN_X, before it's advanced in TEXT_END */
prev_pen_x = EVAS_FONT_WALK_PEN_X; prev_pen_x = EVAS_FONT_WALK_PEN_X;
} }
EVAS_FONT_WALK_OT_TEXT_END(); EVAS_FONT_WALK_TEXT_END();
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
{
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
if (!visible) continue;
/* Keep the width because we'll need it for the last char */
keep_width = EVAS_FONT_WALK_DEFAULT_WIDTH +
EVAS_FONT_WALK_DEFAULT_X_OFF +
EVAS_FONT_WALK_DEFAULT_X_BEAR;
/* Keep the previous EVAS_FONT_WALK_PEN_X, before it's advanced in TEXT_END */
prev_pen_x = EVAS_FONT_WALK_PEN_X;
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
if (w) *w = prev_pen_x + keep_width; if (w) *w = prev_pen_x + keep_width;
if (h) *h = evas_common_font_max_ascent_get(fn) + evas_common_font_max_descent_get(fn); if (h) *h = evas_common_font_max_ascent_get(fn) + evas_common_font_max_descent_get(fn);
evas_common_font_int_use_trim();
} }
/* h & v advance /* h & v advance
* BiDi handling: We receive the shaped string + other props from intl_props, * BiDi handling: We receive the shaped string + other props from text_props,
* We don't care about the order, as heights will remain the same (we already did * We don't care about the order, as heights will remain the same (we already did
* shaping) and as long as we go through the logical string and match the kerning * shaping) and as long as we go through the logical string and match the kerning
* this way, we are safe. * this way, we are safe.
*/ */
EAPI void EAPI void
evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *h_adv, int *v_adv) evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *text_props, int *h_adv, int *v_adv)
{ {
int use_kerning;
RGBA_Font_Int *fi;
EVAS_FONT_WALK_TEXT_INIT(); EVAS_FONT_WALK_TEXT_INIT();
_INIT_FI_AND_KERNING();
#ifndef BIDI_SUPPORT
/* Suppress warnings */
(void) intl_props;
#endif
#ifdef OT_SUPPORT EVAS_FONT_WALK_TEXT_LOGICAL_START()
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{ {
EVAS_FONT_WALK_OT_TEXT_VISUAL_START() EVAS_FONT_WALK_TEXT_WORK();
{
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
if (!visible) continue; if (!visible) continue;
} }
EVAS_FONT_WALK_OT_TEXT_END(); EVAS_FONT_WALK_TEXT_END();
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
{
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
if (!visible) continue;
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
if (v_adv) *v_adv = evas_common_font_get_line_advance(fn); if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
if (h_adv) *h_adv = EVAS_FONT_WALK_PEN_X; if (h_adv) *h_adv = EVAS_FONT_WALK_PEN_X;
evas_common_font_int_use_trim();
} }
/* x y w h for char at char pos for null it returns the position right after /* x y w h for char at char pos for null it returns the position right after
* the last char with 0 as width and height. * the last char with 0 as width and height.
* BiDi handling: We receive the shaped string + other props from intl_props, * BiDi handling: We receive the shaped string + other props from text_props,
* We care about the actual drawing location of the string, this is why we need * We care about the actual drawing location of the string, this is why we need
* the visual string. We need to know how it's printed. After that we need to calculate * the visual string. We need to know how it's printed. After that we need to calculate
* the reverse kerning in case of rtl parts. "pos" passed to this function is an * the reverse kerning in case of rtl parts. "pos" passed to this function is an
@ -238,28 +169,24 @@ evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Ev
*/ */
EAPI int EAPI int
evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch) evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *text_props, int pos, int *cx, int *cy, int *cw, int *ch)
{ {
int asc, desc; int asc, desc;
int position = 0; int position = 0;
const Eina_Unicode *text = in_text;
int ret_val = 0; int ret_val = 0;
int use_kerning;
RGBA_Font_Int *fi;
EVAS_FONT_WALK_TEXT_INIT(); EVAS_FONT_WALK_TEXT_INIT();
_INIT_FI_AND_KERNING();
asc = evas_common_font_max_ascent_get(fn); asc = evas_common_font_max_ascent_get(fn);
desc = evas_common_font_max_descent_get(fn); desc = evas_common_font_max_descent_get(fn);
position = pos; position = pos;
/* If it's the null, choose location according to the direction. */ /* If it's the null, choose location according to the direction. */
if (!text[position]) if (text_props->len == position)
{ {
/* if it's rtl then the location is the left of the string, /* if it's rtl then the location is the left of the string,
* otherwise, the right. */ * otherwise, the right. */
#ifdef BIDI_SUPPORT #ifdef BIDI_SUPPORT
if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{ {
if (cx) *cx = 0; if (cx) *cx = 0;
if (ch) *ch = asc + desc; if (ch) *ch = asc + desc;
@ -267,7 +194,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
else else
#endif #endif
{ {
evas_common_font_query_advance(fn, in_text, intl_props, cx, ch); evas_common_font_query_advance(fn, in_text, text_props, cx, ch);
} }
if (cy) *cy = 0; if (cy) *cy = 0;
if (cw) *cw = 0; if (cw) *cw = 0;
@ -275,18 +202,15 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
goto end; goto end;
} }
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{
Evas_Coord cluster_start, last_end; Evas_Coord cluster_start, last_end;
int prev_cluster = -1; int prev_cluster = -1;
int found = 0, items = 0, item_pos = 1; int found = 0, items = 1, item_pos = 1;
int last_is_visible; int last_is_visible;
EVAS_FONT_WALK_OT_TEXT_VISUAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START()
{ {
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); EVAS_FONT_WALK_TEXT_WORK();
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS) if (prev_cluster != (int) EVAS_FONT_WALK_POS)
{ {
if (found) if (found)
{ {
@ -295,38 +219,48 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
else else
{ {
cluster_start = EVAS_FONT_WALK_PEN_X + cluster_start = EVAS_FONT_WALK_PEN_X +
EVAS_FONT_WALK_OT_X_OFF + EVAS_FONT_WALK_X_OFF +
EVAS_FONT_WALK_OT_X_BEAR; EVAS_FONT_WALK_X_BEAR;
} }
} }
last_is_visible = visible; last_is_visible = visible;
last_end = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_OFF + last_end = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF +
EVAS_FONT_WALK_OT_X_BEAR + EVAS_FONT_WALK_OT_WIDTH; EVAS_FONT_WALK_X_BEAR + EVAS_FONT_WALK_WIDTH;
/* we need to see if the char at the visual position is the char wanted */ /* we need to see if the char at the visual position is the char wanted */
if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) && if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
(EVAS_FONT_WALK_OT_POS <= (size_t) position) && (EVAS_FONT_WALK_POS <= (size_t) position) &&
((((size_t) position) < EVAS_FONT_WALK_OT_POS_NEXT) || ((((size_t) position) < EVAS_FONT_WALK_POS_NEXT) ||
(EVAS_FONT_WALK_OT_IS_LAST))) (EVAS_FONT_WALK_IS_LAST)))
{ {
found = 1; found = 1;
items = evas_common_font_ot_cluster_size_get(intl_props, #ifdef OT_SUPPORT
char_index, EVAS_FONT_WALK_ORIG_LEN); if (evas_common_font_ot_is_enabled())
item_pos = position - EVAS_FONT_WALK_OT_POS + 1; {
items = evas_common_font_ot_cluster_size_get(text_props,
char_index);
} }
else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && #endif
((EVAS_FONT_WALK_OT_POS_PREV > (size_t) position) || item_pos = position - EVAS_FONT_WALK_POS + 1;
(EVAS_FONT_WALK_OT_IS_FIRST)) && }
(((size_t) position) >= EVAS_FONT_WALK_OT_POS)) else if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
((EVAS_FONT_WALK_POS_PREV > (size_t) position) ||
(EVAS_FONT_WALK_IS_FIRST)) &&
(((size_t) position) >= EVAS_FONT_WALK_POS))
{ {
found = 1; found = 1;
items = evas_common_font_ot_cluster_size_get(intl_props, #ifdef OT_SUPPORT
char_index, EVAS_FONT_WALK_ORIG_LEN); if (evas_common_font_ot_is_enabled())
item_pos = items - (position - EVAS_FONT_WALK_OT_POS); {
items = evas_common_font_ot_cluster_size_get(text_props,
char_index);
}
#endif
item_pos = items - (position - EVAS_FONT_WALK_POS);
} }
prev_cluster = EVAS_FONT_WALK_OT_POS; prev_cluster = EVAS_FONT_WALK_POS;
} }
EVAS_FONT_WALK_OT_TEXT_END(); EVAS_FONT_WALK_TEXT_END();
if (found) if (found)
{ {
Evas_Coord cluster_w; Evas_Coord cluster_w;
@ -348,49 +282,15 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
ret_val = 1; ret_val = 1;
goto end; goto end;
} }
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
{
int chr_x, chr_w;
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
if (visible)
{
chr_x = (EVAS_FONT_WALK_PEN_X) + EVAS_FONT_WALK_DEFAULT_X_OFF +
EVAS_FONT_WALK_DEFAULT_X_BEAR;
chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH;
}
else
{
chr_x = EVAS_FONT_WALK_PEN_X;
chr_w = 0;
}
/* we need to see if the char at the visual position is the char wanted */
if (EVAS_FONT_WALK_DEFAULT_POS == (size_t) position)
{
if (cx) *cx = chr_x;
if (cy) *cy = -asc;
if (cw) *cw = chr_w;
if (ch) *ch = asc + desc;
ret_val = 1;
goto end;
}
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
end: end:
evas_common_font_int_use_trim();
return ret_val; return ret_val;
} }
/* x y w h for pen at char pos for null it returns the position right after /* x y w h for pen at char pos for null it returns the position right after
* the last char with 0 as width and height. This is the same as char_coords * the last char with 0 as width and height. This is the same as char_coords
* but it returns the pen_x and adv instead of x and w. * but it returns the pen_x and adv instead of x and w.
* BiDi handling: We receive the shaped string + other props from intl_props, * BiDi handling: We receive the shaped string + other props from text_props,
* We care about the actual drawing location of the string, this is why we need * We care about the actual drawing location of the string, this is why we need
* the visual string. We need to know how it's printed. After that we need to calculate * the visual string. We need to know how it's printed. After that we need to calculate
* the reverse kerning in case of rtl parts. "pos" passed to this function is an * the reverse kerning in case of rtl parts. "pos" passed to this function is an
@ -399,28 +299,24 @@ end:
*/ */
EAPI int EAPI int
evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch) evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *text_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
{ {
int asc, desc; int asc, desc;
int position = 0; int position = 0;
const Eina_Unicode *text = in_text;
int ret_val = 0; int ret_val = 0;
int use_kerning;
RGBA_Font_Int *fi;
EVAS_FONT_WALK_TEXT_INIT(); EVAS_FONT_WALK_TEXT_INIT();
_INIT_FI_AND_KERNING();
asc = evas_common_font_max_ascent_get(fn); asc = evas_common_font_max_ascent_get(fn);
desc = evas_common_font_max_descent_get(fn); desc = evas_common_font_max_descent_get(fn);
position = pos; position = pos;
/* If it's the null, choose location according to the direction. */ /* If it's the null, choose location according to the direction. */
if (!text[position]) if (text_props->len == position)
{ {
/* if it's rtl then the location is the left of the string, /* if it's rtl then the location is the left of the string,
* otherwise, the right. */ * otherwise, the right. */
#ifdef BIDI_SUPPORT #ifdef BIDI_SUPPORT
if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{ {
if (cpen_x) *cpen_x = 0; if (cpen_x) *cpen_x = 0;
if (ch) *ch = asc + desc; if (ch) *ch = asc + desc;
@ -428,25 +324,22 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
else else
#endif #endif
{ {
evas_common_font_query_advance(fn, in_text, intl_props, cpen_x, ch); evas_common_font_query_advance(fn, in_text, text_props, cpen_x, ch);
} }
if (cy) *cy = 0; if (cy) *cy = 0;
if (cadv) *cadv = 0; if (cadv) *cadv = 0;
ret_val = 1; ret_val = 1;
goto end; goto end;
} }
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{
Evas_Coord cluster_start; Evas_Coord cluster_start;
int prev_cluster = -1; int prev_cluster = -1;
int found = 0, items = 0, item_pos = 1; int found = 0, items = 1, item_pos = 1;
int last_is_visible = 1; int last_is_visible = 1;
EVAS_FONT_WALK_OT_TEXT_VISUAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START()
{ {
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); EVAS_FONT_WALK_TEXT_WORK();
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS) if (prev_cluster != (int) EVAS_FONT_WALK_POS)
{ {
if (found) if (found)
{ {
@ -459,30 +352,40 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
} }
last_is_visible = visible; last_is_visible = visible;
if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) && if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
(EVAS_FONT_WALK_OT_POS <= (size_t) position) && (EVAS_FONT_WALK_POS <= (size_t) position) &&
((((size_t) position) < EVAS_FONT_WALK_OT_POS_NEXT) || ((((size_t) position) < EVAS_FONT_WALK_POS_NEXT) ||
(EVAS_FONT_WALK_OT_IS_LAST))) (EVAS_FONT_WALK_IS_LAST)))
{ {
found = 1; found = 1;
items = evas_common_font_ot_cluster_size_get(intl_props, #ifdef OT_SUPPORT
char_index, EVAS_FONT_WALK_ORIG_LEN); if (evas_common_font_ot_is_enabled())
item_pos = position - EVAS_FONT_WALK_OT_POS + 1; {
items = evas_common_font_ot_cluster_size_get(text_props,
char_index);
} }
else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && #endif
((EVAS_FONT_WALK_OT_POS_PREV > (size_t) position) || item_pos = position - EVAS_FONT_WALK_POS + 1;
(EVAS_FONT_WALK_OT_IS_FIRST)) && }
(((size_t) position) >= EVAS_FONT_WALK_OT_POS)) else if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
((EVAS_FONT_WALK_POS_PREV > (size_t) position) ||
(EVAS_FONT_WALK_IS_FIRST)) &&
(((size_t) position) >= EVAS_FONT_WALK_POS))
{ {
found = 1; found = 1;
items = evas_common_font_ot_cluster_size_get(intl_props, #ifdef OT_SUPPORT
char_index, EVAS_FONT_WALK_ORIG_LEN); if (evas_common_font_ot_is_enabled())
item_pos = items - (position - EVAS_FONT_WALK_OT_POS); {
items = evas_common_font_ot_cluster_size_get(text_props,
char_index);
}
#endif
item_pos = items - (position - EVAS_FONT_WALK_POS);
} }
prev_cluster = EVAS_FONT_WALK_OT_POS; prev_cluster = EVAS_FONT_WALK_POS;
} }
EVAS_FONT_WALK_OT_TEXT_END(); EVAS_FONT_WALK_TEXT_END();
if (found) if (found)
{ {
@ -505,46 +408,6 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
ret_val = 1; ret_val = 1;
goto end; goto end;
} }
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
{
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
if ((EVAS_FONT_WALK_DEFAULT_POS == (size_t) position))
{
if (cy) *cy = -asc;
if (ch) *ch = asc + desc;
/* FIXME: A hack to make combining chars work nice, should change
* to take the base char's adv. */
if (visible)
{
if (EVAS_FONT_WALK_DEFAULT_X_ADV > 0)
{
if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_X_ADV;
}
else
{
if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X +
EVAS_FONT_WALK_DEFAULT_X_OFF +
EVAS_FONT_WALK_DEFAULT_X_BEAR;
if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_WIDTH;
}
}
else
{
if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
if (cadv) *cadv = 0;
}
ret_val = 1;
goto end;
}
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
end: end:
return ret_val; return ret_val;
@ -558,32 +421,21 @@ end:
*/ */
EAPI int EAPI int
evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *text_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
{ {
int asc, desc; int asc, desc;
const Eina_Unicode *text = in_text;
int ret_val = -1; int ret_val = -1;
int use_kerning;
RGBA_Font_Int *fi;
EVAS_FONT_WALK_TEXT_INIT(); EVAS_FONT_WALK_TEXT_INIT();
_INIT_FI_AND_KERNING();
#ifndef BIDI_SUPPORT
/* Suppress warnings */
(void) intl_props;
#endif
asc = evas_common_font_max_ascent_get(fn); asc = evas_common_font_max_ascent_get(fn);
desc = evas_common_font_max_descent_get(fn); desc = evas_common_font_max_descent_get(fn);
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{
Evas_Coord cluster_start; Evas_Coord cluster_start;
int prev_cluster = -1; int prev_cluster = -1;
int found = 0, items = 0; int found = 0, items = 1;
EVAS_FONT_WALK_OT_TEXT_VISUAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START()
{ {
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); EVAS_FONT_WALK_TEXT_WORK();
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS) if (prev_cluster != (int) EVAS_FONT_WALK_POS)
{ {
if (found) if (found)
{ {
@ -600,24 +452,29 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
/* we need to see if the char at the visual position is the char, /* we need to see if the char at the visual position is the char,
* we check that by checking if it's before the current pen * we check that by checking if it's before the current pen
* position and the next */ * position and the next */
if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_ADV)) && if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_ADV)) &&
(y >= -asc) && (y <= desc)) (y >= -asc) && (y <= desc))
{ {
items = evas_common_font_ot_cluster_size_get(intl_props, #ifdef OT_SUPPORT
char_index, EVAS_FONT_WALK_ORIG_LEN); if (evas_common_font_ot_is_enabled())
{
items = evas_common_font_ot_cluster_size_get(text_props,
char_index);
}
#endif
found = 1; found = 1;
} }
prev_cluster = EVAS_FONT_WALK_OT_POS; prev_cluster = EVAS_FONT_WALK_POS;
} }
EVAS_FONT_WALK_OT_TEXT_END(); EVAS_FONT_WALK_TEXT_END();
if (found) if (found)
{ {
int item_pos; int item_pos;
Evas_Coord cluster_adv; Evas_Coord cluster_adv;
cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start; cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR)
{ {
double part; double part;
part = cluster_adv / items; part = cluster_adv / items;
@ -637,100 +494,44 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text
ret_val = prev_cluster + item_pos; ret_val = prev_cluster + item_pos;
goto end; goto end;
} }
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
{
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
if (!visible) continue;
/* we need to see if the char at the visual position is the char,
* we check that by checking if it's before the current pen position
* and the next */
if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_ADV))
&& (y >= -asc) && (y <= desc))
{
if (cx) *cx = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_OFF +
EVAS_FONT_WALK_DEFAULT_X_BEAR +
EVAS_FONT_WALK_DEFAULT_X_ADV;
if (cy) *cy = -asc;
if (cw) *cw = EVAS_FONT_WALK_DEFAULT_X_ADV;
if (ch) *ch = asc + desc;
ret_val = EVAS_FONT_WALK_DEFAULT_POS;
goto end;
}
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
end: end:
evas_common_font_int_use_trim();
return ret_val; return ret_val;
} }
/* position of the char after the last char in the text that will fit in xy. /* position of the char after the last char in the text that will fit in xy.
* BiDi handling: We receive the shaped string + other props from intl_props, * BiDi handling: We receive the shaped string + other props from text_props,
* All we care about is char sizes + kerning so we only really need to get the * All we care about is char sizes + kerning so we only really need to get the
* shaped string to utf8, and then just go through it like in english, as it's * shaped string to utf8, and then just go through it like in english, as it's
* just the logical string, nothing special about that. * just the logical string, nothing special about that.
*/ */
EAPI int EAPI int
evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props __UNUSED__, int x, int y) evas_common_font_query_last_up_to_pos(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *text_props __UNUSED__, int x, int y)
{ {
int asc, desc; int asc, desc;
int ret=-1; int ret=-1;
const Eina_Unicode *text = in_text;
int use_kerning;
RGBA_Font_Int *fi;
EVAS_FONT_WALK_TEXT_INIT(); EVAS_FONT_WALK_TEXT_INIT();
_INIT_FI_AND_KERNING();
asc = evas_common_font_max_ascent_get(fn); asc = evas_common_font_max_ascent_get(fn);
desc = evas_common_font_max_descent_get(fn); desc = evas_common_font_max_descent_get(fn);
#ifdef OT_SUPPORT EVAS_FONT_WALK_TEXT_LOGICAL_START()
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{ {
EVAS_FONT_WALK_OT_TEXT_LOGICAL_START() EVAS_FONT_WALK_TEXT_WORK();
{
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
if (!visible) continue; if (!visible) continue;
if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_ADV)) && if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_ADV)) &&
(y >= -asc) && (y <= desc)) (y >= -asc) && (y <= desc))
{ {
ret = EVAS_FONT_WALK_OT_POS; ret = EVAS_FONT_WALK_POS;
goto end; goto end;
} }
} }
EVAS_FONT_WALK_OT_TEXT_END(); EVAS_FONT_WALK_TEXT_END();
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
{
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
if (!visible) continue;
if ((x >= EVAS_FONT_WALK_PEN_X) &&
(x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_ADV)) &&
(y >= -asc) && (y <= desc))
{
ret = char_index;
goto end;
}
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
end: end:
evas_common_font_int_use_trim();
return ret; return ret;
} }

View File

@ -1,3 +1,4 @@
#include "evas_common.h"
#include "evas_text_utils.h" #include "evas_text_utils.h"
#include "language/evas_bidi_utils.h" #include "language/evas_bidi_utils.h"
#include "language/evas_language_utils.h" #include "language/evas_language_utils.h"
@ -37,39 +38,34 @@ evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst,
void void
evas_common_text_props_content_ref(Evas_Text_Props *props) evas_common_text_props_content_ref(Evas_Text_Props *props)
{ {
#ifdef OT_SUPPORT props->info->refcount++;
if (props->ot_data)
{
evas_common_font_ot_props_ref(props->ot_data);
}
#endif
} }
void void
evas_common_text_props_content_unref(Evas_Text_Props *props) evas_common_text_props_content_unref(Evas_Text_Props *props)
{ {
#ifdef OT_SUPPORT /* We allow this, because sometimes we want to have props without info,
if (props->ot_data) * and we don't want to diverge the code paths too much. */
if (!props->info)
return;
if (props->info->refcount == 0)
{ {
evas_common_font_ot_props_unref(props->ot_data); ERR("Trying to unref props with refount == 0");
} return;
#else
(void) props;
#endif
#ifdef BIDI_SUPPORT
evas_bidi_props_clean(&props->bidi);
#else
(void) props;
#endif
} }
/* Won't work in the middle of ligatures */ if (--(props->info->refcount) == 0)
EAPI void
evas_common_text_props_cutoff(Evas_Text_Props *props, int cutoff)
{ {
if (props->info->glyph)
free(props->info->glyph);
#ifdef OT_SUPPORT #ifdef OT_SUPPORT
evas_common_font_ot_cutoff_text_props(props, cutoff); if (props->info->ot)
free(props->info->ot);
#endif #endif
free(props->info);
props->info = NULL;
}
} }
/* Won't work in the middle of ligatures */ /* Won't work in the middle of ligatures */
@ -77,12 +73,20 @@ EAPI void
evas_common_text_props_split(Evas_Text_Props *base, evas_common_text_props_split(Evas_Text_Props *base,
Evas_Text_Props *ext, int cutoff) Evas_Text_Props *ext, int cutoff)
{ {
/* FIXME: move to their own functions */ evas_common_text_props_content_copy_and_ref(ext, base);
memcpy(&ext->bidi, &base->bidi, sizeof(Evas_BiDi_Props)); if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
memcpy(&ext->script, &base->script, sizeof(Evas_Script_Type)); {
#ifdef OT_SUPPORT ext->start = base->start;
evas_common_font_ot_split_text_props(base, ext, cutoff); base->start = cutoff;
#endif ext->len = cutoff;
base->len = base->len - cutoff;
}
else
{
ext->start = cutoff;
ext->len = base->len - cutoff;
base->len = cutoff;
}
} }
/* Won't work in the middle of ligatures */ /* Won't work in the middle of ligatures */
@ -90,9 +94,16 @@ EAPI void
evas_common_text_props_merge(Evas_Text_Props *item1, evas_common_text_props_merge(Evas_Text_Props *item1,
const Evas_Text_Props *item2) const Evas_Text_Props *item2)
{ {
#ifdef OT_SUPPORT if (item1->info != item2->info)
evas_common_font_ot_merge_text_props(item1, item2); {
#endif ERR("tried merge back items that weren't together in the first place.");
return;
}
if (item1->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
item1->start = item2->start;
} }
item1->len += item2->len;
}

View File

@ -2,16 +2,29 @@
# define _EVAS_TEXT_UTILS_H # define _EVAS_TEXT_UTILS_H
typedef struct _Evas_Text_Props Evas_Text_Props; typedef struct _Evas_Text_Props Evas_Text_Props;
typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info;
# include "evas_font_ot.h" # include "evas_font_ot.h"
# include "language/evas_bidi_utils.h" # include "language/evas_bidi_utils.h"
# include "language/evas_language_utils.h" # include "language/evas_language_utils.h"
# include "evas_font_glyph_info.h"
struct _Evas_Text_Props struct _Evas_Text_Props
{ {
/* Start and len represent the start offset and the length in the
* glyphs_info and ot_data fields, they are both internal */
size_t start;
size_t len;
Evas_BiDi_Props bidi; Evas_BiDi_Props bidi;
Evas_Script_Type script; Evas_Script_Type script;
Evas_Font_OT_Data *ot_data; Evas_Text_Props_Info *info;
};
struct _Evas_Text_Props_Info
{
unsigned int refcount;
Evas_Font_Glyph_Info *glyph;
Evas_Font_OT_Info *ot;
}; };
void void
@ -32,9 +45,6 @@ evas_common_text_props_content_ref(Evas_Text_Props *props);
void void
evas_common_text_props_content_unref(Evas_Text_Props *props); evas_common_text_props_content_unref(Evas_Text_Props *props);
EAPI void
evas_common_text_props_cutoff(Evas_Text_Props *props, int cutoff);
EAPI void EAPI void
evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext, evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext,
int cutoff); int cutoff);

View File

@ -1109,9 +1109,9 @@ static Eina_Bool
eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props __UNUSED__, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props __UNUSED__, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
{ {
#ifdef BIDI_SUPPORT #ifdef BIDI_SUPPORT
return !evas_bidi_shape_string(text, par_props, pos, len); evas_bidi_shape_string(text, par_props, pos, len);
#endif #endif
return EINA_TRUE; return evas_common_font_glyph_info_create(font, text, intl_props, len);
} }
static int static int

View File

@ -543,17 +543,23 @@ eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *t
static Eina_Bool static Eina_Bool
eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
{ {
(void) font;
(void) text;
(void) intl_props;
(void) par_props;
(void) pos;
(void) len;
#ifdef OT_SUPPORT #ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled()) if (evas_common_font_ot_is_enabled())
{ {
return evas_common_font_ot_populate_text_props(font, text, return evas_common_font_glyph_info_create(font, text, intl_props, len);
intl_props, len);
} }
else else
#endif #endif
{ {
#ifdef BIDI_SUPPORT #ifdef BIDI_SUPPORT
return !evas_bidi_shape_string(text, par_props, pos, len); evas_bidi_shape_string(text, par_props, pos, len);
return evas_common_font_glyph_info_create(font, text, intl_props, len);
#endif #endif
} }
return EINA_TRUE; return EINA_TRUE;

View File

@ -601,17 +601,23 @@ eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *t
static Eina_Bool static Eina_Bool
eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
{ {
(void) font;
(void) text;
(void) intl_props;
(void) par_props;
(void) pos;
(void) len;
#ifdef OT_SUPPORT #ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled()) if (evas_common_font_ot_is_enabled())
{ {
return evas_common_font_ot_populate_text_props(font, text, return evas_common_font_glyph_info_create(font, text, intl_props, len);
intl_props, len);
} }
else else
#endif #endif
{ {
#ifdef BIDI_SUPPORT #ifdef BIDI_SUPPORT
return !evas_bidi_shape_string(text, par_props, pos, len); evas_bidi_shape_string(text, par_props, pos, len);
return evas_common_font_glyph_info_create(font, text, intl_props, len);
#endif #endif
} }
return EINA_TRUE; return EINA_TRUE;

View File

@ -722,8 +722,7 @@ eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_
#ifdef OT_SUPPORT #ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled()) if (evas_common_font_ot_is_enabled())
{ {
return evas_common_font_ot_populate_text_props(font, text, return evas_common_font_glyph_info_create(font, text, intl_props, len);
intl_props, len);
} }
else else
#endif #endif