Evas font/textblock/text: Started using string objects instead of

strings in most of the font engine (everywhere except draw).
Haven't removed the paramteres yet, but did mark them as UNUSED.
Removing them will be part of a future change.
Removed run-time OT toggling support, OT is now fast, no need for that.
Renamed all of the intl_props->text_props (because it really changed purpose now)
Fixed spliting/merging of text_props to be fast and good, not hacky and
complex like before.
Note to reviewers: Most of the changes are indentation related, sorry
for the mess, but I had to do it all in one commit, splitting was not
trivial (at least not in retrospect). The important parts are
evas_font_default_walk.x and text_utils.c. query and draw were just
adjusted a bit and the rest were only adjusted to conform to renaming or
were renaming on their own.

SVN revision: 56629
This commit is contained in:
Tom Hacohen 2011-02-01 12:17:52 +00:00
parent 22b440ff2a
commit 94b5a536f0
20 changed files with 987 additions and 1613 deletions

View File

@ -528,7 +528,8 @@ _evas_object_text_item_new(Evas_Object *obj, Evas_Object_Text *o,
evas_common_text_props_bidi_set(&it->text_props, o->bidi_par_props,
it->text_pos);
evas_common_text_props_script_set(&it->text_props, it->text);
ENFN->font_shape(ENDT, o->engine_data, it->text, &it->text_props,
ENFN->font_text_props_info_create(ENDT,
o->engine_data, it->text, &it->text_props,
o->bidi_par_props, it->text_pos, len);
if (o->engine_data)
{

View File

@ -1783,6 +1783,7 @@ struct _Ctxt
};
static void _layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Text_Item *ti, const Evas_Object_Textblock_Item *rel);
static void _text_item_update_sizes(Ctxt *c, Evas_Object_Textblock_Text_Item *ti);
/**
* @internal
* Adjust the ascent/descent of the format and context.
@ -2459,12 +2460,6 @@ _layout_item_text_split_strip_white(Ctxt *c,
_layout_text_add_logical_item(c, new_ti, _ITEM(ti));
}
/* FIXME: Will break with kerning and a bunch of other stuff, should
* maybe adjust the last adv of the prev and the offset of the cur
* There's also another similar fixme below (same case, not marked) */
ti->parent.w -= new_ti->parent.w;
ti->parent.adv -= new_ti->parent.adv;
if (cut2 > cut)
{
white_ti = _layout_text_item_new(c, ti->parent.format, &ts[cut]);
@ -2477,8 +2472,6 @@ _layout_item_text_split_strip_white(Ctxt *c,
evas_common_text_props_split(&ti->parent.text_props,
&white_ti->parent.text_props, cut);
_layout_text_add_logical_item(c, white_ti, _ITEM(ti));
ti->parent.w -= white_ti->parent.w;
ti->parent.adv -= white_ti->parent.adv;
}
if (new_ti || white_ti)
@ -2785,7 +2778,8 @@ skip:
ti->parent.text_node->bidi_props, ti->parent.text_pos);
evas_common_text_props_script_set (&ti->parent.text_props,
ti->text);
c->ENFN->font_shape(c->ENDT, ti->parent.format->font.font,
c->ENFN->font_text_props_info_create(c->ENDT,
ti->parent.format->font.font,
ti->text, &ti->parent.text_props,
ti->parent.text_node->bidi_props,
ti->parent.text_pos, tmp_len);
@ -3201,7 +3195,8 @@ _layout_ellipsis_item_new(Ctxt *c, const Evas_Object_Textblock_Item *cur_it)
ellip_ti->parent.text_node->bidi_props, ellip_ti->parent.text_pos);
evas_common_text_props_script_set (&ellip_ti->parent.text_props,
ellip_ti->text);
c->ENFN->font_shape(c->ENDT, ellip_ti->parent.format->font.font,
c->ENFN->font_text_props_info_create(c->ENDT,
ellip_ti->parent.format->font.font,
ellip_ti->text, &ellip_ti->parent.text_props,
ellip_ti->parent.text_node->bidi_props,
ellip_ti->parent.text_pos, eina_unicode_strlen(_ellip_str));

View File

@ -3,190 +3,169 @@
/* 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) \
for (char_index = text_props->start ; char_index < text_props->start + 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 \
{ \
int _char_index_d; \
size_t _i; \
_i = text_props->len; \
if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
{ \
char_index = text - _base_text - 1; \
text--; \
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;
char_index += text_props->start; \
_i += text_props->start; \
for ( ; _i > text_props->start ; char_index += _char_index_d, _i--) \
{
/**
* @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;
#else
#define EVAS_FONT_WALK_TEXT_LOGICAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START()
#endif
#define EVAS_FONT_WALK_ORIG_LEN (_len)
/*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 \
(EVAS_FONT_ROUND_26_6_TO_INT( \
EVAS_FONT_OT_X_OFF_GET( \
text_props->info->ot[char_index])))
# define EVAS_FONT_WALK_Y_OFF \
(EVAS_FONT_ROUND_26_6_TO_INT( \
EVAS_FONT_OT_Y_OFF_GET( \
text_props->info->ot[char_index])))
# define EVAS_FONT_WALK_POS \
(EVAS_FONT_OT_POS_GET( \
text_props->info->ot[char_index]) - text_props->text_offset)
# define EVAS_FONT_WALK_POS_NEXT \
((!EVAS_FONT_WALK_IS_LAST) ? \
EVAS_FONT_OT_POS_GET( \
text_props->info->ot[char_index + 1]) - \
text_props->text_offset : \
EVAS_FONT_WALK_POS \
)
# define EVAS_FONT_WALK_POS_PREV \
((char_index > 0) ? \
EVAS_FONT_OT_POS_GET( \
text_props->info->ot[char_index - 1]) - \
text_props->text_offset : \
EVAS_FONT_WALK_POS \
)
#else
# define EVAS_FONT_WALK_X_OFF 0
# define EVAS_FONT_WALK_Y_OFF 0
# define EVAS_FONT_WALK_POS \
((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \
(text_props->len - (char_index - text_props->start) - 1) : \
(char_index - text_props->start))
# define EVAS_FONT_WALK_POS_NEXT \
((!EVAS_FONT_WALK_IS_LAST) ? \
((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \
text_props->len - ((char_index + 1) - text_props->start) \
: (char_index + 1) - text_props->start) : \
EVAS_FONT_WALK_POS)
# define EVAS_FONT_WALK_POS_PREV \
((char_index > text_props->start) ? \
((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ? \
text_props->len - ((char_index - 1) - text_props->start) \
: (char_index - 1) - text_props->start) : \
EVAS_FONT_WALK_POS)
#endif
#define EVAS_FONT_WALK_IS_VISIBLE \
(text_props->info->glyph[char_index].index != 0)
#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->start + 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() \
if (visible) \
#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 (EVAS_FONT_WALK_IS_VISIBLE) \
{ \
_pen_x += _EVAS_FONT_WALK_DEFAULT_X_ADV; \
_pen_x += _EVAS_FONT_WALK_X_ADV; \
} \
prev_index = index; \
} \
} \
while(0)

View File

@ -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,142 +507,172 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font
im = dst->image.data;
/* 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);
}
EVAS_FONT_WALK_TEXT_VISUAL_START()
{
FT_UInt index;
RGBA_Font_Glyph *fg;
int chr_x, chr_y, chr_w;
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled() && intl_props->ot_data)
{
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
{
int chr_x, chr_y, chr_w;
EVAS_FONT_WALK_OT_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_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;
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)
index = text_props->info->glyph[char_index].index;
#else
/* FIXME: Should be removed once we split according to script without
* the use of harfbuzz */
index =
evas_common_font_glyph_search(fn, &fi, text[EVAS_FONT_WALK_POS]);
#endif
LKL(fi->ft_mutex);
fg = evas_common_font_int_cache_glyph_get(fi, index);
if (!fg)
{
LKU(fi->ft_mutex);
continue;
}
pface = fi->src->ft.face;
LKU(fi->ft_mutex);
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_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))
{
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 < (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)
{
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);
}
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
}
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++)
{
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
int bi, bj;
const DATA8 bitrepl[2] = {0x0, 0xff};
int dx, dy;
int in_x, in_w, end;
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);
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)
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)
{
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++)
{
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++;
*tp = bitrepl[(bits >> (7 - bj)) & 0x1];
tp++;
}
if ((dx < (ext_x + ext_w)) &&
(dy >= (ext_y)) &&
(dy < (ext_y + ext_h)))
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)
{
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);
}
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);
}
}
}
@ -648,166 +681,17 @@ 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();
else
break;
}
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;
@ -929,73 +813,36 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con
/* First pass: Work out how big and populate */
/* 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)
len = text_props->len;
metrics = malloc(sizeof(struct cinfo) * len);
EVAS_FONT_WALK_TEXT_VISUAL_START()
{
len = intl_props->ot_data->len;
metrics = malloc(sizeof(struct cinfo) * len);
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
{
struct cinfo *ci = metrics + char_index;
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE);
/* Currently broken with invisible chars if (!visible) continue; */
ci->index = index;
ci->fg = fg;
struct cinfo *ci = metrics + char_index;
EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE);
/* Currently broken with invisible chars if (!EVAS_FONT_WALK_IS_VISIBLE) continue; */
ci->index = index;
ci->fg = fg;
if (gl)
{
ci->fg->ext_dat =dc->font_ext.func.gl_new(dc->font_ext.data,ci->fg);
ci->fg->ext_dat_free = dc->font_ext.func.gl_free;
}
ci->bm.data = ci->fg->glyph_out->bitmap.buffer;
ci->bm.w = MAX(ci->fg->glyph_out->bitmap.pitch,
ci->fg->glyph_out->bitmap.width);
ci->bm.rows = ci->fg->glyph_out->bitmap.rows;
ci->bm.h = ci->fg->glyph_out->top;
above = ci->bm.rows - (ci->bm.rows - ci->bm.h);
below = ci->bm.rows - ci->bm.h;
if (below > descent) descent = below;
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 -
(ci->bm.w + ci->fg->glyph_out->left);
}
EVAS_FONT_WALK_OT_TEXT_END();
}
else
#endif
{
metrics = malloc(sizeof(struct cinfo) * len);
EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
if (gl)
{
struct cinfo *ci = metrics + char_index;
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE);
/* Currently broken with invisible chars if (!visible) continue; */
ci->index = index;
ci->fg = fg;
if (gl)
{
ci->fg->ext_dat =dc->font_ext.func.gl_new(dc->font_ext.data,ci->fg);
ci->fg->ext_dat_free = dc->font_ext.func.gl_free;
}
ci->bm.data = ci->fg->glyph_out->bitmap.buffer;
ci->bm.w = MAX(ci->fg->glyph_out->bitmap.pitch,
ci->fg->glyph_out->bitmap.width);
ci->bm.rows = ci->fg->glyph_out->bitmap.rows;
ci->bm.h = ci->fg->glyph_out->top;
above = ci->bm.rows - (ci->bm.rows - ci->bm.h);
below = ci->bm.rows - ci->bm.h;
if (below > descent) descent = below;
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 -
(ci->bm.w + ci->fg->glyph_out->left);
ci->fg->ext_dat =dc->font_ext.func.gl_new(dc->font_ext.data,ci->fg);
ci->fg->ext_dat_free = dc->font_ext.func.gl_free;
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
ci->bm.data = ci->fg->glyph_out->bitmap.buffer;
ci->bm.w = MAX(ci->fg->glyph_out->bitmap.pitch,
ci->fg->glyph_out->bitmap.width);
ci->bm.rows = ci->fg->glyph_out->bitmap.rows;
ci->bm.h = ci->fg->glyph_out->top;
above = ci->bm.rows - (ci->bm.rows - ci->bm.h);
below = ci->bm.rows - ci->bm.h;
if (below > descent) descent = below;
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_X_ADV -
(ci->bm.w + ci->fg->glyph_out->left);
}
EVAS_FONT_WALK_TEXT_END();
/* First loop done */
width = EVAS_FONT_WALK_PEN_X;

