forked from enlightenment/efl
parent
debf4d9428
commit
d6feccdebb
|
@ -63,6 +63,7 @@ language/evas_bidi_utils.c \
|
|||
language/evas_language_utils.c \
|
||||
evas_text_utils.c \
|
||||
evas_font_ot.c \
|
||||
evas_font_glyph_info.c \
|
||||
evas_map_image.c \
|
||||
evas_map_image.h
|
||||
|
||||
|
@ -105,6 +106,7 @@ language/evas_bidi_utils.h \
|
|||
language/evas_language_utils.h \
|
||||
evas_text_utils.h \
|
||||
evas_font_ot.h \
|
||||
evas_font_glyph_info.h \
|
||||
evas_map_image_internal.c \
|
||||
evas_map_image_core.c \
|
||||
evas_map_image_loop.c
|
||||
|
|
|
@ -3,190 +3,163 @@
|
|||
/* Macros for text walking */
|
||||
|
||||
/**
|
||||
* @def EVAS_FONT_UPDATE_KERN()
|
||||
* @def EVAS_FONT_WALK_TEXT_INIT
|
||||
* @internal
|
||||
* This macro updates kern according to kerning.
|
||||
* This macro assumes the following variables exist:
|
||||
* intl_props, char_index, fi, kern, index, prev_index
|
||||
* 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
|
||||
*/
|
||||
#ifdef BIDI_SUPPORT
|
||||
#define EVAS_FONT_UPDATE_KERN(is_visual) \
|
||||
do \
|
||||
{ \
|
||||
/* 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
|
||||
# define EVAS_FONT_WALK_TEXT_INIT() \
|
||||
int _pen_x = 0, _pen_y = 0; \
|
||||
size_t char_index; \
|
||||
(void) _pen_y; /* Sometimes it won't be used */
|
||||
|
||||
/**
|
||||
* @def EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
|
||||
* @def EVAS_FONT_WALK_TEXT_VISUAL_START
|
||||
* @internal
|
||||
* This runs through the text in visual 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_LOGICAL_START
|
||||
* 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_LOGICAL_START
|
||||
*/
|
||||
#define EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() \
|
||||
#define EVAS_FONT_WALK_TEXT_VISUAL_START() \
|
||||
do \
|
||||
{ \
|
||||
const Eina_Unicode *_base_text; \
|
||||
int _char_index_d, _i; \
|
||||
int visible; \
|
||||
prev_index = 0; \
|
||||
_base_text = text; \
|
||||
for ( ; *text ; text++); \
|
||||
_i = text - _base_text; \
|
||||
if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
|
||||
int visible = 1; \
|
||||
for (char_index = 0 ; char_index < text_props->len ; char_index++) \
|
||||
{
|
||||
|
||||
/**
|
||||
* @def EVAS_FONT_WALK_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_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; \
|
||||
text--; \
|
||||
int _char_index_d, _i; \
|
||||
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; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
char_index = 0; \
|
||||
text = _base_text; \
|
||||
_char_index_d = 1; \
|
||||
} \
|
||||
for ( ; _i > 0 ; char_index += _char_index_d, text += _char_index_d, _i--) \
|
||||
{ \
|
||||
FT_UInt index; \
|
||||
RGBA_Font_Glyph *fg; \
|
||||
int _gl, kern; \
|
||||
_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;
|
||||
for ( ; _i > 0 ; char_index += _char_index_d, _i--) \
|
||||
{
|
||||
#else
|
||||
#define EVAS_FONT_WALK_TEXT_LOGICAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START()
|
||||
#endif
|
||||
|
||||
/*FIXME: doc */
|
||||
#define EVAS_FONT_WALK_DEFAULT_X_OFF (0)
|
||||
#define EVAS_FONT_WALK_DEFAULT_Y_OFF (0)
|
||||
#define EVAS_FONT_WALK_DEFAULT_X_BEAR (fg->glyph_out->left)
|
||||
#define EVAS_FONT_WALK_DEFAULT_Y_BEAR (fg->glyph_out->top)
|
||||
#define _EVAS_FONT_WALK_DEFAULT_X_ADV (fg->glyph->advance.x >> 10)
|
||||
#define EVAS_FONT_WALK_DEFAULT_X_ADV \
|
||||
(EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_DEFAULT_X_ADV))
|
||||
#define EVAS_FONT_WALK_DEFAULT_Y_ADV (0)
|
||||
#define EVAS_FONT_WALK_DEFAULT_WIDTH (fg->glyph_out->bitmap.width)
|
||||
#define EVAS_FONT_WALK_DEFAULT_POS (char_index)
|
||||
#define EVAS_FONT_WALK_DEFAULT_IS_LAST \
|
||||
(!text[char_index])
|
||||
#define EVAS_FONT_WALK_DEFAULT_IS_FIRST \
|
||||
#ifdef OT_SUPPORT
|
||||
# define EVAS_FONT_WALK_X_OFF \
|
||||
((text_props->info->ot) ? \
|
||||
(EVAS_FONT_ROUND_26_6_TO_INT( \
|
||||
EVAS_FONT_OT_X_OFF_GET( \
|
||||
text_props->info->ot[char_index]))) : \
|
||||
(0))
|
||||
# define EVAS_FONT_WALK_Y_OFF \
|
||||
((text_props->info->ot) ? \
|
||||
(EVAS_FONT_ROUND_26_6_TO_INT( \
|
||||
EVAS_FONT_OT_Y_OFF_GET( \
|
||||
text_props->info->ot[char_index]))) : \
|
||||
(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)
|
||||
#define EVAS_FONT_WALK_DEFAULT_POS_NEXT \
|
||||
((!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); \
|
||||
#define EVAS_FONT_WALK_LEN (text_props->len)
|
||||
|
||||
/**
|
||||
* @def EVAS_FONT_WALK_DEFAULT_TEXT_END
|
||||
* @def EVAS_FONT_WALK_TEXT_WORK
|
||||
* @internal
|
||||
* Closes EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START, needs to end with a ;
|
||||
* @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START
|
||||
* @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT
|
||||
* @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK
|
||||
* This macro actually updates the values mentioned in EVAS_FONT_WALK_TEXT_VISUAL_START
|
||||
* according to the current positing in the walk.
|
||||
* @see EVAS_FONT_WALK_TEXT_VISUAL_START
|
||||
* @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) \
|
||||
{ \
|
||||
_pen_x += _EVAS_FONT_WALK_DEFAULT_X_ADV; \
|
||||
_pen_x += _EVAS_FONT_WALK_X_ADV; \
|
||||
} \
|
||||
prev_index = index; \
|
||||
} \
|
||||
} \
|
||||
while(0)
|
||||
|
|
|
@ -49,7 +49,7 @@ struct cinfo
|
|||
#if defined(METRIC_CACHE) || defined(WORD_CACHE)
|
||||
LK(lock_words); // for word cache call
|
||||
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
|
||||
|
||||
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)
|
||||
* 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).
|
||||
*/
|
||||
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,
|
||||
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
|
||||
)
|
||||
{
|
||||
const Eina_Unicode *text = in_text;
|
||||
DATA32 *im;
|
||||
FT_Face pface = NULL;
|
||||
EVAS_FONT_WALK_TEXT_INIT();
|
||||
|
||||
#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;
|
||||
|
||||
word =
|
||||
evas_font_word_prerender(dc, text, intl_props,
|
||||
evas_font_word_prerender(dc, text, text_props,
|
||||
len, fn, fi, use_kerning);
|
||||
if (word)
|
||||
{
|
||||
|
@ -492,6 +493,8 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
|
|||
# endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void) use_kerning;
|
||||
#endif
|
||||
|
||||
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;
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
|
||||
/* Load the glyph according to the first letter of the script, preety
|
||||
* 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;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
chr_x = x + EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_OFF + EVAS_FONT_WALK_OT_X_BEAR;
|
||||
chr_y = y + EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_OT_Y_OFF + EVAS_FONT_WALK_OT_Y_BEAR;
|
||||
chr_w = EVAS_FONT_WALK_OT_WIDTH;
|
||||
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_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
|
||||
chr_w = EVAS_FONT_WALK_WIDTH;
|
||||
|
||||
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
|
||||
break;
|
||||
}
|
||||
EVAS_FONT_WALK_OT_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_FONT_WALK_TEXT_END();
|
||||
evas_common_font_int_use_trim();
|
||||
}
|
||||
|
||||
EAPI void
|
||||
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text,
|
||||
const Evas_Text_Props *intl_props)
|
||||
const Evas_Text_Props *text_props)
|
||||
{
|
||||
int ext_x, ext_y, ext_w, ext_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)
|
||||
{
|
||||
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,
|
||||
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;
|
||||
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,
|
||||
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 */
|
||||
#if defined(METRIC_CACHE) || defined(WORD_CACHE)
|
||||
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;
|
||||
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,
|
||||
* but that'll have to be good enough ATM */
|
||||
#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);
|
||||
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
|
||||
EVAS_FONT_WALK_TEXT_VISUAL_START()
|
||||
{
|
||||
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; */
|
||||
ci->index = index;
|
||||
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;
|
||||
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;
|
||||
last_delta = EVAS_FONT_WALK_OT_X_ADV -
|
||||
last_delta = EVAS_FONT_WALK_X_ADV -
|
||||
(ci->bm.w + ci->fg->glyph_out->left);
|
||||
}
|
||||
EVAS_FONT_WALK_OT_TEXT_END();
|
||||
EVAS_FONT_WALK_TEXT_END();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
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;
|
||||
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
|
||||
EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE);
|
||||
/* Currently broken with invisible chars if (!visible) continue; */
|
||||
ci->index = index;
|
||||
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;
|
||||
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;
|
||||
last_delta = EVAS_FONT_WALK_DEFAULT_X_ADV -
|
||||
last_delta = EVAS_FONT_WALK_X_ADV -
|
||||
(ci->bm.w + ci->fg->glyph_out->left);
|
||||
}
|
||||
EVAS_FONT_WALK_DEFAULT_TEXT_END();
|
||||
EVAS_FONT_WALK_TEXT_END();
|
||||
}
|
||||
|
||||
/* First loop done */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -34,21 +34,22 @@ evas_common_font_ot_is_enabled(void)
|
|||
#ifdef OT_SUPPORT
|
||||
/* FIXME: doc. returns #items */
|
||||
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 items;
|
||||
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 ;
|
||||
(i >= 0) &&
|
||||
(EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ;
|
||||
(i >= (int) props->start) &&
|
||||
(EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
|
||||
i--)
|
||||
;
|
||||
left_bound = i;
|
||||
for (i = (int) char_index + 1;
|
||||
(i < (int) props->ot_data->len) &&
|
||||
(EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ;
|
||||
(i < (int) (props->start + props->len)) &&
|
||||
(EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
|
||||
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)
|
||||
{
|
||||
items = orig_len -
|
||||
props->ot_data->items[left_bound + 1].source_cluster;
|
||||
items = props->start + props->len -
|
||||
props->info->ot[left_bound + 1].source_cluster;
|
||||
}
|
||||
else
|
||||
{
|
||||
items = props->ot_data->items[left_bound].source_cluster -
|
||||
props->ot_data->items[left_bound + 1].source_cluster;
|
||||
items = props->info->ot[left_bound].source_cluster -
|
||||
props->info->ot[left_bound + 1].source_cluster;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (right_bound == (int) props->ot_data->len)
|
||||
if (right_bound == (int) props->len)
|
||||
{
|
||||
items = orig_len -
|
||||
props->ot_data->items[right_bound - 1].source_cluster;
|
||||
items = props->start + props->len -
|
||||
props->info->ot[right_bound - 1].source_cluster;
|
||||
}
|
||||
else
|
||||
{
|
||||
items = props->ot_data->items[right_bound].source_cluster -
|
||||
props->ot_data->items[right_bound - 1].source_cluster;
|
||||
items = props->info->ot[right_bound].source_cluster -
|
||||
props->info->ot[right_bound - 1].source_cluster;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
|
||||
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;
|
||||
unsigned int i;
|
||||
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;
|
||||
/* 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);
|
||||
|
||||
props->ot_data->len = hb_buffer_get_length(buffer);
|
||||
props->ot_data->items = calloc(props->ot_data->len,
|
||||
sizeof(Evas_Font_OT_Data_Item));
|
||||
props->len = hb_buffer_get_length(buffer);
|
||||
props->info->ot = calloc(props->len,
|
||||
sizeof(Evas_Font_OT_Info));
|
||||
props->info->glyph = calloc(props->len,
|
||||
sizeof(Evas_Font_Glyph_Info));
|
||||
positions = hb_buffer_get_glyph_positions(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->ot_data->items[i].source_cluster = infos[i].cluster;
|
||||
props->ot_data->items[i].x_advance = positions[i].x_advance;
|
||||
props->ot_data->items[i].x_offset = positions[i].x_offset;
|
||||
props->ot_data->items[i].y_offset = positions[i].y_offset;
|
||||
props->info->ot[i].source_cluster = infos[i].cluster;
|
||||
props->info->ot[i].x_offset = positions[i].x_offset;
|
||||
props->info->ot[i].y_offset = positions[i].y_offset;
|
||||
props->info->glyph[i].index = infos[i].codepoint;
|
||||
props->info->glyph[i].advance = positions[i].x_advance;
|
||||
}
|
||||
|
||||
hb_buffer_destroy(buffer);
|
||||
|
@ -343,23 +194,5 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
|
|||
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
|
||||
|
||||
|
|
|
@ -12,58 +12,31 @@
|
|||
|
||||
# ifdef OT_SUPPORT
|
||||
# include <stdlib.h>
|
||||
typedef struct _Evas_Font_OT_Data Evas_Font_OT_Data;
|
||||
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 */
|
||||
};
|
||||
typedef struct _Evas_Font_OT_Info Evas_Font_OT_Info;
|
||||
# else
|
||||
typedef void *Evas_Font_OT_Data;
|
||||
typedef void *Evas_Font_OT_Info;
|
||||
# endif
|
||||
|
||||
# include "Evas.h"
|
||||
|
||||
# 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;
|
||||
Evas_Coord x_offset;
|
||||
Evas_Coord y_offset;
|
||||
Evas_Coord x_advance;
|
||||
};
|
||||
# endif
|
||||
|
||||
# ifdef OT_SUPPORT
|
||||
# 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_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)
|
||||
# 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
|
||||
|
||||
EAPI Eina_Bool
|
||||
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
|
||||
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"
|
||||
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
|
||||
evas_common_font_ot_populate_text_props(void *fn, const Eina_Unicode *text,
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
if (!*tmp && (tmp > text)) 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; \
|
||||
RGBA_Font_Glyph *fg; \
|
||||
|
@ -72,10 +72,10 @@
|
|||
evas_common_font_glyph_search(fn, &fi, *tmp); \
|
||||
} \
|
||||
prev_index = 0; \
|
||||
_i = intl_props->ot_data->len; \
|
||||
_i = intl_props->len; \
|
||||
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; \
|
||||
} \
|
||||
else \
|
||||
|
@ -92,39 +92,39 @@
|
|||
#define EVAS_FONT_WALK_OT_X_OFF \
|
||||
(EVAS_FONT_ROUND_26_6_TO_INT( \
|
||||
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 \
|
||||
(EVAS_FONT_ROUND_26_6_TO_INT( \
|
||||
EVAS_FONT_OT_Y_OFF_GET( \
|
||||
intl_props->ot_data->items[char_index])))
|
||||
#define EVAS_FONT_WALK_OT_X_BEAR (fg->glyph_out->left)
|
||||
intl_props->info->ot[char_index])))
|
||||
#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_X_ADV \
|
||||
(EVAS_FONT_OT_X_ADV_GET( \
|
||||
intl_props->ot_data->items[char_index]))
|
||||
(intl_props->info->glyph[char_index].advance)
|
||||
#define EVAS_FONT_WALK_OT_X_ADV \
|
||||
(EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_OT_X_ADV))
|
||||
#define EVAS_FONT_WALK_OT_WIDTH (fg->glyph_out->bitmap.width)
|
||||
(EVAS_FONT_ROUND_26_6_TO_INT( \
|
||||
_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 \
|
||||
(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 \
|
||||
(char_index + 1 == intl_props->ot_data->len)
|
||||
(char_index + 1 == intl_props->len)
|
||||
#define EVAS_FONT_WALK_OT_IS_FIRST \
|
||||
(!char_index)
|
||||
#define EVAS_FONT_WALK_OT_POS_NEXT \
|
||||
((!EVAS_FONT_WALK_OT_IS_LAST) ? \
|
||||
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 \
|
||||
)
|
||||
#define EVAS_FONT_WALK_OT_POS_PREV \
|
||||
((char_index > 0) ? \
|
||||
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 \
|
||||
)
|
||||
#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
|
||||
* @internal
|
||||
|
@ -135,7 +135,7 @@
|
|||
* @see EVAS_FONT_WALK_OT_TEXT_END
|
||||
*/
|
||||
#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); \
|
||||
fg = evas_common_font_int_cache_glyph_get(fi, index); \
|
||||
if (!fg) \
|
||||
|
|
|
@ -54,26 +54,4 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi);
|
|||
# endif
|
||||
|
||||
# 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 */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "evas_common.h"
|
||||
#include "language/evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */
|
||||
#include "evas_font_private.h" /* for Frame-Queuing support */
|
||||
#include "evas_font_ot.h"
|
||||
|
||||
EAPI int
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* 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.
|
||||
* As long as we follow the logical string and get kerning data like we should,
|
||||
* we are fine.
|
||||
*/
|
||||
|
||||
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 prev_pen_x = 0;
|
||||
int use_kerning;
|
||||
RGBA_Font_Int *fi;
|
||||
EVAS_FONT_WALK_TEXT_INIT();
|
||||
_INIT_FI_AND_KERNING();
|
||||
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
|
||||
EVAS_FONT_WALK_TEXT_VISUAL_START()
|
||||
{
|
||||
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
|
||||
{
|
||||
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
|
||||
EVAS_FONT_WALK_TEXT_WORK();
|
||||
if (!visible) continue;
|
||||
/* 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 +
|
||||
EVAS_FONT_WALK_OT_X_BEAR;
|
||||
keep_width = EVAS_FONT_WALK_WIDTH +
|
||||
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 */
|
||||
prev_pen_x = EVAS_FONT_WALK_PEN_X;
|
||||
}
|
||||
EVAS_FONT_WALK_OT_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();
|
||||
}
|
||||
EVAS_FONT_WALK_TEXT_END();
|
||||
|
||||
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);
|
||||
evas_common_font_int_use_trim();
|
||||
}
|
||||
|
||||
/* 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
|
||||
* shaping) and as long as we go through the logical string and match the kerning
|
||||
* this way, we are safe.
|
||||
*/
|
||||
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();
|
||||
_INIT_FI_AND_KERNING();
|
||||
#ifndef BIDI_SUPPORT
|
||||
/* Suppress warnings */
|
||||
(void) intl_props;
|
||||
#endif
|
||||
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
|
||||
EVAS_FONT_WALK_TEXT_LOGICAL_START()
|
||||
{
|
||||
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
|
||||
{
|
||||
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
|
||||
EVAS_FONT_WALK_TEXT_WORK();
|
||||
if (!visible) continue;
|
||||
}
|
||||
EVAS_FONT_WALK_OT_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();
|
||||
}
|
||||
EVAS_FONT_WALK_TEXT_END();
|
||||
|
||||
if (v_adv) *v_adv = evas_common_font_get_line_advance(fn);
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
|
@ -238,28 +169,24 @@ evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Ev
|
|||
*/
|
||||
|
||||
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 position = 0;
|
||||
const Eina_Unicode *text = in_text;
|
||||
int ret_val = 0;
|
||||
int use_kerning;
|
||||
RGBA_Font_Int *fi;
|
||||
EVAS_FONT_WALK_TEXT_INIT();
|
||||
_INIT_FI_AND_KERNING();
|
||||
|
||||
asc = evas_common_font_max_ascent_get(fn);
|
||||
desc = evas_common_font_max_descent_get(fn);
|
||||
|
||||
position = pos;
|
||||
/* 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,
|
||||
* otherwise, the right. */
|
||||
#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 (ch) *ch = asc + desc;
|
||||
|
@ -267,7 +194,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
|
|||
else
|
||||
#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 (cw) *cw = 0;
|
||||
|
@ -275,18 +202,15 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
|
|||
goto end;
|
||||
}
|
||||
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
|
||||
{
|
||||
Evas_Coord cluster_start, last_end;
|
||||
int prev_cluster = -1;
|
||||
int found = 0, items = 0, item_pos = 1;
|
||||
int found = 0, items = 1, item_pos = 1;
|
||||
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)
|
||||
{
|
||||
|
@ -295,38 +219,48 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
|
|||
else
|
||||
{
|
||||
cluster_start = EVAS_FONT_WALK_PEN_X +
|
||||
EVAS_FONT_WALK_OT_X_OFF +
|
||||
EVAS_FONT_WALK_OT_X_BEAR;
|
||||
EVAS_FONT_WALK_X_OFF +
|
||||
EVAS_FONT_WALK_X_BEAR;
|
||||
}
|
||||
}
|
||||
last_is_visible = visible;
|
||||
last_end = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_OFF +
|
||||
EVAS_FONT_WALK_OT_X_BEAR + EVAS_FONT_WALK_OT_WIDTH;
|
||||
last_end = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF +
|
||||
EVAS_FONT_WALK_X_BEAR + EVAS_FONT_WALK_WIDTH;
|
||||
/* we need to see if the char at the visual position is the char wanted */
|
||||
if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
|
||||
(EVAS_FONT_WALK_OT_POS <= (size_t) position) &&
|
||||
((((size_t) position) < EVAS_FONT_WALK_OT_POS_NEXT) ||
|
||||
(EVAS_FONT_WALK_OT_IS_LAST)))
|
||||
if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
|
||||
(EVAS_FONT_WALK_POS <= (size_t) position) &&
|
||||
((((size_t) position) < EVAS_FONT_WALK_POS_NEXT) ||
|
||||
(EVAS_FONT_WALK_IS_LAST)))
|
||||
{
|
||||
found = 1;
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
item_pos = position - EVAS_FONT_WALK_OT_POS + 1;
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled())
|
||||
{
|
||||
items = evas_common_font_ot_cluster_size_get(text_props,
|
||||
char_index);
|
||||
}
|
||||
else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
|
||||
((EVAS_FONT_WALK_OT_POS_PREV > (size_t) position) ||
|
||||
(EVAS_FONT_WALK_OT_IS_FIRST)) &&
|
||||
(((size_t) position) >= EVAS_FONT_WALK_OT_POS))
|
||||
#endif
|
||||
item_pos = position - EVAS_FONT_WALK_POS + 1;
|
||||
}
|
||||
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;
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
item_pos = items - (position - EVAS_FONT_WALK_OT_POS);
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled())
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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:
|
||||
|
||||
evas_common_font_int_use_trim();
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* 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
|
||||
* 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
|
||||
* 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
|
||||
|
@ -399,28 +299,24 @@ end:
|
|||
*/
|
||||
|
||||
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 position = 0;
|
||||
const Eina_Unicode *text = in_text;
|
||||
int ret_val = 0;
|
||||
int use_kerning;
|
||||
RGBA_Font_Int *fi;
|
||||
EVAS_FONT_WALK_TEXT_INIT();
|
||||
_INIT_FI_AND_KERNING();
|
||||
|
||||
asc = evas_common_font_max_ascent_get(fn);
|
||||
desc = evas_common_font_max_descent_get(fn);
|
||||
|
||||
position = pos;
|
||||
/* 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,
|
||||
* otherwise, the right. */
|
||||
#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 (ch) *ch = asc + desc;
|
||||
|
@ -428,25 +324,22 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
|
|||
else
|
||||
#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 (cadv) *cadv = 0;
|
||||
ret_val = 1;
|
||||
goto end;
|
||||
}
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
|
||||
{
|
||||
Evas_Coord cluster_start;
|
||||
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;
|
||||
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)
|
||||
{
|
||||
|
@ -459,30 +352,40 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
|
|||
}
|
||||
last_is_visible = visible;
|
||||
|
||||
if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
|
||||
(EVAS_FONT_WALK_OT_POS <= (size_t) position) &&
|
||||
((((size_t) position) < EVAS_FONT_WALK_OT_POS_NEXT) ||
|
||||
(EVAS_FONT_WALK_OT_IS_LAST)))
|
||||
if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) &&
|
||||
(EVAS_FONT_WALK_POS <= (size_t) position) &&
|
||||
((((size_t) position) < EVAS_FONT_WALK_POS_NEXT) ||
|
||||
(EVAS_FONT_WALK_IS_LAST)))
|
||||
{
|
||||
found = 1;
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
item_pos = position - EVAS_FONT_WALK_OT_POS + 1;
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled())
|
||||
{
|
||||
items = evas_common_font_ot_cluster_size_get(text_props,
|
||||
char_index);
|
||||
}
|
||||
else if ((intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) &&
|
||||
((EVAS_FONT_WALK_OT_POS_PREV > (size_t) position) ||
|
||||
(EVAS_FONT_WALK_OT_IS_FIRST)) &&
|
||||
(((size_t) position) >= EVAS_FONT_WALK_OT_POS))
|
||||
#endif
|
||||
item_pos = position - EVAS_FONT_WALK_POS + 1;
|
||||
}
|
||||
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;
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
item_pos = items - (position - EVAS_FONT_WALK_OT_POS);
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled())
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -505,46 +408,6 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co
|
|||
ret_val = 1;
|
||||
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:
|
||||
|
||||
return ret_val;
|
||||
|
@ -558,32 +421,21 @@ end:
|
|||
*/
|
||||
|
||||
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;
|
||||
const Eina_Unicode *text = in_text;
|
||||
int ret_val = -1;
|
||||
int use_kerning;
|
||||
RGBA_Font_Int *fi;
|
||||
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);
|
||||
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;
|
||||
int prev_cluster = -1;
|
||||
int found = 0, items = 0;
|
||||
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
|
||||
int found = 0, items = 1;
|
||||
EVAS_FONT_WALK_TEXT_VISUAL_START()
|
||||
{
|
||||
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
|
||||
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
|
||||
EVAS_FONT_WALK_TEXT_WORK();
|
||||
if (prev_cluster != (int) EVAS_FONT_WALK_POS)
|
||||
{
|
||||
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 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_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))
|
||||
{
|
||||
items = evas_common_font_ot_cluster_size_get(intl_props,
|
||||
char_index, EVAS_FONT_WALK_ORIG_LEN);
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled())
|
||||
{
|
||||
items = evas_common_font_ot_cluster_size_get(text_props,
|
||||
char_index);
|
||||
}
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
int item_pos;
|
||||
Evas_Coord cluster_adv;
|
||||
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;
|
||||
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;
|
||||
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:
|
||||
|
||||
evas_common_font_int_use_trim();
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* 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
|
||||
* shaped string to utf8, and then just go through it like in english, as it's
|
||||
* just the logical string, nothing special about that.
|
||||
*/
|
||||
|
||||
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 ret=-1;
|
||||
const Eina_Unicode *text = in_text;
|
||||
int use_kerning;
|
||||
RGBA_Font_Int *fi;
|
||||
EVAS_FONT_WALK_TEXT_INIT();
|
||||
_INIT_FI_AND_KERNING();
|
||||
|
||||
asc = evas_common_font_max_ascent_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_FONT_WALK_TEXT_LOGICAL_START()
|
||||
{
|
||||
EVAS_FONT_WALK_OT_TEXT_LOGICAL_START()
|
||||
{
|
||||
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
|
||||
EVAS_FONT_WALK_TEXT_WORK();
|
||||
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))
|
||||
{
|
||||
ret = EVAS_FONT_WALK_OT_POS;
|
||||
ret = EVAS_FONT_WALK_POS;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
EVAS_FONT_WALK_OT_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();
|
||||
}
|
||||
EVAS_FONT_WALK_TEXT_END();
|
||||
|
||||
end:
|
||||
|
||||
evas_common_font_int_use_trim();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "evas_common.h"
|
||||
#include "evas_text_utils.h"
|
||||
#include "language/evas_bidi_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
|
||||
evas_common_text_props_content_ref(Evas_Text_Props *props)
|
||||
{
|
||||
#ifdef OT_SUPPORT
|
||||
if (props->ot_data)
|
||||
{
|
||||
evas_common_font_ot_props_ref(props->ot_data);
|
||||
}
|
||||
#endif
|
||||
props->info->refcount++;
|
||||
}
|
||||
|
||||
void
|
||||
evas_common_text_props_content_unref(Evas_Text_Props *props)
|
||||
{
|
||||
#ifdef OT_SUPPORT
|
||||
if (props->ot_data)
|
||||
{
|
||||
evas_common_font_ot_props_unref(props->ot_data);
|
||||
}
|
||||
#else
|
||||
(void) props;
|
||||
#endif
|
||||
#ifdef BIDI_SUPPORT
|
||||
evas_bidi_props_clean(&props->bidi);
|
||||
#else
|
||||
(void) props;
|
||||
#endif
|
||||
}
|
||||
/* We allow this, because sometimes we want to have props without info,
|
||||
* and we don't want to diverge the code paths too much. */
|
||||
if (!props->info)
|
||||
return;
|
||||
|
||||
/* Won't work in the middle of ligatures */
|
||||
EAPI void
|
||||
evas_common_text_props_cutoff(Evas_Text_Props *props, int cutoff)
|
||||
{
|
||||
if (props->info->refcount == 0)
|
||||
{
|
||||
ERR("Trying to unref props with refount == 0");
|
||||
return;
|
||||
}
|
||||
|
||||
if (--(props->info->refcount) == 0)
|
||||
{
|
||||
if (props->info->glyph)
|
||||
free(props->info->glyph);
|
||||
#ifdef OT_SUPPORT
|
||||
evas_common_font_ot_cutoff_text_props(props, cutoff);
|
||||
if (props->info->ot)
|
||||
free(props->info->ot);
|
||||
#endif
|
||||
free(props->info);
|
||||
props->info = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Won't work in the middle of ligatures */
|
||||
|
@ -77,12 +73,20 @@ EAPI void
|
|||
evas_common_text_props_split(Evas_Text_Props *base,
|
||||
Evas_Text_Props *ext, int cutoff)
|
||||
{
|
||||
/* FIXME: move to their own functions */
|
||||
memcpy(&ext->bidi, &base->bidi, sizeof(Evas_BiDi_Props));
|
||||
memcpy(&ext->script, &base->script, sizeof(Evas_Script_Type));
|
||||
#ifdef OT_SUPPORT
|
||||
evas_common_font_ot_split_text_props(base, ext, cutoff);
|
||||
#endif
|
||||
evas_common_text_props_content_copy_and_ref(ext, base);
|
||||
if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
|
||||
{
|
||||
ext->start = base->start;
|
||||
base->start = cutoff;
|
||||
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 */
|
||||
|
@ -90,9 +94,16 @@ EAPI void
|
|||
evas_common_text_props_merge(Evas_Text_Props *item1,
|
||||
const Evas_Text_Props *item2)
|
||||
{
|
||||
#ifdef OT_SUPPORT
|
||||
evas_common_font_ot_merge_text_props(item1, item2);
|
||||
#endif
|
||||
if (item1->info != item2->info)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,16 +2,29 @@
|
|||
# define _EVAS_TEXT_UTILS_H
|
||||
|
||||
typedef struct _Evas_Text_Props Evas_Text_Props;
|
||||
typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info;
|
||||
|
||||
# include "evas_font_ot.h"
|
||||
# include "language/evas_bidi_utils.h"
|
||||
# include "language/evas_language_utils.h"
|
||||
# include "evas_font_glyph_info.h"
|
||||
|
||||
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_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
|
||||
|
@ -32,9 +45,6 @@ evas_common_text_props_content_ref(Evas_Text_Props *props);
|
|||
void
|
||||
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
|
||||
evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext,
|
||||
int cutoff);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
#ifdef BIDI_SUPPORT
|
||||
return !evas_bidi_shape_string(text, par_props, pos, len);
|
||||
evas_bidi_shape_string(text, par_props, pos, len);
|
||||
#endif
|
||||
return EINA_TRUE;
|
||||
return evas_common_font_glyph_info_create(font, text, intl_props, len);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -543,17 +543,23 @@ eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *t
|
|||
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)
|
||||
{
|
||||
(void) font;
|
||||
(void) text;
|
||||
(void) intl_props;
|
||||
(void) par_props;
|
||||
(void) pos;
|
||||
(void) len;
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled())
|
||||
{
|
||||
return evas_common_font_ot_populate_text_props(font, text,
|
||||
intl_props, len);
|
||||
return evas_common_font_glyph_info_create(font, text, intl_props, len);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#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
|
||||
}
|
||||
return EINA_TRUE;
|
||||
|
|
|
@ -601,17 +601,23 @@ eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *t
|
|||
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)
|
||||
{
|
||||
(void) font;
|
||||
(void) text;
|
||||
(void) intl_props;
|
||||
(void) par_props;
|
||||
(void) pos;
|
||||
(void) len;
|
||||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled())
|
||||
{
|
||||
return evas_common_font_ot_populate_text_props(font, text,
|
||||
intl_props, len);
|
||||
return evas_common_font_glyph_info_create(font, text, intl_props, len);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#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
|
||||
}
|
||||
return EINA_TRUE;
|
||||
|
|
|
@ -722,8 +722,7 @@ eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_
|
|||
#ifdef OT_SUPPORT
|
||||
if (evas_common_font_ot_is_enabled())
|
||||
{
|
||||
return evas_common_font_ot_populate_text_props(font, text,
|
||||
intl_props, len);
|
||||
return evas_common_font_glyph_info_create(font, text, intl_props, len);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue