From d6feccdebbd9dbd6865340851d2f248c601de14d Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Sun, 30 Jan 2011 13:55:04 +0000 Subject: [PATCH] Snapshot. SVN revision: 56552 --- .../evas/src/lib/engines/common/Makefile.am | 2 + .../engines/common/evas_font_default_walk.x | 281 ++++---- .../src/lib/engines/common/evas_font_draw.c | 444 +++++------- .../lib/engines/common/evas_font_glyph_info.c | 166 +++++ .../lib/engines/common/evas_font_glyph_info.h | 25 + .../src/lib/engines/common/evas_font_ot.c | 221 +----- .../src/lib/engines/common/evas_font_ot.h | 35 +- .../lib/engines/common/evas_font_ot_walk.x | 32 +- .../lib/engines/common/evas_font_private.h | 22 - .../src/lib/engines/common/evas_font_query.c | 663 ++++++------------ .../src/lib/engines/common/evas_text_utils.c | 81 ++- .../src/lib/engines/common/evas_text_utils.h | 18 +- .../src/modules/engines/quartz/evas_engine.c | 4 +- .../modules/engines/software_16/evas_engine.c | 12 +- .../modules/engines/software_8/evas_engine.c | 12 +- .../engines/software_generic/evas_engine.c | 3 +- 16 files changed, 844 insertions(+), 1177 deletions(-) create mode 100644 legacy/evas/src/lib/engines/common/evas_font_glyph_info.c create mode 100644 legacy/evas/src/lib/engines/common/evas_font_glyph_info.h diff --git a/legacy/evas/src/lib/engines/common/Makefile.am b/legacy/evas/src/lib/engines/common/Makefile.am index c3f9dd8426..2128b1874a 100644 --- a/legacy/evas/src/lib/engines/common/Makefile.am +++ b/legacy/evas/src/lib/engines/common/Makefile.am @@ -63,6 +63,7 @@ language/evas_bidi_utils.c \ language/evas_language_utils.c \ evas_text_utils.c \ evas_font_ot.c \ +evas_font_glyph_info.c \ evas_map_image.c \ evas_map_image.h @@ -105,6 +106,7 @@ language/evas_bidi_utils.h \ language/evas_language_utils.h \ evas_text_utils.h \ evas_font_ot.h \ +evas_font_glyph_info.h \ evas_map_image_internal.c \ evas_map_image_core.c \ evas_map_image_loop.c diff --git a/legacy/evas/src/lib/engines/common/evas_font_default_walk.x b/legacy/evas/src/lib/engines/common/evas_font_default_walk.x index 08839e4815..2071e2d0e6 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_default_walk.x +++ b/legacy/evas/src/lib/engines/common/evas_font_default_walk.x @@ -3,190 +3,163 @@ /* Macros for text walking */ /** - * @def EVAS_FONT_UPDATE_KERN() + * @def EVAS_FONT_WALK_TEXT_INIT * @internal - * This macro updates kern according to kerning. - * This macro assumes the following variables exist: - * intl_props, char_index, fi, kern, index, prev_index + * This macro defines the variables that will later be used with the following + * macros, and by font handling functions. + * @see EVAS_FONT_WALK_TEXT_START + * @see EVAS_FONT_WALK_TEXT_WORK + * @see EVAS_FONT_WALK_TEXT_END */ -#ifdef BIDI_SUPPORT -#define EVAS_FONT_UPDATE_KERN(is_visual) \ - do \ - { \ - /* if it's rtl, the kerning matching should be reversed, */ \ - /* i.e prev index is now the index and the other way */ \ - /* around. There is a slight exception when there are */ \ - /* compositing chars involved.*/ \ - if (intl_props && (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && \ - visible && !is_visual) \ - { \ - if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \ - _pen_x += kern; \ - } \ - else \ - { \ - if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \ - _pen_x += kern; \ - } \ - } \ - while (0) -#else -#define EVAS_FONT_UPDATE_KERN(is_visual) \ - do \ - { \ - (void) is_visual; \ - if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) \ - _pen_x += kern; \ - } \ - while (0) -#endif +# define EVAS_FONT_WALK_TEXT_INIT() \ + int _pen_x = 0, _pen_y = 0; \ + size_t char_index; \ + (void) _pen_y; /* Sometimes it won't be used */ /** - * @def EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START + * @def EVAS_FONT_WALK_TEXT_VISUAL_START * @internal * This runs through the text in visual order while updating char_index, * which is the current index in the text. * Does not end with a ; - * Take a look at EVAS_FONT_WALK_DEFAULT_X_OFF and the like. - * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT - * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK - * @see EVAS_FONT_WALK_DEFAULT_TEXT_END - * @see EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START + * Take a look at EVAS_FONT_WALK_X_OFF and the like. + * @see EVAS_FONT_WALK_TEXT_INIT + * @see EVAS_FONT_WALK_TEXT_WORK + * @see EVAS_FONT_WALK_TEXT_END + * @see EVAS_FONT_WALK_TEXT_LOGICAL_START */ -#define EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() \ +#define EVAS_FONT_WALK_TEXT_VISUAL_START() \ + do \ + { \ + int visible = 1; \ + for (char_index = 0 ; char_index < text_props->len ; char_index++) \ + { + +/** + * @def EVAS_FONT_WALK_TEXT_LOGICAL_START + * @internal + * This runs through the text in logical order while updating char_index, + * which is the current index in the text. + * Does not end with a ; + * Take a look at EVAS_FONT_WALK_X_OFF and the like. + * @see EVAS_FONT_WALK_TEXT_INIT + * @see EVAS_FONT_WALK_TEXT_WORK + * @see EVAS_FONT_WALK_TEXT_END + * @see EVAS_FONT_WALK_TEXT_VISUAL_START + */ +#ifdef BIDI_SUPPORT +#define EVAS_FONT_WALK_TEXT_LOGICAL_START() \ do \ { \ - const Eina_Unicode *_base_text; \ int _char_index_d, _i; \ - int visible; \ - prev_index = 0; \ - _base_text = text; \ - for ( ; *text ; text++); \ - _i = text - _base_text; \ - if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \ + int visible = 1; \ + _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; - -/** - * @def EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START - * @internal - * This runs through the text in logical order while updating char_index, - * which is the current index in the text. - * Does not end with a ; - * Take a look at EVAS_FONT_WALK_DEFAULT_X_OFF and the like. - * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT - * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK - * @see EVAS_FONT_WALK_DEFAULT_TEXT_END - * @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START - */ -#define EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() \ - do \ - { \ - int visible; \ - prev_index = 0; \ - for (char_index = 0 ; *text ; text++, char_index++) \ - { \ - FT_UInt index; \ - RGBA_Font_Glyph *fg; \ - int _gl, kern; \ - _gl = *text; \ - if (_gl == 0) break; + for ( ; _i > 0 ; char_index += _char_index_d, _i--) \ + { +#else +#define EVAS_FONT_WALK_TEXT_LOGICAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START() +#endif /*FIXME: doc */ -#define EVAS_FONT_WALK_DEFAULT_X_OFF (0) -#define EVAS_FONT_WALK_DEFAULT_Y_OFF (0) -#define EVAS_FONT_WALK_DEFAULT_X_BEAR (fg->glyph_out->left) -#define EVAS_FONT_WALK_DEFAULT_Y_BEAR (fg->glyph_out->top) -#define _EVAS_FONT_WALK_DEFAULT_X_ADV (fg->glyph->advance.x >> 10) -#define EVAS_FONT_WALK_DEFAULT_X_ADV \ - (EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_DEFAULT_X_ADV)) -#define EVAS_FONT_WALK_DEFAULT_Y_ADV (0) -#define EVAS_FONT_WALK_DEFAULT_WIDTH (fg->glyph_out->bitmap.width) -#define EVAS_FONT_WALK_DEFAULT_POS (char_index) -#define EVAS_FONT_WALK_DEFAULT_IS_LAST \ - (!text[char_index]) -#define EVAS_FONT_WALK_DEFAULT_IS_FIRST \ +#ifdef OT_SUPPORT +# define EVAS_FONT_WALK_X_OFF \ + ((text_props->info->ot) ? \ + (EVAS_FONT_ROUND_26_6_TO_INT( \ + EVAS_FONT_OT_X_OFF_GET( \ + text_props->info->ot[char_index]))) : \ + (0)) +# define EVAS_FONT_WALK_Y_OFF \ + ((text_props->info->ot) ? \ + (EVAS_FONT_ROUND_26_6_TO_INT( \ + EVAS_FONT_OT_Y_OFF_GET( \ + text_props->info->ot[char_index]))) : \ + (0)) +# define EVAS_FONT_WALK_POS \ + ((text_props->info->ot) ? \ + (EVAS_FONT_OT_POS_GET( \ + text_props->info->ot[char_index])) : \ + (char_index)) +# define EVAS_FONT_WALK_POS_NEXT \ + ((text_props->info->ot) ? \ + ((!EVAS_FONT_WALK_IS_LAST) ? \ + EVAS_FONT_OT_POS_GET( \ + text_props->info->ot[char_index + 1]) : \ + EVAS_FONT_WALK_POS \ + ) : \ + ((!EVAS_FONT_WALK_IS_LAST) ? \ + (char_index + 1) : EVAS_FONT_WALK_POS)) +# define EVAS_FONT_WALK_POS_PREV \ + ((text_props->info->ot) ? \ + ((char_index > 0) ? \ + EVAS_FONT_OT_POS_GET( \ + text_props->info->ot[char_index - 1]) : \ + EVAS_FONT_WALK_POS \ + ) : \ + ((char_index > 0) ? \ + (char_index - 1) : EVAS_FONT_WALK_POS)) +#else +# define EVAS_FONT_WALK_X_OFF 0 +# define EVAS_FONT_WALK_Y_OFF 0 +# define EVAS_FONT_WALK_POS (char_index) +# define EVAS_FONT_WALK_POS_NEXT \ + ((!EVAS_FONT_WALK_IS_LAST) ? \ + (char_index + 1) : EVAS_FONT_WALK_POS) +# define EVAS_FONT_WALK_POS_PREV \ + ((char_index > 0) ? \ + (char_index - 1) : EVAS_FONT_WALK_POS) +#endif + +#define EVAS_FONT_WALK_X_BEAR (text_props->info->glyph[char_index].x_bear) +#define EVAS_FONT_WALK_Y_BEAR (fg->glyph_out->top) +#define _EVAS_FONT_WALK_X_ADV \ + (text_props->info->glyph[char_index].advance) +#define EVAS_FONT_WALK_WIDTH (text_props->info->glyph[char_index].width) + +#define EVAS_FONT_WALK_X_ADV \ + (EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_X_ADV)) +#define EVAS_FONT_WALK_PEN_X (EVAS_FONT_ROUND_26_6_TO_INT(_pen_x)) +#define EVAS_FONT_WALK_PEN_Y (EVAS_FONT_ROUND_26_6_TO_INT(_pen_y)) +#define EVAS_FONT_WALK_Y_ADV (0) +#define EVAS_FONT_WALK_IS_LAST \ + (char_index + 1 == text_props->len) +#define EVAS_FONT_WALK_IS_FIRST \ (!char_index) -#define EVAS_FONT_WALK_DEFAULT_POS_NEXT \ - ((!EVAS_FONT_WALK_DEFAULT_IS_LAST) ? \ - (char_index + 1) : \ - (char_index) \ - ) -#define EVAS_FONT_WALK_DEFAULT_POS_PREV \ - ((!EVAS_FONT_WALK_DEFAULT_IS_FIRST) ? \ - (char_index - 1) : \ - EVAS_FONT_WALK_DEFAULT_POS \ - ) -#define EVAS_FONT_WALK_DEFAULT_LEN (EVAS_FONT_WALK_ORIG_LEN) -/** - * @def EVAS_FONT_WALK_DEFAULT_TEXT_WORK - * @internal - * This macro actually updates the values mentioned in EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START - * according to the current positing in the walk. - * @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START - * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT - * @see EVAS_FONT_WALK_DEFAULT_TEXT_END - */ -#define EVAS_FONT_WALK_DEFAULT_TEXT_WORK(is_visual) \ - index = evas_common_font_glyph_search(fn, &fi, _gl); \ - LKL(fi->ft_mutex); \ - fg = evas_common_font_int_cache_glyph_get(fi, index); \ - if (!fg) \ - { \ - LKU(fi->ft_mutex); \ - continue; \ - } \ - kern = 0; \ - if (EVAS_FONT_CHARACTER_IS_INVISIBLE(_gl)) \ - { \ - visible = 0; \ - } \ - else \ - { \ - visible = 1; \ - } \ - /* hmmm kerning means i can't sanely do my own cached metric */ \ - /* tables! grrr - this means font face sharing is kinda... not */ \ - /* an option if you want performance */ \ - if ((use_kerning) && (prev_index) && (index) && \ - (pface == fi->src->ft.face)) \ - { \ - EVAS_FONT_UPDATE_KERN(is_visual); \ - } \ - \ - pface = fi->src->ft.face; \ - LKU(fi->ft_mutex); \ +#define EVAS_FONT_WALK_LEN (text_props->len) /** - * @def EVAS_FONT_WALK_DEFAULT_TEXT_END + * @def EVAS_FONT_WALK_TEXT_WORK * @internal - * Closes EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START, needs to end with a ; - * @see EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START - * @see EVAS_FONT_WALK_DEFAULT_TEXT_INIT - * @see EVAS_FONT_WALK_DEFAULT_TEXT_WORK + * This macro actually updates the values mentioned in EVAS_FONT_WALK_TEXT_VISUAL_START + * according to the current positing in the walk. + * @see EVAS_FONT_WALK_TEXT_VISUAL_START + * @see EVAS_FONT_WALK_TEXT_INIT + * @see EVAS_FONT_WALK_TEXT_END */ -#define EVAS_FONT_WALK_DEFAULT_TEXT_END() \ +#define EVAS_FONT_WALK_TEXT_WORK() do {} while(0); + +/** + * @def EVAS_FONT_WALK_TEXT_END + * @internal + * Closes EVAS_FONT_WALK_TEXT_VISUAL_START, needs to end with a ; + * @see EVAS_FONT_WALK_TEXT_VISUAL_START + * @see EVAS_FONT_WALK_TEXT_INIT + * @see EVAS_FONT_WALK_TEXT_WORK + */ +#define EVAS_FONT_WALK_TEXT_END() \ if (visible) \ { \ - _pen_x += _EVAS_FONT_WALK_DEFAULT_X_ADV; \ + _pen_x += _EVAS_FONT_WALK_X_ADV; \ } \ - prev_index = index; \ } \ } \ while(0) diff --git a/legacy/evas/src/lib/engines/common/evas_font_draw.c b/legacy/evas/src/lib/engines/common/evas_font_draw.c index fde3c12589..9e8cc5c6bb 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_draw.c +++ b/legacy/evas/src/lib/engines/common/evas_font_draw.c @@ -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; -#ifdef OT_SUPPORT - if (evas_common_font_ot_is_enabled() && intl_props->ot_data) + /* Load the glyph according to the first letter of the script, preety + * bad, but will have to do */ { - EVAS_FONT_WALK_OT_TEXT_VISUAL_START() + /* Skip common chars */ + const Eina_Unicode *tmp; + for (tmp = text ; + *tmp && + evas_common_language_char_script_get(*tmp) == + EVAS_SCRIPT_COMMON ; + tmp++) + ; + if (!*tmp && (tmp > text)) tmp--; + evas_common_font_glyph_search(fn, &fi, *tmp); + } + EVAS_FONT_WALK_TEXT_VISUAL_START() + { + FT_UInt index; + RGBA_Font_Glyph *fg; + int chr_x, chr_y, chr_w; + + index = text_props->info->glyph[char_index].index; + LKL(fi->ft_mutex); + fg = evas_common_font_int_cache_glyph_get(fi, index); + if (!fg) { - int chr_x, chr_y, chr_w; + LKU(fi->ft_mutex); + continue; + } + if (EVAS_FONT_CHARACTER_IS_INVISIBLE(text[EVAS_FONT_WALK_POS])) + { + visible = 0; + } + else + { + visible = 1; + } - EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); + pface = fi->src->ft.face; + LKU(fi->ft_mutex); - if (dc->font_ext.func.gl_new) + 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) + ) + */ { - /* 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 ((j > 0) && (chr_x + w > ext_x)) + if ((fg->ext_dat) && (dc->font_ext.func.gl_draw)) { - 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)) { - /* 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++) { - for (i = 0; i < h; i++) - { - int dx, dy; - int in_x, in_w; + int dx, dy; + int in_x, in_w; - 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 + { + 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; @@ -930,14 +814,14 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con /* It's a bit hackish to use index and fg here as they are internal, * but that'll have to be good enough ATM */ #ifdef OT_SUPPORT - if (evas_common_font_ot_is_enabled() && intl_props->ot_data) + if (evas_common_font_ot_is_enabled()) { - len = intl_props->ot_data->len; + len = text_props->info->ot_data->len; metrics = malloc(sizeof(struct cinfo) * len); - EVAS_FONT_WALK_OT_TEXT_VISUAL_START() + EVAS_FONT_WALK_TEXT_VISUAL_START() { struct cinfo *ci = metrics + char_index; - EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); + EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE); /* Currently broken with invisible chars if (!visible) continue; */ ci->index = index; ci->fg = fg; @@ -958,19 +842,19 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con if (above > baseline) baseline = above; ci->pos.x = EVAS_FONT_WALK_PEN_X + ci->fg->glyph_out->left; ci->pos.y = EVAS_FONT_WALK_PEN_Y + ci->fg->glyph_out->top; - last_delta = EVAS_FONT_WALK_OT_X_ADV - + last_delta = EVAS_FONT_WALK_X_ADV - (ci->bm.w + ci->fg->glyph_out->left); } - EVAS_FONT_WALK_OT_TEXT_END(); + EVAS_FONT_WALK_TEXT_END(); } else #endif { metrics = malloc(sizeof(struct cinfo) * len); - EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() + EVAS_FONT_WALK_TEXT_LOGICAL_START() { struct cinfo *ci = metrics + char_index; - EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE); + EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE); /* Currently broken with invisible chars if (!visible) continue; */ ci->index = index; ci->fg = fg; @@ -991,10 +875,10 @@ evas_font_word_prerender(RGBA_Draw_Context *dc, const Eina_Unicode *in_text, con if (above > baseline) baseline = above; ci->pos.x = EVAS_FONT_WALK_PEN_X + ci->fg->glyph_out->left; ci->pos.y = EVAS_FONT_WALK_PEN_Y + ci->fg->glyph_out->top; - last_delta = EVAS_FONT_WALK_DEFAULT_X_ADV - + last_delta = EVAS_FONT_WALK_X_ADV - (ci->bm.w + ci->fg->glyph_out->left); } - EVAS_FONT_WALK_DEFAULT_TEXT_END(); + EVAS_FONT_WALK_TEXT_END(); } /* First loop done */ diff --git a/legacy/evas/src/lib/engines/common/evas_font_glyph_info.c b/legacy/evas/src/lib/engines/common/evas_font_glyph_info.c new file mode 100644 index 0000000000..a2e9911c1d --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_font_glyph_info.c @@ -0,0 +1,166 @@ +#include "evas_common.h" +#include "evas_font_private.h" /* for Frame-Queuing support */ +#include "evas_font_ot.h" +#include "evas_font_glyph_info.h" + +EAPI Eina_Bool +evas_common_font_glyph_info_create(void *_fn, const Eina_Unicode *text, + Evas_Text_Props *text_props, int len) +{ + RGBA_Font *fn = (RGBA_Font *) _fn; + RGBA_Font_Int *fi; + size_t char_index; + + if (text_props->info) + { + evas_common_text_props_content_unref(text_props); + } + text_props->info = calloc(1, sizeof(Evas_Text_Props_Info)); + + fi = fn->fonts->data; + /* evas_common_font_size_use(fn); */ + evas_common_font_int_reload(fi); + if (fi->src->current_size != fi->size) + { + FTLOCK(); + FT_Activate_Size(fi->ft.size); + FTUNLOCK(); + fi->src->current_size = fi->size; + } + +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled()) + { + evas_common_font_ot_populate_text_props(fn, text, text_props, len); + + /* Load the glyph according to the first letter of the script, preety + * bad, but will have to do */ + { + /* Skip common chars */ + const Eina_Unicode *tmp; + for (tmp = text ; + *tmp && + evas_common_language_char_script_get(*tmp) == + EVAS_SCRIPT_COMMON ; + tmp++) + ; + if (!*tmp && (tmp > text)) tmp--; + evas_common_font_glyph_search(fn, &fi, *tmp); + } + + for (char_index = 0 ; char_index < text_props->len ; char_index++) + { + FT_UInt index; + RGBA_Font_Glyph *fg; + index = text_props->info->glyph[char_index].index; + LKL(fi->ft_mutex); + fg = evas_common_font_int_cache_glyph_get(fi, index); + if (!fg) + { + LKU(fi->ft_mutex); + continue; + } + LKU(fi->ft_mutex); + text_props->info->glyph[char_index].x_bear = + fg->glyph_out->left; + text_props->info->glyph[char_index].width = + fg->glyph_out->bitmap.width; + /* text_props->info->glyph[char_index].advance = + * text_props->info->glyph[char_index].index = + * already done by the ot function */ + + /* FIXME add visible handling */ + } + } + else +#endif + { + /* We are walking the string in visual ordering */ + Eina_Bool use_kerning; + FT_UInt prev_index; + FT_Face pface = NULL; + int adv_d, i; + FTLOCK(); + use_kerning = FT_HAS_KERNING(fi->src->ft.face); + FTUNLOCK(); + prev_index = 0; + + i = len; + text_props->info->glyph = calloc(len, + sizeof(Evas_Font_Glyph_Info)); + + if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + { + text += len - 1; + adv_d = -1; + } + else + { + adv_d = 1; + } + char_index = 0; + for ( ; i > 0 ; char_index++, text += adv_d, i--) + { + FT_UInt index; + RGBA_Font_Glyph *fg; + int _gl, kern; + _gl = *text; + if (_gl == 0) break; + + index = evas_common_font_glyph_search(fn, &fi, _gl); + LKL(fi->ft_mutex); + fg = evas_common_font_int_cache_glyph_get(fi, index); + if (!fg) + { + LKU(fi->ft_mutex); + continue; + } + kern = 0; + + if ((use_kerning) && (prev_index) && (index) && + (pface == fi->src->ft.face)) + { +#ifdef BIDI_SUPPORT + /* if it's rtl, the kerning matching should be reversed, */ + /* i.e prev index is now the index and the other way */ + /* around. There is a slight exception when there are */ + /* compositing chars involved.*/ + if (text_props && + (text_props->bidi.dir != EVAS_BIDI_DIRECTION_RTL)) + { + if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) + { + text_props->info->glyph[char_index - 1].advance += + kern; + } + } + else +#endif + { + if (evas_common_font_query_kerning(fi, prev_index, index, &kern)) + { + text_props->info->glyph[char_index - 1].advance += + kern; + } + } + } + + pface = fi->src->ft.face; + LKU(fi->ft_mutex); + + text_props->info->glyph[char_index].index = index; + text_props->info->glyph[char_index].x_bear = + fg->glyph_out->left; + text_props->info->glyph[char_index].advance = + fg->glyph->advance.x >> 10; + text_props->info->glyph[char_index].width = + fg->glyph_out->bitmap.width; + + prev_index = index; + } + text_props->len = len; + } + text_props->info->refcount = 1; + return EINA_TRUE; +} + diff --git a/legacy/evas/src/lib/engines/common/evas_font_glyph_info.h b/legacy/evas/src/lib/engines/common/evas_font_glyph_info.h new file mode 100644 index 0000000000..2bbbf34593 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_font_glyph_info.h @@ -0,0 +1,25 @@ +#ifndef _EVAS_FONT_METRICS_H +# define _EVAS_FONT_METRICS_H +/* Sorted in visual order when created */ +struct _Evas_Font_Glyph_Info +{ + unsigned int index; /* Should conform to FT */ + Evas_Coord x_bear; +#if 0 + /* This one is rarely used, only in draw, in which we already get the glyph + * so it doesn't really save time. Leaving it here just so no one will + * add it thinking it was accidentally skipped */ + Evas_Coord y_bear; +#endif + Evas_Coord width; + Evas_Coord advance; +}; + +typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info; + +EAPI Eina_Bool +evas_common_font_glyph_info_create(void *_fn, const Eina_Unicode *text, + Evas_Text_Props *text_props, int len); + +#endif + diff --git a/legacy/evas/src/lib/engines/common/evas_font_ot.c b/legacy/evas/src/lib/engines/common/evas_font_ot.c index 477a861b8c..b0d1f0dd80 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_ot.c +++ b/legacy/evas/src/lib/engines/common/evas_font_ot.c @@ -34,21 +34,22 @@ evas_common_font_ot_is_enabled(void) #ifdef OT_SUPPORT /* FIXME: doc. returns #items */ EAPI int -evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index, int orig_len) +evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index) { int i; int items; int left_bound, right_bound; - size_t base_cluster = EVAS_FONT_OT_POS_GET(props->ot_data->items[char_index]); + char_index += props->start; + size_t base_cluster = EVAS_FONT_OT_POS_GET(props->info->ot[char_index]); for (i = (int) char_index ; - (i >= 0) && - (EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ; + (i >= (int) props->start) && + (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ; i--) ; left_bound = i; for (i = (int) char_index + 1; - (i < (int) props->ot_data->len) && - (EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ; + (i < (int) (props->start + props->len)) && + (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ; i++) ; right_bound = i; @@ -60,26 +61,26 @@ evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_i { if (left_bound < 0) { - items = orig_len - - props->ot_data->items[left_bound + 1].source_cluster; + items = props->start + props->len - + props->info->ot[left_bound + 1].source_cluster; } else { - items = props->ot_data->items[left_bound].source_cluster - - props->ot_data->items[left_bound + 1].source_cluster; + items = props->info->ot[left_bound].source_cluster - + props->info->ot[left_bound + 1].source_cluster; } } else { - if (right_bound == (int) props->ot_data->len) + if (right_bound == (int) props->len) { - items = orig_len - - props->ot_data->items[right_bound - 1].source_cluster; + items = props->start + props->len - + props->info->ot[right_bound - 1].source_cluster; } else { - items = props->ot_data->items[right_bound].source_cluster - - props->ot_data->items[right_bound - 1].source_cluster; + items = props->info->ot[right_bound].source_cluster - + props->info->ot[right_bound - 1].source_cluster; } } return (items > 0) ? items : 1; @@ -114,152 +115,6 @@ _evas_common_font_ot_shape(hb_buffer_t *buffer, RGBA_Font_Source *src) hb_font_destroy(hb_font); } -/* Won't work in the middle of ligatures */ -EAPI void -evas_common_font_ot_cutoff_text_props(Evas_Text_Props *props, int cutoff) -{ - Evas_Font_OT_Data *new_data; - if ((cutoff <= 0) || (!props->ot_data) || - (((size_t) cutoff) >= props->ot_data->len)) - return; - - new_data = malloc(sizeof(Evas_Font_OT_Data)); - memcpy(new_data, props->ot_data, sizeof(Evas_Font_OT_Data)); - new_data->refcount = 1; - new_data->len = cutoff; - new_data->items = malloc(cutoff * sizeof(Evas_Font_OT_Data_Item)); - - if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) - { - memcpy(new_data->items, - props->ot_data->items + (props->ot_data->len - cutoff), - cutoff * sizeof(Evas_Font_OT_Data_Item)); - } - else - { - memcpy(new_data->items, - props->ot_data->items, - cutoff * sizeof(Evas_Font_OT_Data_Item)); - } - - evas_common_font_ot_props_unref(props->ot_data); - props->ot_data = new_data; -} - -/* Won't work in the middle of ligatures - * aissumes ext doesn't have an already init ot_data - * we assume there's at least one char in each part */ -EAPI void -evas_common_font_ot_split_text_props(Evas_Text_Props *base, - Evas_Text_Props *ext, int cutoff) -{ - Evas_Font_OT_Data *new_data; - int i; - if ((cutoff <= 0) || (!base->ot_data) || - (((size_t) cutoff) >= base->ot_data->len)) - return; - - ext->ot_data = calloc(1, sizeof(Evas_Font_OT_Data)); - ext->ot_data->refcount = 1; - ext->ot_data->len = base->ot_data->len - cutoff; - ext->ot_data->items = calloc(ext->ot_data->len, - sizeof(Evas_Font_OT_Data_Item)); - - new_data = malloc(sizeof(Evas_Font_OT_Data)); - memcpy(new_data, base->ot_data, sizeof(Evas_Font_OT_Data)); - new_data->refcount = 1; - new_data->items = malloc(cutoff * sizeof(Evas_Font_OT_Data_Item)); - new_data->len = cutoff; - - if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL) - { - memcpy(ext->ot_data->items, base->ot_data->items, - ext->ot_data->len * sizeof(Evas_Font_OT_Data_Item)); - memcpy(new_data->items, - base->ot_data->items + ext->ot_data->len, - cutoff * sizeof(Evas_Font_OT_Data_Item)); - } - else - { - memcpy(ext->ot_data->items, base->ot_data->items + cutoff, - ext->ot_data->len * sizeof(Evas_Font_OT_Data_Item)); - memcpy(new_data->items, base->ot_data->items, - cutoff * sizeof(Evas_Font_OT_Data_Item)); - } - evas_common_font_ot_props_unref(base->ot_data); - base->ot_data = new_data; - - /* Adjust the offset of the clusters */ - { - size_t min; - min = ext->ot_data->items[0].source_cluster; - for (i = 1 ; i < (int) ext->ot_data->len ; i++) - { - if (ext->ot_data->items[i].source_cluster < min) - { - min = ext->ot_data->items[i].source_cluster; - } - } - for (i = 0 ; i < (int) ext->ot_data->len ; i++) - { - ext->ot_data->items[i].source_cluster -= min; - } - ext->ot_data->offset = base->ot_data->offset + min; - } -} - -/* Won't work in the middle of ligatures - * assumes both are init correctly and that both are from the - * same origin item, i.e both have the same script + direction. - * assume item1 is logically first */ -EAPI void -evas_common_font_ot_merge_text_props(Evas_Text_Props *item1, - const Evas_Text_Props *item2) -{ - Evas_Font_OT_Data *new_data; - Evas_Font_OT_Data_Item *itr; /* Itr will be used for adding back - the offsets */ - size_t len; - if (!item1->ot_data || !item2->ot_data) - return; - len = item1->ot_data->len + item2->ot_data->len; - - new_data = malloc(sizeof(Evas_Font_OT_Data)); - memcpy(new_data, item1->ot_data, sizeof(Evas_Font_OT_Data)); - new_data->refcount = 1; - new_data->items = malloc(len * sizeof(Evas_Font_OT_Data_Item)); - new_data->len = len; - if (item1->bidi.dir == EVAS_BIDI_DIRECTION_RTL) - { - memcpy(new_data->items, item2->ot_data->items, - item2->ot_data->len * sizeof(Evas_Font_OT_Data_Item)); - memcpy(new_data->items + item2->ot_data->len, item1->ot_data->items, - item1->ot_data->len * sizeof(Evas_Font_OT_Data_Item)); - itr = new_data->items; - } - else - { - memcpy(new_data->items, item1->ot_data->items, - item1->ot_data->len * sizeof(Evas_Font_OT_Data_Item)); - memcpy(new_data->items + item1->ot_data->len, item2->ot_data->items, - item2->ot_data->len * sizeof(Evas_Font_OT_Data_Item)); - itr = new_data->items + item1->ot_data->len; - } - evas_common_font_ot_props_unref(item1->ot_data); - item1->ot_data = new_data; - /* Add back the offset of item2 to the newly created */ - if (item2->ot_data->offset > 0) - { - int i; - for (i = 0 ; i < (int) item2->ot_data->len ; i++, itr++) - { - /* This must be > 0, just because this is how it works */ - itr->source_cluster += item2->ot_data->offset - - item1->ot_data->offset; - } - } -} - EAPI Eina_Bool evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text, Evas_Text_Props *props, int len) @@ -272,12 +127,6 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text, int slen; unsigned int i; if (!evas_common_font_ot_is_enabled()) return EINA_TRUE; - if (props->ot_data) - { - evas_common_font_ot_props_unref(props->ot_data); - } - props->ot_data = calloc(1, sizeof(Evas_Font_OT_Data)); - props->ot_data->refcount = 1; fi = fn->fonts->data; /* Load the font needed for this script */ @@ -323,18 +172,20 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text, _evas_common_font_ot_shape(buffer, fi->src); - props->ot_data->len = hb_buffer_get_length(buffer); - props->ot_data->items = calloc(props->ot_data->len, - sizeof(Evas_Font_OT_Data_Item)); + props->len = hb_buffer_get_length(buffer); + props->info->ot = calloc(props->len, + sizeof(Evas_Font_OT_Info)); + props->info->glyph = calloc(props->len, + sizeof(Evas_Font_Glyph_Info)); positions = hb_buffer_get_glyph_positions(buffer); infos = hb_buffer_get_glyph_infos(buffer); - for (i = 0 ; i < props->ot_data->len ; i++) + for (i = 0 ; i < props->len ; i++) { - props->ot_data->items[i].index = infos[i].codepoint; - props->ot_data->items[i].source_cluster = infos[i].cluster; - props->ot_data->items[i].x_advance = positions[i].x_advance; - props->ot_data->items[i].x_offset = positions[i].x_offset; - props->ot_data->items[i].y_offset = positions[i].y_offset; + props->info->ot[i].source_cluster = infos[i].cluster; + props->info->ot[i].x_offset = positions[i].x_offset; + props->info->ot[i].y_offset = positions[i].y_offset; + props->info->glyph[i].index = infos[i].codepoint; + props->info->glyph[i].advance = positions[i].x_advance; } hb_buffer_destroy(buffer); @@ -343,23 +194,5 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text, return EINA_FALSE; } -EAPI void -evas_common_font_ot_props_ref(Evas_Font_OT_Data *data) -{ - data->refcount++; -} - -EAPI void -evas_common_font_ot_props_unref(Evas_Font_OT_Data *data) -{ - OTLOCK(); - if (--data->refcount == 0) - { - if (data->items) - free(data->items); - free(data); - } - OTUNLOCK(); -} #endif diff --git a/legacy/evas/src/lib/engines/common/evas_font_ot.h b/legacy/evas/src/lib/engines/common/evas_font_ot.h index 01c0ad1399..66ed10d6ba 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_ot.h +++ b/legacy/evas/src/lib/engines/common/evas_font_ot.h @@ -12,58 +12,31 @@ # ifdef OT_SUPPORT # include -typedef struct _Evas_Font_OT_Data Evas_Font_OT_Data; -typedef struct _Evas_Font_OT_Data_Item Evas_Font_OT_Data_Item; -struct _Evas_Font_OT_Data -{ - int refcount; - size_t len; - Evas_Font_OT_Data_Item *items; - size_t offset; /* The offset from the start of the script segment, - this is useful when it's a split item */ -}; +typedef struct _Evas_Font_OT_Info Evas_Font_OT_Info; # else -typedef void *Evas_Font_OT_Data; +typedef void *Evas_Font_OT_Info; # endif # include "Evas.h" # ifdef OT_SUPPORT -struct _Evas_Font_OT_Data_Item +struct _Evas_Font_OT_Info { - unsigned int index; /* Should conform to FT */ size_t source_cluster; Evas_Coord x_offset; Evas_Coord y_offset; - Evas_Coord x_advance; }; # endif # ifdef OT_SUPPORT # define EVAS_FONT_OT_X_OFF_GET(a) ((a).x_offset) # define EVAS_FONT_OT_Y_OFF_GET(a) ((a).y_offset) -# define EVAS_FONT_OT_X_ADV_GET(a) ((a).x_advance) -//# define EVAS_FONT_OT_Y_ADV_GET(a) ((a).y_advance) -# define EVAS_FONT_OT_INDEX_GET(a) ((a).index) # define EVAS_FONT_OT_POS_GET(a) ((a).source_cluster) -# else -# define EVAS_FONT_OT_X_OFF_GET(a) (0) -# define EVAS_FONT_OT_Y_OFF_GET(a) (0) -# define EVAS_FONT_OT_X_ADV_GET(a) (0) -//# define EVAS_FONT_OT_POS_Y_ADV_GET(a) (0) -# define EVAS_FONT_OT_INDEX_GET(a) (0) /* FIXME!!! */ -# define EVAS_FONT_OT_POS_GET(a) (0) /* FIXME!!! */ # endif EAPI Eina_Bool evas_common_font_ot_is_enabled(void); -EAPI void -evas_common_font_ot_props_ref(Evas_Font_OT_Data *data); - -EAPI void -evas_common_font_ot_props_unref(Evas_Font_OT_Data *data); - EAPI void evas_common_font_ot_load_face(void *_font); @@ -72,7 +45,7 @@ evas_common_font_ot_unload_face(void *_font); # include "evas_text_utils.h" EAPI int -evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index, int orig_len); +evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index); EAPI Eina_Bool evas_common_font_ot_populate_text_props(void *fn, const Eina_Unicode *text, diff --git a/legacy/evas/src/lib/engines/common/evas_font_ot_walk.x b/legacy/evas/src/lib/engines/common/evas_font_ot_walk.x index 9c8c7df757..971fb1164e 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_ot_walk.x +++ b/legacy/evas/src/lib/engines/common/evas_font_ot_walk.x @@ -36,7 +36,7 @@ if (!*tmp && (tmp > text)) tmp--; \ evas_common_font_glyph_search(fn, &fi, *tmp); \ } \ - for (char_index = 0 ; char_index < intl_props->ot_data->len ; char_index++) \ + for (char_index = 0 ; char_index < intl_props->len ; char_index++) \ { \ FT_UInt index; \ RGBA_Font_Glyph *fg; \ @@ -72,10 +72,10 @@ evas_common_font_glyph_search(fn, &fi, *tmp); \ } \ prev_index = 0; \ - _i = intl_props->ot_data->len; \ + _i = intl_props->len; \ if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \ { \ - char_index = intl_props->ot_data->len - 1; \ + char_index = intl_props->len - 1; \ _char_index_d = -1; \ } \ else \ @@ -92,39 +92,39 @@ #define EVAS_FONT_WALK_OT_X_OFF \ (EVAS_FONT_ROUND_26_6_TO_INT( \ EVAS_FONT_OT_X_OFF_GET( \ - intl_props->ot_data->items[char_index]))) + intl_props->info->ot[char_index]))) #define EVAS_FONT_WALK_OT_Y_OFF \ (EVAS_FONT_ROUND_26_6_TO_INT( \ EVAS_FONT_OT_Y_OFF_GET( \ - intl_props->ot_data->items[char_index]))) -#define EVAS_FONT_WALK_OT_X_BEAR (fg->glyph_out->left) + intl_props->info->ot[char_index]))) +#define EVAS_FONT_WALK_OT_X_BEAR (intl_props->info->glyph[char_index].x_bear) #define EVAS_FONT_WALK_OT_Y_BEAR (fg->glyph_out->top) #define _EVAS_FONT_WALK_OT_X_ADV \ - (EVAS_FONT_OT_X_ADV_GET( \ - intl_props->ot_data->items[char_index])) + (intl_props->info->glyph[char_index].advance) #define EVAS_FONT_WALK_OT_X_ADV \ - (EVAS_FONT_ROUND_26_6_TO_INT(_EVAS_FONT_WALK_OT_X_ADV)) -#define EVAS_FONT_WALK_OT_WIDTH (fg->glyph_out->bitmap.width) + (EVAS_FONT_ROUND_26_6_TO_INT( \ + _EVAS_FONT_WALK_OT_X_ADV)) +#define EVAS_FONT_WALK_OT_WIDTH (intl_props->info->glyph[char_index].width) #define EVAS_FONT_WALK_OT_POS \ (EVAS_FONT_OT_POS_GET( \ - intl_props->ot_data->items[char_index])) + intl_props->info->ot[char_index])) #define EVAS_FONT_WALK_OT_IS_LAST \ - (char_index + 1 == intl_props->ot_data->len) + (char_index + 1 == intl_props->len) #define EVAS_FONT_WALK_OT_IS_FIRST \ (!char_index) #define EVAS_FONT_WALK_OT_POS_NEXT \ ((!EVAS_FONT_WALK_OT_IS_LAST) ? \ EVAS_FONT_OT_POS_GET( \ - intl_props->ot_data->items[char_index + 1]) : \ + intl_props->info->ot[char_index + 1]) : \ EVAS_FONT_WALK_OT_POS \ ) #define EVAS_FONT_WALK_OT_POS_PREV \ ((char_index > 0) ? \ EVAS_FONT_OT_POS_GET( \ - intl_props->ot_data->items[char_index - 1]) : \ + intl_props->info->ot[char_index - 1]) : \ EVAS_FONT_WALK_OT_POS \ ) -#define EVAS_FONT_WALK_OT_LEN (intl_props->ot_data->len) +#define EVAS_FONT_WALK_OT_LEN (intl_props->len) /** * @def EVAS_FONT_WALK_OT_TEXT_WORK * @internal @@ -135,7 +135,7 @@ * @see EVAS_FONT_WALK_OT_TEXT_END */ #define EVAS_FONT_WALK_OT_TEXT_WORK(is_visual) \ - index = EVAS_FONT_OT_INDEX_GET(intl_props->ot_data->items[char_index]); \ + index = intl_props->info->glyph[char_index].index; \ LKL(fi->ft_mutex); \ fg = evas_common_font_int_cache_glyph_get(fi, index); \ if (!fg) \ diff --git a/legacy/evas/src/lib/engines/common/evas_font_private.h b/legacy/evas/src/lib/engines/common/evas_font_private.h index 0964359483..c85e215348 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_private.h +++ b/legacy/evas/src/lib/engines/common/evas_font_private.h @@ -54,26 +54,4 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi); # endif # include "evas_font_default_walk.x" - -/** - * @def EVAS_FONT_WALK_TEXT_INIT - * @internal - * This macro defines the variables that will later be used with the following - * macros, and by font handling functions. - * @see EVAS_FONT_WALK_TEXT_START - * @see EVAS_FONT_WALK_TEXT_WORK - * @see EVAS_FONT_WALK_TEXT_END - */ -# define EVAS_FONT_WALK_TEXT_INIT() \ - int _pen_x = 0, _pen_y = 0; \ - size_t char_index; \ - FT_UInt prev_index; \ - FT_Face pface = NULL; \ - int _len = eina_unicode_strlen(text); \ - (void) _len; /* We don't have to use it */ \ - (void) _pen_y; /* Sometimes it won't be used */ - -# define EVAS_FONT_WALK_PEN_X (EVAS_FONT_ROUND_26_6_TO_INT(_pen_x)) -# define EVAS_FONT_WALK_PEN_Y (EVAS_FONT_ROUND_26_6_TO_INT(_pen_y)) - #endif /* !_EVAS_FONT_PRIVATE_H */ diff --git a/legacy/evas/src/lib/engines/common/evas_font_query.c b/legacy/evas/src/lib/engines/common/evas_font_query.c index d21340c22d..0f2199287e 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_query.c +++ b/legacy/evas/src/lib/engines/common/evas_font_query.c @@ -1,6 +1,7 @@ #include "evas_common.h" #include "language/evas_bidi_utils.h" /*defines BIDI_SUPPORT if possible */ #include "evas_font_private.h" /* for Frame-Queuing support */ +#include "evas_font_ot.h" EAPI int evas_common_font_query_kerning(RGBA_Font_Int* fi, @@ -104,132 +105,62 @@ evas_common_font_query_inset(RGBA_Font *fn, const Eina_Unicode *text) return fg->glyph_out->left; } -/** - * @def _INIT_FI_AND_KERNINNG() - * @internal - * This macro inits fi and use_kerning. - * Assumes the following variables exist: - * fi, fn and use_kerning. - */ -#define _INIT_FI_AND_KERNING() \ - do \ - { \ - fi = fn->fonts->data; \ - /* evas_common_font_size_use(fn); */ \ - evas_common_font_int_reload(fi); \ - if (fi->src->current_size != fi->size) \ - { \ - FTLOCK(); \ - FT_Activate_Size(fi->ft.size); \ - FTUNLOCK(); \ - fi->src->current_size = fi->size; \ - } \ - FTLOCK(); \ - use_kerning = FT_HAS_KERNING(fi->src->ft.face); \ - FTUNLOCK(); \ - } \ - while (0) - /* size of the string (width and height) in pixels - * BiDi handling: We receive the shaped string + other props from intl_props, + * BiDi handling: We receive the shaped string + other props from text_props, * We only care about the size, and the size does not depend on the visual order. * As long as we follow the logical string and get kerning data like we should, * we are fine. */ EAPI void -evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_props __UNUSED__, int *w, int *h) +evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *text_props __UNUSED__, int *w, int *h) { int keep_width = 0; int prev_pen_x = 0; - int use_kerning; - RGBA_Font_Int *fi; EVAS_FONT_WALK_TEXT_INIT(); - _INIT_FI_AND_KERNING(); -#ifdef OT_SUPPORT - if (evas_common_font_ot_is_enabled() && intl_props->ot_data) + EVAS_FONT_WALK_TEXT_VISUAL_START() { - EVAS_FONT_WALK_OT_TEXT_VISUAL_START() - { - EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); - 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 (!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, 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 (!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 *in_text, const Evas_Text_Props *text_props, int pos, int *cx, int *cy, int *cw, int *ch) { int asc, desc; int position = 0; - const Eina_Unicode *text = in_text; int ret_val = 0; - int use_kerning; - RGBA_Font_Int *fi; EVAS_FONT_WALK_TEXT_INIT(); - _INIT_FI_AND_KERNING(); asc = evas_common_font_max_ascent_get(fn); desc = evas_common_font_max_descent_get(fn); position = pos; /* If it's the null, choose location according to the direction. */ - if (!text[position]) + if (text_props->len == position) { /* if it's rtl then the location is the left of the string, * otherwise, the right. */ #ifdef BIDI_SUPPORT - if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) { if (cx) *cx = 0; if (ch) *ch = asc + desc; @@ -267,7 +194,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c else #endif { - evas_common_font_query_advance(fn, in_text, intl_props, cx, ch); + evas_common_font_query_advance(fn, in_text, text_props, cx, ch); } if (cy) *cy = 0; if (cw) *cw = 0; @@ -275,122 +202,95 @@ 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 = 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 (evas_common_font_ot_is_enabled()) { - if (found) - { - break; - } - else - { - cluster_start = EVAS_FONT_WALK_PEN_X + - EVAS_FONT_WALK_OT_X_OFF + - EVAS_FONT_WALK_OT_X_BEAR; - } + items = evas_common_font_ot_cluster_size_get(text_props, + char_index); } - 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 #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 + if (evas_common_font_ot_is_enabled()) + { + items = evas_common_font_ot_cluster_size_get(text_props, + char_index); + } +#endif + item_pos = items - (position - EVAS_FONT_WALK_POS); + } + + prev_cluster = EVAS_FONT_WALK_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 +299,24 @@ end: */ EAPI int -evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch) +evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *text_props, int pos, int *cpen_x, int *cy, int *cadv, int *ch) { int asc, desc; int position = 0; - const Eina_Unicode *text = in_text; int ret_val = 0; - int use_kerning; - RGBA_Font_Int *fi; EVAS_FONT_WALK_TEXT_INIT(); - _INIT_FI_AND_KERNING(); asc = evas_common_font_max_ascent_get(fn); desc = evas_common_font_max_descent_get(fn); position = pos; /* If it's the null, choose location according to the direction. */ - if (!text[position]) + if (text_props->len == position) { /* if it's rtl then the location is the left of the string, * otherwise, the right. */ #ifdef BIDI_SUPPORT - if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) { if (cpen_x) *cpen_x = 0; if (ch) *ch = asc + desc; @@ -428,122 +324,89 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co else #endif { - evas_common_font_query_advance(fn, in_text, intl_props, cpen_x, ch); + evas_common_font_query_advance(fn, in_text, text_props, cpen_x, ch); } if (cy) *cy = 0; if (cadv) *cadv = 0; ret_val = 1; goto end; } -#ifdef OT_SUPPORT - if (evas_common_font_ot_is_enabled() && intl_props->ot_data) + Evas_Coord cluster_start; + int prev_cluster = -1; + int found = 0, items = 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 = visible; - if ((EVAS_FONT_WALK_DEFAULT_POS == (size_t) position)) + 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()) { - 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; + 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 + if (evas_common_font_ot_is_enabled()) + { + items = evas_common_font_ot_cluster_size_get(text_props, + char_index); + } +#endif + item_pos = items - (position - EVAS_FONT_WALK_POS); + } + + prev_cluster = EVAS_FONT_WALK_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 +421,117 @@ end: */ EAPI int -evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *intl_props, int x, int y, int *cx, int *cy, int *cw, int *ch) +evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text, const Evas_Text_Props *text_props, int x, int y, int *cx, int *cy, int *cw, int *ch) { int asc, desc; - const Eina_Unicode *text = in_text; int ret_val = -1; - int use_kerning; - RGBA_Font_Int *fi; EVAS_FONT_WALK_TEXT_INIT(); - _INIT_FI_AND_KERNING(); -#ifndef BIDI_SUPPORT - /* Suppress warnings */ - (void) intl_props; -#endif asc = evas_common_font_max_ascent_get(fn); desc = evas_common_font_max_descent_get(fn); -#ifdef OT_SUPPORT - if (evas_common_font_ot_is_enabled() && intl_props->ot_data) + Evas_Coord cluster_start; + int prev_cluster = -1; + int found = 0, items = 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 (!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)) +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled()) { - 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; + 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 *in_text, const Evas_Text_Props *text_props __UNUSED__, int x, int y) { int asc, desc; int ret=-1; - const Eina_Unicode *text = in_text; - int use_kerning; - RGBA_Font_Int *fi; EVAS_FONT_WALK_TEXT_INIT(); - _INIT_FI_AND_KERNING(); asc = evas_common_font_max_ascent_get(fn); desc = evas_common_font_max_descent_get(fn); -#ifdef OT_SUPPORT - if (evas_common_font_ot_is_enabled() && intl_props->ot_data) + EVAS_FONT_WALK_TEXT_LOGICAL_START() { - EVAS_FONT_WALK_OT_TEXT_LOGICAL_START() - { - EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); - if (!visible) continue; + EVAS_FONT_WALK_TEXT_WORK(); + if (!visible) continue; - if ((x >= EVAS_FONT_WALK_PEN_X) && (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_OT_X_ADV)) && - (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; } diff --git a/legacy/evas/src/lib/engines/common/evas_text_utils.c b/legacy/evas/src/lib/engines/common/evas_text_utils.c index 026796ec7a..15b21b64b2 100644 --- a/legacy/evas/src/lib/engines/common/evas_text_utils.c +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.c @@ -1,3 +1,4 @@ +#include "evas_common.h" #include "evas_text_utils.h" #include "language/evas_bidi_utils.h" #include "language/evas_language_utils.h" @@ -37,39 +38,34 @@ evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst, void evas_common_text_props_content_ref(Evas_Text_Props *props) { -#ifdef OT_SUPPORT - if (props->ot_data) - { - evas_common_font_ot_props_ref(props->ot_data); - } -#endif + props->info->refcount++; } void evas_common_text_props_content_unref(Evas_Text_Props *props) { -#ifdef OT_SUPPORT - if (props->ot_data) - { - evas_common_font_ot_props_unref(props->ot_data); - } -#else - (void) props; -#endif -#ifdef BIDI_SUPPORT - evas_bidi_props_clean(&props->bidi); -#else - (void) props; -#endif -} + /* We allow this, because sometimes we want to have props without info, + * and we don't want to diverge the code paths too much. */ + if (!props->info) + return; -/* Won't work in the middle of ligatures */ -EAPI void -evas_common_text_props_cutoff(Evas_Text_Props *props, int cutoff) -{ + if (props->info->refcount == 0) + { + ERR("Trying to unref props with refount == 0"); + return; + } + + if (--(props->info->refcount) == 0) + { + if (props->info->glyph) + free(props->info->glyph); #ifdef OT_SUPPORT - evas_common_font_ot_cutoff_text_props(props, cutoff); + if (props->info->ot) + free(props->info->ot); #endif + free(props->info); + props->info = NULL; + } } /* Won't work in the middle of ligatures */ @@ -77,12 +73,20 @@ EAPI void evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext, int cutoff) { - /* FIXME: move to their own functions */ - memcpy(&ext->bidi, &base->bidi, sizeof(Evas_BiDi_Props)); - memcpy(&ext->script, &base->script, sizeof(Evas_Script_Type)); -#ifdef OT_SUPPORT - evas_common_font_ot_split_text_props(base, ext, cutoff); -#endif + evas_common_text_props_content_copy_and_ref(ext, base); + if (base->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + { + ext->start = base->start; + base->start = cutoff; + ext->len = cutoff; + base->len = base->len - cutoff; + } + else + { + ext->start = cutoff; + ext->len = base->len - cutoff; + base->len = cutoff; + } } /* Won't work in the middle of ligatures */ @@ -90,9 +94,16 @@ EAPI void evas_common_text_props_merge(Evas_Text_Props *item1, const Evas_Text_Props *item2) { -#ifdef OT_SUPPORT - evas_common_font_ot_merge_text_props(item1, item2); -#endif + if (item1->info != item2->info) + { + ERR("tried merge back items that weren't together in the first place."); + return; + } + if (item1->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + { + item1->start = item2->start; + } + + item1->len += item2->len; } - diff --git a/legacy/evas/src/lib/engines/common/evas_text_utils.h b/legacy/evas/src/lib/engines/common/evas_text_utils.h index ff18a4bef4..c8cfa38a27 100644 --- a/legacy/evas/src/lib/engines/common/evas_text_utils.h +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.h @@ -2,16 +2,29 @@ # define _EVAS_TEXT_UTILS_H typedef struct _Evas_Text_Props Evas_Text_Props; +typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info; # include "evas_font_ot.h" # include "language/evas_bidi_utils.h" # include "language/evas_language_utils.h" +# include "evas_font_glyph_info.h" struct _Evas_Text_Props { + /* Start and len represent the start offset and the length in the + * glyphs_info and ot_data fields, they are both internal */ + size_t start; + size_t len; Evas_BiDi_Props bidi; Evas_Script_Type script; - Evas_Font_OT_Data *ot_data; + Evas_Text_Props_Info *info; +}; + +struct _Evas_Text_Props_Info +{ + unsigned int refcount; + Evas_Font_Glyph_Info *glyph; + Evas_Font_OT_Info *ot; }; void @@ -32,9 +45,6 @@ evas_common_text_props_content_ref(Evas_Text_Props *props); void evas_common_text_props_content_unref(Evas_Text_Props *props); -EAPI void -evas_common_text_props_cutoff(Evas_Text_Props *props, int cutoff); - EAPI void evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext, int cutoff); diff --git a/legacy/evas/src/modules/engines/quartz/evas_engine.c b/legacy/evas/src/modules/engines/quartz/evas_engine.c index 0a14e7006b..3c9692e006 100644 --- a/legacy/evas/src/modules/engines/quartz/evas_engine.c +++ b/legacy/evas/src/modules/engines/quartz/evas_engine.c @@ -1109,9 +1109,9 @@ static Eina_Bool eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props __UNUSED__, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) { #ifdef BIDI_SUPPORT - return !evas_bidi_shape_string(text, par_props, pos, len); + evas_bidi_shape_string(text, par_props, pos, len); #endif - return EINA_TRUE; + return evas_common_font_glyph_info_create(font, text, intl_props, len); } static int diff --git a/legacy/evas/src/modules/engines/software_16/evas_engine.c b/legacy/evas/src/modules/engines/software_16/evas_engine.c index 999198d661..6aa7ce8dde 100644 --- a/legacy/evas/src/modules/engines/software_16/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_16/evas_engine.c @@ -543,17 +543,23 @@ eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *t static Eina_Bool eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) { + (void) font; + (void) text; + (void) intl_props; + (void) par_props; + (void) pos; + (void) len; #ifdef OT_SUPPORT if (evas_common_font_ot_is_enabled()) { - return evas_common_font_ot_populate_text_props(font, text, - intl_props, len); + return evas_common_font_glyph_info_create(font, text, intl_props, len); } else #endif { #ifdef BIDI_SUPPORT - return !evas_bidi_shape_string(text, par_props, pos, len); + evas_bidi_shape_string(text, par_props, pos, len); + return evas_common_font_glyph_info_create(font, text, intl_props, len); #endif } return EINA_TRUE; diff --git a/legacy/evas/src/modules/engines/software_8/evas_engine.c b/legacy/evas/src/modules/engines/software_8/evas_engine.c index e6d6db2a64..8db0f4dfcb 100644 --- a/legacy/evas/src/modules/engines/software_8/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_8/evas_engine.c @@ -601,17 +601,23 @@ eng_font_pen_coords_get(void *data __UNUSED__, void *font, const Eina_Unicode *t static Eina_Bool eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_Props *intl_props, const Evas_BiDi_Paragraph_Props *par_props, size_t pos, size_t len) { + (void) font; + (void) text; + (void) intl_props; + (void) par_props; + (void) pos; + (void) len; #ifdef OT_SUPPORT if (evas_common_font_ot_is_enabled()) { - return evas_common_font_ot_populate_text_props(font, text, - intl_props, len); + return evas_common_font_glyph_info_create(font, text, intl_props, len); } else #endif { #ifdef BIDI_SUPPORT - return !evas_bidi_shape_string(text, par_props, pos, len); + evas_bidi_shape_string(text, par_props, pos, len); + return evas_common_font_glyph_info_create(font, text, intl_props, len); #endif } return EINA_TRUE; diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c index fe87137728..f66cc1c616 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -722,8 +722,7 @@ eng_font_shape(void *data __UNUSED__, void *font, Eina_Unicode *text, Evas_Text_ #ifdef OT_SUPPORT if (evas_common_font_ot_is_enabled()) { - return evas_common_font_ot_populate_text_props(font, text, - intl_props, len); + return evas_common_font_glyph_info_create(font, text, intl_props, len); } else #endif