View File

@ -46,10 +46,7 @@ _evas_common_font_source_free(RGBA_Font_Source *fs)
FT_Done_Face(fs->ft.face);
FTUNLOCK();
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled())
{
evas_common_font_ot_unload_face(fs);
}
evas_common_font_ot_unload_face(fs);
#endif
if (fs->name) eina_stringshare_del(fs->name);
free(fs);
@ -139,10 +136,7 @@ evas_common_font_source_memory_load(const char *name, const void *data, int data
return NULL;
}
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled())
{
evas_common_font_ot_load_face(fs);
}
evas_common_font_ot_load_face(fs);
#endif
FTUNLOCK();
fs->ft.orig_upem = fs->ft.face->units_per_EM;
@ -178,10 +172,7 @@ evas_common_font_source_unload(RGBA_Font_Source *fs)
FT_Done_Face(fs->ft.face);
fs->ft.face = NULL;
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled())
{
evas_common_font_ot_unload_face(fs);
}
evas_common_font_ot_unload_face(fs);
#endif
FTUNLOCK();
}
@ -233,10 +224,7 @@ evas_common_font_source_load_complete(RGBA_Font_Source *fs)
return error;
}
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled())
{
evas_common_font_ot_load_face(fs);
}
evas_common_font_ot_load_face(fs);
#endif
FTUNLOCK();
fs->ft.orig_upem = fs->ft.face->units_per_EM;

