Efl.Text.Attribute_Factory
authorAli Alzyod <ali198724@gmail.com>
Wed, 27 Nov 2019 04:04:31 +0000 (13:04 +0900)
committerJongmin Lee <jm105.lee@samsung.com>
Wed, 27 Nov 2019 21:24:45 +0000 (06:24 +0900)
Summary:
Implementation of new Efl.Text.Attribute_Factory class which replace the annotation interface.

Currently, we have two public methods:

```
void efl_text_attribute_factory_attribute_insert(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end, const char *format)
unsigned int efl_text_attribute_factory_attribute_clear(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end);
```

Other methods will be internal methods, for the time being, we will redesign internal methods

Reviewers: woohyun, tasn, segfaultxavi, bu5hm4n, zmike

Subscribers: zmike, q66, cedric, segfaultxavi, bu5hm4n, a.srour, #committers, #reviewers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D10646

21 files changed:
src/bin/elementary/test.c
src/bin/elementary/test_efl_ui_text.c
src/lib/efl/Efl.h
src/lib/efl/interfaces/efl_interfaces_main.c
src/lib/efl/interfaces/efl_text_annotate.eo [deleted file]
src/lib/efl/interfaces/efl_text_types.eot
src/lib/efl/interfaces/meson.build
src/lib/elementary/efl_ui_internal_text_interactive.c
src/lib/elementary/efl_ui_text.c
src/lib/evas/Efl_Canvas.h
src/lib/evas/Evas_Eo.h
src/lib/evas/Evas_Internal.h
src/lib/evas/canvas/efl_canvas_text.eo
src/lib/evas/canvas/efl_canvas_text_internal.h
src/lib/evas/canvas/efl_text_attribute_factory.c [new file with mode: 0644]
src/lib/evas/canvas/efl_text_attribute_factory.eo [new file with mode: 0644]
src/lib/evas/canvas/efl_text_cursor.c
src/lib/evas/canvas/efl_text_cursor.eo
src/lib/evas/canvas/evas_object_textblock.c
src/lib/evas/canvas/meson.build
src/tests/evas/evas_test_textblock.c

index a78850a..1d91bf5 100644 (file)
@@ -366,7 +366,6 @@ void test_code_diff_inline(void *data, Evas_Object *obj, void *event_info);
 void test_efl_ui_text(void *data, Evas_Object *obj, void *event_info);
 void test_efl_ui_text_inputfield(void *data, Evas_Object *obj, void *event_info);
 void test_efl_ui_text_label(void *data, Evas_Object *obj, void *event_info);
-void test_ui_text_item_factory(void *data, Evas_Object *obj, void *event_info);
 void test_evas_mask(void *data, Edje_Object *obj, void *event_info);
 void test_gfx_filters(void *data, Evas_Object *obj, void *event_info);
 void test_evas_snapshot(void *data, Evas_Object *obj, void *event_info);
@@ -941,7 +940,6 @@ add_tests:
    ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text", test_efl_ui_text);
    ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text Input Field", test_efl_ui_text_inputfield);
    ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Text Label", test_efl_ui_text_label);
-   ADD_TEST_EO(NULL, "Entries", "Ui.Text Item Factory", test_ui_text_item_factory);
    ADD_TEST_EO(NULL, "Entries", "Efl.Ui.Tags", test_ui_tags);
 
    //------------------------------//
index d56fddb..e060067 100644 (file)
@@ -5,6 +5,7 @@
 #include <Efl_Ui.h>
 #include <Elementary.h>
 #include "elm_priv.h" //FIXME remove this once efl.ui.text doesn't need elm_general.h
+
 static void
 _apply_style(Eo *obj, size_t start_pos, size_t end_pos, const char *style)
 {
@@ -16,7 +17,7 @@ _apply_style(Eo *obj, size_t start_pos, size_t end_pos, const char *style)
    efl_text_cursor_position_set(start, start_pos);
    efl_text_cursor_position_set(end, end_pos);
 
-   efl_text_annotation_insert(obj, efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end), style);
+   efl_text_attribute_factory_attribute_insert(start, end, style);
 
    efl_del(start);
    efl_del(end);
@@ -235,162 +236,3 @@ test_efl_ui_text_inputfield(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED
    efl_gfx_entity_size_set(win, EINA_SIZE2D(300, 200));
 
 }
-
-#define IMAGES_SZ 5
-
-static const char *images[IMAGES_SZ] = {
-     "sky", "logo", "dog", "eet_rock", "eet_plant" };
-
-static void
-_on_factory_bt_image_clicked(void *data, const Efl_Event *event EINA_UNUSED)
-{
-   Evas_Object *en = data;
-   static int image_idx = 0;
-
-   image_idx = (image_idx + 1) % IMAGES_SZ;
-
-   efl_text_cursor_item_insert(en, efl_text_cursor_handle_get(efl_text_interactive_main_cursor_get(en)),
-          images[image_idx], "size=32x32");
-   printf("Inserted image: key = %s\n", images[image_idx]);
-}
-
-static void
-_on_factory_bt_emoticon_clicked(void *data, const Efl_Event *event EINA_UNUSED)
-{
-   Evas_Object *en = data;
-    efl_text_cursor_item_insert(en, efl_text_cursor_handle_get(efl_text_interactive_main_cursor_get(en)),
-          "emoticon/evil-laugh", "size=32x32");
-}
-
-static struct
-{
-   const char *name;
-   Eo *item_factory;
-} factories[3];
-
-static void
-_on_factory_bt_factory_clicked(void *data, const Efl_Event *event EINA_UNUSED)
-{
-   Evas_Object *en = data;
-   static int item_factory_idx = 0;
-
-   item_factory_idx = (item_factory_idx + 1) % 3;
-   efl_ui_text_item_factory_set(en, factories[item_factory_idx].item_factory);
-   printf("Factory set to: %s\n", factories[item_factory_idx].name);
-}
-
-#define FACTORY_NONE     0
-#define FACTORY_IMAGE    1
-#define FACTORY_EMOTICON 2
-
-void
-test_ui_text_item_factory(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
-{
-   Evas_Object *win, *bx, *bx2, *bt, *en;
-   Efl_Text_Cursor *main_cur, *cur;
-   char buf[128];
-   Eina_File *f;
-
-   win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
-                  efl_text_set(efl_added, "Efl Ui Text Item Factory"),
-         efl_ui_win_autodel_set(efl_added, EINA_TRUE));
-
-   bx = efl_add(EFL_UI_BOX_CLASS, win);
-   efl_content_set(win, bx);
-
-   en = efl_add(EFL_UI_TEXT_CLASS, bx,
-         efl_text_multiline_set(efl_added, EINA_TRUE));
-
-   factories[FACTORY_NONE].name = "None (Fallback)";
-   factories[FACTORY_NONE].item_factory = NULL;
-
-   factories[FACTORY_IMAGE].name = "Image Factory";
-   factories[FACTORY_IMAGE].item_factory =
-      efl_add(EFL_UI_TEXT_FACTORY_IMAGES_CLASS, en);
-
-   factories[FACTORY_EMOTICON].name = "Emoticon Factory";
-   factories[FACTORY_EMOTICON].item_factory =
-      efl_add(EFL_UI_TEXT_FACTORY_EMOTICONS_CLASS, en);
-
-   // Test assigning file path source
-   snprintf(buf, sizeof(buf), "%s/images/sky_01.jpg", elm_app_data_dir_get());
-   efl_ui_text_factory_images_matches_add(factories[FACTORY_IMAGE].item_factory,
-         images[0], buf, NULL);
-   snprintf(buf, sizeof(buf), "%s/images/logo.png", elm_app_data_dir_get());
-   efl_ui_text_factory_images_matches_add(factories[FACTORY_IMAGE].item_factory,
-         images[1], buf, NULL);
-   snprintf(buf, sizeof(buf), "%s/images/mystrale.jpg", elm_app_data_dir_get());
-   efl_ui_text_factory_images_matches_add(factories[FACTORY_IMAGE].item_factory,
-         images[2], buf, NULL);
-
-   // Open EET source w/ key
-   snprintf(buf, sizeof(buf), "%s/images/image_items.eet", elm_app_data_dir_get());
-   f = eina_file_open(buf, EINA_FALSE);
-   if (f)
-     {
-        efl_ui_text_factory_images_matches_mmap_add(
-              factories[FACTORY_IMAGE].item_factory,
-              "eet_rock", f, "rock");
-        efl_ui_text_factory_images_matches_mmap_add(
-              factories[FACTORY_IMAGE].item_factory,
-              "eet_plant", f, "plant");
-        eina_file_close(f);
-     }
-   else
-     {
-        printf("Error loading test file. Please review test.");
-     }
-
-
-   printf("Added Efl.Ui.Text object\n");
-   efl_text_set(en, "Hello world! Goodbye world! This is a test text for the"
-         " new UI Text widget.\xE2\x80\xA9This is the next paragraph.\nThis"
-         " is the next line.\nThis is Yet another line! Line and paragraph"
-         " separators are actually different!");
-   efl_text_font_set(en, "Sans", 14);
-   efl_text_normal_color_set(en, 255, 255, 255, 255);
-
-   main_cur = efl_text_interactive_main_cursor_get(en);
-   cur = efl_ui_text_cursor_create(en);
-
-   efl_text_cursor_position_set(cur, 2);
-   efl_text_cursor_item_insert(en, efl_text_cursor_handle_get(cur), "emoticon/happy", "size=32x32");
-   efl_text_cursor_position_set(cur, 50);
-
-   snprintf(buf, sizeof(buf), "file://%s/images/sky_01.jpg", elm_app_data_dir_get());
-   efl_text_cursor_item_insert(en, efl_text_cursor_handle_get(cur), buf, "size=32x32");
-   efl_text_cursor_position_set(main_cur, 5);
-
-   efl_text_interactive_editable_set(en, EINA_TRUE);
-   efl_ui_text_scrollable_set(en, EINA_TRUE);
-   efl_pack(bx, en);
-   elm_object_focus_set(en, EINA_TRUE);
-
-   bx2 = efl_add(EFL_UI_BOX_CLASS, bx);
-   efl_gfx_hint_weight_set(bx2, EFL_GFX_HINT_EXPAND, EFL_GFX_HINT_EXPAND);
-   efl_ui_layout_orientation_set(bx2, EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL);
-
-   bt = efl_add(EFL_UI_BUTTON_CLASS, bx2);
-   efl_text_set(bt, "Image");
-   efl_event_callback_add(bt, EFL_INPUT_EVENT_CLICKED, _on_factory_bt_image_clicked, en);
-   efl_gfx_hint_weight_set(bt, EFL_GFX_HINT_EXPAND, 0.0);
-   efl_pack(bx2, bt);
-   elm_object_focus_allow_set(bt, EINA_FALSE);
-
-   bt = efl_add(EFL_UI_BUTTON_CLASS, bx2);
-   efl_text_set(bt, "Emoticon");
-   efl_event_callback_add(bt, EFL_INPUT_EVENT_CLICKED, _on_factory_bt_emoticon_clicked, en);
-   efl_gfx_hint_weight_set(bt, EFL_GFX_HINT_EXPAND, 0.0);
-   efl_pack(bx2, bt);
-   elm_object_focus_allow_set(bt, EINA_FALSE);
-
-   bt = efl_add(EFL_UI_BUTTON_CLASS, bx2);
-   efl_text_set(bt, "Factory");
-   efl_event_callback_add(bt, EFL_INPUT_EVENT_CLICKED, _on_factory_bt_factory_clicked, en);
-   efl_gfx_hint_weight_set(bt, EFL_GFX_HINT_EXPAND, 0.0);
-   efl_pack(bx2, bt);
-   elm_object_focus_allow_set(bt, EINA_FALSE);
-
-   efl_pack(bx, bx2);
-   efl_gfx_entity_size_set(win, EINA_SIZE2D(480, 320));
-}
index c78d105..a9970e2 100644 (file)
@@ -70,7 +70,7 @@ typedef struct tm Efl_Time;
 
 typedef struct _Efl_Text_Cursor_Handle Efl_Text_Cursor_Handle;
 typedef struct _Efl_Text_Cursor_Handle _Efl_Text_Cursor_Handle;
