Evas bidi: Added a way to ask for bidi segmentation indexes.
authortasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 Apr 2011 07:40:42 +0000 (07:40 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 Apr 2011 07:40:42 +0000 (07:40 +0000)
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

src/lib/canvas/evas_object_text.c
src/lib/canvas/evas_object_textblock.c
src/lib/engines/common/language/evas_bidi_utils.c
src/lib/engines/common/language/evas_bidi_utils.h

index bc26c60..4d6bc4c 100644 (file)
@@ -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;
index 6f88457..ce5267b 100644 (file)
@@ -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
 
index 71c6a94..52a72a8 100644 (file)
@@ -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
+
index be32d22..c741c8f 100644 (file)
@@ -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);