From: tasn Date: Thu, 14 Apr 2011 07:40:42 +0000 (+0000) Subject: Evas bidi: Added a way to ask for bidi segmentation indexes. X-Git-Tag: accepted/2.0/20130306.225542~242^2~813 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2eda74f3a7feee80b188198870a7b6c400a8a0ed;p=profile%2Fivi%2Fevas.git Evas bidi: Added a way to ask for bidi segmentation indexes. This lets you pass the bidi engine a list of indexes in the paragraph, that will segment it bidi-wise. I.e the bidi algorithm will be applied to each segment individually. This implements HL4 of the bidi algorithm. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@58652 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/src/lib/canvas/evas_object_text.c b/src/lib/canvas/evas_object_text.c index bc26c60..4d6bc4c 100644 --- a/src/lib/canvas/evas_object_text.c +++ b/src/lib/canvas/evas_object_text.c @@ -563,7 +563,7 @@ _evas_object_text_layout(Evas_Object *obj, Evas_Object_Text *o, const Eina_Unico int len = eina_unicode_strlen(text); #ifdef BIDI_SUPPORT evas_bidi_paragraph_props_unref(o->bidi_par_props); - o->bidi_par_props = evas_bidi_paragraph_props_get(text, len); + o->bidi_par_props = evas_bidi_paragraph_props_get(text, len, NULL); evas_bidi_props_reorder_line(NULL, 0, len, o->bidi_par_props, &v_to_l); #endif visual_pos = pos = 0; diff --git a/src/lib/canvas/evas_object_textblock.c b/src/lib/canvas/evas_object_textblock.c index 6f88457..ce5267b 100644 --- a/src/lib/canvas/evas_object_textblock.c +++ b/src/lib/canvas/evas_object_textblock.c @@ -6036,7 +6036,8 @@ _evas_textblock_node_update_bidi_props(Evas_Object_Textblock_Node_Text *n) evas_bidi_paragraph_props_unref(n->bidi_props); n->bidi_props = evas_bidi_paragraph_props_get( eina_ustrbuf_string_get(n->unicode), - eina_ustrbuf_length_get(n->unicode)); + eina_ustrbuf_length_get(n->unicode), + NULL); } #endif diff --git a/src/lib/engines/common/language/evas_bidi_utils.c b/src/lib/engines/common/language/evas_bidi_utils.c index 71c6a94..52a72a8 100644 --- a/src/lib/engines/common/language/evas_bidi_utils.c +++ b/src/lib/engines/common/language/evas_bidi_utils.c @@ -150,12 +150,19 @@ evas_bidi_shape_string(Eina_Unicode *eina_ustr, const Evas_BiDi_Paragraph_Props * Allocates bidi properties according to ustr. First checks to see if the * passed has rtl chars, if not, it returns NULL. * + * Assumes all the segment_idxs are either -1 or legal, and > 0 indexes. + * Also assumes that the characters at the override points are of weak/neutral + * bidi type, otherwise unexpected results may occur. + * * @param ustr The string to update according to. + * @param len The length of the string + * @param segment_idxs A -1 terminated array of points to start a new bidi analysis at (used for section high level bidi overrides). - NULL means none. * @return returns allocated paragraph props on success, NULL otherwise. */ Evas_BiDi_Paragraph_Props * -evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len) +evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len, + int *segment_idxs) { Evas_BiDi_Paragraph_Props *bidi_props = NULL; EvasBiDiCharType *char_types = NULL; @@ -203,10 +210,71 @@ evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len) len = -2; goto cleanup; } - if (!fribidi_get_par_embedding_levels(char_types, len, &bidi_props->direction, embedding_levels)) + + if (segment_idxs) { - len = -2; - goto cleanup; + size_t pos = 0; + int *itr; + EvasBiDiLevel base_level = 0; + EvasBiDiParType direction; + + for (itr = segment_idxs ; *itr > 0 ; itr++) + { + direction = EVAS_BIDI_PARAGRAPH_NATURAL; + if (!fribidi_get_par_embedding_levels(char_types + pos, + *itr - pos, + &direction, + embedding_levels + pos)) + { + len = -2; + goto cleanup; + } + + /* Only on the first run */ + if (itr == segment_idxs) + { + bidi_props->direction = direction; + /* adjust base_level to be 1 for rtl paragraphs, and 0 for + * ltr paragraphs. */ + base_level = + EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(bidi_props) ? 1 : 0; + } + + /* We want those chars at the override points to be on the base + * level and we also remove -2 cause we later increment them, + * just for simpler code paths */ + embedding_levels[*itr] = base_level - 2; + pos = *itr + 1; + } + + direction = EVAS_BIDI_PARAGRAPH_NATURAL; + if (!fribidi_get_par_embedding_levels(char_types + pos, + len - pos, + &direction, + embedding_levels + pos)) + { + len = -2; + goto cleanup; + } + + /* Increment all levels by 2 to emulate embedding. */ + { + EvasBiDiLevel *bitr = embedding_levels, *end; + end = bitr + len; + for ( ; bitr < end ; bitr++) + { + *bitr += 2; + } + } + } + else + { + if (!fribidi_get_par_embedding_levels(char_types, len, + &bidi_props->direction, embedding_levels)) + { + len = -2; + goto cleanup; + } } @@ -514,3 +582,15 @@ evas_bidi_props_clean(Evas_BiDi_Props *bidi_props) */ #endif +#if 0 +/* Good for debugging */ +static void +dump_levels(Eina_Unicode *ustr, EvasBiDiLevel *emb) +{ + for ( ; *ustr ; ustr++, emb++) + { + printf("%lc %d\n", *ustr, *emb); + } +} +#endif + diff --git a/src/lib/engines/common/language/evas_bidi_utils.h b/src/lib/engines/common/language/evas_bidi_utils.h index be32d22..c741c8f 100644 --- a/src/lib/engines/common/language/evas_bidi_utils.h +++ b/src/lib/engines/common/language/evas_bidi_utils.h @@ -120,7 +120,7 @@ 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); Evas_BiDi_Paragraph_Props * -evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len) EINA_ARG_NONNULL(1) EINA_MALLOC EINA_WARN_UNUSED_RESULT; +evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len, int *segment_idxs) EINA_ARG_NONNULL(1) EINA_MALLOC EINA_WARN_UNUSED_RESULT; void evas_bidi_props_copy_and_ref(const Evas_BiDi_Props *src, Evas_BiDi_Props *dst);