View File

@ -10,48 +10,32 @@
#include <Eina.h>
#include "evas_font_private.h"
EAPI Eina_Bool
evas_common_font_ot_is_enabled(void)
{
#ifdef OT_SUPPORT
static int ret = -1;
const char *env;
if (ret != -1)
{
return ret;
}
env = getenv("EVAS_USE_OT");
if (env && atoi(env))
{
ret = EINA_TRUE;
return ret;
}
#endif
return EINA_FALSE;
}
#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]);
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;
if (left_bound < 0)
left_bound = 0;
if (right_bound >= (int) (props->start + props->len))
right_bound = props->start + props->len - 1;
if (right_bound == left_bound)
{
items = 1;
@ -60,26 +44,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->start + 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 +98,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)
@ -271,13 +109,6 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
hb_glyph_info_t *infos;
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 +154,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 +176,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

View File

@ -12,58 +12,28 @@
# 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,19 +42,10 @@ 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,
Evas_Text_Props *props, int len);
EAPI void
evas_common_font_ot_cutoff_text_props(Evas_Text_Props *props, int cutoff);
EAPI void
evas_common_font_ot_split_text_props(Evas_Text_Props *base, Evas_Text_Props *ext, int cutoff);
EAPI void
evas_common_font_ot_merge_text_props(Evas_Text_Props *item1, const Evas_Text_Props *item2);
#endif

View File

@ -1,177 +0,0 @@
#ifndef _EVAS_FONT_OT_WALK_X
#define _EVAS_FONT_OT_WALK_X
# include "evas_font_ot.h"
# include "language/evas_language_utils.h"
/* Macros for text walking */
/**
* @def EVAS_FONT_WALK_OT_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_OT_X_OFF and the like.
* @see EVAS_FONT_WALK_OT_TEXT_INIT
* @see EVAS_FONT_WALK_OT_TEXT_WORK
* @see EVAS_FONT_WALK_OT_TEXT_END
* @see EVAS_FONT_WALK_OT_TEXT_LOGICAL_START
*/
#define EVAS_FONT_WALK_OT_TEXT_VISUAL_START() \
do \
{ \
int visible; \
prev_index = 0; \
/* 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 < intl_props->ot_data->len ; char_index++) \
{ \
FT_UInt index; \
RGBA_Font_Glyph *fg; \
/**
* @def EVAS_FONT_WALK_OT_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_OT_X_OFF and the like.
* @see EVAS_FONT_WALK_OT_TEXT_INIT
* @see EVAS_FONT_WALK_OT_TEXT_WORK
* @see EVAS_FONT_WALK_OT_TEXT_END
* @see EVAS_FONT_WALK_OT_TEXT_VISUAL_START
*/
#define EVAS_FONT_WALK_OT_TEXT_LOGICAL_START() \
do \
{ \
int _char_index_d, _i; \
int visible; \
/* Load the font needed for this script */ \
{ \
/* 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); \
} \
prev_index = 0; \
_i = intl_props->ot_data->len; \
if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \
{ \
char_index = intl_props->ot_data->len - 1; \
_char_index_d = -1; \
} \
else \
{ \
char_index = 0; \
_char_index_d = 1; \
} \
for ( ; _i > 0 ; char_index += _char_index_d, _i--) \
{ \
FT_UInt index; \
RGBA_Font_Glyph *fg; \
/*FIXME: doc */
#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])))
#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)
#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]))
#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)
#define EVAS_FONT_WALK_OT_POS \
(EVAS_FONT_OT_POS_GET( \
intl_props->ot_data->items[char_index]))
#define EVAS_FONT_WALK_OT_IS_LAST \
(char_index + 1 == intl_props->ot_data->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]) : \
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]) : \
EVAS_FONT_WALK_OT_POS \
)
#define EVAS_FONT_WALK_OT_LEN (intl_props->ot_data->len)
/**
* @def EVAS_FONT_WALK_OT_TEXT_WORK
* @internal
* This macro actually updates the values mentioned in EVAS_FONT_WALK_OT_TEXT_VISUAL_START
* according to the current positing in the walk.
* @see EVAS_FONT_WALK_OT_TEXT_VISUAL_START
* @see EVAS_FONT_WALK_OT_TEXT_INIT
* @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]); \
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_OT_POS])) \
{ \
visible = 0; \
} \
else \
{ \
visible = 1; \
} \
\
pface = fi->src->ft.face; \
LKU(fi->ft_mutex);
/**
* @def EVAS_FONT_WALK_OT_TEXT_END
* @internal
* Closes EVAS_FONT_WALK_OT_TEXT_VISUAL_START, needs to end with a ;
* @see EVAS_FONT_WALK_OT_TEXT_VISUAL_START
* @see EVAS_FONT_WALK_OT_TEXT_INIT
* @see EVAS_FONT_WALK_OT_TEXT_WORK
*/
#define EVAS_FONT_WALK_OT_TEXT_END() \
if (visible) \
{ \
_pen_x += _EVAS_FONT_WALK_OT_X_ADV; \
} \
prev_index = index; \
} \
} \
while(0)
#endif

