From 99a7eff13055a574fe843ca31557c856f8d99427 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Sun, 30 Jan 2011 10:35:17 +0000 Subject: [PATCH] Evas bidi + font-engine + everything affected: Changed Evas_BiDi_Props to only include the direction of the text and reverse when needed. We don't need to do full processing at this stage, because we should have split to bidi runs before. SVN revision: 56443 --- legacy/evas/src/lib/canvas/evas_object_text.c | 41 +++++----- .../src/lib/canvas/evas_object_textblock.c | 20 +++-- .../src/lib/engines/common/evas_bidi_utils.c | 36 ++++++++- .../src/lib/engines/common/evas_bidi_utils.h | 9 ++- .../src/lib/engines/common/evas_font_draw.c | 20 ++--- .../lib/engines/common/evas_font_private.h | 3 +- .../src/lib/engines/common/evas_font_query.c | 78 +++++++++---------- 7 files changed, 124 insertions(+), 83 deletions(-) diff --git a/legacy/evas/src/lib/canvas/evas_object_text.c b/legacy/evas/src/lib/canvas/evas_object_text.c index 8c8b2c3075..db60c30626 100644 --- a/legacy/evas/src/lib/canvas/evas_object_text.c +++ b/legacy/evas/src/lib/canvas/evas_object_text.c @@ -26,7 +26,8 @@ struct _Evas_Object_Text } outline, shadow, glow, glow2; unsigned char style; - Evas_BiDi_Props intl_props; + Evas_BiDi_Paragraph_Props *bidi_par_props; + Evas_BiDi_Props bidi_props; } cur, prev; float ascent, descent; @@ -235,7 +236,7 @@ evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size siz o->ascent = ENFN->font_ascent_get(ENDT, o->engine_data); ENFN->font_string_size_get(ENDT, o->engine_data, - o->cur.text, &o->cur.intl_props, + o->cur.text, &o->cur.bidi_props, &w, &h); o->ascent = ENFN->font_ascent_get(ENDT, o->engine_data); o->descent = ENFN->font_descent_get(ENDT, o->engine_data); @@ -351,11 +352,11 @@ evas_object_text_text_set(Evas_Object *obj, const char *_text) obj->layer->evas->pointer.x, obj->layer->evas->pointer.y, 1, 1); /* DO II */ - /*Update intl_props*/ + /*Update bidi_props*/ #ifdef BIDI_SUPPORT - evas_bidi_paragraph_props_unref(o->cur.intl_props.props); - o->cur.intl_props.props = evas_bidi_paragraph_props_get(text); - evas_bidi_shape_string(text, o->cur.intl_props.props, 0, len); + evas_bidi_paragraph_props_unref(o->cur.bidi_par_props); + o->cur.bidi_par_props = evas_bidi_paragraph_props_get(text); + evas_bidi_shape_string(text, o->cur.bidi_par_props, 0, len); #endif if (o->cur.text) eina_ustringshare_del(o->cur.text); if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text); @@ -380,7 +381,7 @@ evas_object_text_text_set(Evas_Object *obj, const char *_text) ENFN->font_string_size_get(ENDT, o->engine_data, - o->cur.text, &o->cur.intl_props, + o->cur.text, &o->cur.bidi_props, &w, &h); evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b); obj->cur.geometry.w = w + l + r; @@ -560,7 +561,8 @@ evas_object_text_horiz_advance_get(const Evas_Object *obj) MAGIC_CHECK_END(); if (!o->engine_data) return 0; if (!o->cur.text) return 0; - return ENFN->font_h_advance_get(ENDT, o->engine_data, o->cur.text, &o->cur.intl_props); + return ENFN->font_h_advance_get(ENDT, o->engine_data, o->cur.text, + &o->cur.bidi_props); } /** @@ -583,7 +585,8 @@ evas_object_text_vert_advance_get(const Evas_Object *obj) MAGIC_CHECK_END(); if (!o->engine_data) return 0; if (!o->cur.text) return o->ascent + o->descent; - return ENFN->font_v_advance_get(ENDT, o->engine_data, o->cur.text, &o->cur.intl_props); + return ENFN->font_v_advance_get(ENDT, o->engine_data, o->cur.text, + &o->cur.bidi_props); } /** @@ -620,7 +623,8 @@ evas_object_text_char_pos_get(const Evas_Object *obj, int pos, Evas_Coord *cx, E MAGIC_CHECK_END(); if (!o->engine_data) return EINA_FALSE; if (!o->cur.text) return EINA_FALSE; - ret = ENFN->font_char_coords_get(ENDT, o->engine_data, o->cur.text, &o->cur.intl_props, + ret = ENFN->font_char_coords_get(ENDT, o->engine_data, o->cur.text, + &o->cur.bidi_props, pos, &x, &y, &w, &h); evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b); y += o->max_ascent - t; @@ -672,9 +676,9 @@ evas_object_text_last_up_to_pos(const Evas_Object *obj, Evas_Coord x, Evas_Coord if (!o->cur.text) return -1; return ENFN->font_last_up_to_pos(ENDT, o->engine_data, - o->cur.text, &o->cur.intl_props, + o->cur.text, &o->cur.bidi_props, x, - y - o->max_ascent); + y - o->max_ascent); } /** @@ -701,7 +705,7 @@ evas_object_text_char_coords_get(const Evas_Object *obj, Evas_Coord x, Evas_Coor if (!o->cur.text) return -1; ret = ENFN->font_char_at_coords_get(ENDT, o->engine_data, - o->cur.text, &o->cur.intl_props, + o->cur.text, &o->cur.bidi_props, x, y - o->max_ascent, &rx, &ry, @@ -1519,7 +1523,7 @@ evas_object_text_new(void) o->magic = MAGIC_OBJ_TEXT; o->prev = o->cur; #ifdef BIDI_SUPPORT - o->cur.intl_props.props = evas_bidi_paragraph_props_new(); + o->cur.bidi_par_props = evas_bidi_paragraph_props_new(); #endif return o; } @@ -1541,7 +1545,8 @@ evas_object_text_free(Evas_Object *obj) if (o->cur.source) eina_stringshare_del(o->cur.source); if (o->engine_data) evas_font_free(obj->layer->evas, o->engine_data); #ifdef BIDI_SUPPORT - evas_bidi_props_clean(&o->cur.intl_props); + evas_bidi_paragraph_props_unref(o->cur.bidi_par_props); + evas_bidi_props_clean(&o->cur.bidi_props); #endif o->magic = 0; EVAS_MEMPOOL_FREE(_mp_obj, o); @@ -1628,7 +1633,7 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur obj->cur.geometry.h, \ obj->cur.geometry.w, \ obj->cur.geometry.h, \ - o->cur.text, &o->cur.intl_props); + o->cur.text, &o->cur.bidi_props); #if 0 #define DRAW_TEXT(ox, oy) \ if ((o->engine_data) && (o->cur.text)) \ @@ -1644,7 +1649,7 @@ evas_object_text_render(Evas_Object *obj, void *output, void *context, void *sur obj->cur.cache.geometry.h, \ obj->cur.geometry.w, \ obj->cur.geometry.h, \ - o->cur.text, &o->cur.intl_props); + o->cur.text, &o->cur.bidi_props); #endif /* shadows */ if (o->cur.style == EVAS_TEXT_STYLE_SHADOW) @@ -1969,7 +1974,7 @@ _evas_object_text_rehint(Evas_Object *obj) ENFN->font_string_size_get(ENDT, o->engine_data, - o->cur.text, &o->cur.intl_props, + o->cur.text, &o->cur.bidi_props, &w, &h); evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b); obj->cur.geometry.w = w + l + r; diff --git a/legacy/evas/src/lib/canvas/evas_object_textblock.c b/legacy/evas/src/lib/canvas/evas_object_textblock.c index e31d1ebbd0..da02e5cd14 100644 --- a/legacy/evas/src/lib/canvas/evas_object_textblock.c +++ b/legacy/evas/src/lib/canvas/evas_object_textblock.c @@ -318,7 +318,7 @@ struct _Evas_Object_Textblock_Item size_t visual_pos; #endif Evas_Coord adv, x, w, h; - Evas_BiDi_Props bidi_props; + Evas_BiDi_Props bidi_props; }; struct _Evas_Object_Textblock_Text_Item @@ -2513,8 +2513,10 @@ _layout_text_add_and_split_item(Ctxt *c, Evas_Object_Textblock_Format *fmt, { new_ti->parent.text_node = ti->parent.text_node; new_ti->parent.text_pos = ti->parent.text_pos + cutoff; - new_ti->parent.bidi_props.start = new_ti->parent.text_pos; - new_ti->parent.bidi_props.props = new_ti->parent.text_node->bidi_props; + new_ti->parent.bidi_props.dir = (evas_bidi_is_rtl_char( + new_ti->parent.text_node->bidi_props, + new_ti->parent.text_pos, + 0)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR; ti = new_ti; len -= cutoff; } @@ -2626,8 +2628,10 @@ skip: ti->parent.text_pos = start + str - tbase; if (ti->parent.text_node) { - ti->parent.bidi_props.start = ti->parent.text_pos; - ti->parent.bidi_props.props = ti->parent.text_node->bidi_props; + ti->parent.bidi_props.dir = (evas_bidi_is_rtl_char( + ti->parent.text_node->bidi_props, + ti->parent.text_pos, + 0)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR; } tw = th = 0; if (fmt->font.font) @@ -2844,8 +2848,10 @@ _layout_format_item_add(Ctxt *c, Evas_Object_Textblock_Node_Format *n, const cha fi->parent.text_node = n->text_node; /* FIXME: make it more efficient */ fi->parent.text_pos = _evas_textblock_node_format_pos_get(n); - fi->parent.bidi_props.props = n->text_node->bidi_props; - fi->parent.bidi_props.start = fi->parent.text_pos; + fi->parent.bidi_props.dir = (evas_bidi_is_rtl_char( + fi->parent.text_node->bidi_props, + fi->parent.text_pos, + 0)) ? EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR; } return fi; } diff --git a/legacy/evas/src/lib/engines/common/evas_bidi_utils.c b/legacy/evas/src/lib/engines/common/evas_bidi_utils.c index 2f678e92c8..62c7e152c6 100644 --- a/legacy/evas/src/lib/engines/common/evas_bidi_utils.c +++ b/legacy/evas/src/lib/engines/common/evas_bidi_utils.c @@ -251,8 +251,7 @@ cleanup: void evas_bidi_props_copy_and_ref(const Evas_BiDi_Props *src, Evas_BiDi_Props *dst) { - dst->start = src->start; - dst->props = evas_bidi_paragraph_props_ref(src->props); + dst->dir = src->dir; } /** @@ -330,6 +329,18 @@ error: return EINA_TRUE; } +/** + * @internal + * Reverses the string according to the props + * + * @param str the string to reverse. + */ +void +evas_bidi_reverse_string(Eina_Unicode *str) +{ + eina_unicode_reverse(str); +} + /** * @internal @@ -390,6 +401,24 @@ evas_bidi_position_logical_to_visual(EvasBiDiStrIndex *v_to_l, int len, EvasBiDi return position; } +/** + * @internal + * Returns the reversed pos of the index. + * + * @param dir the direction of the string + * @param len the length of the map. + * @param position the position to convert. + * @return on success the visual position, on failure the same position. + */ +EvasBiDiStrIndex +evas_bidi_position_reverse(const Evas_BiDi_Props *props, int len, EvasBiDiStrIndex position) +{ + if (!props || position >= len) + return position; + + return (props->dir == EVAS_BIDI_DIRECTION_RTL) ? (len - 1) - position : position; +} + /** * @internal * Checks if the char is rtl oriented. I.e even a neutral char can become rtl @@ -482,8 +511,7 @@ void evas_bidi_props_clean(Evas_BiDi_Props *bidi_props) { if (!bidi_props) return; - evas_bidi_paragraph_props_unref(bidi_props->props); - bidi_props->props = NULL; + bidi_props->dir = EVAS_BIDI_DIRECTION_NATURAL; } /** * @} diff --git a/legacy/evas/src/lib/engines/common/evas_bidi_utils.h b/legacy/evas/src/lib/engines/common/evas_bidi_utils.h index 06c21e99d2..ac89799dc5 100644 --- a/legacy/evas/src/lib/engines/common/evas_bidi_utils.h +++ b/legacy/evas/src/lib/engines/common/evas_bidi_utils.h @@ -76,8 +76,7 @@ struct _Evas_BiDi_Paragraph_Props { }; struct _Evas_BiDi_Props { - Evas_BiDi_Paragraph_Props *props; - size_t start; + Evas_BiDi_Direction dir; }; @@ -104,6 +103,9 @@ struct _Evas_BiDi_Props { EvasBiDiStrIndex evas_bidi_position_logical_to_visual(EvasBiDiStrIndex *v_to_l, int len, EvasBiDiStrIndex position); +EvasBiDiStrIndex +evas_bidi_position_reverse(const Evas_BiDi_Props *props, int len, EvasBiDiStrIndex position); + Eina_Bool evas_bidi_is_rtl_str(const Eina_Unicode *str); @@ -116,6 +118,9 @@ evas_bidi_end_of_run_get(const Evas_BiDi_Paragraph_Props *bidi_props, size_t sta Eina_Bool evas_bidi_props_reorder_line(Eina_Unicode *eina_ustr, size_t start, size_t len, const Evas_BiDi_Paragraph_Props *props, EvasBiDiStrIndex **_v_to_l); +void +evas_bidi_reverse_string(Eina_Unicode *str) EINA_ARG_NONNULL(1); + Evas_BiDi_Paragraph_Props * evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr) EINA_ARG_NONNULL(1) EINA_MALLOC EINA_WARN_UNUSED_RESULT; 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 fc9272a11b..3af06036f2 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_draw.c +++ b/legacy/evas/src/lib/engines/common/evas_font_draw.c @@ -494,22 +494,22 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font #endif #ifdef BIDI_SUPPORT - Eina_Unicode *visual_text; + Eina_Unicode *visual_text = NULL; - visual_text = eina_unicode_strdup(in_text); - - if (visual_text) + if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)) { - evas_bidi_props_reorder_line(visual_text, intl_props->start, - eina_unicode_strlen(visual_text), intl_props->props, NULL); - text = visual_text; + visual_text = eina_unicode_strdup(in_text); + + if (visual_text) + { + evas_bidi_reverse_string(visual_text); + text = visual_text; + } } - else + if (!visual_text) { text = in_text; } -#else - intl_props = NULL; #endif if (fi->src->current_size != fi->size) { 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 dbaa5dd035..40a655c07a 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_private.h +++ b/legacy/evas/src/lib/engines/common/evas_font_private.h @@ -51,8 +51,7 @@ void evas_common_font_int_reload(RGBA_Font_Int *fi); /* 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 && \ - evas_bidi_is_rtl_char(intl_props->props, intl_props->start, char_index) && \ + if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL) && \ adv > 0) \ { \ if (evas_common_font_query_kerning(fi, index, prev_index, &kern)) \ 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 edcdddf0b3..1ebaa9dbbb 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_query.c +++ b/legacy/evas/src/lib/engines/common/evas_font_query.c @@ -213,19 +213,20 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c _INIT_FI_AND_KERNING(); #ifdef BIDI_SUPPORT - int len = 0; - EvasBiDiStrIndex *visual_to_logical = NULL; - Eina_Unicode *visual_text; + Eina_Unicode *visual_text = NULL; + int len; - visual_text = eina_unicode_strdup(in_text); - if (visual_text) + if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)) { - evas_bidi_props_reorder_line(visual_text, intl_props->start, - eina_unicode_strlen(visual_text), intl_props->props, - &visual_to_logical); - text = visual_text; + visual_text = eina_unicode_strdup(in_text); + + if (visual_text) + { + evas_bidi_reverse_string(visual_text); + text = visual_text; + } } - else + if (!visual_text) { text = in_text; } @@ -237,7 +238,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c #ifdef BIDI_SUPPORT /* Get the position in the visual string because those are the coords we care about */ - position = evas_bidi_position_logical_to_visual(visual_to_logical, len, pos); + position = evas_bidi_position_reverse(intl_props, len, pos); #else position = pos; #endif @@ -247,7 +248,7 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c /* if it's rtl then the location is the left of the string, * otherwise, the right. */ #ifdef BIDI_SUPPORT - if (evas_bidi_is_rtl_char(intl_props->props, intl_props->start, 0)) + if (intl_props->dir == EVAS_BIDI_DIRECTION_RTL) { if (cx) *cx = 0; if (ch) *ch = asc + desc; @@ -287,7 +288,6 @@ evas_common_font_query_char_coords(RGBA_Font *fn, const Eina_Unicode *in_text, c end: #ifdef BIDI_SUPPORT - if (visual_to_logical) free(visual_to_logical); if (visual_text) free(visual_text); #endif @@ -319,19 +319,20 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co _INIT_FI_AND_KERNING(); #ifdef BIDI_SUPPORT - int len = 0; - EvasBiDiStrIndex *visual_to_logical = NULL; - Eina_Unicode *visual_text; + Eina_Unicode *visual_text = NULL; + int len; - visual_text = eina_unicode_strdup(in_text); - if (visual_text) + if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)) { - evas_bidi_props_reorder_line(visual_text, intl_props->start, - eina_unicode_strlen(visual_text), intl_props->props, - &visual_to_logical); - text = visual_text; + visual_text = eina_unicode_strdup(in_text); + + if (visual_text) + { + evas_bidi_reverse_string(visual_text); + text = visual_text; + } } - else + if (!visual_text) { text = in_text; } @@ -343,7 +344,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co #ifdef BIDI_SUPPORT /* Get the position in the visual string because those are the coords we care about */ - position = evas_bidi_position_logical_to_visual(visual_to_logical, len, pos); + position = evas_bidi_position_reverse(intl_props, len, pos); #else position = pos; #endif @@ -353,7 +354,7 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co /* if it's rtl then the location is the left of the string, * otherwise, the right. */ #ifdef BIDI_SUPPORT - if (evas_bidi_is_rtl_char(intl_props->props, 0, 0)) + if (intl_props->dir == EVAS_BIDI_DIRECTION_RTL) { if (cpen_x) *cpen_x = 0; if (ch) *ch = asc + desc; @@ -387,7 +388,6 @@ evas_common_font_query_pen_coords(RGBA_Font *fn, const Eina_Unicode *in_text, co end: #ifdef BIDI_SUPPORT - if (visual_to_logical) free(visual_to_logical); if (visual_text) free(visual_text); #endif @@ -417,20 +417,20 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text #endif #ifdef BIDI_SUPPORT - int len = 0; - EvasBiDiStrIndex *visual_to_logical = NULL; - Eina_Unicode *visual_text; + Eina_Unicode *visual_text = NULL; + int len; - visual_text = eina_unicode_strdup(in_text); - - if (visual_text) + if (intl_props && (intl_props->dir == EVAS_BIDI_DIRECTION_RTL)) { - evas_bidi_props_reorder_line(visual_text, intl_props->start, - eina_unicode_strlen(visual_text), intl_props->props, - &visual_to_logical); - text = visual_text; + visual_text = eina_unicode_strdup(in_text); + + if (visual_text) + { + evas_bidi_reverse_string(visual_text); + text = visual_text; + } } - else + if (!visual_text) { text = in_text; } @@ -463,8 +463,7 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text /* we found the char position of the wanted char in the * visual string, we now need to translate it to the * position in the logical string */ - position = evas_bidi_position_visual_to_logical(visual_to_logical, - position); + position = evas_bidi_position_reverse(intl_props, len, position); #endif ret_val = position; goto end; @@ -474,7 +473,6 @@ evas_common_font_query_char_at_coords(RGBA_Font *fn, const Eina_Unicode *in_text end: #ifdef BIDI_SUPPORT - if (visual_to_logical) free(visual_to_logical); if (visual_text) free(visual_text); #endif