-typedef struct _Efl_Text_Annotate_Annotation Efl_Text_Annotate_Annotation;
+typedef struct _Efl_Text_Attribute_Handle Efl_Text_Attribute_Handle;
 
 #include "interfaces/efl_types.eot.h"
 
@@ -211,7 +211,6 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
 #include "interfaces/efl_text_font.eo.h"
 #include "interfaces/efl_text_style.eo.h"
 #include "interfaces/efl_text_format.eo.h"
-#include "interfaces/efl_text_annotate.eo.h"
 #include "interfaces/efl_text_markup.eo.h"
 #include "interfaces/efl_text_markup_util.eo.h"
 
index 71162b9..3e94adc 100644 (file)
@@ -24,7 +24,6 @@
 #include "interfaces/efl_text_font.eo.c"
 #include "interfaces/efl_text_style.eo.c"
 #include "interfaces/efl_text_format.eo.c"
-#include "interfaces/efl_text_annotate.eo.c"
 #include "interfaces/efl_text_markup.eo.c"
 
 #include "interfaces/efl_gfx_entity.eo.c"
diff --git a/src/lib/efl/interfaces/efl_text_annotate.eo b/src/lib/efl/interfaces/efl_text_annotate.eo
deleted file mode 100644 (file)
index 5ca1df8..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-import efl_text_types;
-
-interface @beta Efl.Text_Annotate {
-   [[Cursor API
-   ]]
-   c_prefix: efl_text;
-   methods {
-      // Annotation
-      @property annotation {
-         [[A new format for $annotation.
-
-           This will replace the format applied by $annotation with $format.
-           Assumes that $annotation is a handle for an existing annotation,
-           i.e. one that was added using @.annotation_insert to this object.
-           Otherwise, this will fail and return $false.
-         ]]
-         set {
-            return: bool; [[$true on success, $false otherwise.]]
-         }
-         get {
-         }
-         keys {
-            annotation: ptr(Efl.Text_Annotate_Annotation); [[Given annotation]]
-         }
-         values {
-            format: string; [[The new format for the given annotation]]
-         }
-      }
-      range_annotations_get @const {
-         [[Returns an iterator of all the handles in a range.
-         ]]
-         params {
-              @in start: ptr(const(Efl.Text_Cursor_Handle)); [[Start of range]]
-              @in end:   ptr(const(Efl.Text_Cursor_Handle)); [[End of range]]
-         }
-         return: iterator<ptr(Efl.Text_Annotate_Annotation)> @move; [[Handle of the Annotation]]
-      }
-      annotation_insert {
-         [[Inserts an annotation format in a specified range [$start, $end - 1].
-
-           The $format will be applied to the given range, and the $annotation
-           handle will be returned for further handling.
-         ]]
-         params {
-              @in start: ptr(Efl.Text_Cursor_Handle); [[Start of range]]
-              @in end:   ptr(Efl.Text_Cursor_Handle); [[End of range]]
-              @in format: string; [[Annotation format]]
-         }
-         return: ptr(Efl.Text_Annotate_Annotation); [[Handle of inserted annotation]]
-      }
-      annotation_del {
-         [[Deletes given annotation.
-
-           All formats applied by $annotation will be removed and it will be
-           deleted.
-         ]]
-         params {
-            @in annotation: ptr(Efl.Text_Annotate_Annotation); [[Annotation to be
-                removed]]
-         }
-         return: bool; [[$true on success, $false otherwise.]]
-      }
-      annotation_positions_get {
-         [[Sets given cursors to the start and end positions of the annotation.
-
-           The cursors $start and $end will be set to the start and end
-           positions of the given annotation $annotation.
-         ]]
-         params {
-             @in annotation: ptr(const(Efl.Text_Annotate_Annotation)); [[Annotation
-                 handle to query]]
-             @in start: ptr(Efl.Text_Cursor_Handle); [[Cursor to be set to the start
-             position of the annotation in the text]]
-             @in end: ptr(Efl.Text_Cursor_Handle); [[Cursor to be set to the end
-             position of the annotation in the text]]
-         }
-      }
-      annotation_is_item {
-         [[Whether this is an "item" type of annotation. Should be used before
-           querying the annotation's geometry, as only "item" annotations have
-           a geometry.
-
-           see @.cursor_item_insert
-           see @.item_geometry_get
-         ]]
-         params {
-            annotation: ptr(Efl.Text_Annotate_Annotation); [[Given annotation]]
-         }
-         return: bool; [[$true if given annotation is an object item, $false otherwise]]
-      }
-      item_geometry_get {
-         [[Queries a given object item for its geometry.
-
-           Note that the provided annotation should be an object item type.
-         ]]
-         params {
-            @in an: ptr(const(Efl.Text_Annotate_Annotation)); [[Given annotation to query]]
-            @out x: int; [[X coordinate of the annotation]]
-            @out y: int; [[Y coordinate of the annotation]]
-            @out w: int; [[Width of the annotation]]
-            @out h: int; [[Height of the annotation]]
-         }
-         return: bool; [[$true if given annotation is an object item, $false otherwise]]
-      }
-      // Cursor
-      @property cursor_item_annotation {
-         [[The object-item annotation at the cursor's position.]]
-         get {
-         }
-         values {
-            annotation: ptr(Efl.Text_Annotate_Annotation); [[Annotation]]
-         }
-         keys {
-            cur: ptr(Efl.Text_Cursor_Handle); [[Cursor object]]
-         }
-      }
-      cursor_item_insert {
-         [[Inserts a object item at specified position.
-
-           This adds a placeholder to be queried by higher-level code,
-           which in turn place graphics on top of it. It essentially places an
-           OBJECT REPLACEMENT CHARACTER and set a special annotation to it.
-         ]]
-         params {
-            cur: ptr(Efl.Text_Cursor_Handle); [[Cursor object]]
-            @in item: string;   [[Item key to be used in higher-up
-                                  code to query and decided what image, emoticon
-                                  etc. to embed.]]
-            @in format: string; [[Size format of the inserted item.
-                                  This hints how to size the item in the text.]]
-         }
-         return: ptr(Efl.Text_Annotate_Annotation); [[The annotation handle of the
-         inserted item.]]
-      }
-   }
-}
-
index 9c8d3e5..9ae449c 100644 (file)
@@ -28,6 +28,4 @@ struct @beta Efl.Ui.Text_Change_Info {
    merge: bool; [[$true if can be merged with the previous one. Used for example with insertion when something is already selected]]
 }
 
-type @extern @beta Efl.Text_Annotate_Annotation: __undefined_type; [[EFL text annotations data structure]]
-
-struct @beta Efl.Text_Cursor_Handle; [[Opaque handle for Text cursors.]]
+struct @extern @beta Efl.Text_Attribute_Handle; [[EFL text annotations data structure]]
\ No newline at end of file
index f45e743..a823e01 100644 (file)
@@ -44,7 +44,6 @@ pub_eo_files = [
   'efl_text_font.eo',
   'efl_text_style.eo',
   'efl_text_format.eo',
-  'efl_text_annotate.eo',
   'efl_text_markup.eo',
   'efl_text_markup_util.eo',
   'efl_gfx_stack.eo',
index 5f623f8..608f672 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "elm_priv.h"
 #include "efl_ui_internal_text_interactive.h"
+#include "efl_canvas_text_internal.h"
 
 #define MY_CLASS EFL_UI_INTERNAL_TEXT_INTERACTIVE_CLASS
 
index 8542df2..411b344 100644 (file)
@@ -153,7 +153,7 @@ struct _Anchor
 {
    Eo                    *obj;
    char                  *name;
-   Efl_Text_Annotate_Annotation *annotation;
+   Efl_Text_Attribute_Handle *annotation;
    Eina_List             *rects;
    int                   gen;
    Eina_Bool              item : 1;
@@ -3180,13 +3180,12 @@ _efl_ui_text_efl_access_text_range_extents_get(const Eo *obj, Efl_Ui_Text_Data *
 }
 
 static Efl_Access_Text_Attribute*
-_textblock_node_format_to_atspi_text_attr(const Eo *obj,
-      Efl_Text_Annotate_Annotation *annotation)
+_textblock_node_format_to_atspi_text_attr(Efl_Text_Attribute_Handle *annotation)
 {
    Efl_Access_Text_Attribute *ret;
    const char *txt;
 
-   txt = efl_text_annotation_get(obj, annotation);
+   txt = efl_text_attribute_factory_attribute_get(annotation);
    if (!txt) return NULL;
 
    ret = calloc(1, sizeof(Efl_Access_Text_Attribute));
@@ -3202,34 +3201,35 @@ _textblock_node_format_to_atspi_text_attr(const Eo *obj,
 EOLIAN static Eina_Bool
 _efl_ui_text_efl_access_text_attribute_get(const Eo *obj, Efl_Ui_Text_Data *_pd EINA_UNUSED, const char *attr_name EINA_UNUSED, int *start_offset, int *end_offset, char **value)
 {
-   Evas_Textblock_Cursor *cur1, *cur2;
+   Efl_Text_Cursor *cur1, *cur2;
    Efl_Access_Text_Attribute *attr;
    Eina_Iterator *annotations;
-   Efl_Text_Annotate_Annotation *an;
+   Efl_Text_Attribute_Handle *an;
 
-   cur1 = evas_object_textblock_cursor_new(obj);
+   Eo *mobj = (Eo *)obj;
+   cur1 = efl_ui_text_cursor_create(mobj);
    if (!cur1) return EINA_FALSE;
 
-   cur2 = evas_object_textblock_cursor_new(obj);
+   cur2 = efl_ui_text_cursor_create(mobj);
    if (!cur2)
      {
-        evas_textblock_cursor_free(cur1);
+        efl_del(cur1);
         return EINA_FALSE;
      }
 
-   evas_textblock_cursor_pos_set(cur1, *start_offset);
-   evas_textblock_cursor_pos_set(cur2, *end_offset);
+   efl_text_cursor_position_set(cur1, *start_offset);
+   efl_text_cursor_position_set(cur2, *end_offset);
 
-   annotations = efl_text_range_annotations_get(obj, cur1, cur2);
+   annotations = efl_text_attribute_factory_range_attributes_get(cur1, cur2);
 
-   evas_textblock_cursor_free(cur1);
-   evas_textblock_cursor_free(cur2);
+   efl_del(cur1);
+   efl_del(cur2);
 
    if (!annotations) return EINA_FALSE;
 
    EINA_ITERATOR_FOREACH(annotations, an)
      {
-        attr = _textblock_node_format_to_atspi_text_attr(obj, an);
+        attr = _textblock_node_format_to_atspi_text_attr(an);
         if (!attr) continue;
         if (!strcmp(attr->name, attr_name))
           {
@@ -3247,35 +3247,35 @@ _efl_ui_text_efl_access_text_attribute_get(const Eo *obj, Efl_Ui_Text_Data *_pd
 EOLIAN static Eina_List*
 _efl_ui_text_efl_access_text_text_attributes_get(const Eo *obj, Efl_Ui_Text_Data *pd EINA_UNUSED, int *start_offset, int *end_offset)
 {
-   Evas_Textblock_Cursor *cur1, *cur2;
+   Efl_Text_Cursor *cur1, *cur2;
    Eina_List *ret = NULL;
    Efl_Access_Text_Attribute *attr;
    Eina_Iterator *annotations;
-   Efl_Text_Annotate_Annotation *an;
-
-   cur1 = evas_object_textblock_cursor_new(obj);
+   Efl_Text_Attribute_Handle *an;
+   Eo *mobj = (Eo *)obj;
+   cur1 = efl_ui_text_cursor_create(mobj);
    if (!cur1) return NULL;
 
-   cur2 = evas_object_textblock_cursor_new(obj);
+   cur2 = efl_ui_text_cursor_create(mobj);
    if (!cur2)
      {
-        evas_textblock_cursor_free(cur1);
+        efl_del(cur1);
         return NULL;
      }
 
-   evas_textblock_cursor_pos_set(cur1, *start_offset);
-   evas_textblock_cursor_pos_set(cur2, *end_offset);
+   efl_text_cursor_position_set(cur1, *start_offset);
+   efl_text_cursor_position_set(cur2, *end_offset);
 
-   annotations = efl_text_range_annotations_get(obj, cur1, cur2);
+   annotations = efl_text_attribute_factory_range_attributes_get(cur1, cur2);
 
-   evas_textblock_cursor_free(cur1);
-   evas_textblock_cursor_free(cur2);
+   efl_del(cur1);
+   efl_del(cur2);
 
    if (!annotations) return NULL;
 
    EINA_ITERATOR_FOREACH(annotations, an)
      {
-        attr = _textblock_node_format_to_atspi_text_attr(obj, an);
+        attr = _textblock_node_format_to_atspi_text_attr(an);
         if (!attr) continue;
         ret = eina_list_append(ret, attr);
      }
@@ -3291,7 +3291,7 @@ _efl_ui_text_efl_access_text_default_attributes_get(const Eo *obj, Efl_Ui_Text_D
    Efl_Access_Text_Attribute *attr;
    Efl_Text_Cursor *start, *end;
    Eina_Iterator *annotations;
-   Efl_Text_Annotate_Annotation *an;
+   Efl_Text_Attribute_Handle *an;
 
    /* Retrieve all annotations in the text. */
    Eo *mobj = (Eo *)obj; /* XXX const */
@@ -3301,11 +3301,11 @@ _efl_ui_text_efl_access_text_default_attributes_get(const Eo *obj, Efl_Ui_Text_D
    efl_text_cursor_move(start, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_FIRST);
    efl_text_cursor_move(end, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_LAST);
 
-   annotations = efl_text_range_annotations_get(obj, efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end));
+   annotations = efl_text_attribute_factory_range_attributes_get(start, end);
 
    EINA_ITERATOR_FOREACH(annotations, an)
      {
-        attr = _textblock_node_format_to_atspi_text_attr(obj, an);
+        attr = _textblock_node_format_to_atspi_text_attr(an);
         if (!attr) continue;
         ret = eina_list_append(ret, attr);
      }
@@ -3677,20 +3677,20 @@ _anchor_format_parse(const char *item)
 }
 
 static Anchor *
-_anchor_get(Eo *obj, Efl_Ui_Text_Data *sd, Efl_Text_Annotate_Annotation *an)
+_anchor_get(Eo *obj, Efl_Ui_Text_Data *sd, Efl_Text_Attribute_Handle *an)
 {
    Anchor *anc;
    Eina_List *i;
    const char *str;
 
-   str = efl_text_annotation_get(obj, an);
+   str = efl_text_attribute_factory_attribute_get(an);
 
    EINA_LIST_FOREACH(sd->anchors, i, anc)
      {
         if (anc->annotation == an) break;
      }
 
-   if (!anc && (efl_text_annotation_is_item(obj, an) || !strncmp(str, "a ", 2)))
+   if (!anc && (efl_text_attribute_factory_attribute_is_item(an) || !strncmp(str, "a ", 2)))
      {
         const char *p;
 
@@ -3699,7 +3699,7 @@ _anchor_get(Eo *obj, Efl_Ui_Text_Data *sd, Efl_Text_Annotate_Annotation *an)
           {
              anc->obj = obj;
              anc->annotation = an;
-             anc->item = efl_text_annotation_is_item(obj, an);
+             anc->item = efl_text_attribute_factory_attribute_is_item(an);
              p = strstr(str, "href=");
              if (p)
                {
@@ -3723,7 +3723,7 @@ _anchors_update(Eo *obj, Efl_Ui_Text_Data *sd)
    Eina_Iterator *it;
    Eina_Position2D off;
    Efl_Text_Cursor *start, *end;
-   Efl_Text_Annotate_Annotation *an;
+   Efl_Text_Attribute_Handle *an;
    Eina_List *i, *ii;
    Anchor *anc;
 
@@ -3741,7 +3741,7 @@ _anchors_update(Eo *obj, Efl_Ui_Text_Data *sd)
    efl_text_cursor_move(start, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_FIRST);
    efl_text_cursor_move(end, EFL_TEXT_CURSOR_MOVE_TYPE_PARAGRAPH_LAST);
 
-   it = efl_text_range_annotations_get(obj, efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end));
+   it = efl_text_attribute_factory_range_attributes_get(start, end);
    efl_del(start);
    efl_del(end);
 
@@ -3783,8 +3783,7 @@ _anchors_update(Eo *obj, Efl_Ui_Text_Data *sd)
                     }
 
                   rect = eina_list_data_get(anc->rects);
-                  efl_text_item_geometry_get(sd->text_obj,
-                        anc->annotation, &cx, &cy, &cw, &ch);
+                  efl_text_attribute_factory_item_geometry_get(anc->annotation, &cx, &cy, &cw, &ch);
                   efl_gfx_entity_size_set(rect->obj, EINA_SIZE2D(cw, ch));
                   efl_gfx_entity_position_set(rect->obj,
                         EINA_POSITION2D(off.x + cx, off.y + cy));
@@ -3798,8 +3797,7 @@ _anchors_update(Eo *obj, Efl_Ui_Text_Data *sd)
                   size_t count;
                   start = efl_ui_text_cursor_create(obj);
                   end = efl_ui_text_cursor_create(obj);
-                  efl_text_annotation_positions_get(obj, anc->annotation,
-                        efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end));
+                  efl_text_attribute_factory_attribute_cursors_get(anc->annotation, start, end);
 
                   range = efl_text_cursor_range_geometry_get(start, end);
                   count = eina_list_count(eina_iterator_container_get(range));
index a82d6a3..ed30047 100644 (file)
@@ -84,6 +84,7 @@ extern "C" {
 */
 #include <canvas/efl_canvas_snapshot.eo.h>
 #include <canvas/efl_text_cursor.eo.h>
+#include <canvas/efl_text_attribute_factory.eo.h>
 #include <canvas/efl_canvas_text.eo.h>
 #include <canvas/efl_canvas_text_factory.eo.h>
 #include <canvas/efl_canvas_vg_node.eo.h>
index 7b5db77..56971d0 100644 (file)
@@ -155,6 +155,7 @@ struct _Efl_Canvas_Object_Animation_Event
  * @{
  */
 #include "canvas/efl_text_cursor.eo.h"
+#include "canvas/efl_text_attribute_factory.eo.h"
 #include "canvas/efl_canvas_text.eo.h"
 #include "canvas/efl_canvas_text_factory.eo.h"
 /**
index d631cdc..0fa833c 100644 (file)
@@ -318,6 +318,17 @@ EWAPI extern const Efl_Event_Description _EFL_ANIMATION_PLAYER_EVENT_PRE_STARTED
  */
 EAPI Eina_Bool evas_textblock_cursor_at_cluster_as_single_glyph(Evas_Textblock_Cursor *cur,Eina_Bool forward);
 
+
+
+
+/*Attribute Factory Internal function*/
+EAPI const char * efl_text_attribute_factory_attribute_get(Efl_Text_Attribute_Handle *annotation);
+EAPI Eina_Iterator * efl_text_attribute_factory_range_attributes_get(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end);
+EAPI void efl_text_attribute_factory_attribute_cursors_get(const Efl_Text_Attribute_Handle *handle, Efl_Text_Cursor *start, Efl_Text_Cursor *end);
+EAPI void efl_text_attribute_factory_remove(Efl_Text_Attribute_Handle *annotation);
+EAPI Eina_Bool efl_text_attribute_factory_attribute_is_item(Efl_Text_Attribute_Handle *annotation);
+EAPI Eina_Bool efl_text_attribute_factory_item_geometry_get(const Efl_Text_Attribute_Handle *annotation, int *x, int *y, int *w, int *h);
+
 #ifdef __cplusplus
 }
 #endif
index 1e53fdb..10c43c7 100644 (file)
@@ -3,7 +3,7 @@ import efl_text_types;
 class @beta Efl.Canvas.Text extends Efl.Canvas.Object implements Efl.Text,
                        Efl.Canvas.Filter.Internal, Efl.Text_Font,
                        Efl.Text_Style, Efl.Text_Format,
-                       Efl.Text_Annotate, Efl.Text_Markup, Efl.Ui.I18n
+                       Efl.Text_Markup, Efl.Ui.I18n
 {
    [[Efl canvas text class]]
    methods {
@@ -236,15 +236,6 @@ class @beta Efl.Canvas.Text extends Efl.Canvas.Object implements Efl.Text,
       Efl.Text_Format.tabstops { get; set; }
       Efl.Text_Format.password { get; set; }
       Efl.Text_Format.replacement_char { get; set; }
-      Efl.Text_Annotate.annotation { set; get; }
-      Efl.Text_Annotate.range_annotations_get;
-      Efl.Text_Annotate.annotation_insert;
-      Efl.Text_Annotate.annotation_del;
-      Efl.Text_Annotate.annotation_is_item;
-      Efl.Text_Annotate.item_geometry_get;
-      Efl.Text_Annotate.annotation_positions_get;
-      Efl.Text_Annotate.cursor_item_annotation { get; }
-      Efl.Text_Annotate.cursor_item_insert;
       Efl.Text_Markup.markup { set; get; }
       Efl.Gfx.Entity.scale { set; }
    }
index 64659ec..9871008 100644 (file)
@@ -83,10 +83,10 @@ typedef struct _Evas_Object_Textblock_Format      Evas_Object_Textblock_Format;
 typedef struct _Evas_Textblock_Selection_Iterator Evas_Textblock_Selection_Iterator;
 /**
  * @internal
- * @typedef Efl_Text_Annotate_Annotation_Iterator
+ * @typedef Efl_Text_Attribute_Handle_Iterator
  * A textblock annotation iterator.
  */
-typedef struct _Efl_Text_Annotate_Annotation_Iterator Efl_Text_Annotate_Annotation_Iterator;
+typedef struct _Efl_Text_Attribute_Handle_Iterator Efl_Text_Attribute_Handle_Iterator;
 /**
  * @internal
  * @typedef Efl_Canvas_Text_Filter
@@ -143,7 +143,7 @@ struct _Evas_Textblock_Node_Format
    const char                         *format;  /**< Cached, parsed and translated version of orig_format. */
    const char                         *orig_format;  /**< Original format information. */
    Evas_Object_Textblock_Node_Text    *text_node;  /**< The text node it's pointing to. */
-   Efl_Text_Annotate_Annotation         *annotation; /**< Pointer to this node's annotation handle (if exists). */
+   Efl_Text_Attribute_Handle          *annotation; /**< Pointer to this node's annotation handle (if exists). */
    size_t                              offset;  /**< Offset from the last format node of the same text. */
    struct {
       unsigned char l, r, t, b;
@@ -166,8 +166,17 @@ struct _Efl_Text_Cursor_Handle
    Eina_Bool                        changed : 1;
 };
 
+struct _Efl_Text_Attribute_Handle
+{
+   EINA_INLIST;
+   Evas_Object                       *obj;
+   Evas_Object_Textblock_Node_Format *start_node, *end_node;
+   Eina_Bool                         is_item : 1; /**< indicates it is an item/object placeholder */
+};
+
 void evas_textblock_cursor_line_jump_by(Efl_Text_Cursor_Handle *cur, int by);
 int _cursor_text_append(Efl_Text_Cursor_Handle *cur, const char *text);
+void evas_textblock_async_block(Evas_Object *eo_object);
 
 
 // Used in Efl.Text.Cursor, where multible objects can have same handle.
@@ -177,6 +186,76 @@ evas_textblock_cursor_ref(Efl_Text_Cursor_Handle *cursor, Eo * cursor_obj);
 // Used in Efl.Text.Cursor, where multible objects can have same handle.
 void
 evas_textblock_cursor_unref(Efl_Text_Cursor_Handle *cursor, Eo * cursor_obj);
+void _evas_textblock_cursor_init(Efl_Text_Cursor_Handle *cur, const Evas_Object *tb);
+
+/*Annoation Functions*/
+/**
+  * @internal
+  * Returns the value of the current data of list node,
+  * and goes to the next list node.
+  *
+  * @param it the iterator.
+  * @param data the data of the current list node.
+  * @return EINA_FALSE if unsuccessful. Otherwise, returns EINA_TRUE.
+  */
+Eina_Bool
+_evas_textblock_annotation_iterator_next(Efl_Text_Attribute_Handle_Iterator *it, void **data);
+
+/**
+  * @internal
+  * Frees the annotation iterator.
+  * @param it the iterator to free
+  * @return EINA_FALSE if unsuccessful. Otherwise, returns EINA_TRUE.
+  */
+void
+_evas_textblock_annotation_iterator_free(Efl_Text_Attribute_Handle_Iterator *it);
+
+
+/**
+  * @internal
+  * Creates newly allocated  iterator associated to a list.
+  * @param list The list.
+  * @return If the memory cannot be allocated, NULL is returned.
+  * Otherwise, a valid iterator is returned.
+  */
+Eina_Iterator *
+_evas_textblock_annotation_iterator_new(Eina_List *list);
+
+
+
+void
+_textblock_cursor_pos_at_fnode_set(Efl_Text_Cursor_Handle *cur,
+      Evas_Object_Textblock_Node_Format *fnode);
+
+
+Eina_Bool
+_evas_textblock_annotations_set(Evas_Object *eo_obj,
+      Efl_Text_Attribute_Handle *an,
+      Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end,
+      const char *format, Eina_Bool is_item);
+
+void
+_evas_textblock_annotation_remove(Evas_Object *eo_obj, Efl_Canvas_Text_Data *o,
+      Efl_Text_Attribute_Handle *an, Eina_Bool remove_nodes, Eina_Bool invalidate);
+
+void
+_evas_textblock_annotations_clear(const Evas_Object *eo_obj);
+
+
+Efl_Text_Attribute_Handle *
+_evas_textblock_annotations_insert(Eo *eo_obj,
+      Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end,
+      const char *format, Eina_Bool is_item);
+
+
+Eina_Inlist *
+_evas_textblock_annotations_get(Evas_Object *o);
+
+void
+_evas_textblock_annotations_node_format_remove(Evas_Object *o, Evas_Object_Textblock_Node_Format *n, int visual_adjustment);
+
+void
+_evas_textblock_relayout_if_needed(Evas_Object *o);
 
 #ifdef EAPI
 # undef EAPI
@@ -213,7 +292,24 @@ evas_textblock_cursor_unref(Efl_Text_Cursor_Handle *cursor, Eo * cursor_obj);
  */
 EAPI void efl_text_cursor_text_object_set(Eo *cursor, Eo *canvas_text_obj, Eo *text_obj);
 
+
+/**
+ * Internally sets cursor handle(legacy textblock cursor) into cursor object.
+ *
+ * @param obj     the cursor object.
+ * @param handle  the text cursor handle.
+ */
+EAPI void efl_text_cursor_handle_set(Eo *obj, Efl_Text_Cursor_Handle *handle);
+
+/**
+ * Internally gets cursor handle(legacy textblock cursor) from cursor object.
+ *
+ * @param obj     the cursor object.
+ * @return        the internal text cursor handle.
+ */
+EAPI Efl_Text_Cursor_Handle *efl_text_cursor_handle_get(const Eo *obj);
+
 #undef EAPI
 #define EAPI
 
-#endif
\ No newline at end of file
+#endif//#ifndef _EFL_CANVAS_TEXT_INTERNAL_H
diff --git a/src/lib/evas/canvas/efl_text_attribute_factory.c b/src/lib/evas/canvas/efl_text_attribute_factory.c
new file mode 100644 (file)
index 0000000..2e01ee8
--- /dev/null
@@ -0,0 +1,133 @@
+//#define EFL_BETA_API_SUPPORT
+#include "evas_common_private.h"
+#include "evas_private.h"
+#include "efl_canvas_text_internal.h"
+#include "efl_text_cursor.eo.h"
+
+#define MY_CLASS EFL_TEXT_ATTRIBUTE_FACTORY_CLASS
+
+typedef struct
+{
+
+} Efl_Text_Attribute_Factory_Data;
+
+EOLIAN static void
+_efl_text_attribute_factory_attribute_insert(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end, const char *format)
+{
+   EINA_SAFETY_ON_TRUE_RETURN(!efl_text_cursor_handle_get(start) ||
+                              !efl_text_cursor_handle_get(end) ||
+                               efl_text_cursor_handle_get(start)->obj != efl_text_cursor_handle_get(end)->obj);
+
+   Eo *eo_obj= efl_text_cursor_handle_get(start)->obj;
+   evas_textblock_async_block(eo_obj);
+
+   _evas_textblock_annotations_insert(eo_obj, efl_text_cursor_handle_get(start), efl_text_cursor_handle_get(end), format,
+         EINA_FALSE);
+   efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
+}
+
+EOLIAN static unsigned int
+_efl_text_attribute_factory_attribute_clear(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end)
+{
+   unsigned int ret = 0;
+   Eina_Iterator *annotations;
+   Efl_Text_Attribute_Handle *an;
+   annotations = efl_text_attribute_factory_range_attributes_get(start, end);
+
+   if (!annotations) return ret;
+
+   EINA_ITERATOR_FOREACH(annotations, an)
+     {
+        ret++;
+        efl_text_attribute_factory_remove(an);
+     }
+   eina_iterator_free(annotations);
+
+   return ret;
+}
+
+const char *
+efl_text_attribute_factory_attribute_get(Efl_Text_Attribute_Handle *annotation)
+{
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(!annotation || !(annotation->obj), NULL);
+
+   return (annotation->start_node ? annotation->start_node->format : NULL);
+}
+
+Eina_Iterator *
+efl_text_attribute_factory_range_attributes_get(const Efl_Text_Cursor *start, const Efl_Text_Cursor *end)
+{
+   Eina_List *lst = NULL;
+   Efl_Text_Attribute_Handle *it;
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(!efl_text_cursor_handle_get(start) ||
+                              !efl_text_cursor_handle_get(end) ||
+                              efl_text_cursor_handle_get(start)->obj != efl_text_cursor_handle_get(end)->obj, NULL);
+
+   Eina_Inlist *annotations = _evas_textblock_annotations_get(efl_text_cursor_handle_get(start)->obj);
+
+   EINA_INLIST_FOREACH(annotations, it)
+     {
+        Efl_Text_Cursor_Handle start2, end2;
+        _evas_textblock_cursor_init(&start2, efl_text_cursor_handle_get(start)->obj);
+        _evas_textblock_cursor_init(&end2, efl_text_cursor_handle_get(start)->obj);
+
+        if (!it->start_node || !it->end_node) continue;
+        _textblock_cursor_pos_at_fnode_set(&start2, it->start_node);
+        _textblock_cursor_pos_at_fnode_set(&end2, it->end_node);
+        evas_textblock_cursor_char_prev(&end2);
+        if (!((evas_textblock_cursor_compare(&start2, efl_text_cursor_handle_get(end)) > 0) ||
+                 (evas_textblock_cursor_compare(&end2, efl_text_cursor_handle_get(start)) < 0)))
+          {
+             lst = eina_list_append(lst, it);
+          }
+     }
+   return _evas_textblock_annotation_iterator_new(lst);
+}
+
+void
+efl_text_attribute_factory_attribute_cursors_get(const Efl_Text_Attribute_Handle *handle, Efl_Text_Cursor *start, Efl_Text_Cursor *end)
+{
+   EINA_SAFETY_ON_TRUE_RETURN (!handle || !(handle->obj));
+
+   efl_text_cursor_text_object_set(start, handle->obj, handle->obj);
+   efl_text_cursor_text_object_set(end, handle->obj, handle->obj);
+   _textblock_cursor_pos_at_fnode_set(efl_text_cursor_handle_get(start), handle->start_node);
+   _textblock_cursor_pos_at_fnode_set(efl_text_cursor_handle_get(end), handle->end_node);
+}
+
+void
+efl_text_attribute_factory_remove(Efl_Text_Attribute_Handle *annotation)
+{
+   EINA_SAFETY_ON_TRUE_RETURN (!annotation || !(annotation->obj));
+
+   evas_textblock_async_block(annotation->obj);
+   _evas_textblock_annotation_remove(annotation->obj, NULL, annotation, EINA_TRUE, EINA_TRUE);
+}
+
+Eina_Bool
+efl_text_attribute_factory_attribute_is_item(Efl_Text_Attribute_Handle *annotation)
+{
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(!annotation || !(annotation->obj), EINA_FALSE);
+
+   return annotation->is_item;
+}
+
+Eina_Bool
+efl_text_attribute_factory_item_geometry_get(const Efl_Text_Attribute_Handle *annotation, int *x, int *y, int *w, int *h)
+{
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(!annotation || !(annotation->obj), EINA_FALSE);
+
+   Efl_Text_Cursor_Handle cur;
+
+   Eo *eo_obj = annotation->obj;
+   Evas_Object_Protected_Data *obj_data = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+   evas_object_async_block(obj_data);
+   _evas_textblock_relayout_if_needed(eo_obj);
+
+   _evas_textblock_cursor_init(&cur, eo_obj);
+   _textblock_cursor_pos_at_fnode_set(&cur, annotation->start_node);
+   return evas_textblock_cursor_format_item_geometry_get(&cur, x, y, w, h);
+}
+
+#include "efl_text_attribute_factory.eo.c"
diff --git a/src/lib/evas/canvas/efl_text_attribute_factory.eo b/src/lib/evas/canvas/efl_text_attribute_factory.eo
new file mode 100644 (file)
index 0000000..52bc871
--- /dev/null
@@ -0,0 +1,37 @@
+import efl_text_types;
+
+abstract @beta Efl.Text.Attribute.Factory extends Efl.Object {
+   [[Attribute factory API to manage text attributes.
+     Use it to insert and remove style attributes (font, size, color, ...) using @Efl.Text.Cursor on EFL Widgets.
+
+     Attributes can be assigned to character ranges, selected using two @Efl.Text.Cursor instances.
+     Cursor instances are already bound to a text object so there's no need to provide it to this class.
+     Style is specified using format strings as described in Efl.Canvas.Text.style_set.
+
+     There is no need to instantiate this class. Use directly the @.attribute_insert and @.attribute_clear static methods.]]
+   methods {
+      attribute_insert @static {
+         [[Inserts an attribute format in a specified range [$start, $end - 1].
+
+           The $format will be applied to the given range.
+           The passed cursors must belong to same textObject, else insertion will be ignored.
+           Passed format parameter uses same format as style in Efl.Canvas.Text.style_set.
+         ]]
+         params {
+              start: const(Efl.Text.Cursor); [[Start of range.]]
+              end: const(Efl.Text.Cursor); [[End of range.]]
+              format: string; [[Attribute format.]]
+         }
+      }
+
+      attribute_clear @static {
+         [[Clear(remove) attributes  at specified range [$start, $end - 1].
+         ]]
+         params {
+              start: const(Efl.Text.Cursor); [[Start of range.]]
+              end: const(Efl.Text.Cursor); [[End of range.]]
+         }
+         return: uint; [[Number of removed attributes.]]
+      }
+   }
+}
index cfa87d7..238c952 100644 (file)
@@ -406,9 +406,10 @@ _efl_text_cursor_range_delete(Eo *obj EINA_UNUSED, Efl_Text_Cursor_Data *pd, Efl
    evas_textblock_cursor_range_delete(pd->handle, efl_text_cursor_handle_get(cur2));
 }
 
-EOLIAN static void
-_efl_text_cursor_handle_set(Eo *obj, Efl_Text_Cursor_Data *pd, Efl_Text_Cursor_Handle *handle)
+EAPI void
+efl_text_cursor_handle_set(Eo *obj, Efl_Text_Cursor_Handle *handle)
 {
+   Efl_Text_Cursor_Data *pd = efl_data_scope_get(obj, MY_CLASS);
    if (handle == pd->handle)
      return;
 
@@ -422,9 +423,10 @@ _efl_text_cursor_handle_set(Eo *obj, Efl_Text_Cursor_Data *pd, Efl_Text_Cursor_H
      }
 }
 
-EOLIAN static Efl_Text_Cursor_Handle *
-_efl_text_cursor_handle_get(const Eo *obj EINA_UNUSED, Efl_Text_Cursor_Data *pd)
+EAPI Efl_Text_Cursor_Handle *
+efl_text_cursor_handle_get(const Eo *obj)
 {
+   Efl_Text_Cursor_Data *pd = efl_data_scope_get(obj, MY_CLASS);
    return pd->handle;
 }
 
index 0485eb9..01c77fc 100644 (file)
@@ -215,19 +215,6 @@ class @beta Efl.Text.Cursor extends Efl.Object implements Efl.Duplicate{
          }
       }
 
-      @property handle {
-         [[This method should rarely be used by users. It gives you a lightweight handle to a cursor.
-
-         You can either replace the handle to change the object this is working on, or get it for caching
-
-         The handle is freed when the object is freed if set, but otherwise it remains under the control of the caller.]]
-         set {  }
-         get {  }
-         values {
-            handle: Efl.Text_Cursor_Handle @by_ref; [[The handle of the cursor object.]]
-         }
-      }
-
       @property text_object {
          [[The text object this cursor is associated with.]]
          get { }
index b4dc3b8..0cebc18 100644 (file)
@@ -445,13 +445,6 @@ typedef struct _User_Style_Entry
    Evas_Textblock_Style *st;
    const char *key;
 } User_Style_Entry;
-struct _Efl_Text_Annotate_Annotation
-{
-   EINA_INLIST;
-   Evas_Object                       *obj;
-   Evas_Object_Textblock_Node_Format *start_node, *end_node;
-   Eina_Bool                         is_item : 1; /**< indicates it is an item/object placeholder */
-};
 
 #define _FMT(x) (o->default_format.format.x)
 #define _FMT_INFO(x) (o->default_format.info.x)
@@ -487,7 +480,7 @@ struct _Evas_Object_Textblock
    Eina_List                          *anchors_item;
    Eina_List                          *obstacles;
    Eina_List                          *hyphen_items; /* Hyphen items storage to free when clearing lines */
-   Efl_Text_Annotate_Annotation         *annotations; /* All currently applied annotations on the text. */
+   Efl_Text_Attribute_Handle          *annotations; /* All currently applied annotations on the text. */
    int                                 last_w, last_h;
    struct {
       int                              l, r, t, b;
@@ -564,7 +557,7 @@ struct _Evas_Textblock_Selection_Iterator
    Eina_List                           *current; /**< Current node in loop. */
 };
 
-struct _Efl_Text_Annotate_Annotation_Iterator
+struct _Efl_Text_Attribute_Handle_Iterator
 {
    Eina_Iterator                       iterator; /**< Eina Iterator. */
    Eina_List                           *list; /**< Head of list. */
@@ -663,12 +656,9 @@ static void _evas_textblock_changed(Efl_Canvas_Text_Data *o, Evas_Object *eo_obj
 static void _evas_textblock_invalidate_all(Efl_Canvas_Text_Data *o);
 static void _evas_textblock_cursors_update_offset(const Efl_Text_Cursor_Handle *cur, const Evas_Object_Textblock_Node_Text *n, size_t start, int offset);
 static void _evas_textblock_cursors_set_node(Efl_Canvas_Text_Data *o, const Evas_Object_Textblock_Node_Text *n, Evas_Object_Textblock_Node_Text *new_node);
-static void _evas_textblock_annotations_clear(Efl_Canvas_Text_Data *o);
-static void _evas_textblock_annotation_remove(Efl_Canvas_Text_Data *o, Efl_Text_Annotate_Annotation *an, Eina_Bool remove_nodes);
 
 static Eina_Bool _evas_textblock_cursor_format_is_visible_get(const Efl_Text_Cursor_Handle *cur);
 static void _evas_textblock_cursor_at_format_set(Efl_Text_Cursor_Handle *cur, const Evas_Object_Textblock_Node_Format *fmt);
-static void _evas_textblock_cursor_init(Efl_Text_Cursor_Handle *cur, const Evas_Object *tb);
 static Evas_Filter_Program *_format_filter_program_get(Efl_Canvas_Text_Data *o, Evas_Object_Textblock_Format *fmt);
 static const char *_textblock_format_node_from_style_tag(Efl_Canvas_Text_Data *o, Evas_Object_Textblock_Node_Format *fnode, const char *format, size_t format_len);
 #ifdef HAVE_HYPHEN
@@ -678,7 +668,6 @@ static const char *_textblock_format_node_from_style_tag(Efl_Canvas_Text_Data *o
 
 static Eina_Bool _evas_textblock_cursor_format_append(Efl_Text_Cursor_Handle *cur, const char *format, Evas_Object_Textblock_Node_Format **_fnode, Eina_Bool is_item);
 EAPI Eina_Bool evas_textblock_cursor_eol_get(const Evas_Textblock_Cursor *cur);
-static void _evas_textblock_cursor_init(Efl_Text_Cursor_Handle *cur, const Evas_Object *tb);
 static Eina_Bool _evas_textblock_cursor_format_is_visible_get(const Efl_Text_Cursor_Handle *cur);
 static void _find_layout_item_line_match(Evas_Object *eo_obj, Evas_Object_Textblock_Node_Text *n, size_t pos, Evas_Object_Textblock_Line **lnr, Evas_Object_Textblock_Item **itr);
 static Evas_Object_Textblock_Node_Format *_evas_textblock_cursor_node_format_at_pos_get(const Efl_Text_Cursor_Handle *cur);
@@ -862,7 +851,7 @@ _nodes_clear(const Evas_Object *eo_obj)
    Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
 
    /* First, clear all annotations that may have spawned format nodes. */
-   _evas_textblock_annotations_clear(o);
+   _evas_textblock_annotations_clear(eo_obj);
 
    while (o->text_nodes)
      {
@@ -7222,6 +7211,13 @@ _relayout_if_needed(const Evas_Object *eo_obj, Efl_Canvas_Text_Data *o)
    return EINA_TRUE;
 }
 
+void
+_evas_textblock_relayout_if_needed(Evas_Object *eo_obj)
+{
+   Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+   _relayout_if_needed(eo_obj, o);
+}
+
 /**
  * @internal
  * Find the layout item and line that match the text node and position passed.
@@ -9248,7 +9244,7 @@ _find_layout_item_match(const Efl_Text_Cursor_Handle *cur, Evas_Object_Textblock
    return previous_format;
 }
 
-static void
+void
 _evas_textblock_cursor_init(Efl_Text_Cursor_Handle *cur, const Evas_Object *tb)
 {
    memset(cur, 0, sizeof(Efl_Text_Cursor_Handle));
@@ -10392,7 +10388,7 @@ _evas_textblock_node_format_remove_matching(Efl_Canvas_Text_Data *o,
                        if (_FORMAT_IS_CLOSER_OF(
                                 fnode->orig_format, fstr + 1, fstr_len - 1))
                          {
-                            Efl_Text_Annotate_Annotation *an = fmt->annotation;
+                            Efl_Text_Attribute_Handle *an = fmt->annotation;
 
                             fnode = eina_list_data_get(i);
                             formats = eina_list_remove_list(formats, i);
@@ -10402,7 +10398,7 @@ _evas_textblock_node_format_remove_matching(Efl_Canvas_Text_Data *o,
                             if (an)
                               {
                                  _evas_textblock_annotation_remove(
-                                       o, an, EINA_FALSE);
+                                       NULL, o, an, EINA_FALSE, EINA_FALSE);
                               }
                             break;
                          }
@@ -10500,6 +10496,13 @@ _evas_textblock_node_format_remove(Efl_Canvas_Text_Data *o, Evas_Object_Textbloc
    _evas_textblock_node_format_free(o, n);
 }
 
+void
+_evas_textblock_annotations_node_format_remove(Evas_Object *eo_obj, Evas_Object_Textblock_Node_Format *n, int visual_adjustment)
+{
+   Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+   _evas_textblock_node_format_remove(o, n, visual_adjustment);
+}
+
 /**
  * @internal
  * Sets all the offsets of the format nodes between start and end in the text
@@ -15945,6 +15948,12 @@ _efl_canvas_text_efl_text_text_get(const Eo *eo_obj, Efl_Canvas_Text_Data *o)
    return o->utf8;
 }
 
+void evas_textblock_async_block(Evas_Object *eo_obj)
+{
+   Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+   ASYNC_BLOCK;
+}
+
 /**
   * @internal
   * Returns the value of the current data of list node,
@@ -15954,8 +15963,8 @@ _efl_canvas_text_efl_text_text_get(const Eo *eo_obj, Efl_Canvas_Text_Data *o)
   * @param data the data of the current list node.
   * @return EINA_FALSE if unsuccessful. Otherwise, returns EINA_TRUE.
   */
-static Eina_Bool
-_evas_textblock_annotation_iterator_next(Efl_Text_Annotate_Annotation_Iterator *it, void **data)
+Eina_Bool
+_evas_textblock_annotation_iterator_next(Efl_Text_Attribute_Handle_Iterator *it, void **data)
 {
    if (!it->current)
      return EINA_FALSE;
@@ -15972,8 +15981,8 @@ _evas_textblock_annotation_iterator_next(Efl_Text_Annotate_Annotation_Iterator *
   * @param it the iterator to free
   * @return EINA_FALSE if unsuccessful. Otherwise, returns EINA_TRUE.
   */
-static void
-_evas_textblock_annotation_iterator_free(Efl_Text_Annotate_Annotation_Iterator *it)
+void
+_evas_textblock_annotation_iterator_free(Efl_Text_Attribute_Handle_Iterator *it)
 {
    EINA_MAGIC_SET(&it->iterator, 0);
    it->current = NULL;
@@ -15993,7 +16002,7 @@ _evas_textblock_annotation_iterator_new(Eina_List *list)
 {
    Evas_Textblock_Selection_Iterator *it;
 
-   it = calloc(1, sizeof(Efl_Text_Annotate_Annotation_Iterator));
+   it = calloc(1, sizeof(Efl_Text_Attribute_Handle_Iterator));
    if (!it) return NULL;
 
    EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
@@ -16009,24 +16018,24 @@ _evas_textblock_annotation_iterator_new(Eina_List *list)
    return &it->iterator;
 }
 
-static void
-_textblock_cursor_pos_at_fnode_set(const Eo *eo_obj EINA_UNUSED,
-      Efl_Text_Cursor_Handle *cur,
+void
+_textblock_cursor_pos_at_fnode_set(Efl_Text_Cursor_Handle *cur,
       Evas_Object_Textblock_Node_Format *fnode)
 {
    cur->node = fnode->text_node;
    cur->pos = _evas_textblock_node_format_pos_get(fnode);
 }
 
-static Eina_Bool
-_textblock_annotation_set(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o,
-      Efl_Text_Annotate_Annotation *an,
+Eina_Bool
+_evas_textblock_annotations_set(Eo *eo_obj,
+      Efl_Text_Attribute_Handle *an,
       Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end,
       const char *format, Eina_Bool is_item)
 {
    int len;
    char *buf;
    Evas_Textblock_Node_Format *fnode;
+   Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
 
    if (an->is_item)
      {
@@ -16058,60 +16067,20 @@ _textblock_annotation_set(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o,
    return EINA_TRUE;
 }
 
-EOLIAN static const char *
-_efl_canvas_text_efl_text_annotate_annotation_get(const Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED,
-      Efl_Text_Annotate_Annotation *annotation)
+Eina_Inlist *
+_evas_textblock_annotations_get(Eo *eo_obj)
 {
-   if (!annotation || (annotation->obj != eo_obj))
-     {
-        ERR("Used invalid handle or of a different object");
-        return NULL;
-     }
-
-   return (annotation->start_node ? annotation->start_node->format : NULL);
+   Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+   return (Eina_Inlist*)o->annotations;
 }
 
-EOLIAN static Eina_Bool
-_efl_canvas_text_efl_text_annotate_annotation_set(Eo *eo_obj,
-      Efl_Canvas_Text_Data *o, Efl_Text_Annotate_Annotation *annotation,
-      const char *format)
+void
+_evas_textblock_annotation_remove(Eo *eo_obj, Efl_Canvas_Text_Data *o,
+      Efl_Text_Attribute_Handle *an, Eina_Bool remove_nodes, Eina_Bool invalidate)
 {
-   ASYNC_BLOCK;
-   Efl_Text_Cursor_Handle start, end;
-   Eina_Bool ret = EINA_TRUE;
-
-   if (!annotation || (annotation->obj != eo_obj))
-     {
-        ERR("Used invalid handle or of a different object");
-        return EINA_FALSE;
-     }
-
-   if (!annotation->start_node || !annotation->end_node) return EINA_FALSE;
-   if (!format || (format[0] == '\0')) return EINA_FALSE;
-
-   _evas_textblock_cursor_init(&start, eo_obj);
-   _evas_textblock_cursor_init(&end, eo_obj);
-
-   /* XXX: Not efficient but works and saves code */
-   _textblock_cursor_pos_at_fnode_set(eo_obj, &start, annotation->start_node);
-   _textblock_cursor_pos_at_fnode_set(eo_obj, &end, annotation->end_node);
-
-   _evas_textblock_node_format_remove(o, annotation->start_node, 0);
-   _evas_textblock_node_format_remove(o, annotation->end_node, 0);
-
-   if (!_textblock_annotation_set(eo_obj, o, annotation, &start, &end, format,
-         EINA_FALSE))
-     {
-        ret = EINA_FALSE;
-     }
-
-   return ret;
-}
+   if (!o)
+     o = efl_data_scope_get(eo_obj, MY_CLASS);
 
-static void
-_evas_textblock_annotation_remove(Efl_Canvas_Text_Data *o,
-      Efl_Text_Annotate_Annotation *an, Eina_Bool remove_nodes)
-{
    if (remove_nodes)
      {
         if (an->is_item)
@@ -16119,64 +16088,53 @@ _evas_textblock_annotation_remove(Efl_Canvas_Text_Data *o,
              /* Remove the OBJ character along with the cursor. */
              Efl_Text_Cursor_Handle cur;
              _evas_textblock_cursor_init(&cur, an->obj);
-             _textblock_cursor_pos_at_fnode_set(an->obj, &cur, an->start_node);
+             _textblock_cursor_pos_at_fnode_set(&cur, an->start_node);
              evas_textblock_cursor_char_delete(&cur);
              return; // 'an' should be deleted after char deletion.
           }
         _evas_textblock_node_format_remove(o, an->start_node, 0);
         _evas_textblock_node_format_remove(o, an->end_node, 0);
      }
-   o->annotations = (Efl_Text_Annotate_Annotation *)
+   o->annotations = (Efl_Text_Attribute_Handle *)
       eina_inlist_remove(EINA_INLIST_GET(o->annotations),
             EINA_INLIST_GET(an));
    free(an);
-}
+   if (invalidate)
+     {
+        o->format_changed = EINA_TRUE;
 
-static void
-_evas_textblock_annotations_clear(Efl_Canvas_Text_Data *o)
-{
-   Efl_Text_Annotate_Annotation *an;
+        //XXX: It's a workaround. The underlying problem is that only new format
+        // nodes are checks when their respective text nodes are invalidated (see
+        // _format_changes_invalidate_text_nodes). Complete removal of the format
+        // nodes was not handled properly (as formats could only be removed via
+        // text changes e.g. deleting characters).
+        _evas_textblock_invalidate_all(o);
 
-   EINA_INLIST_FREE(o->annotations, an)
-     {
-        _evas_textblock_annotation_remove(o, an, EINA_TRUE);
+        _evas_textblock_changed(o, eo_obj);
      }
 }
 
-EOLIAN static Eina_Bool
-_efl_canvas_text_efl_text_annotate_annotation_del(Eo *eo_obj EINA_UNUSED,
-      Efl_Canvas_Text_Data *o, Efl_Text_Annotate_Annotation *annotation)
+void
+_evas_textblock_annotations_clear(const Eo *eo_obj)
 {
-   ASYNC_BLOCK;
-   if (!annotation || (annotation->obj != eo_obj))
+   Efl_Text_Attribute_Handle *an;
+   Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+
+   EINA_INLIST_FREE(o->annotations, an)
      {
-        ERR("Used invalid handle or of a different object");
-        return EINA_FALSE;
+        _evas_textblock_annotation_remove(NULL, o, an, EINA_TRUE, EINA_FALSE);
      }
-
-   _evas_textblock_annotation_remove(o, annotation, EINA_TRUE);
-   o->format_changed = EINA_TRUE;
-
-   //XXX: It's a workaround. The underlying problem is that only new format
-   // nodes are checks when their respective text nodes are invalidated (see
-   // _format_changes_invalidate_text_nodes). Complete removal of the format
-   // nodes was not handled properly (as formats could only be removed via
-   // text changes e.g. deleting characters).
-   _evas_textblock_invalidate_all(o);
-
-   _evas_textblock_changed(o, eo_obj);
-   return EINA_TRUE;
 }
 
-static Efl_Text_Annotate_Annotation *
-_textblock_annotation_insert(Eo *eo_obj, Efl_Canvas_Text_Data *o,
-      Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end,
+Efl_Text_Attribute_Handle *
+_evas_textblock_annotations_insert(Eo *eo_obj, Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end,
       const char *format, Eina_Bool is_item)
 {
-   Efl_Text_Annotate_Annotation *ret = NULL;
+   Efl_Text_Attribute_Handle *ret = NULL;
    Eina_Strbuf *buf;
    Eina_Bool first = EINA_TRUE;
    const char *item;
+   Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
 
    if (!format || (format[0] == '\0') ||
          evas_textblock_cursor_compare(start, end) > 0)
@@ -16215,15 +16173,15 @@ _textblock_annotation_insert(Eo *eo_obj, Efl_Canvas_Text_Data *o,
    format = eina_strbuf_string_get(buf);
    if (format && (format[0] != '\0'))
      {
-        ret = calloc(1, sizeof(Efl_Text_Annotate_Annotation));
+        ret = calloc(1, sizeof(Efl_Text_Attribute_Handle));
         ret->obj = eo_obj;
 
-        o->annotations = (Efl_Text_Annotate_Annotation *)
+        o->annotations = (Efl_Text_Attribute_Handle *)
            eina_inlist_append(EINA_INLIST_GET(o->annotations),
                  EINA_INLIST_GET(ret));
 
 
-        _textblock_annotation_set(eo_obj, o, ret, start, end, format, is_item);
+        _evas_textblock_annotations_set(eo_obj, ret, start, end, format, is_item);
         ret->is_item = is_item;
         _evas_textblock_changed(o, eo_obj);
      }
@@ -16233,123 +16191,6 @@ _textblock_annotation_insert(Eo *eo_obj, Efl_Canvas_Text_Data *o,
    return ret;
 }
 
-EOLIAN static Efl_Text_Annotate_Annotation *
-_efl_canvas_text_efl_text_annotate_annotation_insert(Eo *eo_obj, Efl_Canvas_Text_Data *o,
-      Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end,
-      const char *format)
-{
-   ASYNC_BLOCK;
-   Efl_Text_Annotate_Annotation *ret;
-
-   ret = _textblock_annotation_insert(eo_obj, o, start, end, format,
-         EINA_FALSE);
-   efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
-   return ret;
-}
-
-EOLIAN static Eina_Iterator *
-_efl_canvas_text_efl_text_annotate_range_annotations_get(const Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED,
-      const Evas_Textblock_Cursor *start, const Evas_Textblock_Cursor *end)
-{
-   Eina_List *lst = NULL;
-   Efl_Text_Annotate_Annotation *it;
-
-   EINA_INLIST_FOREACH(o->annotations, it)
-     {
-        Efl_Text_Cursor_Handle start2, end2;
-        _evas_textblock_cursor_init(&start2, eo_obj);
-        _evas_textblock_cursor_init(&end2, eo_obj);
-
-        if (!it->start_node || !it->end_node) continue;
-        _textblock_cursor_pos_at_fnode_set(eo_obj, &start2, it->start_node);
-        _textblock_cursor_pos_at_fnode_set(eo_obj, &end2, it->end_node);
-        evas_textblock_cursor_char_prev(&end2);
-        if (!((evas_textblock_cursor_compare(&start2, end) > 0) ||
-                 (evas_textblock_cursor_compare(&end2, start) < 0)))
-          {
-             lst = eina_list_append(lst, it);
-          }
-     }
-   return _evas_textblock_annotation_iterator_new(lst);
-}
-
-EOLIAN static Efl_Text_Annotate_Annotation *
-_efl_canvas_text_efl_text_annotate_cursor_item_insert(Eo *eo_obj,
-      Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Handle *cur,
-      const char *item, const char *format)
-{
-   Eina_Strbuf *buf = eina_strbuf_new();
-
-   eina_strbuf_append_printf(buf, "%s href=%s", format, item);
-
-   Efl_Text_Annotate_Annotation *ret =
-      _textblock_annotation_insert(cur->obj, o, cur, cur,
-            eina_strbuf_string_get(buf), EINA_TRUE);
-   eina_strbuf_free(buf);
-   efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
-   return ret;
-}
-
-EOLIAN static Efl_Text_Annotate_Annotation *
-_efl_canvas_text_efl_text_annotate_cursor_item_annotation_get(const Eo *eo_obj EINA_UNUSED,
-      Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Handle *cur)
-{
-   Eina_Iterator *it;
-   Efl_Text_Annotate_Annotation *data, *ret = NULL;
-
-   it = efl_text_range_annotations_get(cur->obj,
-         cur, cur);
-   EINA_ITERATOR_FOREACH(it, data)
-     {
-        if (data->is_item)
-          {
-             ret = data;
-             break;
-          }
-     }
-   eina_iterator_free(it);
-   return ret;
-}
-
-EOLIAN static Eina_Bool
-_efl_canvas_text_efl_text_annotate_annotation_is_item(Eo *eo_obj EINA_UNUSED,
-      Efl_Canvas_Text_Data *o EINA_UNUSED,
-      Efl_Text_Annotate_Annotation *annotation)
-{
-   if (!annotation || (annotation->obj != eo_obj))
-     {
-        ERR("Used invalid handle or of a different object");
-        return EINA_FALSE;
-     }
-
-   return annotation->is_item;
-}
-
-EOLIAN static Eina_Bool
-_efl_canvas_text_efl_text_annotate_item_geometry_get(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED,
-      const Efl_Text_Annotate_Annotation *an, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
-{
-   Efl_Text_Cursor_Handle cur;
-
-   Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
-   evas_object_async_block(obj);
-   _relayout_if_needed(eo_obj, o);
-
-   _evas_textblock_cursor_init(&cur, eo_obj);
-   _textblock_cursor_pos_at_fnode_set(eo_obj, &cur, an->start_node);
-   return _evas_textblock_cursor_format_item_geometry_get(&cur, cx, cy, cw, ch);
-}
-
-EOLIAN static void
-_efl_canvas_text_efl_text_annotate_annotation_positions_get(Eo *eo_obj,
-      Efl_Canvas_Text_Data *o EINA_UNUSED,
-      const Efl_Text_Annotate_Annotation *annotation,
-      Efl_Text_Cursor_Handle *start, Efl_Text_Cursor_Handle *end)
-{
-   _textblock_cursor_pos_at_fnode_set(eo_obj, start, annotation->start_node);
-   _textblock_cursor_pos_at_fnode_set(eo_obj, end, annotation->end_node);
-}
-
 static void
 _canvas_text_format_changed(Eo *eo_obj, Efl_Canvas_Text_Data *o)
 {
index d9e6798..07dd725 100644 (file)
@@ -56,6 +56,7 @@ pub_eo_files = [
   'efl_canvas_event_grabber.eo',
   'efl_text_cursor.eo',
   'efl_canvas_text.eo',
+  'efl_text_attribute_factory.eo',
   'efl_canvas_object_animation.eo',
 ]
 
@@ -208,7 +209,8 @@ evas_src += files([
   'evas_canvas3d_node_callback.h',
   'evas_canvas3d_eet.c',
   'efl_canvas_object_animation.c',
-  'efl_text_cursor.c'
+  'efl_text_cursor.c',
+  'efl_text_attribute_factory.c'
   ])
 
 evas_include_directories += include_directories('.')
index 860c674..163d403 100644 (file)
@@ -37,6 +37,7 @@ static const char *style_buf =
    Evas_Object *tb; \
    Evas_Textblock_Style *st; \
    Evas_Textblock_Cursor *cur; \
+   Efl_Text_Cursor       *cur_obj; \
    evas = EVAS_TEST_INIT_EVAS(); \
    evas_font_hinting_set(evas, EVAS_FONT_HINTING_AUTO); \
    tb = evas_object_textblock_add(evas); \
@@ -48,6 +49,9 @@ static const char *style_buf =
    fail_if(strcmp(style_buf, evas_textblock_style_get(st))); \
    evas_object_textblock_style_set(tb, st); \
    cur = evas_object_textblock_cursor_new(tb); \
+   cur_obj =efl_canvas_text_cursor_create(tb);\
+   (void) cur_obj;\
+   (void) cur;\
 do \
 { \
 } \
@@ -58,6 +62,7 @@ do \
 { \
    evas_textblock_cursor_free(cur); \
    evas_object_del(tb); \
+   efl_del(cur_obj); \
    evas_textblock_style_free(st); \
    evas_free(evas); \
 } \
@@ -4304,43 +4309,6 @@ EFL_START_TEST(evas_textblock_text_iface)
 }
 EFL_END_TEST;
 
-static void
-_test_check_annotation(Evas_Object *tb,
-      size_t start_pos, size_t end_pos,
-      size_t len, const char **formats)
-{
-   Efl_Text_Annotate_Annotation *an;
-   Efl_Text_Cursor_Handle *start, *end;
-
-   start = evas_object_textblock_cursor_new(tb);
-   end = evas_object_textblock_cursor_new(tb);
-
-   evas_textblock_cursor_pos_set(start, start_pos);
-   evas_textblock_cursor_pos_set(end, end_pos);
-
-   Eina_Iterator *it =
-      efl_text_range_annotations_get(tb, start, end);
-
-   evas_textblock_cursor_free(start);
-   evas_textblock_cursor_free(end);
-
-   size_t i = 0;
-   EINA_ITERATOR_FOREACH(it, an)
-     {
-        const char *fmt = efl_text_annotation_get(tb,
-              an);
-        ck_assert_msg((i < len),
-              "No formats to check but current annotation is: %s\n", fmt);
-        ck_assert_str_eq(fmt, *formats);
-        formats++;
-        i++;
-     }
-   ck_assert_msg((i == len),
-         "Expected next format (index %lu): %s, but reached end of annotations\n",
-         i, *formats);
-
-   eina_iterator_free(it);
-}
 
 #define _COMP_STR(...) ((const char *[]) { __VA_ARGS__ })
 #define _CREATE_PARAMS(X) (sizeof(X) / sizeof(X[0])), (X)
@@ -4349,11 +4317,10 @@ _test_check_annotation(Evas_Object *tb,
 EFL_START_TEST(evas_textblock_annotation)
 {
    START_TB_TEST();
-   Efl_Text_Annotate_Annotation *an, *an2;
-   Efl_Text_Cursor_Handle *start, *end;
+   Efl_Text_Cursor *start, *end;
 
-   start = evas_object_textblock_cursor_new(tb);
-   end   = evas_object_textblock_cursor_new(tb);
+   start = efl_canvas_text_cursor_create(tb);
+   end   = efl_canvas_text_cursor_create(tb);
 
    const char *buf =
       "This text will check annotation."
@@ -4365,167 +4332,21 @@ EFL_START_TEST(evas_textblock_annotation)
    efl_text_set(tb, buf);
 
    /* Check some trivial cases */
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 3);
-   ck_assert(!efl_text_annotation_insert(tb, start, end, NULL));
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 3);
-   ck_assert(!efl_text_annotation_insert(tb, start, end, ""));
-   evas_textblock_cursor_pos_set(start, 1);
-   evas_textblock_cursor_pos_set(end, 0);
-   ck_assert(!efl_text_annotation_insert(tb, start, end, "color=#fff"));
-
-   /* Insert and check correct positions */
-   _test_check_annotation(tb, 0, 10, _COMP_PARAMS());
-
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 3);
-   efl_text_annotation_insert(tb, start, end, "font_weight=bold");
-   _test_check_annotation(tb, 0, 2, _COMP_PARAMS("font_weight=bold"));
-   _test_check_annotation(tb, 0, 2, _COMP_PARAMS("font_weight=bold"));
-   _test_check_annotation(tb, 4, 10, _COMP_PARAMS());
-
-   evas_textblock_cursor_pos_set(start, 50);
-   evas_textblock_cursor_pos_set(end, 60);
-   efl_text_annotation_insert(tb, start, end, "color=#0ff");
-   _test_check_annotation(tb, 0, 49, _COMP_PARAMS("font_weight=bold"));
-   _test_check_annotation(tb, 0, 50, _COMP_PARAMS("font_weight=bold", "color=#0ff"));
-   _test_check_annotation(tb, 0, 55, _COMP_PARAMS("font_weight=bold", "color=#0ff"));
-   _test_check_annotation(tb, 0, 59, _COMP_PARAMS("font_weight=bold", "color=#0ff"));
-   _test_check_annotation(tb, 40, 50, _COMP_PARAMS("color=#0ff"));
-   _test_check_annotation(tb, 40, 51, _COMP_PARAMS("color=#0ff"));
-   _test_check_annotation(tb, 40, 61, _COMP_PARAMS("color=#0ff"));
-   _test_check_annotation(tb, 59, 60, _COMP_PARAMS("color=#0ff"));
-   _test_check_annotation(tb, 60, 61, _COMP_PARAMS());
-
-   /* See that annotation's positions are updated as text is inserted */
-   efl_text_set(tb, "hello");
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 2);
-   an = efl_text_annotation_insert(tb, start, end, "color=#fff");
-   _test_check_annotation(tb, 2, 3, _COMP_PARAMS());
-   evas_textblock_cursor_pos_set(cur, 0);
-   evas_textblock_cursor_text_append(cur, "a");
-   _test_check_annotation(tb, 2, 3, _COMP_PARAMS("color=#fff"));
-   _test_check_annotation(tb, 3, 4, _COMP_PARAMS());
-
-   /* Replace annotations's format */
-   efl_text_annotation_set(tb, an, "font_size=14");
-   _test_check_annotation(tb, 2, 3, _COMP_PARAMS("font_size=14"));
-   _test_check_annotation(tb, 3, 4, _COMP_PARAMS());
 
-   efl_text_set(tb, "hello world");
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 2);
-   an = efl_text_annotation_insert(tb, start, end, "color=#fff");
-   evas_textblock_cursor_pos_set(start, 2);
-   evas_textblock_cursor_pos_set(end, 3);
-   an2 = efl_text_annotation_insert(tb, start, end, "font_size=14");
-   _test_check_annotation(tb, 0, 1, _COMP_PARAMS("color=#fff"));
-   _test_check_annotation(tb, 2, 3, _COMP_PARAMS("font_size=14"));
-   _test_check_annotation(tb, 0, 3, _COMP_PARAMS("color=#fff", "font_size=14"));
-   efl_text_annotation_set(tb, an, "font_size=10");
-   efl_text_annotation_set(tb, an2, "color=#000");
-   _test_check_annotation(tb, 2, 3, _COMP_PARAMS("color=#000"));
-   _test_check_annotation(tb, 0, 1, _COMP_PARAMS("font_size=10"));
-   _test_check_annotation(tb, 0, 3, _COMP_PARAMS("font_size=10", "color=#000"));
-
-   /* Delete annotations directly */
-   efl_text_set(tb, "hello world");
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 2);
-   an = efl_text_annotation_insert(tb, start, end, "color=#fff");
-   evas_textblock_cursor_pos_set(start, 3);
-   evas_textblock_cursor_pos_set(end, 4);
-   an2 = efl_text_annotation_insert(tb, start, end, "font_size=14");
-   efl_text_annotation_del(tb, an);
-   _test_check_annotation(tb, 0, 3, _COMP_PARAMS("font_size=14"));
-   efl_text_annotation_del(tb, an2);
-   _test_check_annotation(tb, 0, 3, _COMP_PARAMS());
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 1);
-   an = efl_text_annotation_insert(tb, start, end, "color=#fff");
-   _test_check_annotation(tb, 1, 3, _COMP_PARAMS());
-   _test_check_annotation(tb, 0, 0, _COMP_PARAMS("color=#fff"));
-   efl_text_annotation_del(tb, an);
-   _test_check_annotation(tb, 0, 0, _COMP_PARAMS());
-
-   /* Check blocking of "item formats" */
-   efl_text_set(tb, "hello world");
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 1);
-   efl_text_annotation_insert(tb, start, end, "ps");
-   _test_check_annotation(tb, 0, 1, _COMP_PARAMS());
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 1);
-   efl_text_annotation_insert(tb, start, end, "color=#fff");
-   _test_check_annotation(tb, 0, 1, _COMP_PARAMS("color=#fff"));
-   evas_textblock_cursor_pos_set(start, 2);
-   evas_textblock_cursor_pos_set(end, 3);
-   efl_text_annotation_insert(tb, start, end, "br");
-   evas_textblock_cursor_pos_set(start, 6);
-   evas_textblock_cursor_pos_set(end, 7);
-   efl_text_annotation_insert(tb, start, end, "item");
-   _test_check_annotation(tb, 0, 8, _COMP_PARAMS("color=#fff"));
-
-   /* Check "item" annotations */
-   efl_text_set(tb, "abcd");
-   evas_textblock_cursor_pos_set(cur, 4);
-   an = efl_text_cursor_item_insert(tb, cur, "", "size=16x16");
-   _test_check_annotation(tb, 4, 4, _COMP_PARAMS("size=16x16 href="));
-
-   /* Check that format is not extended if it's an "object item" */
-   evas_textblock_cursor_pos_set(cur, 5);
-   evas_textblock_cursor_text_prepend(cur, "a");
-   _test_check_annotation(tb, 5, 7, _COMP_PARAMS());
-   _test_check_annotation(tb, 0, 3, _COMP_PARAMS());
-
-   /* Remove annotation of "item" also removes the OBJ character */
-     {
-        int blen, len;
-        evas_textblock_cursor_pos_set(cur, 5);
-        blen = evas_textblock_cursor_paragraph_text_length_get(cur);
-        efl_text_annotation_del(tb, an);
-        len = evas_textblock_cursor_paragraph_text_length_get(cur);
-        ck_assert_int_eq(len, blen - 1);
-        _test_check_annotation(tb, 0, 5, _COMP_PARAMS());
-     }
-
-   /* Using annotations with new text API */
-   efl_text_set(tb, "hello");
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 5);
-   efl_text_annotation_insert(tb, start, end, "color=#fff");
-   _test_check_annotation(tb, 3, 3, _COMP_PARAMS("color=#fff"));
-   /* Old API */
-   evas_textblock_cursor_pos_set(cur, 5);
-   evas_textblock_cursor_text_prepend(cur, "a");
-   _test_check_annotation(tb, 0, 0, _COMP_PARAMS("color=#fff"));
-   _test_check_annotation(tb, 5, 5, _COMP_PARAMS());
-
-   /* Specific case with PS */
-   efl_text_set(tb, "hello\nworld");
-   evas_textblock_cursor_pos_set(start, 0);
-   evas_textblock_cursor_pos_set(end, 5);
-   efl_text_annotation_insert(tb, start, end, "color=#fff");
-   _test_check_annotation(tb, 4, 4, _COMP_PARAMS("color=#fff"));
-   evas_textblock_cursor_pos_set(cur, 4);
-   /* Cursor position is now: hello|\nworld */
-   evas_textblock_cursor_text_prepend(cur, "a");
-   _test_check_annotation(tb, 0, 0, _COMP_PARAMS("color=#fff"));
-   _test_check_annotation(tb, 5, 5, _COMP_PARAMS("color=#fff"));
-
-   /* Test getting of object item */
-   evas_textblock_cursor_pos_set(cur, 4);
-   an = efl_text_cursor_item_annotation_get(tb, cur);
-   ck_assert(!an);
-   an = efl_text_cursor_item_insert(tb, cur, "", "size=16x16");
-   evas_textblock_cursor_pos_set(cur, 4);
-   an = efl_text_cursor_item_annotation_get(tb, cur);
-   ck_assert(an);
-   ck_assert_str_eq("size=16x16 href=", efl_text_annotation_get(tb, an));
+   efl_text_cursor_position_set(start, 0);
+   efl_text_cursor_position_set(end, 3);
+   efl_text_attribute_factory_attribute_insert(start, end, "font_size=80");
+   efl_text_cursor_position_set(start, 1);
+   efl_text_cursor_position_set(end, 2);
+   efl_text_attribute_factory_attribute_insert(start, end, "font=arial");
+   efl_text_cursor_position_set(start, 2);
+   efl_text_cursor_position_set(end, 3);
+   efl_text_attribute_factory_attribute_insert(start, end, "color=#fff");
 
-   END_TB_TEST();
+   efl_text_cursor_position_set(start, 0);
+   efl_text_cursor_position_set(end, 3);
+   unsigned int count = efl_text_attribute_factory_attribute_clear(start, end);
+   fail_if(count != 3);
 }
 EFL_END_TEST;
 
@@ -4543,7 +4364,7 @@ EFL_END_TEST;
    fail_if(!efl_canvas_text_style_get(txt, NULL) || \
          strcmp(style_buf, efl_canvas_text_style_get(txt, NULL))); \
    cur_obj = efl_canvas_text_cursor_create(txt);\
-   cur = efl_text_cursor_handle_get(cur_obj); \
+   cur = evas_object_textblock_cursor_new(txt); \
    fail_if(!cur); \
 do \
 { \
@@ -4554,6 +4375,7 @@ while (0)
 do \
 { \
    efl_del(cur_obj); \
+   evas_textblock_cursor_free(cur); \
    efl_del(txt); \
    evas_free(evas); \
 } \