View File

@ -47,33 +47,5 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi);
((0x202A <= (x)) && ((x) <= 0x202E)) /* BIDI stuff */ \
)
# define EVAS_FONT_WALK_ORIG_LEN (_len)
# ifdef OT_SUPPORT
# include "evas_font_ot_walk.x"
# 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 */

View File

@ -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 __UNUSED__, const Evas_Text_Props *text_props, 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);
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 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_WORK();
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
/* Keep the width because we'll need it for the last char */
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_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 __UNUSED__, 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);
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_WORK();
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
}
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 *text __UNUSED__, 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;
size_t position = 0;
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, text, text_props, cx, ch);
}
if (cy) *cy = 0;
if (cw) *cw = 0;
@ -275,122 +202,89 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c
goto end;
}
Evas_Coord cluster_start, last_end;
int prev_cluster = -1;
int found = 0, items = 1, item_pos = 1;
int last_is_visible;
EVAS_FONT_WALK_TEXT_VISUAL_START()
{
EVAS_FONT_WALK_TEXT_WORK();
if (prev_cluster != (int) EVAS_FONT_WALK_POS)
{
if (found)
{
break;
}
else
{
cluster_start = EVAS_FONT_WALK_PEN_X +
EVAS_FONT_WALK_X_OFF +
EVAS_FONT_WALK_X_BEAR;
}
}
last_is_visible = EVAS_FONT_WALK_IS_VISIBLE;
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 ((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;
#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 last_is_visible;
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
{
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
{
if (found)
{
break;
}
else
{
cluster_start = EVAS_FONT_WALK_PEN_X +
EVAS_FONT_WALK_OT_X_OFF +
EVAS_FONT_WALK_OT_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;
/* 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)))
{
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;
}
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))
{
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);
}
prev_cluster = EVAS_FONT_WALK_OT_POS;
}
EVAS_FONT_WALK_OT_TEXT_END();
if (found)
{
Evas_Coord cluster_w;
cluster_w = last_end - cluster_start;
if (cy) *cy = -asc;
if (ch) *ch = asc + desc;
if (last_is_visible)
{
if (cx) *cx = cluster_start +
(cluster_w / items) *
(item_pos - 1);
if (cw) *cw = (cluster_w / items);
}
else
{
if (cx) *cx = cluster_start;
if (cw) *cw = 0;
}
ret_val = 1;
goto end;
}
}
else
items = evas_common_font_ot_cluster_size_get(text_props,
char_index);
#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;
}
item_pos = position - EVAS_FONT_WALK_POS + 1;
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
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;
#ifdef OT_SUPPORT
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_POS;
}
EVAS_FONT_WALK_TEXT_END();
if (found)
{
Evas_Coord cluster_w;
cluster_w = last_end - cluster_start;
if (cy) *cy = -asc;
if (ch) *ch = asc + desc;
if (last_is_visible)
{
if (cx) *cx = cluster_start +
(cluster_w / items) *
(item_pos - 1);
if (cw) *cw = (cluster_w / items);
}
else
{
if (cx) *cx = cluster_start;
if (cw) *cw = 0;
}
ret_val = 1;
goto 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
* 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 +293,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 *text __UNUSED__, 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;
size_t position;
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,122 +318,83 @@ 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, 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 = 1, item_pos = 1;
int last_is_visible = 1;
EVAS_FONT_WALK_TEXT_VISUAL_START()
{
Evas_Coord cluster_start;
int prev_cluster = -1;
int found = 0, items = 0, item_pos = 1;
int last_is_visible = 1;
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
EVAS_FONT_WALK_TEXT_WORK();
if (prev_cluster != (int) EVAS_FONT_WALK_POS)
{
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
if (found)
{
if (found)
{
break;
}
else
{
cluster_start = EVAS_FONT_WALK_PEN_X;
}
}
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)))
{
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;
}
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))
{
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);
}
prev_cluster = EVAS_FONT_WALK_OT_POS;
}
EVAS_FONT_WALK_OT_TEXT_END();
if (found)
{
Evas_Coord cluster_adv;
cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
if (cy) *cy = -asc;
if (ch) *ch = asc + desc;
if (last_is_visible)
{
if (cpen_x) *cpen_x = cluster_start +
(cluster_adv / items) *
(item_pos - 1);
if (cadv) *cadv = (cluster_adv / items);
break;
}
else
{
if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
if (cadv) *cadv = 0;
cluster_start = EVAS_FONT_WALK_PEN_X;
}
ret_val = 1;
goto end;
}
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
{
EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE);
last_is_visible = EVAS_FONT_WALK_IS_VISIBLE;
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;
}
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;
#ifdef OT_SUPPORT
items = evas_common_font_ot_cluster_size_get(text_props,
char_index);
#endif
item_pos = position - EVAS_FONT_WALK_POS + 1;
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
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;
#ifdef OT_SUPPORT
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_POS;
}
EVAS_FONT_WALK_TEXT_END();
if (found)
{
Evas_Coord cluster_adv;
cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
if (cy) *cy = -asc;
if (ch) *ch = asc + desc;
if (last_is_visible)
{
if (cpen_x) *cpen_x = cluster_start +
(cluster_adv / items) *
(item_pos - 1);
if (cadv) *cadv = (cluster_adv / items);
}
else
{
if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X;
if (cadv) *cadv = 0;
}
ret_val = 1;
goto end;
}
end:
@ -558,179 +409,114 @@ 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 *text __UNUSED__, 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 = 1;
EVAS_FONT_WALK_TEXT_VISUAL_START()
{
Evas_Coord cluster_start;
int prev_cluster = -1;
int found = 0, items = 0;
EVAS_FONT_WALK_OT_TEXT_VISUAL_START()
EVAS_FONT_WALK_TEXT_WORK();
if (prev_cluster != (int) EVAS_FONT_WALK_POS)
{
EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE);
if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS)
if (found)
{
if (found)
{
break;
}
else
{
cluster_start = EVAS_FONT_WALK_PEN_X;
}
}
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_OT_X_ADV)) &&
(y >= -asc) && (y <= desc))
{
items = evas_common_font_ot_cluster_size_get(intl_props,
char_index, EVAS_FONT_WALK_ORIG_LEN);
found = 1;
}
prev_cluster = EVAS_FONT_WALK_OT_POS;
}
EVAS_FONT_WALK_OT_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)
{
double part;
part = cluster_adv / items;
item_pos = (int) ((x - cluster_start) / part);
break;
}
else
{
double part;
part = cluster_adv / items;
item_pos = items - ((int) ((x - cluster_start) / part)) - 1;
cluster_start = EVAS_FONT_WALK_PEN_X;
}
if (cx) *cx = EVAS_FONT_WALK_PEN_X +
((cluster_adv / items) * (item_pos - 1));
if (cy) *cy = -asc;
if (cw) *cw = (cluster_adv / items);
if (ch) *ch = asc + desc;
ret_val = prev_cluster + item_pos;
goto end;
}
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START()
if (!EVAS_FONT_WALK_IS_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_X_ADV)) &&
(y >= -asc) && (y <= desc))
{
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;
}
#ifdef OT_SUPPORT
items = evas_common_font_ot_cluster_size_get(text_props,
char_index);
#endif
found = 1;
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
prev_cluster = EVAS_FONT_WALK_POS;
}
EVAS_FONT_WALK_TEXT_END();
if (found)
{
int item_pos;
Evas_Coord cluster_adv;
cluster_adv = EVAS_FONT_WALK_PEN_X - cluster_start;
if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR)
{
double part;
part = cluster_adv / items;
item_pos = (int) ((x - cluster_start) / part);
}
else
{
double part;
part = cluster_adv / items;
item_pos = items - ((int) ((x - cluster_start) / part)) - 1;
}
if (cx) *cx = EVAS_FONT_WALK_PEN_X +
((cluster_adv / items) * (item_pos - 1));
if (cy) *cy = -asc;
if (cw) *cw = (cluster_adv / items);
if (ch) *ch = asc + desc;
ret_val = prev_cluster + item_pos;
goto 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 *text __UNUSED__, const Evas_Text_Props *text_props, 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);
if (!visible) continue;
EVAS_FONT_WALK_TEXT_WORK();
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_ADV)) &&
(y >= -asc) && (y <= desc))
{
ret = EVAS_FONT_WALK_OT_POS;
goto end;
}
}
EVAS_FONT_WALK_OT_TEXT_END();
}
else
#endif
{
EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START()
if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_ADV)) &&
(y >= -asc) && (y <= desc))
{
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;
}
ret = EVAS_FONT_WALK_POS;
goto end;
}
EVAS_FONT_WALK_DEFAULT_TEXT_END();
}
EVAS_FONT_WALK_TEXT_END();
end:
evas_common_font_int_use_trim();
return ret;
}

View File

@ -1,3 +1,5 @@
#include "evas_common.h"
#include "evas_font_private.h"
#include "evas_text_utils.h"
#include "language/evas_bidi_utils.h"
#include "language/evas_language_utils.h"
@ -37,39 +39,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 +74,33 @@ 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));
evas_common_text_props_content_copy_and_ref(ext, base);
if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
{
ext->start = base->start;
ext->len = base->len - cutoff;
base->start = (base->start + base->len) - cutoff;
base->len = cutoff;
#ifdef OT_SUPPORT
evas_common_font_ot_split_text_props(base, ext, cutoff);
ext->text_offset =
ext->info->ot[ext->start + ext->len - 1].source_cluster;
#else
ext->text_offset = base->text_offset + base->len;
#endif
}
else
{
ext->start = base->start + cutoff;
ext->len = base->len - cutoff;
base->len = cutoff;
#ifdef OT_SUPPORT
ext->text_offset = ext->info->ot[ext->start].source_cluster;
#else
ext->text_offset = base->text_offset + base->len;
#endif
}
}
/* Won't work in the middle of ligatures */
@ -90,9 +108,177 @@ 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;
}
EAPI Eina_Bool
evas_common_text_props_content_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
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 */
if (EVAS_FONT_CHARACTER_IS_INVISIBLE(
text[text_props->info->ot[char_index].source_cluster]))
text_props->info->glyph[char_index].index = 0;
}
#else
/* 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);
if (EVAS_FONT_CHARACTER_IS_INVISIBLE(_gl))
text_props->info->glyph[char_index].index = 0;
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;
#endif
text_props->info->refcount = 1;
return EINA_TRUE;
}

View File

@ -2,6 +2,8 @@
# define _EVAS_TEXT_UTILS_H
typedef struct _Evas_Text_Props Evas_Text_Props;
typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info;
typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info;
# include "evas_font_ot.h"
# include "language/evas_bidi_utils.h"
@ -9,11 +11,39 @@ typedef struct _Evas_Text_Props 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;
size_t text_offset; /* The text offset from the start of the info */
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;
};
/* 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;
};
void
evas_common_text_props_bidi_set(Evas_Text_Props *props,
Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start);
@ -22,6 +52,10 @@ void
evas_common_text_props_script_set(Evas_Text_Props *props,
const Eina_Unicode *str);
EAPI Eina_Bool
evas_common_text_props_content_create(void *_fn, const Eina_Unicode *text,
Evas_Text_Props *text_props, int len);
void
evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst,
const Evas_Text_Props *src);
@ -32,8 +66,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,

View File

@ -55,48 +55,49 @@ evas_common_language_script_end_of_run_get(const Eina_Unicode *str,
const Evas_BiDi_Paragraph_Props *bidi_props, size_t start, int len)
{
/* FIXME: Use the standard segmentation instead */
if (evas_common_font_ot_is_enabled())
#ifdef OT_SUPPORT
Evas_Script_Type first = EVAS_SCRIPT_UNKNOWN;
int i;
for (i = 0 ; i < len ; i++, str++)
{
Evas_Script_Type first = EVAS_SCRIPT_UNKNOWN;
int i;
for (i = 0 ; i < len ; i++, str++)
Evas_Script_Type tmp;
tmp = evas_common_language_char_script_get(*str);
/* Arabic is the first script in the array that's not
* common/inherited. */
if ((first == EVAS_SCRIPT_UNKNOWN) && (tmp >= EVAS_SCRIPT_ARABIC))
{
Evas_Script_Type tmp;
tmp = evas_common_language_char_script_get(*str);
/* Arabic is the first script in the array that's not
* common/inherited. */
if ((first == EVAS_SCRIPT_UNKNOWN) && (tmp >= EVAS_SCRIPT_ARABIC))
{
first = tmp;
continue;
}
if ((first != tmp) && (tmp >= EVAS_SCRIPT_ARABIC))
{
break;
}
first = tmp;
continue;
}
#ifdef BIDI_SUPPORT
if ((first != tmp) && (tmp >= EVAS_SCRIPT_ARABIC))
{
int bidi_end;
bidi_end = evas_bidi_end_of_run_get(bidi_props, start, len);
if (bidi_end > 0)
{
i = (i < bidi_end) ? i : bidi_end;
}
break;
}
}
# ifdef BIDI_SUPPORT
{
int bidi_end;
bidi_end = evas_bidi_end_of_run_get(bidi_props, start, len);
if (bidi_end > 0)
{
i = (i < bidi_end) ? i : bidi_end;
}
}
# else
(void) bidi_props;
(void) start;
# endif
return (i < len) ? i : 0;
#elif defined(BIDI_SUPPORT)
(void) str;
return evas_bidi_end_of_run_get(bidi_props, start, len);
#else
(void) bidi_props;
(void) start;
#endif
return (i < len) ? i : 0;
}
else
{
#ifdef BIDI_SUPPORT
return evas_bidi_end_of_run_get(bidi_props, start, len);
#endif
}
(void) bidi_props;
(void) start;
(void) str;
(void) len;
return 0;
#endif
}
Evas_Script_Type

View File

@ -671,7 +671,7 @@ struct _Evas_Func
void (*image_content_hint_set) (void *data, void *surface, int hint);
int (*image_content_hint_get) (void *data, void *surface);
int (*font_pen_coords_get) (void *data, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
Eina_Bool (*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);
Eina_Bool (*font_text_props_info_create) (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);
};
struct _Evas_Image_Load_Func

View File

@ -94,7 +94,7 @@ static int eng_font_h_advance_get(void *data, void *font, char *text);
static int eng_font_v_advance_get(void *data, void *font, char *text);
static int eng_font_char_coords_get(void *data, void *font, char *text, int pos, int *cx, int *cy, int *cw, int *ch);
static int eng_font_pen_coords_get(void *data, void *font, char *text, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
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);
static Eina_Bool eng_font_text_props_info_create(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len);
static int eng_font_char_at_coords_get(void *data, void *font, char *text, int x, int y, int *cx, int *cy, int *cw, int *ch);
static void eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, char *text);
static void eng_font_cache_flush(void *data);
@ -219,7 +219,7 @@ static Evas_Func eng_func =
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
eng_font_pen_coords_get,
eng_font_shape
eng_font_text_props_info_create
/* FUTURE software generic calls go here */
};
@ -1291,7 +1291,7 @@ eng_font_pen_coords_get(void *data, void *font, char *text, int pos, int *cpen_x
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_text_props_info_create(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
{
Render_Engine *re;

View File

@ -1026,7 +1026,7 @@ eng_font_max_descent_get(void *data, void *font)
}
static void
eng_font_string_size_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int *w, int *h)
eng_font_string_size_get(void *data, void *font, const char *text, const Evas_Text_Props *text_props, int *w, int *h)
{
Render_Engine *re = (Render_Engine *)data;
Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font;
@ -1056,28 +1056,28 @@ eng_font_inset_get(void *data, void *font, const char *text)
}
static int
eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props)
eng_font_h_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *text_props)
{
int w;
eng_font_string_size_get(data, font, text, intl_props, &w, NULL);
eng_font_string_size_get(data, font, text, text_props, &w, NULL);
return w + 2; // FIXME: shouldn't need a constant here. from where do we get word spacing?
// it seems we lose the space between differently-styled text in a text block. Why?
}
static int
eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props)
eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *text_props)
{
int h;
eng_font_string_size_get(data, font, text, intl_props, NULL, &h);
eng_font_string_size_get(data, font, text, text_props, NULL, &h);
return h;
}
static int
eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch)
eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *text_props, int pos, int *cx, int *cy, int *cw, int *ch)
{
Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font;
@ -1099,23 +1099,29 @@ eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Te
/*FIXME: this is *NOT* implemennted correctly, look at the other engines to
* see what needed to be done */
static int
eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *text_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
{
return eng_font_char_coords_get(data, font, text, intl_props, pos, cpen_x,
return eng_font_char_coords_get(data, font, text, text_props, pos, cpen_x,
cy, cadv, ch)
}
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_text_props_info_create(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *text_props, 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);
(void) font;
(void) text;
(void) text_props;
(void) par_props;
(void) pos;
(void) len;
#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
evas_bidi_shape_string(text, par_props, pos, len);
#endif
return EINA_TRUE;
return evas_common_text_props_content_create(font, text, text_props, len);
}
static int
eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *text_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
{
// Return the index of the character at the given point, also lookup it's origin x, y, w, and h.
Evas_Quartz_Font *loaded_font = (Evas_Quartz_Font *)font;
@ -1127,8 +1133,8 @@ eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas
int stringIndex = (int) CTLineGetStringIndexForPosition(line, CGPointMake(x, y));
// In order to get the character's size and position, look up the position of this character and the next one
eng_font_char_coords_get(data, font, text, intl_props, stringIndex, cx, cy, NULL, NULL);
eng_font_char_coords_get(data, font, text, intl_props, stringIndex + 1, cw, NULL, NULL, NULL);
eng_font_char_coords_get(data, font, text, text_props, stringIndex, cx, cy, NULL, NULL);
eng_font_char_coords_get(data, font, text, text_props, stringIndex + 1, cw, NULL, NULL, NULL);
if (cw && cx) *cw -= *cx;
if (ch) *ch = loaded_font->size;
@ -1154,7 +1160,7 @@ eng_font_hinting_can_hint(void *data, int hinting)
}
static void
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text, const Evas_Text_Props *intl_props)
eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text, const Evas_Text_Props *text_props)
{
Render_Engine *re = (Render_Engine *)data;
Evas_Quartz_Context *ctxt = (Evas_Quartz_Context *)context;

View File

@ -81,7 +81,7 @@ static int eng_font_h_advance_get(void *data, void *font, const char *text, cons
static int eng_font_v_advance_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props);
static int eng_font_char_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch);
static int eng_font_pen_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch);
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);
static Eina_Bool eng_font_text_props_info_create(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);
static int eng_font_char_at_coords_get(void *data, void *font, const char *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch);
static void eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text, const Evas_Text_Props *intl_props);
static void eng_font_hinting_set(void *data, void *font, int hinting);

