diff --git a/legacy/evas/src/lib/engines/common/Makefile.am b/legacy/evas/src/lib/engines/common/Makefile.am index 2128b1874a..c3f9dd8426 100644 --- a/legacy/evas/src/lib/engines/common/Makefile.am +++ b/legacy/evas/src/lib/engines/common/Makefile.am @@ -63,7 +63,6 @@ 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 @@ -106,7 +105,6 @@ 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 2071e2d0e6..08839e4815 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,163 +3,190 @@ /* Macros for text walking */ /** - * @def EVAS_FONT_WALK_TEXT_INIT + * @def EVAS_FONT_UPDATE_KERN() * @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 + * This macro updates kern according to kerning. + * This macro assumes the following variables exist: + * intl_props, char_index, fi, kern, index, prev_index */ -# 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 */ +#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 /** - * @def EVAS_FONT_WALK_TEXT_VISUAL_START + * @def EVAS_FONT_WALK_DEFAULT_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_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 + * 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 */ -#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() \ +#define EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() \ do \ { \ + const Eina_Unicode *_base_text; \ int _char_index_d, _i; \ - int visible = 1; \ - _i = text_props->len; \ - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \ + int visible; \ + prev_index = 0; \ + _base_text = text; \ + for ( ; *text ; text++); \ + _i = text - _base_text; \ + if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \ { \ - char_index = text_props->len - 1; \ + char_index = text - _base_text - 1; \ + text--; \ _char_index_d = -1; \ } \ else \ { \ char_index = 0; \ + text = _base_text; \ _char_index_d = 1; \ } \ - for ( ; _i > 0 ; char_index += _char_index_d, _i--) \ - { -#else -#define EVAS_FONT_WALK_TEXT_LOGICAL_START() EVAS_FONT_WALK_TEXT_VISUAL_START() -#endif + 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; /*FIXME: doc */ -#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 \ +#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 \ (!char_index) -#define EVAS_FONT_WALK_LEN (text_props->len) - +#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_TEXT_WORK + * @def EVAS_FONT_WALK_DEFAULT_TEXT_WORK * @internal - * This macro actually updates the values mentioned in EVAS_FONT_WALK_TEXT_VISUAL_START + * 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_TEXT_VISUAL_START - * @see EVAS_FONT_WALK_TEXT_INIT - * @see EVAS_FONT_WALK_TEXT_END + * @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_TEXT_WORK() do {} while(0); +#define EVAS_FONT_WALK_DEFAULT_TEXT_WORK(is_visual) \ + index = evas_common_font_glyph_search(fn, &fi, _gl); \ + LKL(fi->ft_mutex); \ + fg = evas_common_font_int_cache_glyph_get(fi, index); \ + if (!fg) \ + { \ + LKU(fi->ft_mutex); \ + continue; \ + } \ + kern = 0; \ + if (EVAS_FONT_CHARACTER_IS_INVISIBLE(_gl)) \ + { \ + visible = 0; \ + } \ + else \ + { \ + visible = 1; \ + } \ + /* hmmm kerning means i can't sanely do my own cached metric */ \ + /* tables! grrr - this means font face sharing is kinda... not */ \ + /* an option if you want performance */ \ + if ((use_kerning) && (prev_index) && (index) && \ + (pface == fi->src->ft.face)) \ + { \ + EVAS_FONT_UPDATE_KERN(is_visual); \ + } \ + \ + pface = fi->src->ft.face; \ + LKU(fi->ft_mutex); \ /** - * @def EVAS_FONT_WALK_TEXT_END + * @def EVAS_FONT_WALK_DEFAULT_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 + * 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 */ -#define EVAS_FONT_WALK_TEXT_END() \ +#define EVAS_FONT_WALK_DEFAULT_TEXT_END() \ if (visible) \ { \ - _pen_x += _EVAS_FONT_WALK_X_ADV; \ + _pen_x += _EVAS_FONT_WALK_DEFAULT_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 9e8cc5c6bb..fde3c12589 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 *text_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 *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning); #endif EAPI void @@ -389,20 +389,19 @@ 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 text_props, + * BiDi handling: We receive the shaped string + other props from intl_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 *text_props, RGBA_Gfx_Func func, int ext_x, int ext_y, int ext_w, + const Evas_Text_Props *intl_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) @@ -416,7 +415,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, text_props, + evas_font_word_prerender(dc, text, intl_props, len, fn, fi, use_kerning); if (word) { @@ -493,8 +492,6 @@ 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) @@ -507,172 +504,142 @@ 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 */ +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - /* 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) + EVAS_FONT_WALK_OT_TEXT_VISUAL_START() { - LKU(fi->ft_mutex); - continue; - } - if (EVAS_FONT_CHARACTER_IS_INVISIBLE(text[EVAS_FONT_WALK_POS])) - { - visible = 0; - } - else - { - visible = 1; - } + int chr_x, chr_y, chr_w; - pface = fi->src->ft.face; - LKU(fi->ft_mutex); + 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_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 (dc->font_ext.func.gl_new) { - 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; + /* 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; + } - 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 + 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++) { - if ((dx < (ext_x + ext_w)) && - (dy >= (ext_y)) && - (dy < (ext_y + ext_h))) + 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 + w > (ext_x + ext_w)) - in_w += (dx + w) - (ext_x + ext_w); - if (dx < ext_x) + if ((dx < (ext_x + ext_w)) && + (dy >= (ext_y)) && + (dy < (ext_y + ext_h))) { - 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); + 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++) + else { - int dx, dy; - int in_x, in_w, end; + DATA8 *tmpbuf = NULL, *dp, *tp, bits; + int bi, bj; + const DATA8 bitrepl[2] = {0x0, 0xff}; - 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 + tmpbuf = alloca(w); + for (i = 0; i < h; i++) { - tp = tmpbuf; - dp = data + (i * fg->glyph_out->bitmap.pitch); - for (bi = 0; bi < w; bi += 8) + 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 { - bits = *dp; - if ((w - bi) < 8) end = w - bi; - else end = 8; - for (bj = 0; bj < end; bj++) + tp = tmpbuf; + dp = data + (i * fg->glyph_out->bitmap.pitch); + for (bi = 0; bi < w; bi += 8) { - *tp = bitrepl[(bits >> (7 - bj)) & 0x1]; - tp++; + 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++; } - 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 < (ext_x + ext_w)) && + (dy >= (ext_y)) && + (dy < (ext_y + ext_h))) { - 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); + 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); + } } } } @@ -681,17 +648,166 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font } } } + else + break; } - else - break; + EVAS_FONT_WALK_OT_TEXT_END(); + } + else +#endif + { + EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() + { + int chr_x, chr_y, chr_w; + + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE); + + if (dc->font_ext.func.gl_new) + { + /* extension calls */ + fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg); + fg->ext_dat_free = dc->font_ext.func.gl_free; + } + + chr_x = x + EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_OFF + EVAS_FONT_WALK_DEFAULT_X_BEAR; + chr_y = y + EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_DEFAULT_Y_OFF + EVAS_FONT_WALK_DEFAULT_Y_BEAR; + chr_w = EVAS_FONT_WALK_DEFAULT_WIDTH; + + if (chr_x < (ext_x + ext_w)) + { + DATA8 *data; + int i, j, w, h; + + data = fg->glyph_out->bitmap.buffer; + j = fg->glyph_out->bitmap.pitch; + w = fg->glyph_out->bitmap.width; + if (j < w) j = w; + h = fg->glyph_out->bitmap.rows; + /* + if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays) + && (fg->glyph_out->bitmap.num_grays == 256) + ) + */ + { + if ((j > 0) && (chr_x + w > ext_x)) + { + if ((fg->ext_dat) && (dc->font_ext.func.gl_draw)) + { + /* ext glyph draw */ + dc->font_ext.func.gl_draw(dc->font_ext.data, + (void *)dst, + dc, fg, chr_x, + y - (chr_y - y)); + } + else + { + if ((fg->glyph_out->bitmap.num_grays == 256) && + (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)) + { + for (i = 0; i < h; i++) + { + int dx, dy; + int in_x, in_w; + + in_x = 0; + in_w = 0; + dx = chr_x; + dy = y - (chr_y - i - y); +#ifdef EVAS_SLI + if (((dy) % dc->sli.h) == dc->sli.y) +#endif + { + if ((dx < (ext_x + ext_w)) && + (dy >= (ext_y)) && + (dy < (ext_y + ext_h))) + { + if (dx + w > (ext_x + ext_w)) + in_w += (dx + w) - (ext_x + ext_w); + if (dx < ext_x) + { + in_w += ext_x - dx; + in_x = ext_x - dx; + dx = ext_x; + } + if (in_w < w) + { + func(NULL, data + (i * j) + in_x, dc->col.col, + im + (dy * im_w) + dx, w - in_w); + } + } + } + } + } + else + { + DATA8 *tmpbuf = NULL, *dp, *tp, bits; + int bi, bj; + const DATA8 bitrepl[2] = {0x0, 0xff}; + + tmpbuf = alloca(w); + for (i = 0; i < h; i++) + { + int dx, dy; + int in_x, in_w, end; + + in_x = 0; + in_w = 0; + dx = chr_x; + dy = y - (chr_y - i - y); +#ifdef EVAS_SLI + if (((dy) % dc->sli.h) == dc->sli.y) +#endif + { + tp = tmpbuf; + dp = data + (i * fg->glyph_out->bitmap.pitch); + for (bi = 0; bi < w; bi += 8) + { + bits = *dp; + if ((w - bi) < 8) end = w - bi; + else end = 8; + for (bj = 0; bj < end; bj++) + { + *tp = bitrepl[(bits >> (7 - bj)) & 0x1]; + tp++; + } + dp++; + } + if ((dx < (ext_x + ext_w)) && + (dy >= (ext_y)) && + (dy < (ext_y + ext_h))) + { + if (dx + w > (ext_x + ext_w)) + in_w += (dx + w) - (ext_x + ext_w); + if (dx < ext_x) + { + in_w += ext_x - dx; + in_x = ext_x - dx; + dx = ext_x; + } + if (in_w < w) + { + func(NULL, tmpbuf + in_x, dc->col.col, + im + (dy * im_w) + dx, w - in_w); + } + } + } + } + } + } + } + } + } + else + break; + } + EVAS_FONT_WALK_DEFAULT_TEXT_END(); } - EVAS_FONT_WALK_TEXT_END(); evas_common_font_int_use_trim(); } EAPI void evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const Eina_Unicode *text, - const Evas_Text_Props *text_props) + const Evas_Text_Props *intl_props) { int ext_x, ext_y, ext_w, ext_h; int im_w, im_h; @@ -743,7 +859,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, text_props, + evas_common_font_draw_internal(dst, dc, fn, x, y, text, intl_props, func, ext_x, ext_y, ext_w, ext_h, fi, im_w, im_h, use_kerning); } @@ -759,7 +875,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, text_props, + evas_common_font_draw_internal(dst, dc, fn, x, y, text, intl_props, func, r->x, r->y, r->w, r->h, fi, im_w, im_h, use_kerning); } @@ -776,7 +892,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 *text_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 *intl_props, int len, RGBA_Font *fn, RGBA_Font_Int *fi,int use_kerning) { struct cinfo *metrics; const Eina_Unicode *text = in_text; @@ -814,14 +930,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()) + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - len = text_props->info->ot_data->len; + len = intl_props->ot_data->len; metrics = malloc(sizeof(struct cinfo) * len); - EVAS_FONT_WALK_TEXT_VISUAL_START() + EVAS_FONT_WALK_OT_TEXT_VISUAL_START() { struct cinfo *ci = metrics + char_index; - EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE); + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); /* Currently broken with invisible chars if (!visible) continue; */ ci->index = index; ci->fg = fg; @@ -842,19 +958,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_X_ADV - + last_delta = EVAS_FONT_WALK_OT_X_ADV - (ci->bm.w + ci->fg->glyph_out->left); } - EVAS_FONT_WALK_TEXT_END(); + EVAS_FONT_WALK_OT_TEXT_END(); } else #endif { metrics = malloc(sizeof(struct cinfo) * len); - EVAS_FONT_WALK_TEXT_LOGICAL_START() + EVAS_FONT_WALK_DEFAULT_TEXT_LOGICAL_START() { struct cinfo *ci = metrics + char_index; - EVAS_FONT_WALK_TEXT_WORK(EINA_FALSE); + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE); /* Currently broken with invisible chars if (!visible) continue; */ ci->index = index; ci->fg = fg; @@ -875,10 +991,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_X_ADV - + last_delta = EVAS_FONT_WALK_DEFAULT_X_ADV - (ci->bm.w + ci->fg->glyph_out->left); } - EVAS_FONT_WALK_TEXT_END(); + EVAS_FONT_WALK_DEFAULT_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 deleted file mode 100644 index a2e9911c1d..0000000000 --- a/legacy/evas/src/lib/engines/common/evas_font_glyph_info.c +++ /dev/null @@ -1,166 +0,0 @@ -#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 deleted file mode 100644 index 2bbbf34593..0000000000 --- a/legacy/evas/src/lib/engines/common/evas_font_glyph_info.h +++ /dev/null @@ -1,25 +0,0 @@ -#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 b0d1f0dd80..477a861b8c 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_ot.c +++ b/legacy/evas/src/lib/engines/common/evas_font_ot.c @@ -34,22 +34,21 @@ 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) +evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index, int orig_len) { int i; int items; int left_bound, right_bound; - char_index += props->start; - size_t base_cluster = EVAS_FONT_OT_POS_GET(props->info->ot[char_index]); + size_t base_cluster = EVAS_FONT_OT_POS_GET(props->ot_data->items[char_index]); for (i = (int) char_index ; - (i >= (int) props->start) && - (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ; + (i >= 0) && + (EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ; i--) ; left_bound = i; for (i = (int) char_index + 1; - (i < (int) (props->start + props->len)) && - (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ; + (i < (int) props->ot_data->len) && + (EVAS_FONT_OT_POS_GET(props->ot_data->items[i]) == base_cluster) ; i++) ; right_bound = i; @@ -61,26 +60,26 @@ evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_i { if (left_bound < 0) { - items = props->start + props->len - - props->info->ot[left_bound + 1].source_cluster; + items = orig_len - + props->ot_data->items[left_bound + 1].source_cluster; } else { - items = props->info->ot[left_bound].source_cluster - - props->info->ot[left_bound + 1].source_cluster; + items = props->ot_data->items[left_bound].source_cluster - + props->ot_data->items[left_bound + 1].source_cluster; } } else { - if (right_bound == (int) props->len) + if (right_bound == (int) props->ot_data->len) { - items = props->start + props->len - - props->info->ot[right_bound - 1].source_cluster; + items = orig_len - + props->ot_data->items[right_bound - 1].source_cluster; } else { - items = props->info->ot[right_bound].source_cluster - - props->info->ot[right_bound - 1].source_cluster; + items = props->ot_data->items[right_bound].source_cluster - + props->ot_data->items[right_bound - 1].source_cluster; } } return (items > 0) ? items : 1; @@ -115,6 +114,152 @@ _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) @@ -127,6 +272,12 @@ 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 */ @@ -172,20 +323,18 @@ evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text, _evas_common_font_ot_shape(buffer, fi->src); - 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)); + props->ot_data->len = hb_buffer_get_length(buffer); + props->ot_data->items = calloc(props->ot_data->len, + sizeof(Evas_Font_OT_Data_Item)); positions = hb_buffer_get_glyph_positions(buffer); infos = hb_buffer_get_glyph_infos(buffer); - for (i = 0 ; i < props->len ; i++) + for (i = 0 ; i < props->ot_data->len ; i++) { - 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; + 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; } hb_buffer_destroy(buffer); @@ -194,5 +343,23 @@ 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 66ed10d6ba..01c0ad1399 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_ot.h +++ b/legacy/evas/src/lib/engines/common/evas_font_ot.h @@ -12,31 +12,58 @@ # ifdef OT_SUPPORT # include -typedef struct _Evas_Font_OT_Info Evas_Font_OT_Info; +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 */ +}; # else -typedef void *Evas_Font_OT_Info; +typedef void *Evas_Font_OT_Data; # endif # include "Evas.h" # ifdef OT_SUPPORT -struct _Evas_Font_OT_Info +struct _Evas_Font_OT_Data_Item { + 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); @@ -45,7 +72,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); +evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index, int orig_len); 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 971fb1164e..9c8c7df757 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->len ; char_index++) \ + for (char_index = 0 ; char_index < intl_props->ot_data->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->len; \ + _i = intl_props->ot_data->len; \ if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) \ { \ - char_index = intl_props->len - 1; \ + char_index = intl_props->ot_data->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->info->ot[char_index]))) + 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->info->ot[char_index]))) -#define EVAS_FONT_WALK_OT_X_BEAR (intl_props->info->glyph[char_index].x_bear) + 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 \ - (intl_props->info->glyph[char_index].advance) + (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 (intl_props->info->glyph[char_index].width) + (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->info->ot[char_index])) + intl_props->ot_data->items[char_index])) #define EVAS_FONT_WALK_OT_IS_LAST \ - (char_index + 1 == intl_props->len) + (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->info->ot[char_index + 1]) : \ + 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->info->ot[char_index - 1]) : \ + intl_props->ot_data->items[char_index - 1]) : \ EVAS_FONT_WALK_OT_POS \ ) -#define EVAS_FONT_WALK_OT_LEN (intl_props->len) +#define EVAS_FONT_WALK_OT_LEN (intl_props->ot_data->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 = intl_props->info->glyph[char_index].index; \ + 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) \ 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 c85e215348..0964359483 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_private.h +++ b/legacy/evas/src/lib/engines/common/evas_font_private.h @@ -54,4 +54,26 @@ 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 0f2199287e..d21340c22d 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_query.c +++ b/legacy/evas/src/lib/engines/common/evas_font_query.c @@ -1,7 +1,6 @@ #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, @@ -105,62 +104,132 @@ 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 text_props, + * BiDi handling: We receive the shaped string + other props from intl_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 *text_props __UNUSED__, int *w, int *h) +evas_common_font_query_size(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_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(); - EVAS_FONT_WALK_TEXT_VISUAL_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - 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_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_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 text_props, + * BiDi handling: We receive the shaped string + other props from intl_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 *text_props, int *h_adv, int *v_adv) +evas_common_font_query_advance(RGBA_Font *fn, const Eina_Unicode *text, const Evas_Text_Props *intl_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 - EVAS_FONT_WALK_TEXT_LOGICAL_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - EVAS_FONT_WALK_TEXT_WORK(); - if (!visible) continue; + 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_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 text_props, + * BiDi handling: We receive the shaped string + other props from intl_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 @@ -169,24 +238,28 @@ 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 *text_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 *intl_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_props->len == position) + if (!text[position]) { /* if it's rtl then the location is the left of the string, * otherwise, the right. */ #ifdef BIDI_SUPPORT - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) { if (cx) *cx = 0; if (ch) *ch = asc + desc; @@ -194,7 +267,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, text_props, cx, ch); + evas_common_font_query_advance(fn, in_text, intl_props, cx, ch); } if (cy) *cy = 0; if (cw) *cw = 0; @@ -202,95 +275,122 @@ 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() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - EVAS_FONT_WALK_TEXT_WORK(); - - if (prev_cluster != (int) EVAS_FONT_WALK_POS) + 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() { - if (found) + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); + + if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS) { - break; + 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 { - cluster_start = EVAS_FONT_WALK_PEN_X + - EVAS_FONT_WALK_X_OFF + - EVAS_FONT_WALK_X_BEAR; + if (cx) *cx = cluster_start; + if (cw) *cw = 0; } + ret_val = 1; + goto end; } - 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()) - { - items = evas_common_font_ot_cluster_size_get(text_props, - char_index); - } -#endif - item_pos = position - EVAS_FONT_WALK_POS + 1; - } - else if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && - ((EVAS_FONT_WALK_POS_PREV > (size_t) position) || - (EVAS_FONT_WALK_IS_FIRST)) && - (((size_t) position) >= EVAS_FONT_WALK_POS)) - { - found = 1; -#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) + else +#endif { - Evas_Coord cluster_w; - cluster_w = last_end - cluster_start; - if (cy) *cy = -asc; - if (ch) *ch = asc + desc; - if (last_is_visible) + EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() { - if (cx) *cx = cluster_start + - (cluster_w / items) * - (item_pos - 1); - if (cw) *cw = (cluster_w / items); + 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; + } } - else - { - if (cx) *cx = cluster_start; - if (cw) *cw = 0; - } - ret_val = 1; - goto end; + EVAS_FONT_WALK_DEFAULT_TEXT_END(); } end: - return ret_val; + evas_common_font_int_use_trim(); + return ret_val; } /* x y w h for pen at char pos for null it returns the position right after * the last char with 0 as width and height. This is the same as char_coords * but it returns the pen_x and adv instead of x and w. - * BiDi handling: We receive the shaped string + other props from text_props, + * BiDi handling: We receive the shaped string + other props from intl_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 @@ -299,24 +399,28 @@ end: */ EAPI int -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) +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) { 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_props->len == position) + if (!text[position]) { /* if it's rtl then the location is the left of the string, * otherwise, the right. */ #ifdef BIDI_SUPPORT - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) + if (intl_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) { if (cpen_x) *cpen_x = 0; if (ch) *ch = asc + desc; @@ -324,89 +428,122 @@ 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, text_props, cpen_x, ch); + evas_common_font_query_advance(fn, in_text, intl_props, cpen_x, ch); } if (cy) *cy = 0; if (cadv) *cadv = 0; ret_val = 1; goto end; } - 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() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - EVAS_FONT_WALK_TEXT_WORK(); - - if (prev_cluster != (int) EVAS_FONT_WALK_POS) + 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() { - if (found) + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); + + if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS) { - break; + 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); } else { - cluster_start = EVAS_FONT_WALK_PEN_X; + if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X; + if (cadv) *cadv = 0; } + ret_val = 1; + goto end; } - last_is_visible = visible; - - 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()) - { - items = evas_common_font_ot_cluster_size_get(text_props, - char_index); - } -#endif - item_pos = position - EVAS_FONT_WALK_POS + 1; - } - else if ((text_props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) && - ((EVAS_FONT_WALK_POS_PREV > (size_t) position) || - (EVAS_FONT_WALK_IS_FIRST)) && - (((size_t) position) >= EVAS_FONT_WALK_POS)) - { - found = 1; -#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) + else +#endif { - 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) + EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() { - if (cpen_x) *cpen_x = cluster_start + - (cluster_adv / items) * - (item_pos - 1); - if (cadv) *cadv = (cluster_adv / items); + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE); + + if ((EVAS_FONT_WALK_DEFAULT_POS == (size_t) position)) + { + if (cy) *cy = -asc; + if (ch) *ch = asc + desc; + /* FIXME: A hack to make combining chars work nice, should change + * to take the base char's adv. */ + if (visible) + { + if (EVAS_FONT_WALK_DEFAULT_X_ADV > 0) + { + if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X; + if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_X_ADV; + } + else + { + if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X + + EVAS_FONT_WALK_DEFAULT_X_OFF + + EVAS_FONT_WALK_DEFAULT_X_BEAR; + if (cadv) *cadv = EVAS_FONT_WALK_DEFAULT_WIDTH; + } + } + else + { + if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X; + if (cadv) *cadv = 0; + } + ret_val = 1; + goto end; + } } - else - { - if (cpen_x) *cpen_x = EVAS_FONT_WALK_PEN_X; - if (cadv) *cadv = 0; - } - ret_val = 1; - goto end; + EVAS_FONT_WALK_DEFAULT_TEXT_END(); } end: @@ -421,117 +558,179 @@ end: */ EAPI int -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) +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) { 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); - Evas_Coord cluster_start; - int prev_cluster = -1; - int found = 0, items = 1; - EVAS_FONT_WALK_TEXT_VISUAL_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - EVAS_FONT_WALK_TEXT_WORK(); - if (prev_cluster != (int) EVAS_FONT_WALK_POS) + Evas_Coord cluster_start; + int prev_cluster = -1; + int found = 0, items = 0; + EVAS_FONT_WALK_OT_TEXT_VISUAL_START() { - if (found) + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_TRUE); + if (prev_cluster != (int) EVAS_FONT_WALK_OT_POS) { - break; + 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); } else { - cluster_start = EVAS_FONT_WALK_PEN_X; + 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; } - - 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)) - { -#ifdef OT_SUPPORT - if (evas_common_font_ot_is_enabled()) - { - items = evas_common_font_ot_cluster_size_get(text_props, - char_index); - } + } + else #endif - found = 1; - } - - 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; + EVAS_FONT_WALK_DEFAULT_TEXT_VISUAL_START() + { + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_TRUE); + if (!visible) continue; - if (text_props->bidi.dir == EVAS_BIDI_DIRECTION_LTR) - { - double part; - part = cluster_adv / items; - item_pos = (int) ((x - cluster_start) / part); + /* 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; + } } - 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; + EVAS_FONT_WALK_DEFAULT_TEXT_END(); } + end: + evas_common_font_int_use_trim(); return ret_val; } /* position of the char after the last char in the text that will fit in xy. - * BiDi handling: We receive the shaped string + other props from text_props, + * BiDi handling: We receive the shaped string + other props from intl_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 *text_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 *intl_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); - EVAS_FONT_WALK_TEXT_LOGICAL_START() +#ifdef OT_SUPPORT + if (evas_common_font_ot_is_enabled() && intl_props->ot_data) { - EVAS_FONT_WALK_TEXT_WORK(); - if (!visible) continue; - - 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_OT_TEXT_LOGICAL_START() { - ret = EVAS_FONT_WALK_POS; - goto end; + EVAS_FONT_WALK_OT_TEXT_WORK(EINA_FALSE); + 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() + { + EVAS_FONT_WALK_DEFAULT_TEXT_WORK(EINA_FALSE); + if (!visible) continue; + + if ((x >= EVAS_FONT_WALK_PEN_X) && + (x <= (EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_DEFAULT_X_ADV)) && + (y >= -asc) && (y <= desc)) + { + ret = char_index; + goto end; + } + } + EVAS_FONT_WALK_DEFAULT_TEXT_END(); } - EVAS_FONT_WALK_TEXT_END(); end: + evas_common_font_int_use_trim(); return ret; } 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 15b21b64b2..026796ec7a 100644 --- a/legacy/evas/src/lib/engines/common/evas_text_utils.c +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.c @@ -1,4 +1,3 @@ -#include "evas_common.h" #include "evas_text_utils.h" #include "language/evas_bidi_utils.h" #include "language/evas_language_utils.h" @@ -38,34 +37,39 @@ evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst, void evas_common_text_props_content_ref(Evas_Text_Props *props) { - props->info->refcount++; +#ifdef OT_SUPPORT + if (props->ot_data) + { + evas_common_font_ot_props_ref(props->ot_data); + } +#endif } void evas_common_text_props_content_unref(Evas_Text_Props *props) { - /* 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; - - 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 - if (props->info->ot) - free(props->info->ot); -#endif - free(props->info); - props->info = NULL; + 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 +} + +/* Won't work in the middle of ligatures */ +EAPI void +evas_common_text_props_cutoff(Evas_Text_Props *props, int cutoff) +{ +#ifdef OT_SUPPORT + evas_common_font_ot_cutoff_text_props(props, cutoff); +#endif } /* Won't work in the middle of ligatures */ @@ -73,20 +77,12 @@ EAPI void evas_common_text_props_split(Evas_Text_Props *base, Evas_Text_Props *ext, int cutoff) { - 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; - } + /* 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 } /* Won't work in the middle of ligatures */ @@ -94,16 +90,9 @@ EAPI void evas_common_text_props_merge(Evas_Text_Props *item1, const Evas_Text_Props *item2) { - 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; +#ifdef OT_SUPPORT + evas_common_font_ot_merge_text_props(item1, item2); +#endif } + 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 c8cfa38a27..ff18a4bef4 100644 --- a/legacy/evas/src/lib/engines/common/evas_text_utils.h +++ b/legacy/evas/src/lib/engines/common/evas_text_utils.h @@ -2,29 +2,16 @@ # 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_Text_Props_Info *info; -}; - -struct _Evas_Text_Props_Info -{ - unsigned int refcount; - Evas_Font_Glyph_Info *glyph; - Evas_Font_OT_Info *ot; + Evas_Font_OT_Data *ot_data; }; void @@ -45,6 +32,9 @@ 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 3c9692e006..0a14e7006b 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 - evas_bidi_shape_string(text, par_props, pos, len); + return !evas_bidi_shape_string(text, par_props, pos, len); #endif - return evas_common_font_glyph_info_create(font, text, intl_props, len); + return EINA_TRUE; } 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 6aa7ce8dde..999198d661 100644 --- a/legacy/evas/src/modules/engines/software_16/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_16/evas_engine.c @@ -543,23 +543,17 @@ 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_glyph_info_create(font, text, intl_props, len); + return evas_common_font_ot_populate_text_props(font, text, + intl_props, len); } else #endif { #ifdef BIDI_SUPPORT - evas_bidi_shape_string(text, par_props, pos, len); - return evas_common_font_glyph_info_create(font, text, intl_props, len); + return !evas_bidi_shape_string(text, par_props, pos, 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 8db0f4dfcb..e6d6db2a64 100644 --- a/legacy/evas/src/modules/engines/software_8/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_8/evas_engine.c @@ -601,23 +601,17 @@ 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_glyph_info_create(font, text, intl_props, len); + return evas_common_font_ot_populate_text_props(font, text, + intl_props, len); } else #endif { #ifdef BIDI_SUPPORT - evas_bidi_shape_string(text, par_props, pos, len); - return evas_common_font_glyph_info_create(font, text, intl_props, len); + return !evas_bidi_shape_string(text, par_props, pos, 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 f66cc1c616..fe87137728 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -722,7 +722,8 @@ 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_glyph_info_create(font, text, intl_props, len); + return evas_common_font_ot_populate_text_props(font, text, + intl_props, len); } else #endif