Evas text/textblock: Add setting bidi_delimiter API.
authortasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 Apr 2011 15:34:01 +0000 (15:34 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 Apr 2011 15:34:01 +0000 (15:34 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@58669 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/Evas.h
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 4e00328..bf0be2e 100644 (file)
@@ -5302,6 +5302,32 @@ EAPI void              evas_object_text_font_get         (const Evas_Object *obj
 EAPI void              evas_object_text_text_set         (Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
 
 /**
+ * @brief Sets the BiDi delimiters used in the textblock.
+ *
+ * BiDi delimiters are use for in-paragraph separation of bidi segments. This
+ * is useful for example in recipients fields of e-mail clients where bidi
+ * oddities can occur when mixing rtl and ltr.
+ *
+ * @param obj The given text object.
+ * @param delim A null terminated string of delimiters, e.g ",|".
+ * @since 1.1.0
+ */
+EAPI void              evas_object_text_bidi_delimiters_set(Evas_Object *obj, const char *delim);
+
+/**
+ * @brief Gets the BiDi delimiters used in the textblock.
+ *
+ * BiDi delimiters are use for in-paragraph separation of bidi segments. This
+ * is useful for example in recipients fields of e-mail clients where bidi
+ * oddities can occur when mixing rtl and ltr.
+ *
+ * @param obj The given text object.
+ * @return A null terminated string of delimiters, e.g ",|". If empty, returns NULL.
+ * @since 1.1.0
+ */
+EAPI const char       *evas_object_text_bidi_delimiters_get(const Evas_Object *obj);
+
+/**
  * Retrieves the text currently being displayed by the given evas text object.
  * @param  obj The given evas text object.
  * @return The text currently being displayed.  Do not free it.
@@ -5596,6 +5622,31 @@ EAPI void                         evas_object_textblock_valign_set(Evas_Object *
  */
 EAPI double                       evas_object_textblock_valign_get(const Evas_Object *obj);
 
+/**
+ * @brief Sets the BiDi delimiters used in the textblock.
+ *
+ * BiDi delimiters are use for in-paragraph separation of bidi segments. This
+ * is useful for example in recipients fields of e-mail clients where bidi
+ * oddities can occur when mixing rtl and ltr.
+ *
+ * @param obj The given textblock object.
+ * @param delim A null terminated string of delimiters, e.g ",|".
+ * @since 1.1.0
+ */
+EAPI void                         evas_object_textblock_bidi_delimiters_set(Evas_Object *obj, const char *delim);
+
+/**
+ * @brief Gets the BiDi delimiters used in the textblock.
+ *
+ * BiDi delimiters are use for in-paragraph separation of bidi segments. This
+ * is useful for example in recipients fields of e-mail clients where bidi
+ * oddities can occur when mixing rtl and ltr.
+ *
+ * @param obj The given textblock object.
+ * @return A null terminated string of delimiters, e.g ",|". If empty, returns NULL.
+ * @since 1.1.0
+ */
+EAPI const char                  *evas_object_textblock_bidi_delimiters_get(const Evas_Object *obj);
 
 /**
  * @brief Sets newline mode. When true, newline character will behave
index 4d6bc4c..5f8b1b3 100644 (file)
@@ -31,6 +31,7 @@ struct _Evas_Object_Text
    float                       ascent, descent;
    float                       max_ascent, max_descent;
    Evas_BiDi_Paragraph_Props  *bidi_par_props;
+   const char                 *bidi_delimiters;
    Evas_Object_Text_Item      *items;
 
    void                       *engine_data;
@@ -562,9 +563,13 @@ _evas_object_text_layout(Evas_Object *obj, Evas_Object_Text *o, const Eina_Unico
    int cutoff;
    int len = eina_unicode_strlen(text);
 #ifdef BIDI_SUPPORT
+   int *segment_idxs = NULL;
+   if (o->bidi_delimiters)
+      segment_idxs = evas_bidi_segment_idxs_get(text, o->bidi_delimiters);
    evas_bidi_paragraph_props_unref(o->bidi_par_props);
-   o->bidi_par_props = evas_bidi_paragraph_props_get(text, len, NULL);
+   o->bidi_par_props = evas_bidi_paragraph_props_get(text, len, segment_idxs);
    evas_bidi_props_reorder_line(NULL, 0, len, o->bidi_par_props, &v_to_l);
+   if (segment_idxs) free(segment_idxs);
 #endif
    visual_pos = pos = 0;
 
@@ -662,6 +667,39 @@ evas_object_text_text_set(Evas_Object *obj, const char *_text)
    if (text) free(text);
 }
 
+EAPI void
+evas_object_text_bidi_delimiters_set(Evas_Object *obj, const char *delim)
+{
+   Evas_Object_Text *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Text *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
+   return;
+   MAGIC_CHECK_END();
+
+   eina_stringshare_replace(&o->bidi_delimiters, delim);
+}
+
+EAPI const char *
+evas_object_text_bidi_delimiters_get(const Evas_Object *obj)
+{
+   Evas_Object_Text *o;
+
+   MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+   return NULL;
+   MAGIC_CHECK_END();
+   o = (Evas_Object_Text *)(obj->object_data);
+   MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
+   return NULL;
+   MAGIC_CHECK_END();
+
+   return o->bidi_delimiters;
+}
+
+
 EAPI const char *
 evas_object_text_text_get(const Evas_Object *obj)
 {
index 7ad67e2..86a6084 100644 (file)
@@ -377,6 +377,7 @@ struct _Evas_Object_Textblock
    char                               *markup_text;
    void                               *engine_data;
    const char                         *repch;
+   const char                         *bidi_delimiters;
    struct {
       int                              w, h;
       unsigned char                    valid : 1;
@@ -1850,15 +1851,23 @@ _layout_paragraph_new(Ctxt *c, Evas_Object_Textblock_Node_Text *n,
  * @param par The paragraph to update
  */
 static inline void
-_layout_update_bidi_props(Evas_Object_Textblock_Paragraph *par)
+_layout_update_bidi_props(const Evas_Object_Textblock *o,
+      Evas_Object_Textblock_Paragraph *par)
 {
    if (par->text_node)
      {
+        const Eina_Unicode *text;
+        int *segment_idxs = NULL;
+        text = eina_ustrbuf_string_get(par->text_node->unicode);
+
+        if (o->bidi_delimiters)
+           segment_idxs = evas_bidi_segment_idxs_get(text, o->bidi_delimiters);
+
         evas_bidi_paragraph_props_unref(par->bidi_props);
-        par->bidi_props = evas_bidi_paragraph_props_get(
-              eina_ustrbuf_string_get(par->text_node->unicode),
+        par->bidi_props = evas_bidi_paragraph_props_get(text,
               eina_ustrbuf_length_get(par->text_node->unicode),
-              NULL);
+              segment_idxs);
+        if (segment_idxs) free(segment_idxs);
      }
 }
 #endif
@@ -3642,7 +3651,7 @@ _layout(const Evas_Object *obj, int calc_only, int w, int h, int *w_ret, int *h_
                }
 
 #ifdef BIDI_SUPPORT
-             _layout_update_bidi_props(c->par);
+             _layout_update_bidi_props(c->o, c->par);
 #endif
 
              /* For each text node to thorugh all of it's format nodes
@@ -4229,6 +4238,20 @@ evas_object_textblock_valign_get(const Evas_Object *obj)
    return o->valign;
 }
 
+EAPI void
+evas_object_textblock_bidi_delimiters_set(Evas_Object *obj, const char *delim)
+{
+   TB_HEAD();
+   eina_stringshare_replace(&o->bidi_delimiters, delim);
+}
+
+EAPI const char *
+evas_object_textblock_bidi_delimiters_get(const Evas_Object *obj)
+{
+   TB_HEAD_RETURN(NULL);
+   return o->bidi_delimiters;
+}
+
 EAPI const char *
 evas_object_textblock_replace_char_get(Evas_Object *obj)
 {
index 52a72a8..999d5f0 100644 (file)
@@ -147,6 +147,62 @@ evas_bidi_shape_string(Eina_Unicode *eina_ustr, const Evas_BiDi_Paragraph_Props
 
 /**
  * @internal
+ * Return a -1 terminated array of the indexes of the delimiters (passed in
+ * delim) found in the string. This result should be used with par_props_get.
+ *
+ * @param str The string to parse
+ * @param delim a list of delimiters to work with.
+ * @return returns a -1 terminated array of indexes according to positions of the delimiters found. NULL if there were none.
+ */
+int *
+evas_bidi_segment_idxs_get(const Eina_Unicode *str, const char *delim)
+{
+   Eina_Unicode *udelim;
+   const Eina_Unicode *str_base = str;
+   int *ret, *tmp_ret;
+   int ret_idx = 0, ret_len = 10; /* arbitrary choice */
+   udelim = eina_unicode_utf8_to_unicode(delim, NULL);
+   ret = malloc(ret_len * sizeof(int));
+   for ( ; *str ; str++)
+     {
+        const Eina_Unicode *del;
+        for (del = udelim ; *del ; del++)
+          {
+             if (*str == *del)
+               {
+                  if (ret_idx >= ret_len)
+                    {
+                       /* arbitrary choice */
+                       ret_len += 20;
+                       tmp_ret = realloc(ret, ret_len * sizeof(int));
+                       if (!tmp_ret)
+                         {
+                            free(ret);
+                            return NULL;
+                         }
+                    }
+                  ret[ret_idx++] = str - str_base;
+                  break;
+               }
+          }
+     }
+   free(udelim);
+
+   /* If no indexes were found return NULL */
+   if (ret_idx == 0)
+     {
+        free(ret);
+        return NULL;
+     }
+
+   ret[ret_idx] = -1;
+   tmp_ret = realloc(ret, (ret_idx + 1) * sizeof(int));
+
+   return (tmp_ret) ? tmp_ret : ret;
+}
+
+/**
+ * @internal
  * Allocates bidi properties according to ustr. First checks to see if the
  * passed has rtl chars, if not, it returns NULL.
  *
@@ -159,7 +215,6 @@ evas_bidi_shape_string(Eina_Unicode *eina_ustr, const Evas_BiDi_Paragraph_Props
  * @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,
       int *segment_idxs)
index c741c8f..75e518b 100644 (file)
@@ -143,6 +143,9 @@ evas_bidi_paragraph_props_unref(Evas_BiDi_Paragraph_Props *bidi_props) EINA_ARG_
 Evas_BiDi_Paragraph_Props *
 evas_bidi_paragraph_props_new(void) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
 
+int *
+evas_bidi_segment_idxs_get(const Eina_Unicode *str, const char *delim) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT EINA_MALLOC;
+
 #endif
 /**
  * @}