View File

@ -505,9 +505,9 @@ eng_font_max_descent_get(void *data __UNUSED__, void *font)
}
static void
eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *w, int *h)
eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int *w, int *h)
{
evas_common_font_query_size(font, text, intl_props, w, h);
evas_common_font_query_size(font, text, text_props, w, h);
}
static int
@ -517,68 +517,64 @@ eng_font_inset_get(void *data __UNUSED__, void *font, const Eina_Unicode *text)
}
static int
eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props)
{
int h, v;
evas_common_font_query_advance(font, text, intl_props, &h, &v);
evas_common_font_query_advance(font, text, text_props, &h, &v);
return h;
}
static int
eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props)
{
int h, v;
evas_common_font_query_advance(font, text, intl_props, &h, &v);
evas_common_font_query_advance(font, text, text_props, &h, &v);
return v;
}
static int
eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
{
return evas_common_font_query_pen_coords(font, text, intl_props, pos, cpen_x, cy, cadv, ch);
return evas_common_font_query_pen_coords(font, text, text_props, pos, cpen_x, cy, cadv, ch);
}
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_text_props_info_create(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
{
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled())
{
return evas_common_font_ot_populate_text_props(font, text,
intl_props, len);
}
else
(void) font;
(void) text;
(void) text_props;
(void) par_props;
(void) pos;
(void) len;
#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
evas_bidi_shape_string(text, par_props, pos, len);
#endif
{
#ifdef BIDI_SUPPORT
return !evas_bidi_shape_string(text, par_props, pos, len);
#endif
}
return EINA_TRUE;
return evas_common_text_props_content_create(font, text, text_props, len);
}
static int
eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch)
eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int pos, int *cx, int *cy, int *cw, int *ch)
{
return evas_common_font_query_char_coords(font, text, intl_props, pos, cx, cy, cw, ch);
return evas_common_font_query_char_coords(font, text, text_props, pos, cx, cy, cw, ch);
}
static int
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
{
return evas_common_font_query_char_at_coords(font, text, intl_props, x, y, cx, cy, cw, ch);
return evas_common_font_query_char_at_coords(font, text, text_props, x, y, cx, cy, cw, ch);
}
static int
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y)
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int x, int y)
{
return evas_common_font_query_last_up_to_pos(font, text, intl_props, x, y);
return evas_common_font_query_last_up_to_pos(font, text, text_props, x, y);
}
static void
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *text_props)
{
static RGBA_Image *im = NULL;
Soft16_Image *dst = surface;
@ -591,7 +587,7 @@ eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, i
evas_common_soft16_font_glyph_new,
evas_common_soft16_font_glyph_free,
evas_common_soft16_font_glyph_draw);
evas_common_font_draw(im, context, font, x, y, text, intl_props);
evas_common_font_draw(im, context, font, x, y, text, text_props);
evas_common_draw_context_font_ext_set(context,
NULL,
NULL,
@ -750,7 +746,7 @@ static Evas_Func func =
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
eng_font_pen_coords_get,
eng_font_shape
eng_font_text_props_info_create
/* FUTURE software generic calls go here */
};

View File

@ -561,10 +561,10 @@ eng_font_max_descent_get(void *data __UNUSED__, void *font)
}
static void
eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props,
int *w, int *h)
{
evas_common_font_query_size(font, text, intl_props, w, h);
evas_common_font_query_size(font, text, text_props, w, h);
}
static int
@ -574,75 +574,71 @@ eng_font_inset_get(void *data __UNUSED__, void *font, const Eina_Unicode *text)
}
static int
eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props)
{
int h, v;
evas_common_font_query_advance(font, text, intl_props, &h, &v);
evas_common_font_query_advance(font, text, text_props, &h, &v);
return h;
}
static int
eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props)
{
int h, v;
evas_common_font_query_advance(font, text, intl_props, &h, &v);
evas_common_font_query_advance(font, text, text_props, &h, &v);
return v;
}
static int
eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props,
int pos, int *cpen, int *cy, int *cadv, int *ch)
{
return evas_common_font_query_pen_coords(font, text, intl_props, pos, cpen, cy, cadv, ch);
return evas_common_font_query_pen_coords(font, text, text_props, pos, cpen, cy, cadv, ch);
}
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_text_props_info_create(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
{
#ifdef OT_SUPPORT
if (evas_common_font_ot_is_enabled())
{
return evas_common_font_ot_populate_text_props(font, text,
intl_props, len);
}
else
(void) font;
(void) text;
(void) text_props;
(void) par_props;
(void) pos;
(void) len;
#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
evas_bidi_shape_string(text, par_props, pos, len);
#endif
{
#ifdef BIDI_SUPPORT
return !evas_bidi_shape_string(text, par_props, pos, len);
#endif
}
return EINA_TRUE;
return evas_common_text_props_content_create(font, text, text_props, len);
}
static int
eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props,
int pos, int *cx, int *cy, int *cw, int *ch)
{
return evas_common_font_query_char_coords(font, text, intl_props, pos, cx, cy, cw, ch);
return evas_common_font_query_char_coords(font, text, text_props, pos, cx, cy, cw, ch);
}
static int
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props,
int x, int y, int *cx, int *cy, int *cw, int *ch)
{
return evas_common_font_query_char_at_coords(font, text, intl_props, x, y, cx, cy, cw, ch);
return evas_common_font_query_char_at_coords(font, text, text_props, x, y, cx, cy, cw, ch);
}
static int
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props,
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props,
int x, int y)
{
return evas_common_font_query_last_up_to_pos(font, text, intl_props, x, y);
return evas_common_font_query_last_up_to_pos(font, text, text_props, x, y);
}
static void
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font,
int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *text_props)
{
evas_common_font_draw(surface, context, font, x, y, text, intl_props);
evas_common_font_draw(surface, context, font, x, y, text, text_props);
evas_common_draw_context_font_ext_set(context, NULL, NULL, NULL, NULL);
}
@ -796,7 +792,7 @@ static Evas_Func func = {
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
eng_font_pen_coords_get,
eng_font_shape
eng_font_text_props_info_create
/* FUTURE software generic calls go here */
};

View File

@ -675,9 +675,9 @@ eng_font_max_descent_get(void *data __UNUSED__, void *font)
}
static void
eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int *w, int *h)
eng_font_string_size_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int *w, int *h)
{
evas_common_font_query_size(font, text, intl_props, w, h);
evas_common_font_query_size(font, text, text_props, w, h);
}
static int
@ -687,74 +687,64 @@ eng_font_inset_get(void *data __UNUSED__, void *font, const Eina_Unicode *text)
}
static int
eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
eng_font_h_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props)
{
int h, v;
evas_common_font_query_advance(font, text, intl_props, &h, &v);
evas_common_font_query_advance(font, text, text_props, &h, &v);
return h;
}
static int
eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
eng_font_v_advance_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props)
{
int h, v;
evas_common_font_query_advance(font, text, intl_props, &h, &v);
evas_common_font_query_advance(font, text, text_props, &h, &v);
return v;
}
static int
eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch)
{
return evas_common_font_query_pen_coords(font, text, intl_props, pos, cpen_x, cy, cadv, ch);
return evas_common_font_query_pen_coords(font, text, text_props, pos, cpen_x, cy, cadv, ch);
}
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_text_props_info_create(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *text_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len)
{
(void) font;
(void) text;
(void) intl_props;
(void) text_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);
}
else
#if !defined(OT_SUPPORT) && defined(BIDI_SUPPORT)
evas_bidi_shape_string(text, par_props, pos, len);
#endif
{
#ifdef BIDI_SUPPORT
return !evas_bidi_shape_string(text, par_props, pos, len);
#endif
}
return EINA_TRUE;
return evas_common_text_props_content_create(font, text, text_props, len);
}
static int
eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int pos, int *cx, int *cy, int *cw, int *ch)
eng_font_char_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int pos, int *cx, int *cy, int *cw, int *ch)
{
return evas_common_font_query_char_coords(font, text, intl_props, pos, cx, cy, cw, ch);
return evas_common_font_query_char_coords(font, text, text_props, pos, cx, cy, cw, ch);
}
static int
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
eng_font_char_at_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int x, int y, int *cx, int *cy, int *cw, int *ch)
{
return evas_common_font_query_char_at_coords(font, text, intl_props, x, y, cx, cy, cw, ch);
return evas_common_font_query_char_at_coords(font, text, text_props, x, y, cx, cy, cw, ch);
}
static int
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *intl_props, int x, int y)
eng_font_last_up_to_pos(void *data __UNUSED__, void *font, const Eina_Unicode *text, const Evas_Text_Props *text_props, int x, int y)
{
return evas_common_font_query_last_up_to_pos(font, text, intl_props, x, y);
return evas_common_font_query_last_up_to_pos(font, text, text_props, x, y);
}
static void
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *intl_props)
eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Eina_Unicode *text, const Evas_Text_Props *text_props)
{
#ifdef BUILD_PIPE_RENDER
if ((cpunum > 1)
@ -762,11 +752,11 @@ eng_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, i
&& evas_common_frameq_enabled()
#endif
)
evas_common_pipe_text_draw(surface, context, font, x, y, text, intl_props);
evas_common_pipe_text_draw(surface, context, font, x, y, text, text_props);
else
#endif
{
evas_common_font_draw(surface, context, font, x, y, text, intl_props);
evas_common_font_draw(surface, context, font, x, y, text, text_props);
evas_common_cpu_end_opt();
}
}
@ -923,7 +913,7 @@ static Evas_Func func =
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
eng_font_pen_coords_get,
eng_font_shape
eng_font_text_props_info_create
/* FUTURE software generic calls go here */
};