edje: Add ellipsize feature and refactory fade_ellipsis, marquee features. 40/126340/42
authorYoungbok Shin <youngb.shin@samsung.com>
Fri, 21 Apr 2017 04:40:21 +0000 (13:40 +0900)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Wed, 5 Jul 2017 02:56:50 +0000 (02:56 +0000)
* example:
    description {
       text {
          ellipsize {
             mode: FADE_MARQUEE; // NONE(default), NORMAL, FADE, FADE_MARQUEE, MARQUEE
             align: END;         // END(default), START, LEFT, RIGHT, LOCALE
             marquee {
                type: ROLL;      // NORMAL(default), ROLL
                speed: 50;       // pixel per sec. It is a scalable variable when its part is scalable.
                // duration: 4.0;// sec per loop. The speed will be changed according to text's length.
                loop: 3;
                loop_delay: 2.0; // sec. delay before starting each loop
             }
          }
       }
    }

@tizen_fix

Change-Id: Iaa1d5d29ed4c2ddfc071c407ca6b7425eb4da199

13 files changed:
data/Makefile.am
data/edje/images/edje_default_fade_image.png [new file with mode: 0644]
data/edje/images/edje_default_left_fade_image.png [deleted file]
data/edje/images/edje_default_right_fade_image.png [deleted file]
src/bin/edje/edje_cc_handlers.c
src/lib/edje/Edje_Common.h
src/lib/edje/edje_calc.c
src/lib/edje/edje_data.c
src/lib/edje/edje_load.c
src/lib/edje/edje_private.h
src/lib/edje/edje_smart.c
src/lib/evas/Evas_Legacy.h
src/lib/evas/canvas/evas_object_textblock.c

index c776c6f..b856e35 100644 (file)
@@ -72,8 +72,7 @@ edjefiles_DATA = edje/include/edje.inc
 EXTRA_DIST += $(edjefiles_DATA)
 
 edjeimagesdir = $(datadir)/edje/images
-edjeimages_DATA = edje/images/edje_default_left_fade_image.png \
-                  edje/images/edje_default_right_fade_image.png
+edjeimages_DATA = edje/images/edje_default_fade_image.png
 EXTRA_DIST += $(edjeimages_DATA)
 
 mimedir = $(datadir)/mime/packages
diff --git a/data/edje/images/edje_default_fade_image.png b/data/edje/images/edje_default_fade_image.png
new file mode 100644 (file)
index 0000000..e2c889e
Binary files /dev/null and b/data/edje/images/edje_default_fade_image.png differ
diff --git a/data/edje/images/edje_default_left_fade_image.png b/data/edje/images/edje_default_left_fade_image.png
deleted file mode 100644 (file)
index 4eea173..0000000
Binary files a/data/edje/images/edje_default_left_fade_image.png and /dev/null differ
diff --git a/data/edje/images/edje_default_right_fade_image.png b/data/edje/images/edje_default_right_fade_image.png
deleted file mode 100644 (file)
index a5a8ca9..0000000
Binary files a/data/edje/images/edje_default_right_fade_image.png and /dev/null differ
index 510dc8e..1fc20d4 100644 (file)
@@ -395,6 +395,14 @@ static void st_collections_group_parts_part_description_text_fade_ellipsis(void)
 static void st_collections_group_parts_part_description_text_ellipsize_mode(void);
 static void st_collections_group_parts_part_description_text_ellipsize_marquee_repeat_limit(void);
 //
+/* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+static void st_collections_group_parts_part_description_text_ellipsize_align(void);
+static void st_collections_group_parts_part_description_text_ellipsize_marquee_type(void);
+static void st_collections_group_parts_part_description_text_ellipsize_marquee_loop(void);
+static void st_collections_group_parts_part_description_text_ellipsize_marquee_loop_delay(void);
+static void st_collections_group_parts_part_description_text_ellipsize_marquee_speed(void);
+static void st_collections_group_parts_part_description_text_ellipsize_marquee_duration(void);
+/* END */
 static void st_collections_group_parts_part_description_box_layout(void);
 static void st_collections_group_parts_part_description_box_align(void);
 static void st_collections_group_parts_part_description_box_padding(void);
@@ -894,6 +902,14 @@ New_Statement_Handler statement_handlers[] =
      {"collections.group.parts.part.description.text.ellipsize.mode", st_collections_group_parts_part_description_text_ellipsize_mode},
      {"collections.group.parts.part.description.text.ellipsize.marquee_repeat_limit", st_collections_group_parts_part_description_text_ellipsize_marquee_repeat_limit},
      //
+     /* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+     {"collections.group.parts.part.description.text.ellipsize.align", st_collections_group_parts_part_description_text_ellipsize_align},
+     {"collections.group.parts.part.description.text.ellipsize.marquee.type", st_collections_group_parts_part_description_text_ellipsize_marquee_type},
+     {"collections.group.parts.part.description.text.ellipsize.marquee.loop", st_collections_group_parts_part_description_text_ellipsize_marquee_loop},
+     {"collections.group.parts.part.description.text.ellipsize.marquee.loop_delay", st_collections_group_parts_part_description_text_ellipsize_marquee_loop_delay},
+     {"collections.group.parts.part.description.text.ellipsize.marquee.speed", st_collections_group_parts_part_description_text_ellipsize_marquee_speed},
+     {"collections.group.parts.part.description.text.ellipsize.marquee.duration", st_collections_group_parts_part_description_text_ellipsize_marquee_duration},
+     /* END */
      {"collections.group.parts.part.description.text.filter", st_collections_group_parts_part_description_filter_code}, /* dup */
      /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to TEXTBLOCK, TEXT part. */
      {"collections.group.parts.part.description.text.fade_ellipsis", st_collections_group_parts_part_description_text_fade_ellipsis},
@@ -1301,6 +1317,9 @@ New_Object_Handler object_handlers[] =
      {"collections.group.parts.part.description.fill.size", NULL},
      {"collections.group.parts.part.description.text", NULL},
      {"collections.group.parts.part.description.text.ellipsize", NULL},
+     /* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+     {"collections.group.parts.part.description.text.ellipsize.marquee", NULL},
+     /* END */
      {"collections.group.parts.part.description.text.fonts", NULL}, /* dup */
      {"collections.group.parts.part.description.images", NULL}, /* dup */
      {"collections.group.parts.part.description.images.set", ob_images_set}, /* dup */
@@ -10077,6 +10096,9 @@ st_collections_group_parts_part_description_text_ellipsize_mode(void)
                                        "FADE_START", EDJE_TEXT_ELLIPSIZE_MODE_FADE_START,
                                        "FADE_END", EDJE_TEXT_ELLIPSIZE_MODE_FADE_END,
                                        "MARQUEE", EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE,
+                                       "NORMAL", EDJE_TEXT_ELLIPSIZE_MODE_NORMAL,
+                                       "FADE", EDJE_TEXT_ELLIPSIZE_MODE_FADE,
+                                       "FADE_MARQUEE", EDJE_TEXT_ELLIPSIZE_MODE_FADE_MARQUEE,
                                        NULL);
 }
 
@@ -10099,6 +10121,140 @@ st_collections_group_parts_part_description_text_ellipsize_marquee_repeat_limit(
 
    ed->text.ellipsize.marquee_repeat_limit = parse_int_range(0, -1, 0x7fffffff);
 }
+
+/* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+static void
+st_collections_group_parts_part_description_text_ellipsize_align(void)
+{
+   Edje_Part_Description_Text *ed;
+
+   check_arg_count(1);
+
+   if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
+       (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
+     {
+        ERR("parse error %s:%i. text attributes in non-TEXT part.",
+            file_in, line - 1);
+        exit(-1);
+     }
+
+   ed = (Edje_Part_Description_Text*) current_desc;
+
+   ed->text.ellipsize.align = parse_enum(0,
+                                         "END", EDJE_TEXT_ELLIPSIZE_ALIGN_END,
+                                         "START", EDJE_TEXT_ELLIPSIZE_ALIGN_START,
+                                         "RIGHT", EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT,
+                                         "LEFT", EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT,
+                                         "LOCALE", EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE,
+                                         NULL);
+}
+
+static void
+st_collections_group_parts_part_description_text_ellipsize_marquee_type(void)
+{
+   Edje_Part_Description_Text *ed;
+
+   check_arg_count(1);
+
+   if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
+       (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
+     {
+        ERR("parse error %s:%i. text attributes in non-TEXT part.",
+            file_in, line - 1);
+        exit(-1);
+     }
+
+   ed = (Edje_Part_Description_Text*) current_desc;
+
+   ed->text.ellipsize.marquee.type = parse_enum(0,
+                                                "DEFAULT", EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_DEFAULT,
+                                                "ROLL", EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL,
+                                                NULL);
+}
+
+static void
+st_collections_group_parts_part_description_text_ellipsize_marquee_loop(void)
+{
+   Edje_Part_Description_Text *ed;
+
+   check_arg_count(1);
+
+   if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
+       (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
+     {
+        ERR("parse error %s:%i. text attributes in non-TEXT part.",
+            file_in, line - 1);
+        exit(-1);
+     }
+
+   ed = (Edje_Part_Description_Text*) current_desc;
+
+   ed->text.ellipsize.marquee_repeat_limit = parse_int_range(0, -1, 0x7fffffff);
+}
+
+static void
+st_collections_group_parts_part_description_text_ellipsize_marquee_loop_delay(void)
+{
+   Edje_Part_Description_Text *ed;
+
+   check_arg_count(1);
+
+   if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
+       (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
+     {
+        ERR("parse error %s:%i. text attributes in non-TEXT part.",
+            file_in, line - 1);
+        exit(-1);
+     }
+
+   ed = (Edje_Part_Description_Text*) current_desc;
+
+   ed->text.ellipsize.marquee.loop_delay = parse_float(0);
+}
+
+static void
+st_collections_group_parts_part_description_text_ellipsize_marquee_speed(void)
+{
+   Edje_Part_Description_Text *ed;
+
+   check_arg_count(1);
+
+   if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
+       (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
+     {
+        ERR("parse error %s:%i. text attributes in non-TEXT part.",
+            file_in, line - 1);
+        exit(-1);
+     }
+
+   ed = (Edje_Part_Description_Text*) current_desc;
+
+   ed->text.ellipsize.marquee.speed = parse_float(0);
+   ed->text.ellipsize.marquee.duration = 0.0;
+}
+
+static void
+st_collections_group_parts_part_description_text_ellipsize_marquee_duration(void)
+{
+   Edje_Part_Description_Text *ed;
+
+   check_arg_count(1);
+
+   if ((current_part->type != EDJE_PART_TYPE_TEXT) &&
+       (current_part->type != EDJE_PART_TYPE_TEXTBLOCK))
+     {
+        ERR("parse error %s:%i. text attributes in non-TEXT part.",
+            file_in, line - 1);
+        exit(-1);
+     }
+
+   ed = (Edje_Part_Description_Text*) current_desc;
+
+   ed->text.ellipsize.marquee.duration = parse_float(0);
+   ed->text.ellipsize.marquee.speed = 0.0;
+}
+/* END */
+
 //
 /** @edcsubsection{collections_group_parts_description_box,
  *                 Group.Parts.Part.Description.Box} */
index 47da82c..76034a5 100644 (file)
@@ -1468,17 +1468,39 @@ typedef enum _Edje_Text_Effect
 //TIZEN_ONLY(20160923): introduction of text marquee
 typedef enum _Edje_Text_Ellipsize_Mode
 {
-   EDJE_TEXT_ELLIPSIZE_MODE_NONE       = 0,
-   EDJE_TEXT_ELLIPSIZE_MODE_START      = 1,
-   EDJE_TEXT_ELLIPSIZE_MODE_MIDDLE     = 2,
-   EDJE_TEXT_ELLIPSIZE_MODE_END        = 3,
-   EDJE_TEXT_ELLIPSIZE_MODE_FADE_START = 4,
-   EDJE_TEXT_ELLIPSIZE_MODE_FADE_END   = 5,
-   EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE    = 6,
-   EDJE_TEXT_ELLIPSIZE_MODE_LAST       = 7
+   EDJE_TEXT_ELLIPSIZE_MODE_NONE         = 0,
+   EDJE_TEXT_ELLIPSIZE_MODE_START        = 1, /* Deprecated */
+   EDJE_TEXT_ELLIPSIZE_MODE_MIDDLE       = 2, /* Deprecated */
+   EDJE_TEXT_ELLIPSIZE_MODE_END          = 3, /* Deprecated */
+   EDJE_TEXT_ELLIPSIZE_MODE_FADE_START   = 4, /* Deprecated */
+   EDJE_TEXT_ELLIPSIZE_MODE_FADE_END     = 5, /* Deprecated */
+   EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE      = 6,
+   EDJE_TEXT_ELLIPSIZE_MODE_NORMAL       = 7,
+   EDJE_TEXT_ELLIPSIZE_MODE_FADE         = 8,
+   EDJE_TEXT_ELLIPSIZE_MODE_FADE_MARQUEE = 9,
+   EDJE_TEXT_ELLIPSIZE_MODE_LAST         = 10
 } Edje_Text_Ellipsize_Mode;
 //
 
+/* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+typedef enum _Edje_Text_Ellipsize_Align
+{
+   EDJE_TEXT_ELLIPSIZE_ALIGN_END    = 0,
+   EDJE_TEXT_ELLIPSIZE_ALIGN_START  = 1,
+   EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT  = 2,
+   EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT   = 3,
+   EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE = 4,
+   EDJE_TEXT_ELLIPSIZE_ALIGN_LAST   = 5
+} Edje_Text_Ellipsize_Align;
+
+typedef enum _Edje_Text_Ellipsize_Marquee_Type
+{
+   EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_DEFAULT = 0,
+   EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL    = 1,
+   EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_LAST    = 2
+} Edje_Text_Ellipsize_Marquee_Type;
+/* END */
+
 /**
  * @typedef (*Edje_Text_Change_Cb)
  *
index 6837d13..0087ebd 100644 (file)
@@ -15,6 +15,11 @@ static void                          _edje_part_recalc_single(Edje *ed, Edje_Rea
                                                               Edje_Calc_Params *params,
                                                               Evas_Coord mmw, Evas_Coord mmh,
                                                               FLOAT_T pos);
+/* TIZEN_ONLY(20170703): Add ellipsize.marquee, ellipsize.fade features */
+static void                          _edje_text_ellipsize_apply(Edje *ed, Edje_Real_Part *ep,
+                                                                Edje_Calc_Params *pf,
+                                                                Edje_Part_Description_Text *chosen_desc);
+/* END */
 
 #define EINA_COW_CALC_PHYSICS_BEGIN(Calc, Write) \
   EINA_COW_WRITE_BEGIN(_edje_calc_params_physics_cow, Calc->physics, Edje_Calc_Params_Physics, Write)
@@ -721,10 +726,6 @@ _edje_part_description_apply(Edje *ed, Edje_Real_Part *ep, const char *d1, doubl
    Edje_Part_Description_Common *last_desc;
    Eina_Bool change_w, change_h;
    Edje_Part_Description_Image *epdi;
-   //TIZEN_ONLY(20160923): introduction of text marquee
-   Edje_Part_Description_Text *last_desc_text;
-   Edje_Part_Description_Text *desc_text;
-   //
 
    if (!d1) d1 = "default";
 
@@ -836,49 +837,6 @@ _edje_part_description_apply(Edje *ed, Edje_Real_Part *ep, const char *d1, doubl
              edje_object_mirrored_set(ep->typedata.swallow->swallowed_object,
                    edje_object_mirrored_get(ed->obj));
           }
-        //TIZEN_ONLY(20160923): introduction of text marquee
-        /* reset margquee_repeat_count */
-        else if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK ||
-                 ep->part->type == EDJE_PART_TYPE_TEXT)
-          {
-             if (last_desc)
-               {
-                  last_desc_text = (Edje_Part_Description_Text *)last_desc;
-                  last_desc_text->text.ellipsize.marquee_repeat_count = 0;
-
-                  desc_text = (Edje_Part_Description_Text *)ep->chosen_description;
-                  if (ep->part->type == EDJE_PART_TYPE_TEXT)
-                    {
-                       if (desc_text->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE)
-                         {
-                            desc_text->text.ellipsis = -1;
-                            evas_object_text_ellipsis_set(ep->object, -1.0);
-                         }
-                       else if ((last_desc_text->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE) &&
-                                (last_desc_text->text.ellipsize.mode != desc_text->text.ellipsize.mode))
-                         {
-                            //FIXME: Need to enhancement using other ellipsize modes
-                            evas_object_text_ellipsis_set(ep->object, desc_text->text.ellipsis);
-                            evas_object_resize(ep->object, ep->w, ep->h);
-                         }
-                    }
-                  else if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
-                    {
-                       if (desc_text->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE)
-                         {
-                            evas_object_textblock_ellipsis_disabled_set(ep->object, EINA_TRUE);
-                         }
-                       else if (last_desc_text->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE &&
-                                last_desc_text->text.ellipsize.mode != desc_text->text.ellipsize.mode)
-                         {
-                            //FIXME: Need to enhancement using other ellipsize modes
-                            Eina_Bool ellipsis = evas_object_textblock_ellipsis_disabled_get(ep->object);
-                            evas_object_textblock_ellipsis_disabled_set(ep->object, ellipsis);
-                         }
-                    }
-               }
-          }
-        //
      }
 
    ed->recalc_hints = EINA_TRUE;
@@ -4137,1861 +4095,2452 @@ _circular_dependency_find(Edje *ed, Edje_Real_Part *ep, Edje_Real_Part *cep, Ein
    return EINA_FALSE;
 }
 
-/*
- * TIZEN_ONLY(20160920): Add fade_ellipsis feature to TEXTBLOCK, TEXT part.
- */
-#define EDJE_DEFAULT_LEFT_FADE_IMAGE "edje_default_left_fade_image.png"
-#define EDJE_DEFAULT_RIGHT_FADE_IMAGE "edje_default_right_fade_image.png"
-
-static void
-_edje_real_part_text_fade_image_set(Edje *ed EINA_UNUSED, Edje_Real_Part *ep, double align)
+void
+_edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *state)
 {
-   Evas_Object *fade_obj = fade_obj = ep->typedata.text->fade.object;
-   char buf[1024];
-
-   if (align == 1.0)
-     snprintf(buf, sizeof(buf), "/usr/share/edje/images/%s", EDJE_DEFAULT_RIGHT_FADE_IMAGE);
-   else
-     snprintf(buf, sizeof(buf), "/usr/share/edje/images/%s", EDJE_DEFAULT_LEFT_FADE_IMAGE);
-
-   evas_object_image_file_set(fade_obj, buf, NULL);
+#ifdef EDJE_CALC_CACHE
+   Eina_Bool proxy_invalidate = EINA_FALSE;
+   int state1 = -1;
+   int state2 = -1;
+   int statec = -1;
+   int statet = -1;
+#else
+   Edje_Calc_Params lp1, lp2;
+#endif
+   int statec1 = -1;
+   int statec2 = -1;
+   int statel1 = -1;
+   int statel2 = -1;
+   int statep1 = -1;
+   int statep2 = -1;
+   int statecl = -1;
+   Edje_Real_Part *center[2] = { NULL, NULL };
+   Edje_Real_Part *light[2] = { NULL, NULL };
+   Edje_Real_Part *persp[2] = { NULL, NULL };
+   Edje_Real_Part *rp1[4] = { NULL, NULL, NULL, NULL };
+   Edje_Real_Part *rp2[4] = { NULL, NULL, NULL, NULL };
+   Edje_Real_Part *clip1 = NULL, *clip2 = NULL;
+   Edje_Calc_Params *p1, *pf;
+   Edje_Part_Description_Common *chosen_desc;
+   Edje_Real_Part *confine_to = NULL;
+   Edje_Real_Part *threshold = NULL;
+   FLOAT_T pos = ZERO, pos2;
+   Edje_Calc_Params lp3;
+   Evas_Coord mmw = 0, mmh = 0;
+   Eina_Bool map_colors_free = EINA_FALSE;
 
-   if (evas_object_image_load_error_get(fade_obj) != EVAS_LOAD_ERROR_NONE)
+   /* GRADIENT ARE GONE, WE MUST IGNORE IT FROM OLD FILE. */
+   if (ep->part->type == EDJE_PART_TYPE_GRADIENT)
      {
-        ERR("Error loading fade image from file \"%s\".", buf);
-
-        switch (evas_object_image_load_error_get(fade_obj))
-          {
-           case EVAS_LOAD_ERROR_GENERIC:
-              ERR("Error type: EVAS_LOAD_ERROR_GENERIC");
-              break;
-           case EVAS_LOAD_ERROR_DOES_NOT_EXIST:
-              ERR("Error type: EVAS_LOAD_ERROR_DOES_NOT_EXIST");
-              break;
-           case EVAS_LOAD_ERROR_PERMISSION_DENIED:
-              ERR("Error type: EVAS_LOAD_ERROR_PERMISSION_DENIED");
-              break;
-           case EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED:
-              ERR("Error type: EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED");
-              break;
-           case EVAS_LOAD_ERROR_CORRUPT_FILE:
-              ERR("Error type: EVAS_LOAD_ERROR_CORRUPT_FILE");
-              break;
-           case EVAS_LOAD_ERROR_UNKNOWN_FORMAT:
-              ERR("Error type: EVAS_LOAD_ERROR_UNKNOWN_FORMAT");
-              break;
-           default:
-              ERR("Error type: ???");
-              break;
-          }
+        ERR("GRADIENT spotted during recalc ! That should never happen ! Send your edje file to devel ml.");
+        return;
      }
-}
-
-static void
-_real_part_object_move_cb_for_fade_object(void *data,
-                                         Evas *e EINA_UNUSED,
-                                         Evas_Object *obj EINA_UNUSED,
-                                         void *event_info EINA_UNUSED)
-{
-   Edje_Real_Part *ep = (Edje_Real_Part *)data;
 
-   if (ep->typedata.text && ep->typedata.text->fade.object)
+   if ((ep->calculated & FLAG_XY) == FLAG_XY && !state)
      {
-        Evas_Coord x, y;
-
-        evas_object_geometry_get(ep->object, &x, &y, NULL, NULL);
-        evas_object_move(ep->typedata.text->fade.object, x, y);
+        return;
      }
-}
-
-/* TIZEN_ONLY(20170322): fix crash issue when Edje tries to clean up fade object */
-void
-_edje_fade_ellipsis_remove(Edje_Real_Part *ep)
-{
-   if (!ep || !ep->typedata.text) return;
-   if (!ep->typedata.text->fade.object) return;
-
-   if (ep->object)
-     evas_object_event_callback_del_full(ep->object, EVAS_CALLBACK_MOVE, _real_part_object_move_cb_for_fade_object, ep);
-
-   evas_object_del(ep->typedata.text->fade.object);
-   ep->typedata.text->fade.object = NULL;
-}
-/* END */
-
-static void
-_edje_fade_ellipsis_apply(Edje *ed, Edje_Real_Part *ep,
-                          Edje_Calc_Params *pf,
-                          Edje_Part_Description_Text *chosen_desc)
-{
-   // DEBUGGING FLAG
-#define FADE_CLIP 1
-#define FADE_IMAGE 1
-#define FADE_IMAGE_BORDER 1
-   //
-   Evas_Coord tw, th;
-   Evas_Coord lx, ly, lw, lh;
-   Evas_Coord iw;
-   Evas_Coord clipper_h;
-   Evas_BiDi_Direction dir;
-   Evas_Object *clipper;
-   Evas_Object *fade_obj;
-   double align;
-   Eina_Bool ellipsis_status;
+   if (ep->calculating & flags)
+     {
+#if 1
+        const char *axes = "NONE", *faxes = "NONE";
 
-   if ((ep->part->type != EDJE_PART_TYPE_TEXTBLOCK) &&
-       (ep->part->type != EDJE_PART_TYPE_TEXT))
-     return;
+        if ((ep->calculating & FLAG_X) &&
+            (ep->calculating & FLAG_Y))
+          axes = "XY";
+        else if ((ep->calculating & FLAG_X))
+          axes = "X";
+        else if ((ep->calculating & FLAG_Y))
+          axes = "Y";
 
-   if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
-     ellipsis_status = evas_object_textblock_ellipsis_status_get(ep->object);
-   else
-     ellipsis_status = evas_object_text_ellipsis_status_get(ep->object);
+        if ((flags & FLAG_X) &&
+            (flags & FLAG_Y))
+          faxes = "XY";
+        else if ((flags & FLAG_X))
+          faxes = "X";
+        else if ((flags & FLAG_Y))
+          faxes = "Y";
+        ERR("Circular dependency when calculating part \"%s\". "
+            "Already calculating %s [%02x] axes. "
+            "Need to calculate %s [%02x] axes",
+            ep->part->name,
+            axes, ep->calculating,
+            faxes, flags);
 
-   // Hide fade image if fade_ellipsis option is off or object size is zero.
-   if ((chosen_desc->text.fade_ellipsis == 0.0) ||
-       (pf->final.w == 0) || (pf->final.h == 0))
-     {
-        if (ep->typedata.text->fade.object)
+        Eina_List *clist = NULL;
+        Eina_List *l = NULL;
+        char *part_name;
+        char depends_path[PATH_MAX] = "";
+        _circular_dependency_find(ed, ep, NULL, &clist);
+        strncat(depends_path, ep->part->name,
+                sizeof(depends_path) - strlen(depends_path) - 1);
+        EINA_LIST_FOREACH(clist, l, part_name)
           {
-#if FADE_CLIP
-             clipper = evas_object_clip_get(ep->typedata.text->fade.object);
-
-             if (clipper) evas_object_clip_set(ep->object, clipper);
-#endif
-             evas_object_hide(ep->typedata.text->fade.object);
+             strncat(depends_path, " -> ",
+                     sizeof(depends_path) - strlen(depends_path) - 1);
+             strncat(depends_path, part_name,
+                     sizeof(depends_path) - strlen(depends_path) - 1);
           }
-
+        ERR("Circular dependency in the group '%s' : %s", ed->group, depends_path);
+        eina_list_free(clist);
+#endif
         return;
      }
 
-   if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
-     {
-        evas_object_textblock_size_formatted_get(ep->object, &tw, &th);
-     }
-   else
+   if (ep->part->type == EDJE_PART_TYPE_GROUP &&
+       ((ep->type == EDJE_RP_TYPE_SWALLOW) &&
+        (ep->typedata.swallow)) &&
+       ep->typedata.swallow->swallowed_object)
      {
-        tw = evas_object_text_horiz_advance_get(ep->object),
-        th = evas_object_text_vert_advance_get(ep->object);
-     }
+        edje_object_scale_set(ep->typedata.swallow->swallowed_object, TO_DOUBLE(ed->scale));
 
-   // Hide fade image if text is not exceed the given area.
-   if ((tw <= pf->final.w) && (th <= pf->final.h) && !ellipsis_status)
-     {
-        if (ep->typedata.text->fade.object)
+        if (ep->description_pos > FROM_DOUBLE(0.5) && ep->param2)
           {
-#if FADE_CLIP
-             clipper = evas_object_clip_get(ep->typedata.text->fade.object);
-
-             if (clipper) evas_object_clip_set(ep->object, clipper);
-#endif
-             evas_object_hide(ep->typedata.text->fade.object);
+             edje_object_update_hints_set(ep->typedata.swallow->swallowed_object, ep->param2->description->min.limit);
+          }
+        else
+          {
+             edje_object_update_hints_set(ep->typedata.swallow->swallowed_object, ep->param1.description->min.limit);
           }
+        if (edje_object_update_hints_get(ep->typedata.swallow->swallowed_object))
+          {
+             Edje *ted;
 
-        return;
+             ted = _edje_fetch(ep->typedata.swallow->swallowed_object);
+             _edje_recalc_do(ted);
+          }
      }
-
-   // Make and show fade image.
-   if (!ep->typedata.text->fade.object)
+   if (ep->part->type == EDJE_PART_TYPE_GROUP &&
+       ((ep->type == EDJE_RP_TYPE_SWALLOW) &&
+        (ep->typedata.swallow)) &&
+       ep->typedata.swallow->swallowed_object)
      {
-#if FADE_IMAGE
-        ep->typedata.text->fade.object = evas_object_image_add(evas_object_evas_get(ep->object));
-#else
-        ep->typedata.text->fade.object = evas_object_rectangle_add(evas_object_evas_get(ep->object));
-        evas_object_color_set(ep->typedata.text->fade.object, 200, 0, 0, 200);
-#endif
-        evas_object_pass_events_set(ep->typedata.text->fade.object, 1);
-        evas_object_pointer_mode_set(ep->typedata.text->fade.object, EVAS_OBJECT_POINTER_MODE_NOGRAB);
-        evas_object_smart_member_add(ep->typedata.text->fade.object, ed->obj);
-        evas_object_event_callback_add(ep->object, EVAS_CALLBACK_MOVE, _real_part_object_move_cb_for_fade_object, ep);
+        Edje_Size *min = NULL, *max = NULL;
 
-        ep->typedata.text->fade.align = -1;
+        if (ep->chosen_description)
+          {
+             min = &ep->chosen_description->min;
+             max = &ep->chosen_description->max;
+          }
+        if (min && max && (min->w == max->w) && (min->h == max->h) && (min->w > 0) && (min->h > 0))
+          mmw = min->w, mmh = min->h;
+        else
+          edje_object_size_min_calc(ep->typedata.swallow->swallowed_object,
+                                    &mmw, &mmh);
      }
 
-   fade_obj = ep->typedata.text->fade.object;
+#ifdef EDJE_CALC_CACHE
+   if (ep->state == ed->state && !state)
+     return;
+#endif
 
-   if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
+   if (ep->param1.description)
      {
-        Evas_Textblock_Cursor *cur;
-
-        cur = evas_object_textblock_cursor_new(ep->object);
-        evas_textblock_cursor_line_coord_set(cur, pf->final.h);
-        evas_textblock_cursor_line_geometry_get(cur, &lx, &ly, &lw, &lh);
-        evas_textblock_cursor_geometry_get(cur,
-                                           NULL, NULL, NULL, NULL, &dir,
-                                           EVAS_TEXTBLOCK_CURSOR_BEFORE);
-
-        if (ly + lh > pf->final.h)
+        if (ep->param1.description->rel1.id_x >= 0)
+          rp1[Rel1X] = ed->table_parts[ep->param1.description->rel1.id_x];
+        if (ep->param1.description->rel2.id_x >= 0)
+          rp1[Rel2X] = ed->table_parts[ep->param1.description->rel2.id_x];
+        if (ep->param1.description->rel1.id_y >= 0)
+          rp1[Rel1Y] = ed->table_parts[ep->param1.description->rel1.id_y];
+        if (ep->param1.description->rel2.id_y >= 0)
+          rp1[Rel2Y] = ed->table_parts[ep->param1.description->rel2.id_y];
+        if (ep->param1.description->clip_to_id >= 0)
           {
-             evas_textblock_cursor_line_coord_set(cur, pf->final.h - lh);
-             evas_textblock_cursor_line_geometry_get(cur, &lx, &ly, &lw, &lh);
-             evas_textblock_cursor_geometry_get(cur,
-                                                NULL, NULL, NULL, NULL, &dir,
-                                                EVAS_TEXTBLOCK_CURSOR_BEFORE);
+             clip1 = ed->table_parts[ep->param1.description->clip_to_id % ed->table_parts_size];
+             ed->has_state_clip = EINA_TRUE;
           }
-
-        evas_textblock_cursor_free(cur);
      }
-   else
+   if (ep->param2)
      {
-        // FIXME: I don't know how should I handle this in evas text.
-        lx = ly = 0;
-        dir = evas_object_text_direction_get(ep->object);
-        evas_object_geometry_get(ep->object, NULL, NULL, &lw, &lh);
+        if (ep->param2->description->rel1.id_x >= 0)
+          rp2[Rel1X] = ed->table_parts[ep->param2->description->rel1.id_x];
+        if (ep->param2->description->rel2.id_x >= 0)
+          rp2[Rel2X] = ed->table_parts[ep->param2->description->rel2.id_x];
+        if (ep->param2->description->rel1.id_y >= 0)
+          rp2[Rel1Y] = ed->table_parts[ep->param2->description->rel1.id_y];
+        if (ep->param2->description->rel2.id_y >= 0)
+          rp2[Rel2Y] = ed->table_parts[ep->param2->description->rel2.id_y];
+        if (ep->param2->description->clip_to_id >= 0)
+          {
+             clip2 = ed->table_parts[ep->param2->description->clip_to_id % ed->table_parts_size];
+             ed->has_state_clip = EINA_TRUE;
+          }
      }
 
-   if (dir != EVAS_BIDI_DIRECTION_RTL)
-     align = chosen_desc->text.fade_ellipsis - 1.0;
-   else
-     align = 1.0 - (chosen_desc->text.fade_ellipsis - 1.0);
-
-#if FADE_IMAGE
-   if (ep->typedata.text->fade.align != align)
+   if (flags & FLAG_X)
      {
-        // Load image from edje.
-        _edje_real_part_text_fade_image_set(ed, ep, align);
-
-        // Default fade image is for LTR.
-        // Assume 10% of fadeout image's left side is opaque. (alpha = 255)
-        if (align == 1.0)
+        ep->calculating |= flags & FLAG_X;
+        if (rp1[Rel1X])
           {
-#if FADE_IMAGE_BORDER
-             evas_object_image_size_get(fade_obj, &iw, NULL);
-             evas_object_image_border_set(fade_obj, 0, iw - (iw * 0.1), 0, 0);
-             evas_object_image_border_scale_set(fade_obj, 1.0);
-             evas_object_image_border_center_fill_set(fade_obj, EVAS_BORDER_FILL_DEFAULT);
+             _edje_part_recalc(ed, rp1[Rel1X], FLAG_X, NULL);
+#ifdef EDJE_CALC_CACHE
+             state1 = rp1[Rel1X]->state;
 #endif
           }
-        else
+        if (rp1[Rel2X])
           {
-#if FADE_IMAGE_BORDER
-             evas_object_image_size_get(fade_obj, &iw, NULL);
-             evas_object_image_border_set(fade_obj, iw - (iw * 0.1), 0, 0, 0);
-             evas_object_image_border_scale_set(fade_obj, 1.0);
-             evas_object_image_border_center_fill_set(fade_obj, EVAS_BORDER_FILL_DEFAULT);
+             _edje_part_recalc(ed, rp1[Rel2X], FLAG_X, NULL);
+#ifdef EDJE_CALC_CACHE
+             if (state1 < rp1[Rel2X]->state)
+               state1 = rp1[Rel2X]->state;
 #endif
           }
-
-        ep->typedata.text->fade.align = (float)align;
-     }
-#endif
-
-   // This will prevent to show horizontally cut off text in multiline textblock.
-   if (ly != 0)
-     clipper_h = ly + lh;
-   else
-     clipper_h = pf->final.h;
-
-#if FADE_IMAGE
-   evas_object_image_fill_set(fade_obj, 0, 0, pf->final.w, clipper_h);
-#endif
-   evas_object_resize(fade_obj, pf->final.w, clipper_h);
-   evas_object_move(fade_obj, ed->x + pf->final.x, ed->y + pf->final.y);
-
-#if FADE_CLIP
-   clipper = evas_object_clip_get(ep->object);
-
-   if (clipper != fade_obj)
-     {
-        evas_object_clip_set(fade_obj, clipper);
-        evas_object_clip_set(ep->object, fade_obj);
-        evas_object_show(fade_obj);
-     }
+        if (ep->param2)
+          {
+             if (rp2[Rel1X])
+               {
+                  _edje_part_recalc(ed, rp2[Rel1X], FLAG_X, NULL);
+#ifdef EDJE_CALC_CACHE
+                  state2 = rp2[Rel1X]->state;
 #endif
-}
-/* END */
-//TIZEN_ONLY(20160923): introduction of text marquee
-#define MARQUEE_CLIP 1
-static void
-_text_marquee_clipper_update(Edje_Real_Part *ep, int x, int y, int w, int h)
-{
-   Evas_Object *prev_clipper;
-
-   if (!ep->text_marquee_clipper)
-     {
-        ep->text_marquee_clipper = evas_object_rectangle_add(evas_object_evas_get(ep->object));
-        evas_object_show(ep->text_marquee_clipper);
-#if MARQUEE_CLIP
-        evas_object_color_set(ep->text_marquee_clipper, 255, 255, 255, 255);
-        prev_clipper = evas_object_clip_get(ep->object);
-        if (prev_clipper) evas_object_clip_set(ep->text_marquee_clipper, prev_clipper);
-        evas_object_clip_set(ep->object, ep->text_marquee_clipper);
-#else
-        /* ambient red color rectangle for debugging clipper object */
-        evas_object_color_set(ep->text_marquee_clipper, 150, 0, 0, 150);
+               }
+             if (rp2[Rel2X])
+               {
+                  _edje_part_recalc(ed, rp2[Rel2X], FLAG_X, NULL);
+#ifdef EDJE_CALC_CACHE
+                  if (state2 < rp2[Rel2X]->state)
+                    state2 = rp2[Rel2X]->state;
 #endif
+               }
+          }
      }
-   else
+   if (flags & FLAG_Y)
      {
-#if MARQUEE_CLIP
-        prev_clipper = evas_object_clip_get(ep->object);
-
-        /* reset marquee clipper changed in _edje_part_recalc */
-        if (prev_clipper && prev_clipper != ep->text_marquee_clipper)
+        ep->calculating |= flags & FLAG_Y;
+        if (rp1[Rel1Y])
+          {
+             _edje_part_recalc(ed, rp1[Rel1Y], FLAG_Y, NULL);
+#ifdef EDJE_CALC_CACHE
+             if (state1 < rp1[Rel1Y]->state)
+               state1 = rp1[Rel1Y]->state;
+#endif
+          }
+        if (rp1[Rel2Y])
           {
-             evas_object_clip_set(ep->text_marquee_clipper, prev_clipper);
-             evas_object_clip_set(ep->object, ep->text_marquee_clipper);
+             _edje_part_recalc(ed, rp1[Rel2Y], FLAG_Y, NULL);
+#ifdef EDJE_CALC_CACHE
+             if (state1 < rp1[Rel2Y]->state)
+               state1 = rp1[Rel2Y]->state;
+#endif
           }
+        if (ep->param2)
+          {
+             if (rp2[Rel1Y])
+               {
+                  _edje_part_recalc(ed, rp2[Rel1Y], FLAG_Y, NULL);
+#ifdef EDJE_CALC_CACHE
+                  if (state2 < rp2[Rel1Y]->state)
+                    state2 = rp2[Rel1Y]->state;
+#endif
+               }
+             if (rp2[Rel2Y])
+               {
+                  _edje_part_recalc(ed, rp2[Rel2Y], FLAG_Y, NULL);
+#ifdef EDJE_CALC_CACHE
+                  if (state2 < rp2[Rel2Y]->state)
+                    state2 = rp2[Rel2Y]->state;
 #endif
+               }
+          }
      }
-
-   evas_object_move(ep->text_marquee_clipper, x, y);
-   evas_object_resize(ep->text_marquee_clipper, w, h);
-}
-
-static void
-_text_marquee_clipper_del(Edje_Real_Part *ep)
-{
-   Evas_Object *prev_clipper;
-
-   if (!ep->text_marquee_clipper) return;
-
-#if MARQUEE_CLIP
-   prev_clipper = evas_object_clip_get(ep->object);
-
-   /* reset marquee clipper changed in _edje_part_recalc */
-   if (prev_clipper && prev_clipper != ep->text_marquee_clipper)
+   if (clip1)
      {
-        evas_object_clip_unset(ep->text_marquee_clipper);
-        evas_object_del(ep->text_marquee_clipper);
-        ep->text_marquee_clipper = NULL;
-
-        evas_object_clip_set(ep->object, prev_clipper);
+        _edje_part_recalc(ed, clip1, flags, NULL);
+        statecl = clip1->state;
      }
-   else
+   if (clip2)
      {
-        prev_clipper = evas_object_clip_get(ep->text_marquee_clipper);
-        evas_object_clip_unset(ep->text_marquee_clipper);
-        evas_object_del(ep->text_marquee_clipper);
-        ep->text_marquee_clipper = NULL;
-
-        if (prev_clipper) evas_object_clip_set(ep->object, prev_clipper);
+        _edje_part_recalc(ed, clip2, flags, NULL);
+        if (statecl < clip2->state)
+          statecl = clip2->state;
      }
-#else
-   evas_object_del(ep->text_marquee_clipper);
-   ep->text_marquee_clipper = NULL;
+   if (ep->drag)
+     {
+        if (ep->drag->confine_to)
+          {
+             confine_to = ep->drag->confine_to;
+             _edje_part_recalc(ed, confine_to, flags, NULL);
+#ifdef EDJE_CALC_CACHE
+             statec = confine_to->state;
 #endif
-}
-
-static Eina_Bool
-_text_object_marquee_animator(void *data)
-{
-   double cur_time;
-   double elapsed_time;
-   double default_time = 0.025; /* moving 1 px for 0.025 sec makes 40 px/sec */
-   Evas_Coord move_length = 0;
-   Edje_Real_Part *ep;
-   Edje_Part_Description_Text *chosen_desc;
-   Evas_Coord_Rectangle text_cur_area;
-   Evas_Coord_Rectangle clipper_area;
-
-   ep = data;
-   chosen_desc = (Edje_Part_Description_Text *)ep->chosen_description;
-
-   evas_object_geometry_get(ep->object, &text_cur_area.x, &text_cur_area.y,
-                                        &text_cur_area.w, &text_cur_area.h);
+          }
+        if (ep->drag->threshold)
+          {
+             threshold = ep->drag->threshold;
+             // We shall not recalculate the threshold position as
+             // we use it's previous position to assert the threshold
+             // the one before moving take action.
+#ifdef EDJE_CALC_CACHE
+             statet = threshold->state;
+#endif
+          }
+     }
+   //   if (ep->text.source)       _edje_part_recalc(ed, ep->text.source, flags);
+   //   if (ep->text.text_source)  _edje_part_recalc(ed, ep->text.text_source, flags);
 
-   if (text_cur_area.w <= ep->w)
+   /* actually calculate now */
+   chosen_desc = ep->chosen_description;
+   if (!chosen_desc)
      {
-        /* text marquee will not work */
-        if (ep->text_marquee_clipper)
-          _text_marquee_clipper_del(ep);
-
-        ep->text_marquee_animator = NULL;
-        return ECORE_CALLBACK_CANCEL;
+        ep->calculating = FLAG_NONE;
+        ep->calculated |= flags;
+        return;
      }
 
-   evas_object_geometry_get(ep->text_marquee_clipper, &clipper_area.x, &clipper_area.y,
-                                                      &clipper_area.w, &clipper_area.h);
-   _text_marquee_clipper_update(ep, clipper_area.x, clipper_area.y,
-                                clipper_area.w, clipper_area.h);
+   pos = ep->description_pos;
 
-   cur_time = ecore_time_get();
-   elapsed_time = cur_time - ep->text_marquee_prev_time;
-   default_time = default_time / evas_object_scale_get(ep->object);
-   while (elapsed_time > default_time)
-    {
-       elapsed_time -= default_time;
-       move_length++;
-    }
-   ep->text_marquee_prev_time = cur_time - elapsed_time;
-   if (ep->text_marquee_to_left)
+   if ((ep->part->type == EDJE_PART_TYPE_PROXY) && chosen_desc->visible)
      {
-        if (text_cur_area.x + text_cur_area.w < clipper_area.x)
-          {
-             if (chosen_desc->text.ellipsize.marquee_repeat_limit != -1)
-               chosen_desc->text.ellipsize.marquee_repeat_count++;
+        int part_id = -1;
 
-             text_cur_area.x = clipper_area.x + clipper_area.w;
-          }
+        if (ep->param2 && (pos >= FROM_DOUBLE(0.5)))
+          part_id = ((Edje_Part_Description_Proxy *)ep->param2->description)->proxy.id;
         else
-          {
-             text_cur_area.x -= move_length;
-          }
+          part_id = ((Edje_Part_Description_Proxy *)chosen_desc)->proxy.id;
+
+#ifdef EDJE_CALC_CACHE
+        Edje_Real_Part *pp;
+        pp = _edje_real_part_state_get(ed, ep, flags, part_id, NULL);
+        if (pp && pp->invalidate) proxy_invalidate = EINA_TRUE;
+#else
+        _edje_real_part_state_get(ed, ep, flags, part_id, NULL);
+#endif
      }
-   else
+
+   /* Recalc if needed the map center && light source */
+   if (ep->param1.description->map.on)
      {
-        if (text_cur_area.x > clipper_area.x + clipper_area.w)
-          {
-             if (chosen_desc->text.ellipsize.marquee_repeat_limit != -1)
-               chosen_desc->text.ellipsize.marquee_repeat_count++;
+        center[0] = _edje_real_part_state_get(ed, ep, flags, ep->param1.description->map.rot.id_center, &statec1);
+        light[0] = _edje_real_part_state_get(ed, ep, flags, ep->param1.description->map.id_light, &statel1);
 
-             text_cur_area.x = clipper_area.x - text_cur_area.w;
-          }
-        else
+        if (chosen_desc->map.persp_on)
           {
-             text_cur_area.x += move_length;
+             persp[0] = _edje_real_part_state_get(ed, ep, flags, ep->param1.description->map.id_persp, &statep1);
           }
      }
 
-   /* check condition to stop marquee animator */
-   if (chosen_desc->text.ellipsize.marquee_repeat_limit ==
-       chosen_desc->text.ellipsize.marquee_repeat_count)
-    {
-       if ((ep->text_marquee_to_left &&
-            text_cur_area.x <= chosen_desc->text.ellipsize.marquee_start_point.x) ||
-           (!ep->text_marquee_to_left &&
-            text_cur_area.x >= chosen_desc->text.ellipsize.marquee_start_point.x))
-         {
-            evas_object_move(ep->object,
-                             chosen_desc->text.ellipsize.marquee_start_point.x,
-                             chosen_desc->text.ellipsize.marquee_start_point.y);
-            ep->text_marquee_animator = NULL;
-            return ECORE_CALLBACK_CANCEL;
-         }
-    }
-
-   evas_object_move(ep->object, text_cur_area.x, text_cur_area.y);
-   return ECORE_CALLBACK_RENEW;
-}
-
-static void
-_text_object_del_cb(void *data, EINA_UNUSED Evas *e, EINA_UNUSED Evas_Object *obj, EINA_UNUSED void *event_info)
-{
-   Edje_Real_Part *ep;
-
-   ep = data;
-
-   if (ep->text_marquee_animator)
+   if (ep->param2 && ep->param2->description->map.on)
      {
-        ecore_animator_del(ep->text_marquee_animator);
-        ep->text_marquee_animator = NULL;
-        _text_marquee_clipper_del(ep);
-     }
-}
+        center[1] = _edje_real_part_state_get(ed, ep, flags, ep->param2->description->map.rot.id_center, &statec2);
+        light[1] = _edje_real_part_state_get(ed, ep, flags, ep->param2->description->map.id_light, &statel2);
 
-static void
-_edje_text_marquee_apply(Edje *ed EINA_UNUSED, Edje_Real_Part *ep,
-                         Edje_Calc_Params *pf,
-                         Edje_Part_Description_Text *chosen_desc)
-{
-   Eina_Bool is_marquee_on;
+        if (chosen_desc->map.persp_on)
+          {
+             persp[1] = _edje_real_part_state_get(ed, ep, flags, ep->param2->description->map.id_persp, &statep2);
+          }
+     }
 
-   is_marquee_on = ((chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE) &&
-                    (chosen_desc->text.ellipsize.marquee_repeat_count !=
-                     chosen_desc->text.ellipsize.marquee_repeat_limit));
+#ifndef EDJE_CALC_CACHE
+   p1 = &lp1;
+   p1.map = eina_cow_alloc(_edje_calc_params_map_cow);
+#ifdef HAVE_EPHYSICS
+   p1.physics = eina_cow_alloc(_edje_calc_params_physics_cow);
+#endif
+#else
+   p1 = &ep->param1.p;
+#endif
 
-   if (ep->text_marquee_animator)
+   if (ep->param1.description)
      {
-        ecore_animator_del(ep->text_marquee_animator);
-        ep->text_marquee_animator = NULL;
+#ifdef EDJE_CALC_CACHE
+        if (ed->all_part_change ||
+            ep->invalidate ||
+            (state1 >= ep->param1.state) ||
+            (statec >= ep->param1.state) ||
+            (statet >= ep->param1.state) ||
+            (statec1 >= ep->param1.state) ||
+            (statel1 >= ep->param1.state) ||
+            (statep1 >= ep->param1.state) ||
+            (statecl >= ep->param1.state) ||
+            proxy_invalidate ||
+            state ||
+            ed->need_map_update ||
+            ((ep->part->type == EDJE_PART_TYPE_TEXT ||
+              ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) &&
+             ed->text_part_change))
+#endif
+        {
+           _edje_part_recalc_single(ed, ep, ep->param1.description,
+                                    chosen_desc, center[0], light[0],
+                                    persp[0], rp1[Rel1X], rp1[Rel1Y],
+                                    rp1[Rel2X], rp1[Rel2Y], clip1, confine_to,
+                                    threshold, p1, mmw, mmh,
+                                    pos);
+#ifdef EDJE_CALC_CACHE
+           if (flags == FLAG_XY) ep->param1.state = ed->state;
+#endif
+        }
      }
-
-   /* in case of marquee mode, do not remove existing clipper */
-   if (is_marquee_on)
+   if (ep->param2)
      {
-        Evas_BiDi_Direction dir;
-        int width, height;
-        int offset_x = 0, offset_y = 0;
-
-
-        ep->text_marquee_prev_time = ecore_time_get();
+        int beginning_pos, part_type;
+        Edje_Calc_Params *p2, *p3;
 
-        /* check text direction */
-        if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
-          {
-             dir = evas_object_paragraph_direction_get(ep->object);
-             if (dir == EVAS_BIDI_DIRECTION_NEUTRAL)
-               {
-                  Evas_Textblock_Cursor *cur;
-                  cur = evas_object_textblock_cursor_new(ep->object);
-                  evas_textblock_cursor_geometry_get(cur,
-                                                     NULL, NULL, NULL, NULL, &dir,
-                                                     EVAS_TEXTBLOCK_CURSOR_BEFORE);
-                  evas_textblock_cursor_free(cur);
-               }
-             evas_object_textblock_size_formatted_get(ep->object, &width, NULL);
-          }
-        else
+        if (ep->current)
           {
-             dir = evas_object_text_direction_get(ep->object);
+             const Edje_Calc_Params_Map *map;
+#ifdef HAVE_EPHYSICS
+             const Edje_Calc_Params_Physics *physics;
+#endif
 
-             /* force recalc by calling resize */
-             evas_object_resize(ep->object, pf->final.w, pf->final.h);
-             width = evas_object_text_horiz_advance_get(ep->object);
-             height = evas_object_text_vert_advance_get(ep->object);
+             map = p1->map;
+#ifdef HAVE_EPHYSICS
+             physics = p1->physics;
+#endif
 
-             /* Handle alignment */
-               {
-                  FLOAT_T align_x;
-                  if (pf->type.text.align.x < FROM_INT(0))
-                    {
-                       if (evas_object_text_direction_get(ep->object) ==
-                           EVAS_BIDI_DIRECTION_RTL)
-                         {
-                            align_x = FROM_INT(1);
-                         }
-                       else
-                         {
-                            align_x = FROM_INT(0);
-                         }
-                    }
-                  else
-                    {
-                       align_x = pf->type.text.align.x;
-                    }
-                  if (width < pf->final.w)
-                    offset_x = TO_INT(SCALE(align_x, (pf->final.w - width)));
-                  if (height < pf->final.h)
-                    offset_y = TO_INT(SCALE(pf->type.text.align.y, (pf->final.h - height)));
-               }
+             /* FIXME: except for text, we don't need in that case to recalc p1 at all*/
+             memcpy(p1, ep->current, sizeof (Edje_Calc_Params));
+
+             p1->map = map;
+#ifdef HAVE_EPHYSICS
+             p1->physics = physics;
+#endif
           }
 
-        chosen_desc->text.ellipsize.marquee_start_point.x = ed->x + pf->final.x + offset_x;
-        chosen_desc->text.ellipsize.marquee_start_point.y = ed->y + pf->final.y + offset_y;
+        p3 = &lp3;
+        lp3.map = eina_cow_alloc(_edje_calc_params_map_cow);
+#ifdef HAVE_EPHYSICS
+        lp3.physics = eina_cow_alloc(_edje_calc_params_physics_cow);
+#endif
 
-        _text_marquee_clipper_update(ep, ed->x + pf->final.x, ed->y + pf->final.y, pf->final.w, pf->final.h);
-
-        /* define marquee direction */
-        ep->text_marquee_to_left = (dir != EVAS_BIDI_DIRECTION_RTL);
+#ifndef EDJE_CALC_CACHE
+        p2 = &lp2;
+        lp2.map = eina_cow_alloc(_edje_calc_params_map_cow);
+#ifdef HAVE_EPHYSICS
+        lp2.physics = eina_cow_alloc(_edje_calc_params_physics_cow);
+#endif
+#else
+        p2 = &ep->param2->p;
 
-        /* adjust start position for RTL text */
-        if (!ep->text_marquee_to_left)
-          chosen_desc->text.ellipsize.marquee_start_point.x += pf->final.w - width;
+        if (ed->all_part_change ||
+            ep->invalidate ||
+            (state2 >= ep->param2->state) ||
+            (statec >= ep->param2->state) ||
+            (statet >= ep->param2->state) ||
+            (statec2 >= ep->param2->state) ||
+            (statel2 >= ep->param2->state) ||
+            (statep2 >= ep->param2->state) ||
+            (statecl >= ep->param2->state) ||
+            proxy_invalidate ||
+            state ||
+            ed->need_map_update ||
+            ((ep->part->type == EDJE_PART_TYPE_TEXT ||
+              ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) &&
+             ed->text_part_change))
+#endif
+        {
+           _edje_part_recalc_single(ed, ep, ep->param2->description,
+                                    chosen_desc, center[1], light[1],
+                                    persp[1], rp2[Rel1X], rp2[Rel1Y],
+                                    rp2[Rel2X], rp2[Rel2Y], clip2, confine_to,
+                                    threshold, p2, mmw, mmh,
+                                    pos);
+#ifdef EDJE_CALC_CACHE
+           if (flags == FLAG_XY) ep->param2->state = ed->state;
+#endif
+        }
 
-        /* move the object to the start point */
-        evas_object_move(ep->object,
-                         chosen_desc->text.ellipsize.marquee_start_point.x,
-                         chosen_desc->text.ellipsize.marquee_start_point.y);
+        pos2 = pos;
+        if (pos2 < ZERO) pos2 = ZERO;
+        else if (pos2 > FROM_INT(1))
+          pos2 = FROM_INT(1);
+        beginning_pos = (pos < FROM_DOUBLE(0.5));
+        part_type = ep->part->type;
 
-        ep->text_marquee_animator = ecore_animator_add(_text_object_marquee_animator, ep);
-        evas_object_event_callback_add(ep->object, EVAS_CALLBACK_DEL,
-                                       _text_object_del_cb, ep);
-     }
-   else
-     {
-        _text_marquee_clipper_del(ep);
-     }
-}
-//
+        /* visible is special */
+        if ((p1->visible) && (!p2->visible))
+          p3->visible = (pos != FROM_INT(1));
+        else if ((!p1->visible) && (p2->visible))
+          p3->visible = (pos != ZERO);
+        else
+          p3->visible = p1->visible;
 
-void
-_edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *state)
-{
-#ifdef EDJE_CALC_CACHE
-   Eina_Bool proxy_invalidate = EINA_FALSE;
-   int state1 = -1;
-   int state2 = -1;
-   int statec = -1;
-   int statet = -1;
-#else
-   Edje_Calc_Params lp1, lp2;
-#endif
-   int statec1 = -1;
-   int statec2 = -1;
-   int statel1 = -1;
-   int statel2 = -1;
-   int statep1 = -1;
-   int statep2 = -1;
-   int statecl = -1;
-   Edje_Real_Part *center[2] = { NULL, NULL };
-   Edje_Real_Part *light[2] = { NULL, NULL };
-   Edje_Real_Part *persp[2] = { NULL, NULL };
-   Edje_Real_Part *rp1[4] = { NULL, NULL, NULL, NULL };
-   Edje_Real_Part *rp2[4] = { NULL, NULL, NULL, NULL };
-   Edje_Real_Part *clip1 = NULL, *clip2 = NULL;
-   Edje_Calc_Params *p1, *pf;
-   Edje_Part_Description_Common *chosen_desc;
-   Edje_Real_Part *confine_to = NULL;
-   Edje_Real_Part *threshold = NULL;
-   FLOAT_T pos = ZERO, pos2;
-   Edje_Calc_Params lp3;
-   Evas_Coord mmw = 0, mmh = 0;
-   Eina_Bool map_colors_free = EINA_FALSE;
-   //TIZEN_ONLY(20160923): introduction of text marquee
-   Evas_Coord tw, th;
-   Edje_Part_Description_Text *text_chosen_desc;
-   //
+        /* clip_to will behave a bit like visible */
+        if (pos == ZERO)
+          p3->clip_to = p1->clip_to;
+        else if (pos == FROM_INT(1))
+          p3->clip_to = p2->clip_to;
+        else if (!p1->clip_to)
+          p3->clip_to = p2->clip_to;
+        else
+          p3->clip_to = p1->clip_to;
 
-   /* GRADIENT ARE GONE, WE MUST IGNORE IT FROM OLD FILE. */
-   if (ep->part->type == EDJE_PART_TYPE_GRADIENT)
-     {
-        ERR("GRADIENT spotted during recalc ! That should never happen ! Send your edje file to devel ml.");
-        return;
-     }
+        p3->smooth = (beginning_pos) ? p1->smooth : p2->smooth;
 
-   if ((ep->calculated & FLAG_XY) == FLAG_XY && !state)
-     {
-        return;
-     }
-   if (ep->calculating & flags)
-     {
-#if 1
-        const char *axes = "NONE", *faxes = "NONE";
+        /* FIXME: do x and y separately base on flag */
 
-        if ((ep->calculating & FLAG_X) &&
-            (ep->calculating & FLAG_Y))
-          axes = "XY";
-        else if ((ep->calculating & FLAG_X))
-          axes = "X";
-        else if ((ep->calculating & FLAG_Y))
-          axes = "Y";
+        p3->final.x = INTP(p1->final.x, p2->final.x, pos);
+        p3->final.y = INTP(p1->final.y, p2->final.y, pos);
+        p3->final.w = INTP(p1->final.w, p2->final.w, pos);
+        p3->final.h = INTP(p1->final.h, p2->final.h, pos);
 
-        if ((flags & FLAG_X) &&
-            (flags & FLAG_Y))
-          faxes = "XY";
-        else if ((flags & FLAG_X))
-          faxes = "X";
-        else if ((flags & FLAG_Y))
-          faxes = "Y";
-        ERR("Circular dependency when calculating part \"%s\". "
-            "Already calculating %s [%02x] axes. "
-            "Need to calculate %s [%02x] axes",
-            ep->part->name,
-            axes, ep->calculating,
-            faxes, flags);
+        p3->eval.x = FFP(p1->eval.x, p2->eval.x, pos);
+        p3->eval.y = FFP(p1->eval.y, p2->eval.y, pos);
+        p3->eval.w = FFP(p1->eval.w, p2->eval.w, pos);
+        p3->eval.h = FFP(p1->eval.h, p2->eval.h, pos);
 
-        Eina_List *clist = NULL;
-        Eina_List *l = NULL;
-        char *part_name;
-        char depends_path[PATH_MAX] = "";
-        _circular_dependency_find(ed, ep, NULL, &clist);
-        strncat(depends_path, ep->part->name,
-                sizeof(depends_path) - strlen(depends_path) - 1);
-        EINA_LIST_FOREACH(clist, l, part_name)
-          {
-             strncat(depends_path, " -> ",
-                     sizeof(depends_path) - strlen(depends_path) - 1);
-             strncat(depends_path, part_name,
-                     sizeof(depends_path) - strlen(depends_path) - 1);
-          }
-        ERR("Circular dependency in the group '%s' : %s", ed->group, depends_path);
-        eina_list_free(clist);
-#endif
-        return;
-     }
+        p3->req.x = INTP(p1->req.x, p2->req.x, pos);
+        p3->req.y = INTP(p1->req.y, p2->req.y, pos);
+        p3->req.w = INTP(p1->req.w, p2->req.w, pos);
+        p3->req.h = INTP(p1->req.h, p2->req.h, pos);
 
-   if (ep->part->type == EDJE_PART_TYPE_GROUP &&
-       ((ep->type == EDJE_RP_TYPE_SWALLOW) &&
-        (ep->typedata.swallow)) &&
-       ep->typedata.swallow->swallowed_object)
-     {
-        edje_object_scale_set(ep->typedata.swallow->swallowed_object, TO_DOUBLE(ed->scale));
+        _edje_part_pixel_adjust(ed, ep, p3);
 
-        if (ep->description_pos > FROM_DOUBLE(0.5) && ep->param2)
+        if (ep->part->dragable.x)
           {
-             edje_object_update_hints_set(ep->typedata.swallow->swallowed_object, ep->param2->description->min.limit);
+             p3->req_drag.x = INTP(p1->req_drag.x, p2->req_drag.x, pos);
+             p3->req_drag.w = INTP(p1->req_drag.w, p2->req_drag.w, pos);
           }
-        else
+        if (ep->part->dragable.y)
           {
-             edje_object_update_hints_set(ep->typedata.swallow->swallowed_object, ep->param1.description->min.limit);
+             p3->req_drag.y = INTP(p1->req_drag.y, p2->req_drag.y, pos);
+             p3->req_drag.h = INTP(p1->req_drag.h, p2->req_drag.h, pos);
           }
-        if (edje_object_update_hints_get(ep->typedata.swallow->swallowed_object))
-          {
-             Edje *ted;
 
-             ted = _edje_fetch(ep->typedata.swallow->swallowed_object);
-             _edje_recalc_do(ted);
-          }
-     }
-   if (ep->part->type == EDJE_PART_TYPE_GROUP &&
-       ((ep->type == EDJE_RP_TYPE_SWALLOW) &&
-        (ep->typedata.swallow)) &&
-       ep->typedata.swallow->swallowed_object)
-     {
-        Edje_Size *min = NULL, *max = NULL;
+        p3->color.r = INTP(p1->color.r, p2->color.r, pos2);
+        p3->color.g = INTP(p1->color.g, p2->color.g, pos2);
+        p3->color.b = INTP(p1->color.b, p2->color.b, pos2);
+        p3->color.a = INTP(p1->color.a, p2->color.a, pos2);
 
-        if (ep->chosen_description)
+#ifdef HAVE_EPHYSICS
+        if (ep->part->physics_body || ep->body)
           {
-             min = &ep->chosen_description->min;
-             max = &ep->chosen_description->max;
-          }
-        if (min && max && (min->w == max->w) && (min->h == max->h) && (min->w > 0) && (min->h > 0))
-          mmw = min->w, mmh = min->h;
-        else
-          edje_object_size_min_calc(ep->typedata.swallow->swallowed_object,
-                                    &mmw, &mmh);
-     }
+             EINA_COW_CALC_PHYSICS_BEGIN(p3, p3_write)
+             {
+                p3_write->mass = TO_DOUBLE(FINTP(p1->physics->mass, p2->physics->mass,
+                                                 pos));
+                p3_write->restitution = TO_DOUBLE(FINTP(p1->physics->restitution,
+                                                        p2->physics->restitution,
+                                                        pos));
+                p3_write->friction = TO_DOUBLE(FINTP(p1->physics->friction,
+                                                     p2->physics->friction, pos));
+                p3_write->density = TO_DOUBLE(FINTP(p1->physics->density,
+                                                    p2->physics->density, pos));
+                p3_write->hardness = TO_DOUBLE(FINTP(p1->physics->hardness,
+                                                     p2->physics->hardness, pos));
 
-#ifdef EDJE_CALC_CACHE
-   if (ep->state == ed->state && !state)
-     return;
-#endif
+                p3_write->damping.linear = TO_DOUBLE(FINTP(p1->physics->damping.linear,
+                                                           p2->physics->damping.linear, pos));
+                p3_write->damping.angular = TO_DOUBLE(FINTP(p1->physics->damping.angular,
+                                                            p2->physics->damping.angular, pos));
 
-   if (ep->param1.description)
-     {
-        if (ep->param1.description->rel1.id_x >= 0)
-          rp1[Rel1X] = ed->table_parts[ep->param1.description->rel1.id_x];
-        if (ep->param1.description->rel2.id_x >= 0)
-          rp1[Rel2X] = ed->table_parts[ep->param1.description->rel2.id_x];
-        if (ep->param1.description->rel1.id_y >= 0)
-          rp1[Rel1Y] = ed->table_parts[ep->param1.description->rel1.id_y];
-        if (ep->param1.description->rel2.id_y >= 0)
-          rp1[Rel2Y] = ed->table_parts[ep->param1.description->rel2.id_y];
-        if (ep->param1.description->clip_to_id >= 0)
-          {
-             clip1 = ed->table_parts[ep->param1.description->clip_to_id % ed->table_parts_size];
-             ed->has_state_clip = EINA_TRUE;
-          }
-     }
-   if (ep->param2)
-     {
-        if (ep->param2->description->rel1.id_x >= 0)
-          rp2[Rel1X] = ed->table_parts[ep->param2->description->rel1.id_x];
-        if (ep->param2->description->rel2.id_x >= 0)
-          rp2[Rel2X] = ed->table_parts[ep->param2->description->rel2.id_x];
-        if (ep->param2->description->rel1.id_y >= 0)
-          rp2[Rel1Y] = ed->table_parts[ep->param2->description->rel1.id_y];
-        if (ep->param2->description->rel2.id_y >= 0)
-          rp2[Rel2Y] = ed->table_parts[ep->param2->description->rel2.id_y];
-        if (ep->param2->description->clip_to_id >= 0)
-          {
-             clip2 = ed->table_parts[ep->param2->description->clip_to_id % ed->table_parts_size];
-             ed->has_state_clip = EINA_TRUE;
+                p3_write->sleep.linear = TO_DOUBLE(FINTP(p1->physics->sleep.linear,
+                                                         p2->physics->sleep.linear, pos));
+                p3_write->sleep.angular = TO_DOUBLE(FINTP(p1->physics->sleep.angular,
+                                                          p2->physics->sleep.angular, pos));
+
+                p3_write->z = INTP(p1->physics->z, p2->physics->z, pos);
+                p3_write->depth = INTP(p1->physics->depth, p2->physics->depth, pos);
+
+                if ((p1->physics->ignore_part_pos) && (p2->physics->ignore_part_pos))
+                  p3_write->ignore_part_pos = 1;
+                else
+                  p3_write->ignore_part_pos = 0;
+
+                if ((p1->physics->material) && (p2->physics->material))
+                  p3_write->material = p1->physics->material;
+                else
+                  p3_write->material = EPHYSICS_BODY_MATERIAL_CUSTOM;
+
+                p3_write->light_on = p1->physics->light_on || p2->physics->light_on;
+                p3_write->backcull = p1->physics->backcull || p2->physics->backcull;
+
+                p3_write->mov_freedom.lin.x = p1->physics->mov_freedom.lin.x ||
+                  p2->physics->mov_freedom.lin.x;
+                p3_write->mov_freedom.lin.y = p1->physics->mov_freedom.lin.y ||
+                  p2->physics->mov_freedom.lin.y;
+                p3_write->mov_freedom.lin.z = p1->physics->mov_freedom.lin.z ||
+                  p2->physics->mov_freedom.lin.z;
+                p3_write->mov_freedom.ang.x = p1->physics->mov_freedom.ang.x ||
+                  p2->physics->mov_freedom.ang.x;
+                p3_write->mov_freedom.ang.y = p1->physics->mov_freedom.ang.y ||
+                  p2->physics->mov_freedom.ang.y;
+                p3_write->mov_freedom.ang.z = p1->physics->mov_freedom.ang.z ||
+                  p2->physics->mov_freedom.ang.z;
+             }
+             EINA_COW_CALC_PHYSICS_END(p3, p3_write);
           }
-     }
+#endif
 
-   if (flags & FLAG_X)
-     {
-        ep->calculating |= flags & FLAG_X;
-        if (rp1[Rel1X])
+        switch (part_type)
           {
-             _edje_part_recalc(ed, rp1[Rel1X], FLAG_X, NULL);
-#ifdef EDJE_CALC_CACHE
-             state1 = rp1[Rel1X]->state;
-#endif
+           case EDJE_PART_TYPE_IMAGE:
+             p3->type.common.spec.image.l = INTP(p1->type.common.spec.image.l, p2->type.common.spec.image.l, pos);
+             p3->type.common.spec.image.r = INTP(p1->type.common.spec.image.r, p2->type.common.spec.image.r, pos);
+             p3->type.common.spec.image.t = INTP(p1->type.common.spec.image.t, p2->type.common.spec.image.t, pos);
+             p3->type.common.spec.image.b = INTP(p1->type.common.spec.image.b, p2->type.common.spec.image.b, pos);
+             p3->type.common.spec.image.border_scale_by = FFP(p1->type.common.spec.image.border_scale_by, p2->type.common.spec.image.border_scale_by, pos);
+
+           case EDJE_PART_TYPE_PROXY:
+             p3->type.common.fill.x = INTP(p1->type.common.fill.x, p2->type.common.fill.x, pos);
+             p3->type.common.fill.y = INTP(p1->type.common.fill.y, p2->type.common.fill.y, pos);
+             p3->type.common.fill.w = INTP(p1->type.common.fill.w, p2->type.common.fill.w, pos);
+             p3->type.common.fill.h = INTP(p1->type.common.fill.h, p2->type.common.fill.h, pos);
+             break;
+
+           case EDJE_PART_TYPE_TEXT:
+             p3->type.text.size = INTP(p1->type.text.size, p2->type.text.size, pos);
+
+           /* no break as we share code with the TEXTBLOCK type here. Intended fall-through */
+           case EDJE_PART_TYPE_TEXTBLOCK:
+             p3->type.text.color2.r = INTP(p1->type.text.color2.r, p2->type.text.color2.r, pos2);
+             p3->type.text.color2.g = INTP(p1->type.text.color2.g, p2->type.text.color2.g, pos2);
+             p3->type.text.color2.b = INTP(p1->type.text.color2.b, p2->type.text.color2.b, pos2);
+             p3->type.text.color2.a = INTP(p1->type.text.color2.a, p2->type.text.color2.a, pos2);
+
+             p3->type.text.color3.r = INTP(p1->type.text.color3.r, p2->type.text.color3.r, pos2);
+             p3->type.text.color3.g = INTP(p1->type.text.color3.g, p2->type.text.color3.g, pos2);
+             p3->type.text.color3.b = INTP(p1->type.text.color3.b, p2->type.text.color3.b, pos2);
+             p3->type.text.color3.a = INTP(p1->type.text.color3.a, p2->type.text.color3.a, pos2);
+
+             p3->type.text.align.x = FFP(p1->type.text.align.x, p2->type.text.align.x, pos);
+             p3->type.text.align.y = FFP(p1->type.text.align.y, p2->type.text.align.y, pos);
+             p3->type.text.ellipsis = TO_DOUBLE(FINTP(p1->type.text.ellipsis, p2->type.text.ellipsis, pos2));
+             break;
           }
-        if (rp1[Rel2X])
+
+        /* mapped is a special case like visible */
+        if ((p1->mapped) && (!p2->mapped))
+          p3->mapped = (pos != FROM_INT(1));
+        else if ((!p1->mapped) && (p2->mapped))
+          p3->mapped = (pos != ZERO);
+        else
+          p3->mapped = p1->mapped;
+
+        p3->persp_on = p3->mapped ? p1->persp_on | p2->persp_on : 0;
+        p3->lighted = p3->mapped ? p1->lighted | p2->lighted : 0;
+        if (p3->mapped)
           {
-             _edje_part_recalc(ed, rp1[Rel2X], FLAG_X, NULL);
-#ifdef EDJE_CALC_CACHE
-             if (state1 < rp1[Rel2X]->state)
-               state1 = rp1[Rel2X]->state;
-#endif
+             EINA_COW_CALC_MAP_BEGIN(p3, p3_write)
+             {
+                p3_write->center.x = INTP(p1->map->center.x, p2->map->center.x, pos);
+                p3_write->center.y = INTP(p1->map->center.y, p2->map->center.y, pos);
+                p3_write->center.z = INTP(p1->map->center.z, p2->map->center.z, pos);
+                p3_write->rotation.x = FFP(p1->map->rotation.x, p2->map->rotation.x, pos);
+                p3_write->rotation.y = FFP(p1->map->rotation.y, p2->map->rotation.y, pos);
+                p3_write->rotation.z = FFP(p1->map->rotation.z, p2->map->rotation.z, pos);
+                p3_write->zoom.x = FFP(p1->map->zoom.x, p2->map->zoom.x, pos);
+                p3_write->zoom.y = FFP(p1->map->zoom.y, p2->map->zoom.y, pos);
+
+#define MIX(P1, P2, P3, pos, info) \
+  P3->info = P1->map->info + TO_INT(SCALE(pos, P2->map->info - P1->map->info));
+                map_colors_free = _map_colors_interp(p1, p2, p3_write, pos);
+
+                if (p1->lighted && p2->lighted)
+                  {
+                     MIX(p1, p2, p3_write, pos, light.x);
+                     MIX(p1, p2, p3_write, pos, light.y);
+                     MIX(p1, p2, p3_write, pos, light.z);
+                     MIX(p1, p2, p3_write, pos, light.r);
+                     MIX(p1, p2, p3_write, pos, light.g);
+                     MIX(p1, p2, p3_write, pos, light.b);
+                     MIX(p1, p2, p3_write, pos, light.ar);
+                     MIX(p1, p2, p3_write, pos, light.ag);
+                     MIX(p1, p2, p3_write, pos, light.ab);
+                  }
+                else if (p1->lighted)
+                  {
+                     memcpy(&p3_write->light, &p1->map->light, sizeof (p1->map->light));
+                  }
+                else if (p2->lighted)
+                  {
+                     memcpy(&p3_write->light, &p2->map->light, sizeof (p2->map->light));
+                  }
+
+                if (p1->persp_on && p2->persp_on)
+                  {
+                     MIX(p1, p2, p3_write, pos, persp.x);
+                     MIX(p1, p2, p3_write, pos, persp.y);
+                     MIX(p1, p2, p3_write, pos, persp.z);
+                     MIX(p1, p2, p3_write, pos, persp.focal);
+                  }
+                else if (p1->persp_on)
+                  {
+                     memcpy(&p3_write->persp, &p1->map->persp, sizeof (p1->map->persp));
+                  }
+                else if (p2->persp_on)
+                  {
+                     memcpy(&p3_write->persp, &p2->map->persp, sizeof (p2->map->persp));
+                  }
+             }
+             EINA_COW_CALC_MAP_END(p3, p3_write);
           }
-        if (ep->param2)
-          {
-             if (rp2[Rel1X])
-               {
-                  _edje_part_recalc(ed, rp2[Rel1X], FLAG_X, NULL);
-#ifdef EDJE_CALC_CACHE
-                  state2 = rp2[Rel1X]->state;
+
+#ifndef EDJE_CALC_CACHE
+        eina_cow_free(_edje_calc_params_map_cow, (const Eina_Cow_Data **)&lp2.map);
+#ifdef HAVE_EPHYSICS
+        eina_cow_free(_edje_calc_params_physics_cow, (const Eina_Cow_Data **)&lp2.physics);
 #endif
-               }
-             if (rp2[Rel2X])
-               {
-                  _edje_part_recalc(ed, rp2[Rel2X], FLAG_X, NULL);
-#ifdef EDJE_CALC_CACHE
-                  if (state2 < rp2[Rel2X]->state)
-                    state2 = rp2[Rel2X]->state;
 #endif
-               }
-          }
+        pf = p3;
      }
-   if (flags & FLAG_Y)
+   else
      {
-        ep->calculating |= flags & FLAG_Y;
-        if (rp1[Rel1Y])
+        pf = p1;
+     }
+
+   if (!pf->persp_on && chosen_desc->map.persp_on)
+     {
+        if (ed->persp)
           {
-             _edje_part_recalc(ed, rp1[Rel1Y], FLAG_Y, NULL);
-#ifdef EDJE_CALC_CACHE
-             if (state1 < rp1[Rel1Y]->state)
-               state1 = rp1[Rel1Y]->state;
-#endif
+             EINA_COW_CALC_MAP_BEGIN(pf, pf_write)
+             {
+                pf_write->persp.x = ed->persp->px;
+                pf_write->persp.y = ed->persp->py;
+                pf_write->persp.z = ed->persp->z0;
+                pf_write->persp.focal = ed->persp->foc;
+             }
+             EINA_COW_CALC_MAP_END(pf, pf_write);
           }
-        if (rp1[Rel2Y])
+        else
           {
-             _edje_part_recalc(ed, rp1[Rel2Y], FLAG_Y, NULL);
-#ifdef EDJE_CALC_CACHE
-             if (state1 < rp1[Rel2Y]->state)
-               state1 = rp1[Rel2Y]->state;
-#endif
+             const Edje_Perspective *ps;
+
+             // fixme: a tad inefficient as this is a has lookup
+             ps = edje_object_perspective_get(ed->obj);
+             if (!ps)
+               ps = edje_evas_global_perspective_get(evas_object_evas_get(ed->obj));
+             EINA_COW_CALC_MAP_BEGIN(pf, pf_write)
+             {
+                if (ps)
+                  {
+                     pf_write->persp.x = ps->px;
+                     pf_write->persp.y = ps->py;
+                     pf_write->persp.z = ps->z0;
+                     pf_write->persp.focal = ps->foc;
+                  }
+                else
+                  {
+                     pf_write->persp.x = ed->x + (ed->w / 2);
+                     pf_write->persp.y = ed->y + (ed->h / 2);
+                     pf_write->persp.z = 0;
+                     pf_write->persp.focal = 1000;
+                  }
+             }
+             EINA_COW_CALC_MAP_END(pf, pf_write);
           }
-        if (ep->param2)
-          {
-             if (rp2[Rel1Y])
-               {
-                  _edje_part_recalc(ed, rp2[Rel1Y], FLAG_Y, NULL);
-#ifdef EDJE_CALC_CACHE
-                  if (state2 < rp2[Rel1Y]->state)
-                    state2 = rp2[Rel1Y]->state;
+     }
+
+   if (state)
+     {
+        const Edje_Calc_Params_Map *map;
+#ifdef HAVE_EPHYSICS
+        const Edje_Calc_Params_Physics *physics;
+#endif
+
+        map = state->map;
+#ifdef HAVE_EPHYSICS
+        physics = state->physics;
+#endif
+
+        memcpy(state, pf, sizeof (Edje_Calc_Params));
+
+        state->map = map;
+#ifdef HAVE_EPHYSICS
+        state->physics = physics;
+#endif
+        eina_cow_memcpy(_edje_calc_params_map_cow, (const Eina_Cow_Data **)&state->map, pf->map);
+#ifdef HAVE_EPHYSICS
+        eina_cow_memcpy(_edje_calc_params_physics_cow, (const Eina_Cow_Data **)&state->physics, pf->physics);
+#endif
+     }
+
+   ep->req = pf->req;
+
+   if (ep->drag && ep->drag->need_reset)
+     {
+        FLOAT_T dx, dy;
+
+        dx = ZERO;
+        dy = ZERO;
+        _edje_part_dragable_calc(ed, ep, &dx, &dy);
+        ep->drag->x = dx;
+        ep->drag->y = dy;
+        ep->drag->tmp.x = 0;
+        ep->drag->tmp.y = 0;
+        ep->drag->need_reset = 0;
+     }
+   if (!ed->calc_only)
+     {
+        Evas_Object *mo;
+
+        /* Common move, resize and color_set for all part. */
+        switch (ep->part->type)
+          {
+           case EDJE_PART_TYPE_IMAGE:
+           {
+              Edje_Part_Description_Image *img_desc = (Edje_Part_Description_Image *)chosen_desc;
+
+              evas_object_image_scale_hint_set(ep->object,
+                                               img_desc->image.scale_hint);
+              /* No break here as we share the rest of the code for all types. Intended fall-through*/
+           }
+
+           case EDJE_PART_TYPE_PROXY:
+           case EDJE_PART_TYPE_RECTANGLE:
+           case EDJE_PART_TYPE_TEXTBLOCK:
+           case EDJE_PART_TYPE_BOX:
+           case EDJE_PART_TYPE_TABLE:
+           case EDJE_PART_TYPE_SNAPSHOT:
+           case EDJE_PART_TYPE_VECTOR:
+             evas_object_color_set(ep->object,
+                                   (pf->color.r * pf->color.a) / 255,
+                                   (pf->color.g * pf->color.a) / 255,
+                                   (pf->color.b * pf->color.a) / 255,
+                                   pf->color.a);
+
+#ifdef HAVE_EPHYSICS
+/* body attributes should be updated for invisible objects */
+             if (!ep->part->physics_body)
+               {
+                  if (!pf->visible)
+                    {
+                       evas_object_hide(ep->object);
+                       break;
+                    }
+                  evas_object_show(ep->object);
+               }
+             else if (!pf->visible)
+               {
+                  Evas_Object *face_obj;
+                  Eina_List *l;
+
+                  EINA_LIST_FOREACH(ep->body_faces, l, face_obj)
+                    evas_object_hide(face_obj);
+                  evas_object_hide(ep->object);
+               }
+#else
+             if (!pf->visible)
+               {
+                  evas_object_hide(ep->object);
+                  break;
+               }
+             evas_object_show(ep->object);
+
+#endif
+           /* move and resize are needed for all previous object => no break here. */
+           case EDJE_PART_TYPE_SWALLOW:
+           case EDJE_PART_TYPE_GROUP:
+           case EDJE_PART_TYPE_EXTERNAL:
+             /* visibility and color have no meaning on SWALLOW and GROUP part. */
+#ifdef HAVE_EPHYSICS
+             eo_do(ep->object,
+                   efl_gfx_size_set(pf->final.w, pf->final.h));
+             if ((ep->part->physics_body) && (!ep->body))
+               {
+                  if (_edje_physics_world_geometry_check(ed->world))
+                    {
+                       _edje_physics_body_add(ed, ep, ed->world);
+                       _edje_physics_body_props_update(ed, ep, pf, EINA_TRUE);
+                    }
+               }
+             else if (ep->body)
+               {
+                  if (((ep->prev_description) &&
+                       (chosen_desc != ep->prev_description)) ||
+                      (pf != p1))
+                    _edje_physics_body_props_update(ed, ep, pf, !pf->physics->ignore_part_pos);
+               }
+             else
+               eo_do(ep->object,
+                     efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y));
+#else
+             eo_do(ep->object,
+                   efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y));
+
+             eo_do(ep->object,
+                   efl_gfx_size_set(pf->final.w, pf->final.h));
+#endif
+
+             if (ep->nested_smart) /* Move, Resize all nested parts */
+               {   /* Not really needed but will improve the bounding box evaluation done by Evas */
+                  eo_do(ep->nested_smart,
+                        efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
+                        efl_gfx_size_set(pf->final.w, pf->final.h));
+               }
+             if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
+               _edje_entry_real_part_configure(ed, ep);
+
+             /* handle clip overrides */
+             if (ed->has_state_clip)
+               {
+                  if (pf->clip_to && pf->clip_to->object)
+                    evas_object_clip_set(ep->object, pf->clip_to->object);
+                  else if (ep->part->clip_to_id >= 0)
+                    evas_object_clip_set(ep->object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object);
+                  else
+                    evas_object_clip_set(ep->object, ed->base->clipper);
+               }
+             break;
+
+           case EDJE_PART_TYPE_TEXT:
+             /* This is correctly handle in _edje_text_recalc_apply at the moment. */
+             break;
+
+           case EDJE_PART_TYPE_GRADIENT:
+             /* FIXME: definitivly remove this code when we switch to new format. */
+             abort();
+             break;
+
+           case EDJE_PART_TYPE_SPACER:
+             /* We really should do nothing on SPACER part */
+             break;
+           case EDJE_PART_TYPE_CAMERA:
+             {
+                Evas_Canvas3D_Camera *camera = NULL;
+                Edje_Part_Description_Camera *pd_camera;
+
+                pd_camera = (Edje_Part_Description_Camera*) ep->chosen_description;
+                eo_do(ep->node, camera = evas_canvas3d_node_camera_get());
+
+                eo_do(camera,
+                      evas_canvas3d_camera_projection_perspective_set(pd_camera->camera.camera.fovy, pd_camera->camera.camera.aspect,
+                                                                pd_camera->camera.camera.frustum_near, pd_camera->camera.camera.frustum_far));
+
+                eo_do(ep->node,
+                      evas_canvas3d_node_position_set(pd_camera->camera.position.point.x, pd_camera->camera.position.point.y,
+                                                  pd_camera->camera.position.point.z));
+                switch (pd_camera->camera.orientation.type)
+                  {
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_NONE:
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_QUATERNION:
+                       {
+                          SET_QUATERNION(camera)
+                          break;
+                       }
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT:
+                       SET_LOOK_AT(camera)
+                       break;
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_TO:
+                       {
+                          SET_LOOK_TO(camera)
+                          break;
+                       }
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_ANGLE_AXIS:
+                       SET_ANGLE_AXIS(camera)
+                       break;
+                  }
+                break;
+             }
+           case EDJE_PART_TYPE_LIGHT:
+             {
+                Evas_Canvas3D_Light *light_node = NULL;
+                Edje_Part_Description_Light *pd_light;
+
+                pd_light = (Edje_Part_Description_Light*) ep->chosen_description;
+                eo_do(ep->node, light_node = evas_canvas3d_node_light_get());
+
+                eo_do(light_node,
+                      evas_canvas3d_light_ambient_set(pd_light->light.properties.ambient.r / 255, pd_light->light.properties.ambient.g / 255,
+                                                pd_light->light.properties.ambient.b / 255, pd_light->light.properties.ambient.a / 255),
+                      evas_canvas3d_light_diffuse_set(pd_light->light.properties.diffuse.r / 255, pd_light->light.properties.diffuse.g / 255,
+                                                pd_light->light.properties.diffuse.b / 255, pd_light->light.properties.diffuse.a / 255),
+                      evas_canvas3d_light_specular_set(pd_light->light.properties.specular.r / 255, pd_light->light.properties.specular.g / 255,
+                                                 pd_light->light.properties.specular.b / 255, pd_light->light.properties.specular.a / 255),
+                      evas_canvas3d_light_directional_set(EINA_TRUE));
+
+                eo_do(ep->node,
+                      evas_canvas3d_node_position_set(pd_light->light.position.point.x, pd_light->light.position.point.y,
+                                                  pd_light->light.position.point.z));
+                switch (pd_light->light.orientation.type)
+                  {
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_NONE:
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_QUATERNION:
+                       {
+                          SET_QUATERNION(light);
+                          break;
+                       }
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT:
+                       SET_LOOK_AT(light)
+                       break;
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_TO:
+                       {
+                          SET_LOOK_TO(light)
+                          break;
+                       }
+                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_ANGLE_AXIS:
+                       SET_ANGLE_AXIS(light)
+                       break;
+                  }
+                break;
+             }
+           case EDJE_PART_TYPE_MESH_NODE:
+             {
+                Evas_Canvas3D_Material *material = NULL;
+                Evas_Canvas3D_Texture *texture = NULL;
+                Evas_Canvas3D_Mesh *mesh = NULL;
+                const char *proxy;
+                Edje_Part_Description_Mesh_Node *pd_mesh_node;
+                const Eina_List *meshes;
+                const Eina_List *list;
+
+                eo_do(ep->node, meshes = evas_canvas3d_node_mesh_list_get());
+
+                EINA_LIST_FOREACH(meshes, list, mesh)
+                  {
+                     eo_do(mesh,  material = evas_canvas3d_mesh_frame_material_get(0));
+                     eo_do(material,  texture = evas_canvas3d_material_texture_get(EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE));
+
+                     pd_mesh_node = (Edje_Part_Description_Mesh_Node*) ep->chosen_description;
+
+                     eo_do(material,
+                           evas_canvas3d_material_enable_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_AMBIENT, EINA_TRUE),
+                           evas_canvas3d_material_enable_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE, EINA_TRUE),
+                           evas_canvas3d_material_enable_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_SPECULAR, EINA_TRUE),
+                           evas_canvas3d_material_enable_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_NORMAL, pd_mesh_node->mesh_node.properties.normal),
+                           evas_canvas3d_material_color_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_AMBIENT,
+                                                      pd_mesh_node->mesh_node.properties.ambient.r / 255,
+                                                      pd_mesh_node->mesh_node.properties.ambient.g / 255,
+                                                      pd_mesh_node->mesh_node.properties.ambient.b / 255,
+                                                      pd_mesh_node->mesh_node.properties.ambient.a / 255),
+                           evas_canvas3d_material_color_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE,
+                                                      pd_mesh_node->mesh_node.properties.diffuse.r / 255,
+                                                      pd_mesh_node->mesh_node.properties.diffuse.g / 255,
+                                                      pd_mesh_node->mesh_node.properties.diffuse.b / 255,
+                                                      pd_mesh_node->mesh_node.properties.diffuse.a / 255),
+                           evas_canvas3d_material_color_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_SPECULAR,
+                                                      pd_mesh_node->mesh_node.properties.specular.r / 255,
+                                                      pd_mesh_node->mesh_node.properties.specular.g / 255,
+                                                      pd_mesh_node->mesh_node.properties.specular.b / 255,
+                                                      pd_mesh_node->mesh_node.properties.specular.a / 255),
+                           evas_canvas3d_material_shininess_set(pd_mesh_node->mesh_node.properties.shininess));
+
+                     switch(pd_mesh_node->mesh_node.mesh.primitive)
+                       {
+                          case EVAS_CANVAS3D_MESH_PRIMITIVE_CUBE:
+                            {
+                               Eo *primitive = NULL;
+
+                               eo_do(primitive,
+                                     evas_canvas3d_primitive_form_set(EVAS_CANVAS3D_MESH_PRIMITIVE_CUBE));
+
+                               eo_do(mesh,
+                                     evas_canvas3d_mesh_from_primitive_set(0, primitive));
+                               break;
+                            }
+                          case EVAS_CANVAS3D_MESH_PRIMITIVE_SPHERE:
+                            {
+                               Eo *primitive = NULL;
+
+                               eo_do(primitive,
+                                     evas_canvas3d_primitive_form_set(EVAS_CANVAS3D_MESH_PRIMITIVE_SPHERE),
+                                     evas_canvas3d_primitive_precision_set(20));
+
+                               eo_do(mesh,
+                                     evas_canvas3d_mesh_from_primitive_set(0, primitive));
+                               break;
+                            }
+                          default:
+                            break;
+                       }
+
+                     if (pd_mesh_node->mesh_node.texture.need_texture && pd_mesh_node->mesh_node.texture.textured)
+                       {
+                          proxy = NULL;
+
+                          eo_do(material,
+                                texture = evas_canvas3d_material_texture_get(EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE));
+
+                          //proxy = _edje_image_name_find(ed, pd_mesh_node->mesh_node.texture.id);
+                          /*FIXME Conflict with function _edje_image_name_find (two places in edje_utils and edje_edit.c,
+                          temporary desicion need to clarify up to commit to phab*/
+                          proxy = ed->file->image_dir->entries[pd_mesh_node->mesh_node.texture.id].entry;
+                          if (proxy)
+                            {
+                               eo_do(texture,
+                                     evas_canvas3d_texture_file_set(eina_stringshare_add(proxy), NULL),
+                                     evas_canvas3d_texture_filter_set(pd_mesh_node->mesh_node.texture.filter1,
+                                                                pd_mesh_node->mesh_node.texture.filter2),
+                                     evas_canvas3d_texture_wrap_set(pd_mesh_node->mesh_node.texture.wrap1,
+                                                              pd_mesh_node->mesh_node.texture.wrap2));
+                            }
+                       }
+
+                     eo_do(mesh,
+                           evas_canvas3d_mesh_frame_material_set(0, material),
+                           evas_canvas3d_mesh_shade_mode_set(pd_mesh_node->mesh_node.properties.shade),
+                           evas_canvas3d_mesh_vertex_assembly_set(pd_mesh_node->mesh_node.mesh.assembly));
+                     eo_do(ep->node,
+                           evas_canvas3d_node_scale_set(ep->part->scale_3d.x, ep->part->scale_3d.y,
+                                                  ep->part->scale_3d.z),
+                           evas_canvas3d_node_position_set(pd_mesh_node->mesh_node.position.point.x,
+                                                     pd_mesh_node->mesh_node.position.point.y,
+                                                     pd_mesh_node->mesh_node.position.point.z));
+                     switch (pd_mesh_node->mesh_node.orientation.type)
+                       {
+                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_NONE:
+                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_QUATERNION:
+                            {
+                               SET_QUATERNION(mesh_node)
+                               break;
+                            }
+                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT:
+                            SET_LOOK_AT(mesh_node)
+                            break;
+                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_TO:
+                            {
+                               SET_LOOK_TO(mesh_node)
+                               break;
+                            }
+                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_ANGLE_AXIS:
+                            SET_ANGLE_AXIS(mesh_node)
+                            break;
+                       }
+                  }
+                break;
+             }
+          }
+
+        /* Some object need special recalc. */
+        switch (ep->part->type)
+          {
+           case EDJE_PART_TYPE_TEXT:
+             _edje_text_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc, EINA_FALSE);
+             break;
+
+           case EDJE_PART_TYPE_PROXY:
+             _edje_proxy_recalc_apply(ed, ep, pf, (Edje_Part_Description_Proxy *)chosen_desc, pos);
+             break;
+
+           case EDJE_PART_TYPE_IMAGE:
+             _edje_image_recalc_apply(ed, ep, pf, (Edje_Part_Description_Image *)chosen_desc, pos);
+             break;
+
+           case EDJE_PART_TYPE_BOX:
+             _edje_box_recalc_apply(ed, ep, pf, (Edje_Part_Description_Box *)chosen_desc);
+             break;
+
+           case EDJE_PART_TYPE_TABLE:
+             _edje_table_recalc_apply(ed, ep, pf, (Edje_Part_Description_Table *)chosen_desc);
+             break;
+
+           case EDJE_PART_TYPE_TEXTBLOCK:
+             _edje_textblock_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text *)chosen_desc);
+             break;
+
+           case EDJE_PART_TYPE_VECTOR:
+             _edje_svg_recalc_apply(ed, ep, pf, (Edje_Part_Description_Vector *)chosen_desc, pos);
+             break;
+
+           case EDJE_PART_TYPE_EXTERNAL:
+           case EDJE_PART_TYPE_RECTANGLE:
+           case EDJE_PART_TYPE_SWALLOW:
+           case EDJE_PART_TYPE_GROUP:
+             /* Nothing special to do for this type of object. */
+             break;
+
+           case EDJE_PART_TYPE_GRADIENT:
+             /* FIXME: definitivly remove this code when we switch to new format. */
+             abort();
+             break;
+
+           case EDJE_PART_TYPE_SPACER:
+             /* We really should do nothing on SPACER part */
+             break;
+          }
+
+        if (((ep->type == EDJE_RP_TYPE_SWALLOW) &&
+             (ep->typedata.swallow)) &&
+            (ep->typedata.swallow->swallowed_object))
+          {
+             if (ed->has_state_clip)
+               {
+                  if (pf->clip_to && pf->clip_to->object)
+                    evas_object_clip_set(ep->typedata.swallow->swallowed_object, pf->clip_to->object);
+                  else if (ep->part->clip_to_id >= 0)
+                    evas_object_clip_set(ep->typedata.swallow->swallowed_object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object);
+                  else
+                    evas_object_clip_set(ep->typedata.swallow->swallowed_object, ed->base->clipper);
+               }
+
+             if (pf->visible)
+               {
+                  Eina_Bool vis = EINA_TRUE;
+
+                  if (ep->part->type == EDJE_PART_TYPE_GROUP)
+                    vis = evas_object_visible_get(ed->obj);
+                  eo_do(ep->typedata.swallow->swallowed_object,
+                        efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
+                        efl_gfx_size_set(pf->final.w, pf->final.h),
+                        efl_gfx_visible_set(vis));
+               }
+             else evas_object_hide(ep->typedata.swallow->swallowed_object);
+             mo = ep->typedata.swallow->swallowed_object;
+          }
+        else mo = ep->object;
+
+        Evas_Object *map_obj;
+
+        /* Apply map to smart obj holding nested parts */
+        if (ep->nested_smart) map_obj = ep->nested_smart;
+        else map_obj = mo;
+
+        if (ep->part->type != EDJE_PART_TYPE_SPACER)
+          {
+             if (chosen_desc->map.on)
+               {
+                  static Evas_Map *map = NULL;
+
+                  ed->have_mapped_part = EINA_TRUE;
+                  // create map and populate with part geometry
+                  if (!map) map = evas_map_new(4);
+
+                  _edje_map_prop_set(map, pf, chosen_desc, ep, mo);
+
+                  if (map_obj)
+                    {
+                       eo_do(map_obj,
+                             evas_obj_map_set(map),
+                             evas_obj_map_enable_set(EINA_TRUE));
+                    }
+               }
+             else
+               {
+                  Eina_Bool ret;
+
+                  if (map_obj && eo_do_ret(map_obj, ret, evas_obj_map_enable_get()))
+                    {
+#ifdef HAVE_EPHYSICS
+                       if (!ep->nested_smart && !ep->body)
+                         {
 #endif
-               }
-             if (rp2[Rel2Y])
-               {
-                  _edje_part_recalc(ed, rp2[Rel2Y], FLAG_Y, NULL);
-#ifdef EDJE_CALC_CACHE
-                  if (state2 < rp2[Rel2Y]->state)
-                    state2 = rp2[Rel2Y]->state;
+                            eo_do(map_obj,
+                                  evas_obj_map_enable_set(EINA_FALSE),
+                                  evas_obj_map_set(NULL));
+#ifdef HAVE_EPHYSICS
+                         }
 #endif
+                    }
                }
+
+             /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to TEXTBLOCK, TEXT part. */
+             if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK ||
+                 ep->part->type == EDJE_PART_TYPE_TEXT)
+               _edje_text_ellipsize_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc);
+             /* END */
           }
      }
-   if (clip1)
-     {
-        _edje_part_recalc(ed, clip1, flags, NULL);
-        statecl = clip1->state;
-     }
-   if (clip2)
-     {
-        _edje_part_recalc(ed, clip2, flags, NULL);
-        if (statecl < clip2->state)
-          statecl = clip2->state;
-     }
-   if (ep->drag)
+
+   if (map_colors_free) _map_colors_free(pf);
+
+#ifdef HAVE_EPHYSICS
+   ep->prev_description = chosen_desc;
+   if (!ep->body)
      {
-        if (ep->drag->confine_to)
-          {
-             confine_to = ep->drag->confine_to;
-             _edje_part_recalc(ed, confine_to, flags, NULL);
-#ifdef EDJE_CALC_CACHE
-             statec = confine_to->state;
-#endif
-          }
-        if (ep->drag->threshold)
-          {
-             threshold = ep->drag->threshold;
-             // We shall not recalculate the threshold position as
-             // we use it's previous position to assert the threshold
-             // the one before moving take action.
-#ifdef EDJE_CALC_CACHE
-             statet = threshold->state;
 #endif
-          }
+        ep->x = pf->final.x;
+        ep->y = pf->final.y;
+        ep->w = pf->final.w;
+        ep->h = pf->final.h;
+#ifdef HAVE_EPHYSICS
      }
-   //   if (ep->text.source)       _edje_part_recalc(ed, ep->text.source, flags);
-   //   if (ep->text.text_source)  _edje_part_recalc(ed, ep->text.text_source, flags);
 
-   /* actually calculate now */
-   chosen_desc = ep->chosen_description;
-   if (!chosen_desc)
-     {
-        ep->calculating = FLAG_NONE;
-        ep->calculated |= flags;
-        return;
-     }
+#endif
 
-   pos = ep->description_pos;
+   ep->calculated |= flags;
+   ep->calculating = FLAG_NONE;
 
-   if ((ep->part->type == EDJE_PART_TYPE_PROXY) && chosen_desc->visible)
+   if (pf == &lp3)
      {
-        int part_id = -1;
-
-        if (ep->param2 && (pos >= FROM_DOUBLE(0.5)))
-          part_id = ((Edje_Part_Description_Proxy *)ep->param2->description)->proxy.id;
-        else
-          part_id = ((Edje_Part_Description_Proxy *)chosen_desc)->proxy.id;
+        eina_cow_free(_edje_calc_params_map_cow, (const Eina_Cow_Data **)&lp3.map);
+        lp3.map = NULL;
+#ifdef HAVE_EPHYSICS
+        eina_cow_free(_edje_calc_params_physics_cow, (const Eina_Cow_Data **)&lp3.physics);
+        lp3.physics = NULL;
+#endif
+     }
 
 #ifdef EDJE_CALC_CACHE
-        Edje_Real_Part *pp;
-        pp = _edje_real_part_state_get(ed, ep, flags, part_id, NULL);
-        if (pp && pp->invalidate) proxy_invalidate = EINA_TRUE;
+   if (ep->calculated == FLAG_XY)
+     {
+        ep->state = ed->state;
+        ep->invalidate = EINA_FALSE;
+     }
 #else
-        _edje_real_part_state_get(ed, ep, flags, part_id, NULL);
+   eina_cow_free(_edje_calc_params_map_cow, (const Eina_Cow_Data **)&lp1.map);
+#ifdef HAVE_EPHYSICS
+   eina_cow_free(_edje_calc_params_physics_cow, (const Eina_Cow_Data **)&lp1.physics);
 #endif
-     }
+#endif
+}
 
-   /* Recalc if needed the map center && light source */
-   if (ep->param1.description->map.on)
-     {
-        center[0] = _edje_real_part_state_get(ed, ep, flags, ep->param1.description->map.rot.id_center, &statec1);
-        light[0] = _edje_real_part_state_get(ed, ep, flags, ep->param1.description->map.id_light, &statel1);
 
-        if (chosen_desc->map.persp_on)
-          {
-             persp[0] = _edje_real_part_state_get(ed, ep, flags, ep->param1.description->map.id_persp, &statep1);
-          }
-     }
 
-   if (ep->param2 && ep->param2->description->map.on)
+/**********************************************************************************
+ *
+ * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part.
+ * 20160920: Add fade_ellipsis feature to TEXTBLOCK, TEXT part.
+ * 20160923: introduction of text marquee
+ * 20170322: fix crash issue when Edje tries to clean up fade object
+ * 20170427: fix clipper loop issue caused by clipper object for fade
+ * 20170703: Add ellipsize feature and refactory fade_ellipsis, marquee features.
+ *
+ **********************************************************************************/
+#define EDJE_DEFAULT_FADE_IMAGE "edje_default_fade_image.png"
+#define LEFT_BORDER 20
+#define RIGHT_BORDER 20
+#define TOP_BORDER 20
+#define BOTTOM_BORDER 20
+#define EDJE_ELLIPSIZE_FADE_SENSITIVITY 4
+
+/* moving 1 px for 0.025 sec makes 40 px/sec */
+#define EDJE_TEXT_ELLIPSIZE_MARQUEE_DEFAULT_SEC_PER_PIXEL 0.025
+#define EDJE_TEXT_ELLIPSIZE_MARQUEE_ROLL_GAP 60
+
+static Evas_Object *
+_edje_text_ellipsize_fade_mask_object_get(Edje_Real_Part *ep)
+{
+   if (!ep->typedata.text->ellipsize.fade.mask_obj)
      {
-        center[1] = _edje_real_part_state_get(ed, ep, flags, ep->param2->description->map.rot.id_center, &statec2);
-        light[1] = _edje_real_part_state_get(ed, ep, flags, ep->param2->description->map.id_light, &statel2);
+        Evas_Object *smart_parent;
+        Evas_Object *mask_obj;
+        char buf[1024];
+        int iw = 0;
 
-        if (chosen_desc->map.persp_on)
-          {
-             persp[1] = _edje_real_part_state_get(ed, ep, flags, ep->param2->description->map.id_persp, &statep2);
-          }
-     }
+        smart_parent = evas_object_smart_parent_get(ep->object);
 
-#ifndef EDJE_CALC_CACHE
-   p1 = &lp1;
-   p1.map = eina_cow_alloc(_edje_calc_params_map_cow);
-#ifdef HAVE_EPHYSICS
-   p1.physics = eina_cow_alloc(_edje_calc_params_physics_cow);
-#endif
+#if 0
+        mask_obj = evas_object_rectangle_add(evas_object_evas_get(ep->object));
+        evas_object_color_set(mask_obj, 150, 0, 0, 150);
 #else
-   p1 = &ep->param1.p;
-#endif
+        mask_obj = evas_object_image_add(evas_object_evas_get(ep->object));
+        snprintf(buf, sizeof(buf), "/usr/share/edje/images/%s", EDJE_DEFAULT_FADE_IMAGE);
+        evas_object_image_file_set(mask_obj, buf, NULL);
 
-   if (ep->param1.description)
-     {
-#ifdef EDJE_CALC_CACHE
-        if (ed->all_part_change ||
-            ep->invalidate ||
-            (state1 >= ep->param1.state) ||
-            (statec >= ep->param1.state) ||
-            (statet >= ep->param1.state) ||
-            (statec1 >= ep->param1.state) ||
-            (statel1 >= ep->param1.state) ||
-            (statep1 >= ep->param1.state) ||
-            (statecl >= ep->param1.state) ||
-            proxy_invalidate ||
-            state ||
-            ed->need_map_update ||
-            ((ep->part->type == EDJE_PART_TYPE_TEXT ||
-              ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) &&
-             ed->text_part_change))
-#endif
-        {
-           _edje_part_recalc_single(ed, ep, ep->param1.description,
-                                    chosen_desc, center[0], light[0],
-                                    persp[0], rp1[Rel1X], rp1[Rel1Y],
-                                    rp1[Rel2X], rp1[Rel2Y], clip1, confine_to,
-                                    threshold, p1, mmw, mmh,
-                                    pos);
-#ifdef EDJE_CALC_CACHE
-           if (flags == FLAG_XY) ep->param1.state = ed->state;
+        if (evas_object_image_load_error_get(mask_obj) != EVAS_LOAD_ERROR_NONE)
+          {
+             ERR("Error loading fade image from file \"%s\".", buf);
+
+             switch (evas_object_image_load_error_get(mask_obj))
+               {
+                case EVAS_LOAD_ERROR_GENERIC:
+                   ERR("Error type: EVAS_LOAD_ERROR_GENERIC");
+                   break;
+                case EVAS_LOAD_ERROR_DOES_NOT_EXIST:
+                   ERR("Error type: EVAS_LOAD_ERROR_DOES_NOT_EXIST");
+                   break;
+                case EVAS_LOAD_ERROR_PERMISSION_DENIED:
+                   ERR("Error type: EVAS_LOAD_ERROR_PERMISSION_DENIED");
+                   break;
+                case EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED:
+                   ERR("Error type: EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED");
+                   break;
+                case EVAS_LOAD_ERROR_CORRUPT_FILE:
+                   ERR("Error type: EVAS_LOAD_ERROR_CORRUPT_FILE");
+                   break;
+                case EVAS_LOAD_ERROR_UNKNOWN_FORMAT:
+                   ERR("Error type: EVAS_LOAD_ERROR_UNKNOWN_FORMAT");
+                   break;
+                default:
+                   ERR("Error type: ???");
+                   break;
+               }
+          }
+
+        evas_object_image_size_get(mask_obj, &iw, NULL);
+        evas_object_pass_events_set(mask_obj, 1);
+        evas_object_pointer_mode_set(mask_obj, EVAS_OBJECT_POINTER_MODE_NOGRAB);
+        evas_object_image_border_set(mask_obj, LEFT_BORDER, RIGHT_BORDER, TOP_BORDER, BOTTOM_BORDER);
+        evas_object_image_border_scale_set(mask_obj, 1.0);
+        evas_object_image_border_center_fill_set(mask_obj, EVAS_BORDER_FILL_DEFAULT);
 #endif
-        }
+        evas_object_smart_member_add(mask_obj, smart_parent);
+        ep->typedata.text->ellipsize.fade.mask_obj = mask_obj;
      }
-   if (ep->param2)
-     {
-        int beginning_pos, part_type;
-        Edje_Calc_Params *p2, *p3;
 
-        if (ep->current)
-          {
-             const Edje_Calc_Params_Map *map;
-#ifdef HAVE_EPHYSICS
-             const Edje_Calc_Params_Physics *physics;
-#endif
+   return ep->typedata.text->ellipsize.fade.mask_obj;
+}
 
-             map = p1->map;
-#ifdef HAVE_EPHYSICS
-             physics = p1->physics;
-#endif
+void
+_edje_text_ellipsize_marquee_remove(Edje_Real_Part *ep)
+{
+   if (!ep || !ep->typedata.text) return;
 
-             /* FIXME: except for text, we don't need in that case to recalc p1 at all*/
-             memcpy(p1, ep->current, sizeof (Edje_Calc_Params));
+   if (ep->typedata.text->ellipsize.marquee.proxy_obj)
+     {
+        evas_object_del(ep->typedata.text->ellipsize.marquee.proxy_obj);
+        ep->typedata.text->ellipsize.marquee.proxy_obj = NULL;
+     }
 
-             p1->map = map;
-#ifdef HAVE_EPHYSICS
-             p1->physics = physics;
-#endif
-          }
+   if (ep->typedata.text->ellipsize.marquee.animator)
+     {
+        ecore_animator_del(ep->typedata.text->ellipsize.marquee.animator);
+        ep->typedata.text->ellipsize.marquee.animator = NULL;
+     }
 
-        p3 = &lp3;
-        lp3.map = eina_cow_alloc(_edje_calc_params_map_cow);
-#ifdef HAVE_EPHYSICS
-        lp3.physics = eina_cow_alloc(_edje_calc_params_physics_cow);
-#endif
+   ep->typedata.text->ellipsize.marquee.loop_count = 0;
+   ep->typedata.text->ellipsize.marquee.distance = 0;
+}
 
-#ifndef EDJE_CALC_CACHE
-        p2 = &lp2;
-        lp2.map = eina_cow_alloc(_edje_calc_params_map_cow);
-#ifdef HAVE_EPHYSICS
-        lp2.physics = eina_cow_alloc(_edje_calc_params_physics_cow);
-#endif
-#else
-        p2 = &ep->param2->p;
+void
+_edje_text_ellipsize_fade_remove(Edje_Real_Part *ep)
+{
+   if (!ep || !ep->typedata.text) return;
 
-        if (ed->all_part_change ||
-            ep->invalidate ||
-            (state2 >= ep->param2->state) ||
-            (statec >= ep->param2->state) ||
-            (statet >= ep->param2->state) ||
-            (statec2 >= ep->param2->state) ||
-            (statel2 >= ep->param2->state) ||
-            (statep2 >= ep->param2->state) ||
-            (statecl >= ep->param2->state) ||
-            proxy_invalidate ||
-            state ||
-            ed->need_map_update ||
-            ((ep->part->type == EDJE_PART_TYPE_TEXT ||
-              ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) &&
-             ed->text_part_change))
-#endif
-        {
-           _edje_part_recalc_single(ed, ep, ep->param2->description,
-                                    chosen_desc, center[1], light[1],
-                                    persp[1], rp2[Rel1X], rp2[Rel1Y],
-                                    rp2[Rel2X], rp2[Rel2Y], clip2, confine_to,
-                                    threshold, p2, mmw, mmh,
-                                    pos);
-#ifdef EDJE_CALC_CACHE
-           if (flags == FLAG_XY) ep->param2->state = ed->state;
-#endif
-        }
+   if (ep->typedata.text->ellipsize.fade.animator)
+     {
+        ecore_animator_del(ep->typedata.text->ellipsize.fade.animator);
+        ep->typedata.text->ellipsize.fade.animator = NULL;
+     }
 
-        pos2 = pos;
-        if (pos2 < ZERO) pos2 = ZERO;
-        else if (pos2 > FROM_INT(1))
-          pos2 = FROM_INT(1);
-        beginning_pos = (pos < FROM_DOUBLE(0.5));
-        part_type = ep->part->type;
+   if (ep->typedata.text->ellipsize.fade.mask_obj)
+     {
+        evas_object_del(ep->typedata.text->ellipsize.fade.mask_obj);
+        ep->typedata.text->ellipsize.fade.mask_obj = NULL;
+     }
+}
+
+/* TIZEN_ONLY(20170322): fix crash issue when Edje tries to clean up fade object */
+void
+_edje_text_ellipsize_remove(Edje_Real_Part *ep)
+{
+   if (!ep || !ep->typedata.text) return;
 
-        /* visible is special */
-        if ((p1->visible) && (!p2->visible))
-          p3->visible = (pos != FROM_INT(1));
-        else if ((!p1->visible) && (p2->visible))
-          p3->visible = (pos != ZERO);
-        else
-          p3->visible = p1->visible;
+   _edje_text_ellipsize_marquee_remove(ep);
+   _edje_text_ellipsize_fade_remove(ep);
 
-        /* clip_to will behave a bit like visible */
-        if (pos == ZERO)
-          p3->clip_to = p1->clip_to;
-        else if (pos == FROM_INT(1))
-          p3->clip_to = p2->clip_to;
-        else if (!p1->clip_to)
-          p3->clip_to = p2->clip_to;
-        else
-          p3->clip_to = p1->clip_to;
+   if (ep->typedata.text->ellipsize.clipper_obj)
+     {
+        evas_object_del(ep->typedata.text->ellipsize.clipper_obj);
+        ep->typedata.text->ellipsize.clipper_obj = NULL;
+     }
+}
+/* END */
 
-        p3->smooth = (beginning_pos) ? p1->smooth : p2->smooth;
+/* Get alignment of ellipsize according to ellipsize.align and Text/Textblock's status */
+static void
+_edje_text_ellipsize_align_get(Edje_Real_Part *ep, Edje_Calc_Params *pf, Edje_Part_Description_Text *chosen_desc, double *halign, double *valign)
+{
+   Evas_BiDi_Direction bidi_dir;
+   Edje_Text_Ellipsize_Align ellip_align;
+   Evas_Coord tw, th;
+   double valign_ret = -1.0;
+   double halign_ret = -1.0;
 
-        /* FIXME: do x and y separately base on flag */
+   if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
+     {
+        Evas_Textblock_Cursor *cur;
 
-        p3->final.x = INTP(p1->final.x, p2->final.x, pos);
-        p3->final.y = INTP(p1->final.y, p2->final.y, pos);
-        p3->final.w = INTP(p1->final.w, p2->final.w, pos);
-        p3->final.h = INTP(p1->final.h, p2->final.h, pos);
+        cur = evas_object_textblock_cursor_new(ep->object);
 
-        p3->eval.x = FFP(p1->eval.x, p2->eval.x, pos);
-        p3->eval.y = FFP(p1->eval.y, p2->eval.y, pos);
-        p3->eval.w = FFP(p1->eval.w, p2->eval.w, pos);
-        p3->eval.h = FFP(p1->eval.h, p2->eval.h, pos);
+        bidi_dir = evas_textblock_cursor_paragraph_direction_get(cur);
+        evas_object_textblock_size_formatted_get(ep->object, &tw, &th);
 
-        p3->req.x = INTP(p1->req.x, p2->req.x, pos);
-        p3->req.y = INTP(p1->req.y, p2->req.y, pos);
-        p3->req.w = INTP(p1->req.w, p2->req.w, pos);
-        p3->req.h = INTP(p1->req.h, p2->req.h, pos);
+        evas_textblock_cursor_free(cur);
+     }
+   else
+     {
+        bidi_dir = evas_object_text_direction_get(ep->object);
+        tw = evas_object_text_horiz_advance_get(ep->object);
+        th = evas_object_text_vert_advance_get(ep->object);
+     }
 
-        _edje_part_pixel_adjust(ed, ep, p3);
+   if (chosen_desc->text.fade_ellipsis == 2.0)
+     chosen_desc->text.ellipsize.align = EDJE_TEXT_ELLIPSIZE_ALIGN_END;
+   else if (chosen_desc->text.fade_ellipsis == 1.0)
+     chosen_desc->text.ellipsize.align = EDJE_TEXT_ELLIPSIZE_ALIGN_START;
 
-        if (ep->part->dragable.x)
+   ellip_align = chosen_desc->text.ellipsize.align;
+
+   /* Handle NORMAL ellipsis. It considers difference of TEXTBLOCK and TEXT.
+    * Also, it considers a logic inside of each type of object with the given ellipsis value.
+    */
+   if (chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_NORMAL)
+     {
+        /* variable for improving readability */
+        double text_ellipsis_end;
+        double text_ellipsis_start;
+
+        if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
           {
-             p3->req_drag.x = INTP(p1->req_drag.x, p2->req_drag.x, pos);
-             p3->req_drag.w = INTP(p1->req_drag.w, p2->req_drag.w, pos);
+             text_ellipsis_end = 1.0;
+             text_ellipsis_start = 0.0;
           }
-        if (ep->part->dragable.y)
+        else
           {
-             p3->req_drag.y = INTP(p1->req_drag.y, p2->req_drag.y, pos);
-             p3->req_drag.h = INTP(p1->req_drag.h, p2->req_drag.h, pos);
+             text_ellipsis_end = 0.0;
+             text_ellipsis_start = 1.0;
           }
 
-        p3->color.r = INTP(p1->color.r, p2->color.r, pos2);
-        p3->color.g = INTP(p1->color.g, p2->color.g, pos2);
-        p3->color.b = INTP(p1->color.b, p2->color.b, pos2);
-        p3->color.a = INTP(p1->color.a, p2->color.a, pos2);
+        switch (ellip_align)
+          {
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT:
+              if (bidi_dir != EVAS_BIDI_DIRECTION_RTL)
+                halign_ret = text_ellipsis_start;
+              else
+                halign_ret = text_ellipsis_end;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT:
+              if (bidi_dir != EVAS_BIDI_DIRECTION_RTL)
+                halign_ret = text_ellipsis_end;
+              else
+                halign_ret = text_ellipsis_start;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_START:
+              halign_ret = text_ellipsis_start;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_END:
+              halign_ret = text_ellipsis_end;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE:
+              if (evas_language_direction_get() == EVAS_BIDI_DIRECTION_RTL)
+                {
+                   if (bidi_dir == EVAS_BIDI_DIRECTION_RTL)
+                     halign_ret = text_ellipsis_end;
+                   else
+                     halign_ret = text_ellipsis_start;
+                }
+              else
+                {
+                   if (bidi_dir == EVAS_BIDI_DIRECTION_RTL)
+                     halign_ret = text_ellipsis_start;
+                   else
+                     halign_ret = text_ellipsis_end;
+                }
+              break;
+           default:
+              halign_ret = -1.0;
+          }
+     }
+   else
+     {
+        /* variable for improving readability */
+        double text_ellipsis_left;
+        double text_ellipsis_right;
 
-#ifdef HAVE_EPHYSICS
-        if (ep->part->physics_body || ep->body)
+        text_ellipsis_left = 0.0;
+        text_ellipsis_right = 1.0;
+
+        switch (ellip_align)
           {
-             EINA_COW_CALC_PHYSICS_BEGIN(p3, p3_write)
-             {
-                p3_write->mass = TO_DOUBLE(FINTP(p1->physics->mass, p2->physics->mass,
-                                                 pos));
-                p3_write->restitution = TO_DOUBLE(FINTP(p1->physics->restitution,
-                                                        p2->physics->restitution,
-                                                        pos));
-                p3_write->friction = TO_DOUBLE(FINTP(p1->physics->friction,
-                                                     p2->physics->friction, pos));
-                p3_write->density = TO_DOUBLE(FINTP(p1->physics->density,
-                                                    p2->physics->density, pos));
-                p3_write->hardness = TO_DOUBLE(FINTP(p1->physics->hardness,
-                                                     p2->physics->hardness, pos));
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT:
+              halign_ret = text_ellipsis_left;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT:
+              halign_ret = text_ellipsis_right;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_START:
+              if (bidi_dir != EVAS_BIDI_DIRECTION_RTL)
+                halign_ret = text_ellipsis_left;
+              else
+                halign_ret = text_ellipsis_right;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_END:
+              if (bidi_dir != EVAS_BIDI_DIRECTION_RTL)
+                halign_ret = text_ellipsis_right;
+              else
+                halign_ret = text_ellipsis_left;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE:
+              if (evas_language_direction_get() == EVAS_BIDI_DIRECTION_RTL)
+                halign_ret = text_ellipsis_left;
+              else
+                halign_ret = text_ellipsis_right;
+              break;
+           default:
+              halign_ret = -1.0;
+          }
+     }
 
-                p3_write->damping.linear = TO_DOUBLE(FINTP(p1->physics->damping.linear,
-                                                           p2->physics->damping.linear, pos));
-                p3_write->damping.angular = TO_DOUBLE(FINTP(p1->physics->damping.angular,
-                                                            p2->physics->damping.angular, pos));
+   if ((ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) &&
+       (th > ep->h))
+     {
+        /* variable for improving readability */
+        double text_ellipsis_top;
+        double text_ellipsis_bottom;
 
-                p3_write->sleep.linear = TO_DOUBLE(FINTP(p1->physics->sleep.linear,
-                                                         p2->physics->sleep.linear, pos));
-                p3_write->sleep.angular = TO_DOUBLE(FINTP(p1->physics->sleep.angular,
-                                                          p2->physics->sleep.angular, pos));
+        text_ellipsis_top = 0.0;
+        text_ellipsis_bottom = 1.0;
 
-                p3_write->z = INTP(p1->physics->z, p2->physics->z, pos);
-                p3_write->depth = INTP(p1->physics->depth, p2->physics->depth, pos);
+        /* LEFT, RIGHT, LOCALE are meaningless for vertical direction.
+         * So, LEFT, RIGHT, LOCALE will work just like END (default).
+         * Only START, END will work. */
+         switch (ellip_align)
+          {
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT:
+              valign_ret = text_ellipsis_bottom;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT:
+              valign_ret = text_ellipsis_bottom;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_START:
+              valign_ret = text_ellipsis_top;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_END:
+              valign_ret = text_ellipsis_bottom;
+              break;
+           case EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE:
+              valign_ret = text_ellipsis_bottom;
+              break;
+           default:
+              valign_ret = -1.0;
+          }
+     }
 
-                if ((p1->physics->ignore_part_pos) && (p2->physics->ignore_part_pos))
-                  p3_write->ignore_part_pos = 1;
-                else
-                  p3_write->ignore_part_pos = 0;
+   if (halign)
+     *halign = halign_ret;
 
-                if ((p1->physics->material) && (p2->physics->material))
-                  p3_write->material = p1->physics->material;
-                else
-                  p3_write->material = EPHYSICS_BODY_MATERIAL_CUSTOM;
+   if (valign)
+     *valign = valign_ret;
+}
 
-                p3_write->light_on = p1->physics->light_on || p2->physics->light_on;
-                p3_write->backcull = p1->physics->backcull || p2->physics->backcull;
+static Evas_Object *
+_edje_text_ellipsize_marquee_proxy_object_get(Edje_Real_Part *ep)
+{
+   if (!ep->typedata.text->ellipsize.marquee.proxy_obj)
+     {
+        Evas_Object *p_obj;
+        Evas_Object *smart_parent;
+        double scale = evas_object_scale_get(ep->object);
+        int pr, pg, pb, pa;
 
-                p3_write->mov_freedom.lin.x = p1->physics->mov_freedom.lin.x ||
-                  p2->physics->mov_freedom.lin.x;
-                p3_write->mov_freedom.lin.y = p1->physics->mov_freedom.lin.y ||
-                  p2->physics->mov_freedom.lin.y;
-                p3_write->mov_freedom.lin.z = p1->physics->mov_freedom.lin.z ||
-                  p2->physics->mov_freedom.lin.z;
-                p3_write->mov_freedom.ang.x = p1->physics->mov_freedom.ang.x ||
-                  p2->physics->mov_freedom.ang.x;
-                p3_write->mov_freedom.ang.y = p1->physics->mov_freedom.ang.y ||
-                  p2->physics->mov_freedom.ang.y;
-                p3_write->mov_freedom.ang.z = p1->physics->mov_freedom.ang.z ||
-                  p2->physics->mov_freedom.ang.z;
-             }
-             EINA_COW_CALC_PHYSICS_END(p3, p3_write);
-          }
-#endif
+        smart_parent = evas_object_smart_parent_get(ep->object);
+        evas_object_color_get(ep->object, &pr, &pg, &pb, &pa);
 
-        switch (part_type)
+        if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
           {
-           case EDJE_PART_TYPE_IMAGE:
-             p3->type.common.spec.image.l = INTP(p1->type.common.spec.image.l, p2->type.common.spec.image.l, pos);
-             p3->type.common.spec.image.r = INTP(p1->type.common.spec.image.r, p2->type.common.spec.image.r, pos);
-             p3->type.common.spec.image.t = INTP(p1->type.common.spec.image.t, p2->type.common.spec.image.t, pos);
-             p3->type.common.spec.image.b = INTP(p1->type.common.spec.image.b, p2->type.common.spec.image.b, pos);
-             p3->type.common.spec.image.border_scale_by = FFP(p1->type.common.spec.image.border_scale_by, p2->type.common.spec.image.border_scale_by, pos);
+             const Evas_Textblock_Style *st = evas_object_textblock_style_get(ep->object);
 
-           case EDJE_PART_TYPE_PROXY:
-             p3->type.common.fill.x = INTP(p1->type.common.fill.x, p2->type.common.fill.x, pos);
-             p3->type.common.fill.y = INTP(p1->type.common.fill.y, p2->type.common.fill.y, pos);
-             p3->type.common.fill.w = INTP(p1->type.common.fill.w, p2->type.common.fill.w, pos);
-             p3->type.common.fill.h = INTP(p1->type.common.fill.h, p2->type.common.fill.h, pos);
-             break;
+             p_obj = evas_object_textblock_add(evas_object_evas_get(ep->object));
+             evas_object_textblock_style_set(p_obj, st);
+             evas_object_textblock_text_markup_set(p_obj, ep->typedata.text->text);
+          }
+        else
+          {
+             const char *font = NULL;
+             int font_size = 0;
+             Evas_Text_Style_Type style;
+             int tr, tg, tb, ta;
 
-           case EDJE_PART_TYPE_TEXT:
-             p3->type.text.size = INTP(p1->type.text.size, p2->type.text.size, pos);
+             evas_object_text_font_get(ep->object, &font, &font_size);
+             style = evas_object_text_style_get(ep->object);
 
-           /* no break as we share code with the TEXTBLOCK type here. Intended fall-through */
-           case EDJE_PART_TYPE_TEXTBLOCK:
-             p3->type.text.color2.r = INTP(p1->type.text.color2.r, p2->type.text.color2.r, pos2);
-             p3->type.text.color2.g = INTP(p1->type.text.color2.g, p2->type.text.color2.g, pos2);
-             p3->type.text.color2.b = INTP(p1->type.text.color2.b, p2->type.text.color2.b, pos2);
-             p3->type.text.color2.a = INTP(p1->type.text.color2.a, p2->type.text.color2.a, pos2);
+             p_obj = evas_object_text_add(evas_object_evas_get(ep->object));
+             evas_object_text_font_set(p_obj, font, font_size);
+             evas_object_text_style_set(p_obj, style);
 
-             p3->type.text.color3.r = INTP(p1->type.text.color3.r, p2->type.text.color3.r, pos2);
-             p3->type.text.color3.g = INTP(p1->type.text.color3.g, p2->type.text.color3.g, pos2);
-             p3->type.text.color3.b = INTP(p1->type.text.color3.b, p2->type.text.color3.b, pos2);
-             p3->type.text.color3.a = INTP(p1->type.text.color3.a, p2->type.text.color3.a, pos2);
+             evas_object_text_outline_color_get(ep->object, &tr, &tg, &tb, &ta);
+             evas_object_text_outline_color_set(p_obj, tr, tg, tb, ta);
+             evas_object_text_shadow_color_get(ep->object, &tr, &tg, &tb, &ta);
+             evas_object_text_shadow_color_set(p_obj, tr, tg, tb, ta);
+             evas_object_text_glow_color_get(ep->object, &tr, &tg, &tb, &ta);
+             evas_object_text_glow_color_set(p_obj, tr, tg, tb, ta);
+             evas_object_text_glow2_color_get(ep->object, &tr, &tg, &tb, &ta);
+             evas_object_text_glow2_color_set(p_obj, tr, tg, tb, ta);
 
-             p3->type.text.align.x = FFP(p1->type.text.align.x, p2->type.text.align.x, pos);
-             p3->type.text.align.y = FFP(p1->type.text.align.y, p2->type.text.align.y, pos);
-             p3->type.text.ellipsis = TO_DOUBLE(FINTP(p1->type.text.ellipsis, p2->type.text.ellipsis, pos2));
-             break;
+             evas_object_text_text_set(p_obj, ep->typedata.text->text);
           }
 
-        /* mapped is a special case like visible */
-        if ((p1->mapped) && (!p2->mapped))
-          p3->mapped = (pos != FROM_INT(1));
-        else if ((!p1->mapped) && (p2->mapped))
-          p3->mapped = (pos != ZERO);
+        evas_object_smart_member_add(p_obj, smart_parent);
+        evas_object_color_set(p_obj, pr, pg, pb, pa);
+
+        if (ep->typedata.text->ellipsize.is_fade)
+          evas_object_clip_set(p_obj, ep->typedata.text->ellipsize.fade.mask_obj);
         else
-          p3->mapped = p1->mapped;
+          evas_object_clip_set(p_obj, ep->typedata.text->ellipsize.clipper_obj);
 
-        p3->persp_on = p3->mapped ? p1->persp_on | p2->persp_on : 0;
-        p3->lighted = p3->mapped ? p1->lighted | p2->lighted : 0;
-        if (p3->mapped)
-          {
-             EINA_COW_CALC_MAP_BEGIN(p3, p3_write)
-             {
-                p3_write->center.x = INTP(p1->map->center.x, p2->map->center.x, pos);
-                p3_write->center.y = INTP(p1->map->center.y, p2->map->center.y, pos);
-                p3_write->center.z = INTP(p1->map->center.z, p2->map->center.z, pos);
-                p3_write->rotation.x = FFP(p1->map->rotation.x, p2->map->rotation.x, pos);
-                p3_write->rotation.y = FFP(p1->map->rotation.y, p2->map->rotation.y, pos);
-                p3_write->rotation.z = FFP(p1->map->rotation.z, p2->map->rotation.z, pos);
-                p3_write->zoom.x = FFP(p1->map->zoom.x, p2->map->zoom.x, pos);
-                p3_write->zoom.y = FFP(p1->map->zoom.y, p2->map->zoom.y, pos);
+        evas_object_scale_set(p_obj, scale);
+        ep->typedata.text->ellipsize.marquee.proxy_obj = p_obj;
+     }
+
+   return ep->typedata.text->ellipsize.marquee.proxy_obj;
+}
+
+static Eina_Bool
+_edje_text_ellipsize_fade_animator_cb(void *data)
+{
+   Edje_Real_Part *ep = (Edje_Real_Part *)data;
+   Evas_Object *mask_obj = _edje_text_ellipsize_fade_mask_object_get(ep);
+   int x, y, w, h;
+
+   if (!mask_obj)
+     {
+        ep->typedata.text->ellipsize.fade.animator = NULL;
+        return ECORE_CALLBACK_CANCEL;
+     }
+
+   evas_object_geometry_get(mask_obj, &x, &y, &w, &h);
+
+   if ((x == ep->typedata.text->ellipsize.fade.x) &&
+       (y == ep->typedata.text->ellipsize.fade.y) &&
+       (w == ep->typedata.text->ellipsize.fade.w) &&
+       (h == ep->typedata.text->ellipsize.fade.h))
+     {
+        ep->typedata.text->ellipsize.fade.animator = NULL;
+        return ECORE_CALLBACK_DONE;
+     }
+
+   if (x < ep->typedata.text->ellipsize.fade.x)
+     {
+        x += EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (x > ep->typedata.text->ellipsize.fade.x)
+          x = ep->typedata.text->ellipsize.fade.x;
+     }
+   else if (x > ep->typedata.text->ellipsize.fade.x)
+     {
+        x -= EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (x < ep->typedata.text->ellipsize.fade.x)
+          x = ep->typedata.text->ellipsize.fade.x;
+     }
+
+   if (y < ep->typedata.text->ellipsize.fade.y)
+     {
+        y += EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (y > ep->typedata.text->ellipsize.fade.y)
+          y = ep->typedata.text->ellipsize.fade.y;
+     }
+   else if (y > ep->typedata.text->ellipsize.fade.y)
+     {
+        y -= EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (y < ep->typedata.text->ellipsize.fade.y)
+          y = ep->typedata.text->ellipsize.fade.y;
+     }
+
+   if (w < ep->typedata.text->ellipsize.fade.w)
+     {
+        w += EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (w > ep->typedata.text->ellipsize.fade.w)
+          w = ep->typedata.text->ellipsize.fade.w;
+     }
+   else if (w > ep->typedata.text->ellipsize.fade.w)
+     {
+        w -= EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (w < ep->typedata.text->ellipsize.fade.w)
+          w = ep->typedata.text->ellipsize.fade.w;
+     }
+
+   if (h < ep->typedata.text->ellipsize.fade.h)
+     {
+        h += EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (h > ep->typedata.text->ellipsize.fade.h)
+          h = ep->typedata.text->ellipsize.fade.h;
+     }
+   else if (h > ep->typedata.text->ellipsize.fade.h)
+     {
+        h -= EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (h < ep->typedata.text->ellipsize.fade.h)
+          h = ep->typedata.text->ellipsize.fade.h;
+     }
+
+   evas_object_resize(mask_obj, w, h);
+   evas_object_image_fill_set(mask_obj, 0, 0, w, h);
+   evas_object_move(mask_obj, x, y);
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+void
+_edje_text_ellipsize_fade_update(Edje_Real_Part *ep, Eina_Bool anim)
+{
+   Evas_Object *mask_obj = _edje_text_ellipsize_fade_mask_object_get(ep);
+   int left_fade_off_x, right_fade_off_x, left_fade_x, right_fade_x;
+   int top_fade_off_y, bottom_fade_off_y, top_fade_y, bottom_fade_y;
+   int tx, ty, tw, th;
+   int cx, cy, cw, ch;
 
-#define MIX(P1, P2, P3, pos, info) \
-  P3->info = P1->map->info + TO_INT(SCALE(pos, P2->map->info - P1->map->info));
-                map_colors_free = _map_colors_interp(p1, p2, p3_write, pos);
+   evas_object_geometry_get(ep->typedata.text->ellipsize.clipper_obj, &cx, &cy, &cw, &ch);
 
-                if (p1->lighted && p2->lighted)
-                  {
-                     MIX(p1, p2, p3_write, pos, light.x);
-                     MIX(p1, p2, p3_write, pos, light.y);
-                     MIX(p1, p2, p3_write, pos, light.z);
-                     MIX(p1, p2, p3_write, pos, light.r);
-                     MIX(p1, p2, p3_write, pos, light.g);
-                     MIX(p1, p2, p3_write, pos, light.b);
-                     MIX(p1, p2, p3_write, pos, light.ar);
-                     MIX(p1, p2, p3_write, pos, light.ag);
-                     MIX(p1, p2, p3_write, pos, light.ab);
-                  }
-                else if (p1->lighted)
-                  {
-                     memcpy(&p3_write->light, &p1->map->light, sizeof (p1->map->light));
-                  }
-                else if (p2->lighted)
-                  {
-                     memcpy(&p3_write->light, &p2->map->light, sizeof (p2->map->light));
-                  }
+   left_fade_x = left_fade_off_x = cx - LEFT_BORDER;
+   right_fade_x = right_fade_off_x = cx + cw + RIGHT_BORDER;
+   top_fade_y = top_fade_off_y = cy - TOP_BORDER;
+   bottom_fade_y = bottom_fade_off_y = cy + ch + BOTTOM_BORDER;
 
-                if (p1->persp_on && p2->persp_on)
-                  {
-                     MIX(p1, p2, p3_write, pos, persp.x);
-                     MIX(p1, p2, p3_write, pos, persp.y);
-                     MIX(p1, p2, p3_write, pos, persp.z);
-                     MIX(p1, p2, p3_write, pos, persp.focal);
-                  }
-                else if (p1->persp_on)
-                  {
-                     memcpy(&p3_write->persp, &p1->map->persp, sizeof (p1->map->persp));
-                  }
-                else if (p2->persp_on)
-                  {
-                     memcpy(&p3_write->persp, &p2->map->persp, sizeof (p2->map->persp));
-                  }
-             }
-             EINA_COW_CALC_MAP_END(p3, p3_write);
-          }
+   evas_object_geometry_get(ep->object, &tx, &ty, NULL, NULL);
+   tw = ep->typedata.text->ellipsize.text_w;
+   th = ep->typedata.text->ellipsize.text_h;
 
-#ifndef EDJE_CALC_CACHE
-        eina_cow_free(_edje_calc_params_map_cow, (const Eina_Cow_Data **)&lp2.map);
-#ifdef HAVE_EPHYSICS
-        eina_cow_free(_edje_calc_params_physics_cow, (const Eina_Cow_Data **)&lp2.physics);
-#endif
-#endif
-        pf = p3;
+   /* Calculate position and size of fade mask object */
+   if ((tx < cx) && (tx + tw > cx))
+     {
+        if (left_fade_x < left_fade_off_x + (cx - tx) * EDJE_ELLIPSIZE_FADE_SENSITIVITY)
+          left_fade_x = left_fade_off_x + (cx - tx) * EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (left_fade_x > cx)
+          left_fade_x = cx;
      }
-   else
+
+   if ((tx < cx + cw) && (tx + tw > cx + cw))
      {
-        pf = p1;
+        if (right_fade_x > right_fade_off_x - ((tx + tw) - (cx + cw)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY)
+          right_fade_x = right_fade_off_x - ((tx + tw) - (cx + cw)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (right_fade_x < cx + cw)
+          right_fade_x = cx + cw;
      }
 
-   if (!pf->persp_on && chosen_desc->map.persp_on)
+   if ((ty < cy) && (ty + th > cy))
      {
-        if (ed->persp)
-          {
-             EINA_COW_CALC_MAP_BEGIN(pf, pf_write)
-             {
-                pf_write->persp.x = ed->persp->px;
-                pf_write->persp.y = ed->persp->py;
-                pf_write->persp.z = ed->persp->z0;
-                pf_write->persp.focal = ed->persp->foc;
-             }
-             EINA_COW_CALC_MAP_END(pf, pf_write);
-          }
-        else
-          {
-             const Edje_Perspective *ps;
+        if (top_fade_y < top_fade_off_y + (cy - ty) * EDJE_ELLIPSIZE_FADE_SENSITIVITY)
+          top_fade_y = top_fade_off_y + (cy - ty) * EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (top_fade_y > cy)
+          top_fade_y = cy;
+     }
 
-             // fixme: a tad inefficient as this is a has lookup
-             ps = edje_object_perspective_get(ed->obj);
-             if (!ps)
-               ps = edje_evas_global_perspective_get(evas_object_evas_get(ed->obj));
-             EINA_COW_CALC_MAP_BEGIN(pf, pf_write)
-             {
-                if (ps)
-                  {
-                     pf_write->persp.x = ps->px;
-                     pf_write->persp.y = ps->py;
-                     pf_write->persp.z = ps->z0;
-                     pf_write->persp.focal = ps->foc;
-                  }
-                else
-                  {
-                     pf_write->persp.x = ed->x + (ed->w / 2);
-                     pf_write->persp.y = ed->y + (ed->h / 2);
-                     pf_write->persp.z = 0;
-                     pf_write->persp.focal = 1000;
-                  }
-             }
-             EINA_COW_CALC_MAP_END(pf, pf_write);
-          }
+   if ((ty < cy + ch) && (ty + th > cy + ch))
+     {
+        if (bottom_fade_y > bottom_fade_off_y - ((ty + th) - (cy + ch)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY)
+          bottom_fade_y = bottom_fade_off_y - ((ty + th) - (cy + ch)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+        if (bottom_fade_y < cy + ch)
+          bottom_fade_y = cy + ch;
      }
 
-   if (state)
+   if (ep->typedata.text->ellipsize.marquee.proxy_obj &&
+       evas_object_visible_get(ep->typedata.text->ellipsize.marquee.proxy_obj))
      {
-        const Edje_Calc_Params_Map *map;
-#ifdef HAVE_EPHYSICS
-        const Edje_Calc_Params_Physics *physics;
-#endif
+        evas_object_geometry_get(ep->typedata.text->ellipsize.marquee.proxy_obj,
+                                 &tx, &ty, NULL, NULL);
 
-        map = state->map;
-#ifdef HAVE_EPHYSICS
-        physics = state->physics;
-#endif
+        if ((tx < cx) && (tx + tw > cx))
+          {
+             if (left_fade_x < left_fade_off_x + (cx - tx) * EDJE_ELLIPSIZE_FADE_SENSITIVITY)
+               left_fade_x = left_fade_off_x + (cx - tx) * EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+             if (left_fade_x > cx)
+               left_fade_x = cx;
+          }
 
-        memcpy(state, pf, sizeof (Edje_Calc_Params));
+        if ((tx < cx + cw) && (tx + tw > cx + cw))
+          {
+             if (right_fade_x > right_fade_off_x - ((tx + tw) - (cx + cw)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY)
+               right_fade_x = right_fade_off_x - ((tx + tw) - (cx + cw)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+             if (right_fade_x < cx + cw)
+               right_fade_x = cx + cw;
+          }
 
-        state->map = map;
-#ifdef HAVE_EPHYSICS
-        state->physics = physics;
-#endif
-        eina_cow_memcpy(_edje_calc_params_map_cow, (const Eina_Cow_Data **)&state->map, pf->map);
-#ifdef HAVE_EPHYSICS
-        eina_cow_memcpy(_edje_calc_params_physics_cow, (const Eina_Cow_Data **)&state->physics, pf->physics);
-#endif
+        if ((ty < cy) && (ty + th > cy))
+          {
+             if (top_fade_y < top_fade_off_y + (cy - ty) * EDJE_ELLIPSIZE_FADE_SENSITIVITY)
+               top_fade_y = top_fade_off_y + (cy - ty) * EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+             if (top_fade_y > cy)
+               top_fade_y = cy;
+          }
+
+        if ((ty < cy + ch) && (ty + th > cy + ch))
+          {
+             if (bottom_fade_y > bottom_fade_off_y - ((ty + th) - (cy + ch)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY)
+               bottom_fade_y = bottom_fade_off_y - ((ty + th) - (cy + ch)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY;
+             if (bottom_fade_y < cy + ch)
+               bottom_fade_y = cy + ch;
+          }
      }
 
-   ep->req = pf->req;
+   ep->typedata.text->ellipsize.fade.x = left_fade_x;
+   ep->typedata.text->ellipsize.fade.y = top_fade_y;
+   ep->typedata.text->ellipsize.fade.w = right_fade_x - left_fade_x;
+   ep->typedata.text->ellipsize.fade.h = bottom_fade_y - top_fade_y;
 
-   if (ep->drag && ep->drag->need_reset)
+   if (anim)
      {
-        FLOAT_T dx, dy;
-
-        dx = ZERO;
-        dy = ZERO;
-        _edje_part_dragable_calc(ed, ep, &dx, &dy);
-        ep->drag->x = dx;
-        ep->drag->y = dy;
-        ep->drag->tmp.x = 0;
-        ep->drag->tmp.y = 0;
-        ep->drag->need_reset = 0;
+        if (!ep->typedata.text->ellipsize.fade.animator)
+          ep->typedata.text->ellipsize.fade.animator = ecore_animator_add(_edje_text_ellipsize_fade_animator_cb, ep);
      }
-   if (!ed->calc_only)
+   else
      {
-        Evas_Object *mo;
-
-        /* Common move, resize and color_set for all part. */
-        switch (ep->part->type)
+        if (ep->typedata.text->ellipsize.fade.animator)
           {
-           case EDJE_PART_TYPE_IMAGE:
-           {
-              Edje_Part_Description_Image *img_desc = (Edje_Part_Description_Image *)chosen_desc;
+             ecore_animator_del(ep->typedata.text->ellipsize.fade.animator);
+             ep->typedata.text->ellipsize.fade.animator = NULL;
+          }
 
-              evas_object_image_scale_hint_set(ep->object,
-                                               img_desc->image.scale_hint);
-              /* No break here as we share the rest of the code for all types. Intended fall-through*/
-           }
+        evas_object_resize(mask_obj,
+                           ep->typedata.text->ellipsize.fade.w,
+                           ep->typedata.text->ellipsize.fade.h);
+        evas_object_image_fill_set(mask_obj, 0, 0,
+                                   ep->typedata.text->ellipsize.fade.w,
+                                   ep->typedata.text->ellipsize.fade.h);
+        evas_object_move(mask_obj,
+                         ep->typedata.text->ellipsize.fade.x,
+                         ep->typedata.text->ellipsize.fade.y);
+     }
+}
 
-           case EDJE_PART_TYPE_PROXY:
-           case EDJE_PART_TYPE_RECTANGLE:
-           case EDJE_PART_TYPE_TEXTBLOCK:
-           case EDJE_PART_TYPE_BOX:
-           case EDJE_PART_TYPE_TABLE:
-           case EDJE_PART_TYPE_SNAPSHOT:
-           case EDJE_PART_TYPE_VECTOR:
-             evas_object_color_set(ep->object,
-                                   (pf->color.r * pf->color.a) / 255,
-                                   (pf->color.g * pf->color.a) / 255,
-                                   (pf->color.b * pf->color.a) / 255,
-                                   pf->color.a);
+static Eina_Bool
+_edje_text_ellipsize_marquee_animator_cb(void *data)
+{
+   double cur_time;
+   double elapsed_time;
+   Edje_Real_Part *ep = (Edje_Real_Part *)data;
+   Edje_Part_Description_Text *chosen_desc = (Edje_Part_Description_Text *)ep->chosen_description;
+   Evas_Object *clipper_obj = ep->typedata.text->ellipsize.clipper_obj;
+   Evas_Coord_Rectangle text_cur_area;
+   Evas_Coord_Rectangle clipper_area;
+   /* TODO: roll_gap should be controlled by edc developers? */
+   double time_sec_per_pixel = ep->typedata.text->ellipsize.marquee.sec_per_pixel;
+   int roll_gap = EDJE_TEXT_ELLIPSIZE_MARQUEE_ROLL_GAP;
+   int loop_jump_from_pos = 0;
+   int loop_jump_to_pos = 0;
+   int distance_per_loop = 0;
+   int move_pixel = 0;
+   Eina_Bool text_marquee_top_left;
+   Eina_Bool text_marquee_vertical;
 
-#ifdef HAVE_EPHYSICS
-/* body attributes should be updated for invisible objects */
-             if (!ep->part->physics_body)
-               {
-                  if (!pf->visible)
-                    {
-                       evas_object_hide(ep->object);
-                       break;
-                    }
-                  evas_object_show(ep->object);
-               }
-             else if (!pf->visible)
-               {
-                  Evas_Object *face_obj;
-                  Eina_List *l;
+   evas_object_geometry_get(ep->object, &text_cur_area.x, &text_cur_area.y,
+                            &text_cur_area.w, &text_cur_area.h);
 
-                  EINA_LIST_FOREACH(ep->body_faces, l, face_obj)
-                    evas_object_hide(face_obj);
-                  evas_object_hide(ep->object);
-               }
-#else
-             if (!pf->visible)
-               {
-                  evas_object_hide(ep->object);
-                  break;
-               }
-             evas_object_show(ep->object);
+   if ((text_cur_area.w != ep->typedata.text->ellipsize.text_w) ||
+       (text_cur_area.h != ep->typedata.text->ellipsize.text_h))
+     {
+        text_cur_area.w = ep->typedata.text->ellipsize.text_w;
+        text_cur_area.h = ep->typedata.text->ellipsize.text_h;
+        evas_object_resize(ep->object, text_cur_area.w, text_cur_area.h);
+     }
 
-#endif
-           /* move and resize are needed for all previous object => no break here. */
-           case EDJE_PART_TYPE_SWALLOW:
-           case EDJE_PART_TYPE_GROUP:
-           case EDJE_PART_TYPE_EXTERNAL:
-             /* visibility and color have no meaning on SWALLOW and GROUP part. */
-#ifdef HAVE_EPHYSICS
-             eo_do(ep->object,
-                   efl_gfx_size_set(pf->final.w, pf->final.h));
-             if ((ep->part->physics_body) && (!ep->body))
-               {
-                  if (_edje_physics_world_geometry_check(ed->world))
-                    {
-                       _edje_physics_body_add(ed, ep, ed->world);
-                       _edje_physics_body_props_update(ed, ep, pf, EINA_TRUE);
-                    }
-               }
-             else if (ep->body)
-               {
-                  if (((ep->prev_description) &&
-                       (chosen_desc != ep->prev_description)) ||
-                      (pf != p1))
-                    _edje_physics_body_props_update(ed, ep, pf, !pf->physics->ignore_part_pos);
-               }
-             else
-               eo_do(ep->object,
-                     efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y));
-#else
-             eo_do(ep->object,
-                   efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y));
+   if (ep->typedata.text->ellipsize.valign != -1.0)
+     text_marquee_vertical = EINA_TRUE;
+   else
+     text_marquee_vertical = EINA_FALSE;
 
-             //TIZEN_ONLY(20160923): introduction of text marquee
-             if(ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
-               {
-                  tw = pf->final.w;
-                  th = pf->final.h;
+   if (text_marquee_vertical)
+     {
+        if (ep->typedata.text->ellipsize.valign == 1.0)
+          text_marquee_top_left = EINA_TRUE;
+        else
+          text_marquee_top_left = EINA_FALSE;
+     }
+   else
+     {
+        if (ep->typedata.text->ellipsize.halign == 1.0)
+          text_marquee_top_left = EINA_TRUE;
+        else
+          text_marquee_top_left = EINA_FALSE;
+     }
 
-                  text_chosen_desc = (Edje_Part_Description_Text *)ep->chosen_description;
-                  if (text_chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE &&
-                      text_chosen_desc->text.ellipsize.marquee_repeat_limit != 0)
-                    {
-                       eo_do(ep->object,
-                             evas_obj_textblock_size_formatted_get(&tw, &th));
-                       if (tw < pf->final.w) tw = pf->final.w;
-                       if (th < pf->final.h) th = pf->final.h;
-                    }
-                  eo_do(ep->object,
-                        efl_gfx_size_set(tw, th));
-               }
-             //
-              else
-                eo_do(ep->object,
-                      efl_gfx_size_set(pf->final.w, pf->final.h));
-#endif
+   /* If text's current width is smaller than part's width, cancel marquee */
+   if ((text_cur_area.w <= ep->w) && (text_cur_area.h <= ep->h))
+     {
+        evas_object_move(ep->object,
+                         ep->typedata.text->ellipsize.marquee.orig_x,
+                         ep->typedata.text->ellipsize.marquee.orig_y);
+        ep->typedata.text->ellipsize.marquee.animator = NULL;
+        _edje_text_ellipsize_marquee_remove(ep);
+        _edje_text_ellipsize_fade_update(ep, EINA_FALSE);
 
-             if (ep->nested_smart) /* Move, Resize all nested parts */
-               {   /* Not really needed but will improve the bounding box evaluation done by Evas */
-                  eo_do(ep->nested_smart,
-                        efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
-                        efl_gfx_size_set(pf->final.w, pf->final.h));
-               }
-             if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
-               _edje_entry_real_part_configure(ed, ep);
+        return ECORE_CALLBACK_CANCEL;
+     }
 
-             /* handle clip overrides */
-             if (ed->has_state_clip)
-               {
-                  if (pf->clip_to && pf->clip_to->object)
-                    evas_object_clip_set(ep->object, pf->clip_to->object);
-                  else if (ep->part->clip_to_id >= 0)
-                    evas_object_clip_set(ep->object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object);
-                  else
-                    evas_object_clip_set(ep->object, ed->base->clipper);
-               }
-             break;
+   evas_object_geometry_get(clipper_obj,
+                            &clipper_area.x, &clipper_area.y,
+                            &clipper_area.w, &clipper_area.h);
 
-           case EDJE_PART_TYPE_TEXT:
-             /* This is correctly handle in _edje_text_recalc_apply at the moment. */
-             break;
+   cur_time = ecore_time_get();
+   elapsed_time = cur_time - ep->typedata.text->ellipsize.marquee.animator_prev_time;
 
-           case EDJE_PART_TYPE_GRADIENT:
-             /* FIXME: definitivly remove this code when we switch to new format. */
-             abort();
-             break;
+   /* Calculates move_pixel when only elapsed_time has positive value.
+    * The elapsed_time variable could have negative value if there is loop_delay. */
+   if (elapsed_time > 0.0)
+     {
+        while (elapsed_time > time_sec_per_pixel)
+          {
+             elapsed_time -= time_sec_per_pixel;
+             move_pixel++;
+          }
 
-           case EDJE_PART_TYPE_SPACER:
-             /* We really should do nothing on SPACER part */
-             break;
-           case EDJE_PART_TYPE_CAMERA:
-             {
-                Evas_Canvas3D_Camera *camera = NULL;
-                Edje_Part_Description_Camera *pd_camera;
+        ep->typedata.text->ellipsize.marquee.animator_prev_time = cur_time - elapsed_time;
+     }
 
-                pd_camera = (Edje_Part_Description_Camera*) ep->chosen_description;
-                eo_do(ep->node, camera = evas_canvas3d_node_camera_get());
+   if (move_pixel > 0)
+     {
+        double overpixel_for_jump = 0.0;
+        double overtime_for_loop = 0.0;
+        double overpixel_for_loop = 0.0;
+        int clipper_pos, clipper_length;
+        int text_pos, text_length;
 
-                eo_do(camera,
-                      evas_canvas3d_camera_projection_perspective_set(pd_camera->camera.camera.fovy, pd_camera->camera.camera.aspect,
-                                                                pd_camera->camera.camera.frustum_near, pd_camera->camera.camera.frustum_far));
+        if (text_marquee_vertical)
+          {
+             clipper_pos = clipper_area.y;
+             clipper_length = clipper_area.h;
+             text_pos = text_cur_area.y;
+             text_length = text_cur_area.h;
+          }
+        else
+          {
+             clipper_pos = clipper_area.x;
+             clipper_length = clipper_area.w;
+             text_pos = text_cur_area.x;
+             text_length = text_cur_area.w;
+          }
 
-                eo_do(ep->node,
-                      evas_canvas3d_node_position_set(pd_camera->camera.position.point.x, pd_camera->camera.position.point.y,
-                                                  pd_camera->camera.position.point.z));
-                switch (pd_camera->camera.orientation.type)
-                  {
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_NONE:
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_QUATERNION:
-                       {
-                          SET_QUATERNION(camera)
-                          break;
-                       }
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT:
-                       SET_LOOK_AT(camera)
-                       break;
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_TO:
-                       {
-                          SET_LOOK_TO(camera)
-                          break;
-                       }
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_ANGLE_AXIS:
-                       SET_ANGLE_AXIS(camera)
-                       break;
-                  }
-                break;
-             }
-           case EDJE_PART_TYPE_LIGHT:
-             {
-                Evas_Canvas3D_Light *light_node = NULL;
-                Edje_Part_Description_Light *pd_light;
+        /* Calculate basic information of a loop according to marquee type */
+        switch (chosen_desc->text.ellipsize.marquee.type)
+          {
+           case EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL:
+              distance_per_loop = text_length + roll_gap;
 
-                pd_light = (Edje_Part_Description_Light*) ep->chosen_description;
-                eo_do(ep->node, light_node = evas_canvas3d_node_light_get());
+              if (text_marquee_top_left)
+                {
+                   loop_jump_from_pos = clipper_pos - text_length - roll_gap;
+                   loop_jump_to_pos = clipper_pos;
+                }
+              else
+                {
+                   loop_jump_from_pos = clipper_pos + clipper_length + roll_gap;
+                   loop_jump_to_pos = clipper_pos + clipper_length - text_length;
+                }
+              break;
+           case EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_DEFAULT:
+           default:
+              distance_per_loop = text_length + clipper_length;
 
-                eo_do(light_node,
-                      evas_canvas3d_light_ambient_set(pd_light->light.properties.ambient.r / 255, pd_light->light.properties.ambient.g / 255,
-                                                pd_light->light.properties.ambient.b / 255, pd_light->light.properties.ambient.a / 255),
-                      evas_canvas3d_light_diffuse_set(pd_light->light.properties.diffuse.r / 255, pd_light->light.properties.diffuse.g / 255,
-                                                pd_light->light.properties.diffuse.b / 255, pd_light->light.properties.diffuse.a / 255),
-                      evas_canvas3d_light_specular_set(pd_light->light.properties.specular.r / 255, pd_light->light.properties.specular.g / 255,
-                                                 pd_light->light.properties.specular.b / 255, pd_light->light.properties.specular.a / 255),
-                      evas_canvas3d_light_directional_set(EINA_TRUE));
+              if (text_marquee_top_left)
+                {
+                   loop_jump_from_pos = clipper_pos - text_length;
+                   loop_jump_to_pos = clipper_pos + clipper_length;
+                }
+              else
+                {
+                   loop_jump_from_pos = clipper_pos + clipper_length;
+                   loop_jump_to_pos = clipper_pos - text_length;
+                }
+          }
 
-                eo_do(ep->node,
-                      evas_canvas3d_node_position_set(pd_light->light.position.point.x, pd_light->light.position.point.y,
-                                                  pd_light->light.position.point.z));
-                switch (pd_light->light.orientation.type)
-                  {
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_NONE:
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_QUATERNION:
-                       {
-                          SET_QUATERNION(light);
-                          break;
-                       }
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT:
-                       SET_LOOK_AT(light)
-                       break;
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_TO:
-                       {
-                          SET_LOOK_TO(light)
-                          break;
-                       }
-                     case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_ANGLE_AXIS:
-                       SET_ANGLE_AXIS(light)
-                       break;
-                  }
-                break;
-             }
-           case EDJE_PART_TYPE_MESH_NODE:
-             {
-                Evas_Canvas3D_Material *material = NULL;
-                Evas_Canvas3D_Texture *texture = NULL;
-                Evas_Canvas3D_Mesh *mesh = NULL;
-                const char *proxy;
-                Edje_Part_Description_Mesh_Node *pd_mesh_node;
-                const Eina_List *meshes;
-                const Eina_List *list;
+        /* Calculate new x, y position according to current marquee direction */
+        if (text_marquee_top_left)
+          {
+             text_pos -= move_pixel;
 
-                eo_do(ep->node, meshes = evas_canvas3d_node_mesh_list_get());
+             /* If x pos exceed loop_jump_from_pos, jump to loop_jump_to_pos */
+             if (text_pos <= loop_jump_from_pos)
+               {
+                  overpixel_for_jump = loop_jump_from_pos - text_pos;
+                  text_pos = loop_jump_to_pos - overpixel_for_jump;
+               }
+          }
+        else
+          {
+             text_pos += move_pixel;
 
-                EINA_LIST_FOREACH(meshes, list, mesh)
-                  {
-                     eo_do(mesh,  material = evas_canvas3d_mesh_frame_material_get(0));
-                     eo_do(material,  texture = evas_canvas3d_material_texture_get(EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE));
+             /* If x pos exceed loop_jump_from_pos, jump to loop_jump_to_pos */
+             if (text_pos >= loop_jump_from_pos)
+               {
+                  overpixel_for_jump = text_pos - loop_jump_from_pos;
+                  text_pos = loop_jump_to_pos + overpixel_for_jump;
+               }
+          }
 
-                     pd_mesh_node = (Edje_Part_Description_Mesh_Node*) ep->chosen_description;
+        /* If there is a loop limit, update loop and check it */
+        if (chosen_desc->text.ellipsize.marquee_repeat_limit > 0)
+          {
+             /* Update moved distance which is used to update loop count */
+             ep->typedata.text->ellipsize.marquee.distance += move_pixel;
 
-                     eo_do(material,
-                           evas_canvas3d_material_enable_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_AMBIENT, EINA_TRUE),
-                           evas_canvas3d_material_enable_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE, EINA_TRUE),
-                           evas_canvas3d_material_enable_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_SPECULAR, EINA_TRUE),
-                           evas_canvas3d_material_enable_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_NORMAL, pd_mesh_node->mesh_node.properties.normal),
-                           evas_canvas3d_material_color_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_AMBIENT,
-                                                      pd_mesh_node->mesh_node.properties.ambient.r / 255,
-                                                      pd_mesh_node->mesh_node.properties.ambient.g / 255,
-                                                      pd_mesh_node->mesh_node.properties.ambient.b / 255,
-                                                      pd_mesh_node->mesh_node.properties.ambient.a / 255),
-                           evas_canvas3d_material_color_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE,
-                                                      pd_mesh_node->mesh_node.properties.diffuse.r / 255,
-                                                      pd_mesh_node->mesh_node.properties.diffuse.g / 255,
-                                                      pd_mesh_node->mesh_node.properties.diffuse.b / 255,
-                                                      pd_mesh_node->mesh_node.properties.diffuse.a / 255),
-                           evas_canvas3d_material_color_set(EVAS_CANVAS3D_MATERIAL_ATTRIB_SPECULAR,
-                                                      pd_mesh_node->mesh_node.properties.specular.r / 255,
-                                                      pd_mesh_node->mesh_node.properties.specular.g / 255,
-                                                      pd_mesh_node->mesh_node.properties.specular.b / 255,
-                                                      pd_mesh_node->mesh_node.properties.specular.a / 255),
-                           evas_canvas3d_material_shininess_set(pd_mesh_node->mesh_node.properties.shininess));
+             /* Update loop count */
+             if (ep->typedata.text->ellipsize.marquee.distance >= distance_per_loop)
+               {
+                  ep->typedata.text->ellipsize.marquee.loop_count += ep->typedata.text->ellipsize.marquee.distance / distance_per_loop;
+                  ep->typedata.text->ellipsize.marquee.distance %= distance_per_loop;
 
-                     switch(pd_mesh_node->mesh_node.mesh.primitive)
-                       {
-                          case EVAS_CANVAS3D_MESH_PRIMITIVE_CUBE:
-                            {
-                               Eo *primitive = NULL;
+                  /* Give a latency for next loop. The code below corrects the latency of the next loop,
+                     taking into account the pixels beyond the loop. */
+                  if (chosen_desc->text.ellipsize.marquee.loop_delay > 0.0)
+                    {
+                       double next_delay_time;
 
-                               eo_do(primitive,
-                                     evas_canvas3d_primitive_form_set(EVAS_CANVAS3D_MESH_PRIMITIVE_CUBE));
+                       overpixel_for_loop = ep->typedata.text->ellipsize.marquee.distance;
+                       overtime_for_loop = overpixel_for_loop * time_sec_per_pixel;
+                       next_delay_time = chosen_desc->text.ellipsize.marquee.loop_delay - overtime_for_loop;
 
-                               eo_do(mesh,
-                                     evas_canvas3d_mesh_from_primitive_set(0, primitive));
-                               break;
-                            }
-                          case EVAS_CANVAS3D_MESH_PRIMITIVE_SPHERE:
-                            {
-                               Eo *primitive = NULL;
+                       if (next_delay_time >= 0.0)
+                         {
+                            ep->typedata.text->ellipsize.marquee.animator_prev_time += next_delay_time;
+                            overpixel_for_loop = -ep->typedata.text->ellipsize.marquee.distance;
+                         }
+                       else
+                         {
+                            /* Below is a code of extraordinary situations.
+                               If the time beyond a loop is greater than the latency of a given loop,
+                               then it is necessary to remove the pixels of the corresponding delay.
+                               The overpixel_for_loop variable will have negative value. */
+                            overpixel_for_loop = next_delay_time * time_sec_per_pixel;
+                         }
 
-                               eo_do(primitive,
-                                     evas_canvas3d_primitive_form_set(EVAS_CANVAS3D_MESH_PRIMITIVE_SPHERE),
-                                     evas_canvas3d_primitive_precision_set(20));
+                       ep->typedata.text->ellipsize.marquee.distance += overpixel_for_loop;
+                    }
+               }
 
-                               eo_do(mesh,
-                                     evas_canvas3d_mesh_from_primitive_set(0, primitive));
-                               break;
-                            }
-                          default:
-                            break;
-                       }
+             /* Check if the loop count reaches the given loop limit. */
+             if (ep->typedata.text->ellipsize.marquee.loop_count >=
+                 chosen_desc->text.ellipsize.marquee_repeat_limit)
+               {
+                  evas_object_move(ep->object,
+                                   ep->typedata.text->ellipsize.marquee.orig_x,
+                                   ep->typedata.text->ellipsize.marquee.orig_y);
 
-                     if (pd_mesh_node->mesh_node.texture.need_texture && pd_mesh_node->mesh_node.texture.textured)
-                       {
-                          proxy = NULL;
+                  ep->typedata.text->ellipsize.marquee.animator = NULL;
+                  _edje_text_ellipsize_marquee_remove(ep);
+                  _edje_text_ellipsize_fade_update(ep, EINA_TRUE);
 
-                          eo_do(material,
-                                texture = evas_canvas3d_material_texture_get(EVAS_CANVAS3D_MATERIAL_ATTRIB_DIFFUSE));
+                  return ECORE_CALLBACK_DONE;
+               }
+          }
 
-                          //proxy = _edje_image_name_find(ed, pd_mesh_node->mesh_node.texture.id);
-                          /*FIXME Conflict with function _edje_image_name_find (two places in edje_utils and edje_edit.c,
-                          temporary desicion need to clarify up to commit to phab*/
-                          proxy = ed->file->image_dir->entries[pd_mesh_node->mesh_node.texture.id].entry;
-                          if (proxy)
-                            {
-                               eo_do(texture,
-                                     evas_canvas3d_texture_file_set(eina_stringshare_add(proxy), NULL),
-                                     evas_canvas3d_texture_filter_set(pd_mesh_node->mesh_node.texture.filter1,
-                                                                pd_mesh_node->mesh_node.texture.filter2),
-                                     evas_canvas3d_texture_wrap_set(pd_mesh_node->mesh_node.texture.wrap1,
-                                                              pd_mesh_node->mesh_node.texture.wrap2));
-                            }
-                       }
+        if (text_marquee_top_left)
+          text_pos -= overpixel_for_loop;
+        else
+          text_pos += overpixel_for_loop;
 
-                     eo_do(mesh,
-                           evas_canvas3d_mesh_frame_material_set(0, material),
-                           evas_canvas3d_mesh_shade_mode_set(pd_mesh_node->mesh_node.properties.shade),
-                           evas_canvas3d_mesh_vertex_assembly_set(pd_mesh_node->mesh_node.mesh.assembly));
-                     eo_do(ep->node,
-                           evas_canvas3d_node_scale_set(ep->part->scale_3d.x, ep->part->scale_3d.y,
-                                                  ep->part->scale_3d.z),
-                           evas_canvas3d_node_position_set(pd_mesh_node->mesh_node.position.point.x,
-                                                     pd_mesh_node->mesh_node.position.point.y,
-                                                     pd_mesh_node->mesh_node.position.point.z));
-                     switch (pd_mesh_node->mesh_node.orientation.type)
-                       {
-                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_NONE:
-                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_QUATERNION:
-                            {
-                               SET_QUATERNION(mesh_node)
-                               break;
-                            }
-                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_AT:
-                            SET_LOOK_AT(mesh_node)
-                            break;
-                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_LOOK_TO:
-                            {
-                               SET_LOOK_TO(mesh_node)
-                               break;
-                            }
-                          case EVAS_CANVAS3D_NODE_ORIENTATION_TYPE_ANGLE_AXIS:
-                            SET_ANGLE_AXIS(mesh_node)
-                            break;
-                       }
-                  }
-                break;
-             }
+        /* If current marquee type needs a proxy object, update it, too. */
+        if (chosen_desc->text.ellipsize.marquee.type == EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL)
+          {
+             Evas_Object *p_obj = _edje_text_ellipsize_marquee_proxy_object_get(ep);
+             int proxy_text_x, proxy_text_y;
+             int proxy_text_pos = text_pos;
+
+             if (text_marquee_top_left)
+               proxy_text_pos += text_length + roll_gap;
+             else
+               proxy_text_pos -= text_length + roll_gap;
+
+             if (text_marquee_vertical)
+               {
+                  proxy_text_x = text_cur_area.x;
+                  proxy_text_y = proxy_text_pos;
+               }
+             else
+               {
+                  proxy_text_x = proxy_text_pos;
+                  proxy_text_y = text_cur_area.y;
+               }
+
+             evas_object_move(p_obj, proxy_text_x, proxy_text_y);
+             evas_object_resize(p_obj, text_cur_area.w, text_cur_area.h);
+             evas_object_show(p_obj);
           }
 
-        /* Some object need special recalc. */
-        switch (ep->part->type)
-          {
-           case EDJE_PART_TYPE_TEXT:
-             _edje_text_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc, EINA_FALSE);
-             break;
+        if (text_marquee_vertical)
+          text_cur_area.y = text_pos;
+        else
+          text_cur_area.x = text_pos;
 
-           case EDJE_PART_TYPE_PROXY:
-             _edje_proxy_recalc_apply(ed, ep, pf, (Edje_Part_Description_Proxy *)chosen_desc, pos);
-             break;
+        /* Update Textblock/Text object using updated position */
+        evas_object_move(ep->object, text_cur_area.x, text_cur_area.y);
 
-           case EDJE_PART_TYPE_IMAGE:
-             _edje_image_recalc_apply(ed, ep, pf, (Edje_Part_Description_Image *)chosen_desc, pos);
-             break;
+        _edje_text_ellipsize_fade_update(ep, EINA_TRUE);
+     }
 
-           case EDJE_PART_TYPE_BOX:
-             _edje_box_recalc_apply(ed, ep, pf, (Edje_Part_Description_Box *)chosen_desc);
-             break;
+   return ECORE_CALLBACK_RENEW;
+}
 
-           case EDJE_PART_TYPE_TABLE:
-             _edje_table_recalc_apply(ed, ep, pf, (Edje_Part_Description_Table *)chosen_desc);
-             break;
+/*
+ * _edje_text_ellipsize_apply() is a main function to apply ellipsis, fade, marquee.
+ * ellipsize.mode: NONE will off this feature and respect old way of ellipsis.
+ *
+ * example:
+ *    description {
+ *       text {
+ *          ellipsize {
+ *             mode: FADE_MARQUEE; // NONE(default), NORMAL, FADE, FADE_MARQUEE, MARQUEE
+ *             align: END;         // END(default), START, LEFT, RIGHT, LOCALE
+ *             marquee {
+ *                type: ROLL;      // NORMAL(default), ROLL
+ *                speed: 50;       // pixel per sec. It is a scalable variable when its part is scalable.
+ *                // duration: 4.0;// sec per loop. The speed will be changed according to text's length.
+ *                loop: 3;
+ *                loop_delay: 2.0; // sec. delay for starting each loop
+ *             }
+ *          }
+ *       }
+ *    }
+ *
+ * It also support legacy fade_ellipsis.
+ */
+static void
+_edje_text_ellipsize_apply(Edje *ed, Edje_Real_Part *ep,
+                           Edje_Calc_Params *pf,
+                           Edje_Part_Description_Text *chosen_desc)
+{
+   Evas_Object *edje_orig_clipper;
+   Evas_Object *clipper_obj;
+   Evas_Object *mask_obj;
+   double halign, valign;
+   Eina_Bool ellipsis_status;
+   Eina_Bool is_fade = EINA_FALSE;
+   Eina_Bool is_marquee = EINA_FALSE;
+   /* TODO: roll_gap should be controlled by edc developers? */
+   int roll_gap = EDJE_TEXT_ELLIPSIZE_MARQUEE_ROLL_GAP;
+   int clipper_x, clipper_y, clipper_w, clipper_h;
+   int tx, ty, tw, th;
 
-           case EDJE_PART_TYPE_TEXTBLOCK:
-             _edje_textblock_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text *)chosen_desc);
-             break;
+   if ((ep->part->type != EDJE_PART_TYPE_TEXTBLOCK) &&
+       (ep->part->type != EDJE_PART_TYPE_TEXT))
+     return;
 
-           case EDJE_PART_TYPE_VECTOR:
-             _edje_svg_recalc_apply(ed, ep, pf, (Edje_Part_Description_Vector *)chosen_desc, pos);
-             break;
+   if (pf->clip_to && pf->clip_to->object)
+     evas_object_clip_set(ep->object, pf->clip_to->object);
+   else if (ep->part->clip_to_id >= 0)
+     evas_object_clip_set(ep->object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object);
+   else
+     evas_object_clip_set(ep->object, ed->base->clipper);
 
-           case EDJE_PART_TYPE_EXTERNAL:
-           case EDJE_PART_TYPE_RECTANGLE:
-           case EDJE_PART_TYPE_SWALLOW:
-           case EDJE_PART_TYPE_GROUP:
-             /* Nothing special to do for this type of object. */
-             break;
+   if (ep->typedata.text->ellipsize.fade.animator)
+     {
+        ecore_animator_del(ep->typedata.text->ellipsize.fade.animator);
+        ep->typedata.text->ellipsize.fade.animator = NULL;
+     }
 
-           case EDJE_PART_TYPE_GRADIENT:
-             /* FIXME: definitivly remove this code when we switch to new format. */
-             abort();
-             break;
+   if (ep->typedata.text->ellipsize.marquee.animator)
+     {
+        _edje_text_ellipsize_marquee_remove(ep);
+        _edje_text_ellipsize_fade_update(ep, EINA_FALSE);
+     }
 
-           case EDJE_PART_TYPE_SPACER:
-             /* We really should do nothing on SPACER part */
-             break;
+   /* Hide fade image if fade_ellipsis option is off or object size is zero. */
+   if ((pf->final.w == 0) || (pf->final.h == 0) ||
+       ((chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_NONE) &&
+        (chosen_desc->text.fade_ellipsis - 1.0 == -1.0)))
+     {
+        if (ep->typedata.text->ellipsize.clipper_obj)
+          {
+             evas_object_clip_unset(ep->typedata.text->ellipsize.clipper_obj);
+             evas_object_hide(ep->typedata.text->ellipsize.clipper_obj);
           }
 
-        if (((ep->type == EDJE_RP_TYPE_SWALLOW) &&
-             (ep->typedata.swallow)) &&
-            (ep->typedata.swallow->swallowed_object))
+        if (ep->typedata.text->ellipsize.fade.mask_obj)
           {
-             if (ed->has_state_clip)
-               {
-                  if (pf->clip_to && pf->clip_to->object)
-                    evas_object_clip_set(ep->typedata.swallow->swallowed_object, pf->clip_to->object);
-                  else if (ep->part->clip_to_id >= 0)
-                    evas_object_clip_set(ep->typedata.swallow->swallowed_object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object);
-                  else
-                    evas_object_clip_set(ep->typedata.swallow->swallowed_object, ed->base->clipper);
-               }
+             evas_object_clip_unset(ep->typedata.text->ellipsize.fade.mask_obj);
+             evas_object_hide(ep->typedata.text->ellipsize.fade.mask_obj);
+          }
 
-             if (pf->visible)
-               {
-                  Eina_Bool vis = EINA_TRUE;
+        /* Disable normal ellipsis and proceed */
+        if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
+          evas_object_textblock_ellipsis_set(ep->object, -1.0);
+        else if (ep->part->type == EDJE_PART_TYPE_TEXT)
+          evas_object_text_ellipsis_set(ep->object, -1.0);
 
-                  if (ep->part->type == EDJE_PART_TYPE_GROUP)
-                    vis = evas_object_visible_get(ed->obj);
-                  eo_do(ep->typedata.swallow->swallowed_object,
-                        efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
-                        efl_gfx_size_set(pf->final.w, pf->final.h),
-                        efl_gfx_visible_set(vis));
-               }
-             else evas_object_hide(ep->typedata.swallow->swallowed_object);
-             mo = ep->typedata.swallow->swallowed_object;
-          }
-        else mo = ep->object;
+        return;
+     }
 
-        Evas_Object *map_obj;
+   if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
+     ellipsis_status = evas_object_textblock_ellipsis_status_get(ep->object);
+   else
+     ellipsis_status = evas_object_text_ellipsis_status_get(ep->object);
 
-        /* Apply map to smart obj holding nested parts */
-        if (ep->nested_smart) map_obj = ep->nested_smart;
-        else map_obj = mo;
+   /* Get alignment of ellipsize according to ellipsize.align and Text/Textblock's status */
+   _edje_text_ellipsize_align_get(ep, pf, chosen_desc, &halign, &valign);
 
-        if (ep->part->type != EDJE_PART_TYPE_SPACER)
+   /* Enable normal ellipsis and quit the function */
+   if (chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_NORMAL)
+     {
+        if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
           {
-             if (chosen_desc->map.on)
-               {
-                  static Evas_Map *map = NULL;
+             evas_object_textblock_ellipsis_set(ep->object, halign);
+          }
+        else if (ep->part->type == EDJE_PART_TYPE_TEXT)
+          {
+             evas_object_text_ellipsis_set(ep->object, halign);
+             evas_object_resize(ep->object, pf->final.w, pf->final.h);
+          }
 
-                  ed->have_mapped_part = EINA_TRUE;
-                  // create map and populate with part geometry
-                  if (!map) map = evas_map_new(4);
+        if (ep->typedata.text->ellipsize.clipper_obj)
+          {
+             evas_object_clip_unset(ep->typedata.text->ellipsize.clipper_obj);
+             evas_object_hide(ep->typedata.text->ellipsize.clipper_obj);
+          }
 
-                  _edje_map_prop_set(map, pf, chosen_desc, ep, mo);
+        if (ep->typedata.text->ellipsize.fade.mask_obj)
+          {
+             evas_object_clip_unset(ep->typedata.text->ellipsize.fade.mask_obj);
+             evas_object_hide(ep->typedata.text->ellipsize.fade.mask_obj);
+          }
 
-                  if (map_obj)
-                    {
-                       eo_do(map_obj,
-                             evas_obj_map_set(map),
-                             evas_obj_map_enable_set(EINA_TRUE));
-                    }
-               }
-             else
-               {
-                  Eina_Bool ret;
+        return;
+     }
 
-                  if (map_obj && eo_do_ret(map_obj, ret, evas_obj_map_enable_get()))
-                    {
-#ifdef HAVE_EPHYSICS
-                       if (!ep->nested_smart && !ep->body)
-                         {
-#endif
-                            eo_do(map_obj,
-                                  evas_obj_map_enable_set(EINA_FALSE),
-                                  evas_obj_map_set(NULL));
-#ifdef HAVE_EPHYSICS
-                         }
-#endif
-                    }
-               }
+   /* Disable normal ellipsis and proceed */
+   if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
+     evas_object_textblock_ellipsis_set(ep->object, -1.0);
+   else if (ep->part->type == EDJE_PART_TYPE_TEXT)
+     evas_object_text_ellipsis_set(ep->object, -1.0);
 
-             /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to TEXTBLOCK, TEXT part. */
-             if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK ||
-                 ep->part->type == EDJE_PART_TYPE_TEXT)
-               {
-                  /* TIZEN_ONLY(20170427): fix clipper loop issue caused by clipper object for fade ellipsis.
-                   * Reset clipper for Textblock to fix the issue. */
-                  if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
-                    {
-                       if (pf->clip_to && pf->clip_to->object)
-                         evas_object_clip_set(ep->object, pf->clip_to->object);
-                       else if (ep->part->clip_to_id >= 0)
-                         evas_object_clip_set(ep->object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object);
-                       else
-                         evas_object_clip_set(ep->object, ed->base->clipper);
-                    }
-                  /* END */
+   /* Enable fade if one of fade types is set or legacy fade_ellipsis option is set */
+   if ((chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_FADE) ||
+       (chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_FADE_MARQUEE) ||
+       (chosen_desc->text.fade_ellipsis > 0.0))
+     is_fade = EINA_TRUE;
 
-                  _edje_fade_ellipsis_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc);
-                  //TIZEN_ONLY(20160923): introduction of text marquee
-                  _edje_text_marquee_apply(ed, ep, pf, (Edje_Part_Description_Text *) chosen_desc);
-                  //
-               }
-             /* END */
+   /* Enable marquee if one of marquee types is set and loop count is bigger than zero */
+   if (((chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE) ||
+        (chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_FADE_MARQUEE)) &&
+       (chosen_desc->text.ellipsize.marquee_repeat_limit != 0))
+     is_marquee = EINA_TRUE;
+
+   if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
+     {
+        evas_object_textblock_size_formatted_get(ep->object, &tw, &th);
+     }
+   else
+     {
+        tw = evas_object_text_horiz_advance_get(ep->object);
+        th = evas_object_text_vert_advance_get(ep->object);
+     }
+
+   /* Hide fade image if text is not exceed the given area. */
+   if ((tw <= pf->final.w) && (th <= pf->final.h) && !ellipsis_status)
+     {
+        if (ep->typedata.text->ellipsize.clipper_obj)
+          {
+             evas_object_clip_unset(ep->typedata.text->ellipsize.clipper_obj);
+             evas_object_hide(ep->typedata.text->ellipsize.clipper_obj);
           }
+
+        if (ep->typedata.text->ellipsize.fade.mask_obj)
+          {
+             evas_object_clip_unset(ep->typedata.text->ellipsize.fade.mask_obj);
+             evas_object_hide(ep->typedata.text->ellipsize.fade.mask_obj);
+          }
+
+        return;
      }
 
-   if (map_colors_free) _map_colors_free(pf);
+   if (ellipsis_status)
+     {
+        if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
+          {
+             evas_object_textblock_ellipsis_disabled_set(ep->object, EINA_TRUE);
+             evas_object_textblock_size_formatted_get(ep->object, &tw, &th);
+             evas_object_textblock_ellipsis_disabled_set(ep->object, EINA_FALSE);
+          }
+        else
+          {
+             tw = evas_object_text_horiz_width_without_ellipsis_get(ep->object);
+          }
+     }
 
-#ifdef HAVE_EPHYSICS
-   ep->prev_description = chosen_desc;
-   if (!ep->body)
+   /* Add a cllipper object */
+   if (!ep->typedata.text->ellipsize.clipper_obj)
      {
-#endif
-        ep->x = pf->final.x;
-        ep->y = pf->final.y;
-        ep->w = pf->final.w;
-        ep->h = pf->final.h;
-#ifdef HAVE_EPHYSICS
+        ep->typedata.text->ellipsize.clipper_obj = evas_object_rectangle_add(evas_object_evas_get(ep->object));
+        evas_object_pass_events_set(ep->typedata.text->ellipsize.clipper_obj, 1);
+        evas_object_pointer_mode_set(ep->typedata.text->ellipsize.clipper_obj, EVAS_OBJECT_POINTER_MODE_NOGRAB);
+        evas_object_smart_member_add(ep->typedata.text->ellipsize.clipper_obj, ed->obj);
      }
 
-#endif
+   clipper_obj = ep->typedata.text->ellipsize.clipper_obj;
+   clipper_x = ed->x + pf->final.x;
+   clipper_y = ed->y + pf->final.y;
+   clipper_w = pf->final.w;
+   clipper_h = pf->final.h;
 
-   ep->calculated |= flags;
-   ep->calculating = FLAG_NONE;
+   if (halign == 0.0)
+     tx = ed->x + pf->final.x + pf->final.w - tw;
+   else
+     tx = ed->x + pf->final.x;
 
-   if (pf == &lp3)
+   if (valign == 0.0)
+     ty = ed->y + pf->final.y + pf->final.h - th;
+   else
+     ty = ed->y + pf->final.y;
+
+   ep->typedata.text->ellipsize.text_w = tw;
+   ep->typedata.text->ellipsize.text_h = th;
+   ep->typedata.text->ellipsize.is_fade = is_fade;
+   ep->typedata.text->ellipsize.is_marquee = is_marquee;
+   ep->typedata.text->ellipsize.halign = (float)halign;
+   ep->typedata.text->ellipsize.valign = (float)valign;
+
+   /* Set clippers for ellipsize */
+   edje_orig_clipper = evas_object_clip_get(ep->object);
+   evas_object_clip_set(clipper_obj, edje_orig_clipper);
+
+   /* If fade feature is enabled, set additional clipper for masking. */
+   if (is_fade)
      {
-        eina_cow_free(_edje_calc_params_map_cow, (const Eina_Cow_Data **)&lp3.map);
-        lp3.map = NULL;
-#ifdef HAVE_EPHYSICS
-        eina_cow_free(_edje_calc_params_physics_cow, (const Eina_Cow_Data **)&lp3.physics);
-        lp3.physics = NULL;
+        mask_obj = _edje_text_ellipsize_fade_mask_object_get(ep);
+#if 0
+        evas_object_clip_set(ep->object, clipper_obj);
+#else
+        evas_object_clip_set(ep->object, mask_obj);
+        evas_object_clip_set(mask_obj, clipper_obj);
 #endif
+        evas_object_show(mask_obj);
+     }
+   else
+     {
+        evas_object_hide(ep->typedata.text->ellipsize.fade.mask_obj);
+        evas_object_clip_set(ep->object, clipper_obj);
      }
 
-#ifdef EDJE_CALC_CACHE
-   if (ep->calculated == FLAG_XY)
+   evas_object_resize(clipper_obj, clipper_w, clipper_h);
+   evas_object_move(clipper_obj, clipper_x, clipper_y);
+   evas_object_show(clipper_obj);
+
+   evas_object_resize(ep->object, tw, th);
+   evas_object_move(ep->object, tx, ty);
+
+   if (is_marquee)
      {
-        ep->state = ed->state;
-        ep->invalidate = EINA_FALSE;
+        Eina_Bool text_marquee_vertical;
+
+        if (valign != -1.0)
+          text_marquee_vertical = EINA_TRUE;
+        else
+          text_marquee_vertical = EINA_FALSE;
+
+        if (chosen_desc->text.ellipsize.marquee.speed > 0.0)
+          {
+             /* Convert px_per_sec (speed) to sec_per_pixel */
+             FLOAT_T sc = 1.0;
+
+             if (ep->part->scale)
+               {
+                  sc = DIV(ed->scale, ed->file->base_scale);
+                  if (sc == 0.0) sc = 1.0;
+               }
+
+             ep->typedata.text->ellipsize.marquee.sec_per_pixel = 1.0 / (chosen_desc->text.ellipsize.marquee.speed * TO_DOUBLE(sc));
+          }
+        else if (chosen_desc->text.ellipsize.marquee.duration > 0.0)
+          {
+             /* Convert sec_per_loop (duration) to sec_per_pixel */
+             int distance_per_loop = 0.0;
+
+             switch (chosen_desc->text.ellipsize.marquee.type)
+               {
+                case EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL:
+                   if (text_marquee_vertical)
+                     distance_per_loop = th + pf->final.h;
+                   else
+                     distance_per_loop = tw + pf->final.w;
+                   break;
+                case EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_DEFAULT:
+                default:
+                   if (text_marquee_vertical)
+                     distance_per_loop = th + roll_gap;
+                   else
+                     distance_per_loop = tw + roll_gap;
+               }
+
+             ep->typedata.text->ellipsize.marquee.sec_per_pixel =
+                chosen_desc->text.ellipsize.marquee.duration / (double)distance_per_loop;
+          }
+        else
+          {
+             /* If there is no description for speed or duration, set default speed */
+             FLOAT_T sc = 1.0;
+
+             if (ep->part->scale)
+               {
+                  sc = DIV(ed->scale, ed->file->base_scale);
+                  if (sc == 0.0) sc = 1.0;
+               }
+
+             ep->typedata.text->ellipsize.marquee.sec_per_pixel = EDJE_TEXT_ELLIPSIZE_MARQUEE_DEFAULT_SEC_PER_PIXEL / TO_DOUBLE(sc);
+          }
+
+        ep->typedata.text->ellipsize.marquee.animator_prev_time = ecore_time_get();
+        ep->typedata.text->ellipsize.marquee.orig_x = tx;
+        ep->typedata.text->ellipsize.marquee.orig_y = ty;
+
+        /* Give a latency for first loop. */
+        if (chosen_desc->text.ellipsize.marquee.loop_delay > 0.0)
+          ep->typedata.text->ellipsize.marquee.animator_prev_time += chosen_desc->text.ellipsize.marquee.loop_delay;
+
+        ep->typedata.text->ellipsize.marquee.animator = ecore_animator_add(_edje_text_ellipsize_marquee_animator_cb, ep);
      }
-#else
-   eina_cow_free(_edje_calc_params_map_cow, (const Eina_Cow_Data **)&lp1.map);
-#ifdef HAVE_EPHYSICS
-   eina_cow_free(_edje_calc_params_physics_cow, (const Eina_Cow_Data **)&lp1.physics);
-#endif
-#endif
+
+   if (is_fade)
+     _edje_text_ellipsize_fade_update(ep, EINA_FALSE);
 }
+
+/**********************************************************************************
+ *
+ * TIZEN_ONLY_FEATURE_END: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part.
+ *
+ **********************************************************************************/
index 333651b..2f3fa02 100644 (file)
@@ -1146,6 +1146,13 @@ _edje_edd_init(void)
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.mode", text.ellipsize.mode, EET_T_INT);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee_repeat_limit", text.ellipsize.marquee_repeat_limit, EET_T_INT);
    //
+   /* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.align", text.ellipsize.align, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee.type", text.ellipsize.marquee.type, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee.loop_delay", text.ellipsize.marquee.loop_delay, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee.speed", text.ellipsize.marquee.speed, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee.duration", text.ellipsize.marquee.duration, EET_T_DOUBLE);
+   /* END */
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.filter", filter.code, EET_T_STRING);
    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.filter_sources", filter.sources);
    EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.filter.data", filter.data, _edje_edd_edje_part_description_filter_data); // @since 1.15
@@ -1189,6 +1196,13 @@ _edje_edd_init(void)
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.mode", text.ellipsize.mode, EET_T_INT);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee_repeat_limit", text.ellipsize.marquee_repeat_limit, EET_T_INT);
    //
+   /* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.align", text.ellipsize.align, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee.type", text.ellipsize.marquee.type, EET_T_INT);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee.loop_delay", text.ellipsize.marquee.loop_delay, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee.speed", text.ellipsize.marquee.speed, EET_T_DOUBLE);
+   EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee.duration", text.ellipsize.marquee.duration, EET_T_DOUBLE);
+   /* END */
 
    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Box);
    eddc.func.mem_free = mem_free_box;
index d348850..2d89acb 100644 (file)
@@ -1598,7 +1598,7 @@ _edje_file_del(Edje *ed, Eina_Bool reuse_ic)
                   eina_stringshare_del(rp->typedata.text->cache.in_str);
                   eina_stringshare_del(rp->typedata.text->cache.out_str);
                   /* TIZEN_ONLY(20170322): fix crash issue when Edje tries to clean up fade object */
-                  _edje_fade_ellipsis_remove(rp);
+                  _edje_text_ellipsize_remove(rp);
                   /* END */
                   free(rp->typedata.text);
                }
index dd7cf7e..8ac3152 100644 (file)
@@ -1430,8 +1430,19 @@ struct _Edje_Part_Description_Spec_Text
    struct {
       Edje_Text_Ellipsize_Mode mode;
       int marquee_repeat_limit;
-      int marquee_repeat_count;
-      Evas_Coord_Point marquee_start_point;
+      int marquee_repeat_count;             /* Deprecated: Use loop_count in Edje_Real_Part_Text */
+      Evas_Coord_Point marquee_start_point; /* Deprecated: Use marquee_start_x, y in Edje_Real_Part_Text */
+
+      /* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+      Edje_Text_Ellipsize_Align align;
+
+      struct {
+         Edje_Text_Ellipsize_Marquee_Type type;
+         double                           loop_delay;
+         double                           speed;
+         double                           duration;
+      } marquee;
+      /* END */
    } ellipsize;
    //
 };
@@ -1928,9 +1939,29 @@ struct _Edje_Real_Part_Text
    /* END */
    /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to TEXTBLOCK, TEXT part. */
    struct {
-      Evas_Object *object; // 4
-      float align;         // 4
-   } fade;
+      Evas_Object    *clipper_obj; // 4
+      float           halign;      // 4
+      float           valign;      // 4
+      int             text_w, text_h;
+      Eina_Bool       is_fade;
+      Eina_Bool       is_marquee;
+
+      struct {
+         Evas_Object    *mask_obj;
+         Ecore_Animator *animator;
+         int             x, y, w, h;
+      } fade;
+
+      struct {
+         Evas_Object    *proxy_obj;
+         Ecore_Animator *animator;
+         double          animator_prev_time;
+         double          sec_per_pixel;
+         int             orig_x, orig_y;
+         int             loop_count;
+         int             distance;
+      } marquee;
+   } ellipsize;
    /* END */
    struct {
       unsigned char       fit_x, fit_y; // 2
@@ -2014,11 +2045,6 @@ struct _Edje_Real_Part
 #endif
    Evas_Event_Flags          ignore_flags;
    Evas_Event_Flags          mask_flags;
-   //TIZEN_ONLY(20160923): introduction of text marquee
-   double                    text_marquee_prev_time;
-   Ecore_Animator           *text_marquee_animator;
-   Evas_Object              *text_marquee_clipper;
-   //
    unsigned char             type; // 1
    unsigned char             calculated : 2; // 1
    unsigned char             calculating : 2; // 0
@@ -2026,9 +2052,6 @@ struct _Edje_Real_Part
 #ifdef EDJE_CALC_CACHE
    Eina_Bool                 invalidate : 1; // 0
 #endif
-   //TIZEN_ONLY(20160923): introduction of text marquee
-   unsigned char             text_marquee_to_left : 1;
-   //
    unsigned char             mouse_events : 1;
    unsigned char             repeat_events : 1;
 }; // 128
@@ -3072,7 +3095,7 @@ void _edje_real_part_ignore_flags_set(Edje *ed, Edje_Real_Part *rp, Evas_Event_F
 Evas_Event_Flags _edje_real_part_mask_flags_get(Edje *ed, Edje_Real_Part *rp);
 void _edje_real_part_mask_flags_set(Edje *ed, Edje_Real_Part *rp, Evas_Event_Flags mask_flags);
 /* TIZEN_ONLY(20170322): fix crash issue when Edje tries to clean up fade object */
-void _edje_fade_ellipsis_remove(Edje_Real_Part *ep);
+void _edje_text_ellipsize_remove(Edje_Real_Part *ep);
 /* END */
 
 #ifdef HAVE_LIBREMIX
index 4372a61..cfd028b 100644 (file)
@@ -145,24 +145,56 @@ _edje_object_evas_object_smart_del(Eo *obj, Edje *ed)
 
 //TIZEN_ONLY(20160923): introduction of text marquee
 static void
-_marquee_text_object_move(Edje *ed, Edje_Real_Part *ep, Evas_Coord_Point ed_diff)
+_edje_object_text_ellipsize_clipper_move(Edje *ed, Edje_Real_Part *ep, Evas_Coord_Point ed_diff)
 {
-   Evas_Coord x, y;
-   Edje_Part_Description_Text *chosen_desc;
+   Evas_Coord x = 0, y = 0;
 
-   chosen_desc = (Edje_Part_Description_Text *)ep->chosen_description;
+   if (ep->typedata.text->ellipsize.marquee.animator)
+     {
+        evas_object_geometry_get(ep->object, &x, &y, NULL, NULL);
 
-   evas_object_geometry_get(ep->object, &x, &y, NULL, NULL);
+        /* Horizontal Case */
+        x += ed_diff.x;
+        y += ed_diff.y;
 
-   /* ed_diff should be handled because of horizontal scroll */
-   evas_object_move(ep->object,
-                    x + ed_diff.x,
-                    ed->y + ep->y + ep->typedata.text->offset.y);
+        /* ed_diff should be handled because of horizontal scroll */
+        ep->typedata.text->ellipsize.marquee.orig_x += ed_diff.x;
+        ep->typedata.text->ellipsize.marquee.orig_y += ed_diff.y;
+     }
+   else
+     {
+        x = ed->x + ep->x + ep->typedata.text->offset.x;
+        y = ed->y + ep->y + ep->typedata.text->offset.y;
+     }
 
-   evas_object_move(ep->text_marquee_clipper, ed->x + ep->x, ed->y + ep->y);
+   if (ep->typedata.text->ellipsize.marquee.proxy_obj)
+     {
+        int px, py;
 
-   chosen_desc->text.ellipsize.marquee_start_point.x += ed_diff.x;
-   chosen_desc->text.ellipsize.marquee_start_point.y += ed_diff.y;
+        evas_object_geometry_get(ep->typedata.text->ellipsize.marquee.proxy_obj,
+                                 &px, &py, NULL, NULL);
+        evas_object_move(ep->typedata.text->ellipsize.marquee.proxy_obj,
+                         px + ed_diff.x, py + ed_diff.y);
+     }
+
+   if (ep->typedata.text->ellipsize.fade.animator)
+     {
+        ep->typedata.text->ellipsize.fade.x += ed_diff.x;
+        ep->typedata.text->ellipsize.fade.y += ed_diff.y;
+     }
+
+   if (ep->typedata.text->ellipsize.fade.mask_obj)
+     {
+        int mx, my;
+
+        evas_object_geometry_get(ep->typedata.text->ellipsize.fade.mask_obj,
+                                 &mx, &my, NULL, NULL);
+        evas_object_move(ep->typedata.text->ellipsize.fade.mask_obj,
+                         mx + ed_diff.x, my + ed_diff.y);
+     }
+
+   evas_object_move(ep->typedata.text->ellipsize.clipper_obj, ed->x + ep->x, ed->y + ep->y);
+   evas_object_move(ep->object, x, y);
 }
 //
 
@@ -195,8 +227,9 @@ _edje_object_evas_object_smart_move(Eo *obj EINA_UNUSED, Edje *ed, Evas_Coord x,
         if ((ep->type == EDJE_RP_TYPE_TEXT) && (ep->typedata.text))
           {
              //TIZEN_ONLY(20160923): introduction of text marquee
-             if (ep->text_marquee_animator)
-               _marquee_text_object_move(ed, ep, ed_diff);
+             if (ep->typedata.text->ellipsize.clipper_obj &&
+                 evas_object_visible_get(ep->typedata.text->ellipsize.clipper_obj))
+               _edje_object_text_ellipsize_clipper_move(ed, ep, ed_diff);
              else
              //
                evas_object_move(ep->object,
@@ -205,12 +238,7 @@ _edje_object_evas_object_smart_move(Eo *obj EINA_UNUSED, Edje *ed, Evas_Coord x,
           }
         else
           {
-             //TIZEN_ONLY(20160923): introduction of text marquee
-             if (ep->text_marquee_animator && ep->typedata.text)
-               _marquee_text_object_move(ed, ep, ed_diff);
-             else
-             //
-               evas_object_move(ep->object, ed->x + ep->x, ed->y + ep->y);
+             evas_object_move(ep->object, ed->x + ep->x, ed->y + ep->y);
 
              if ((ep->type == EDJE_RP_TYPE_SWALLOW) &&
                  (ep->typedata.swallow))
index 85f8b9b..2ab97c2 100644 (file)
@@ -3896,6 +3896,27 @@ EAPI Eina_Bool
 evas_object_textblock_ellipsis_disabled_get(Evas_Object *eo_obj);
 /* END */
 
+/**
+ * TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features.
+ * @internal
+ */
+EAPI void
+evas_object_textblock_ellipsis_set(Evas_Object *eo_obj, double ellipsis);
+
+/**
+ * TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features.
+ * @internal
+ */
+EAPI double
+evas_object_textblock_ellipsis_get(const Evas_Object *eo_obj);
+
+/**
+ * TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features.
+ * @internal
+ */
+EAPI Evas_BiDi_Direction
+evas_textblock_cursor_paragraph_direction_get(const Evas_Textblock_Cursor *cur);
+
 #include "canvas/evas_textblock.eo.legacy.h"
 
 /**
index 26c9a10..470b332 100644 (file)
@@ -550,6 +550,9 @@ struct _Evas_Object_Textblock
       int                              l, r, t, b;
    } style_pad;
    double                              valign;
+   /* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+   double                              ellipsis;
+   /* END */
    Eina_Stringshare                   *markup_text;
    void                               *engine_data;
    const char                         *repch;
@@ -5336,6 +5339,10 @@ _layout_par(Ctxt *c)
      {
         double ellip;
         ellip = it->format->ellipsis;
+        /* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+        if (c->o->ellipsis != -1.0)
+          ellip = c->o->ellipsis;
+        /* END */
         /* TIZEN_ONLY(20161011): add ellipsis_disabled_set/get APIs
         if ((0 <= ellip) && (ellip < 1.0) && c->line_no == 0)
          */
@@ -5511,7 +5518,7 @@ _layout_par(Ctxt *c)
                      !it->format->wrap_mixed && !it->format->wrap_hyphenation)))
               */
              if (!c->o->ellipsis_disabled &&
-                 (it->format->ellipsis == 1.0) && (c->h >= 0) &&
+                 ((c->o->ellipsis == 1.0) || (it->format->ellipsis == 1.0)) && (c->h >= 0) &&
                    ((c->y + ellip_h_thresh >
                      c->h - c->o->style_pad.t - c->o->style_pad.b) ||
                     (!it->format->wrap_word && !it->format->wrap_char &&
@@ -5660,7 +5667,11 @@ _layout_par(Ctxt *c)
                          {
                             /* FIXME: Should redo the ellipsis handling.
                              * If we can do ellipsis, just cut here. */
+                            /* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features.
                             if (it->format->ellipsis == 1.0)
+                             */
+                            if ((c->o->ellipsis == 1.0) || (it->format->ellipsis == 1.0))
+                            /* END */
                               {
                                  _layout_handle_ellipsis(c, it, i);
                                  ret = 1;
@@ -6540,6 +6551,9 @@ _evas_textblock_eo_base_constructor(Eo *eo_obj, Evas_Textblock_Data *class_data
 
    o = obj->private_data;
    o->cursor = calloc(1, sizeof(Evas_Textblock_Cursor));
+   /* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+   o->ellipsis = -1.0;
+   /* END */
    _format_command_init();
    evas_object_textblock_init(eo_obj);
 
@@ -13861,6 +13875,66 @@ evas_object_textblock_ellipsis_disabled_get(Evas_Object *eo_obj)
 }
 /* END */
 
+/* TIZEN_ONLY(20170703): Add ellipsize feature and refactory fade_ellipsis, marquee features. */
+EAPI void
+evas_object_textblock_ellipsis_set(Evas_Object *eo_obj, double ellipsis)
+{
+   TB_HEAD();
+
+   if (o->ellipsis == ellipsis) return;
+
+   o->ellipsis = ellipsis;
+
+   _evas_textblock_invalidate_all(o);
+   _evas_textblock_changed(o, eo_obj);
+}
+
+EAPI double
+evas_object_textblock_ellipsis_get(const Evas_Object *eo_obj)
+{
+   Evas_Object_Textblock_Paragraph *par;
+   Evas_Object_Textblock_Item *it;
+   Evas_Textblock_Data *o;
+   Eina_List *l;
+
+   TB_HEAD_RETURN(-1.0);
+
+   o = eo_data_scope_get(eo_obj, MY_CLASS);
+
+   if (o->ellipsis != -1.0)
+     return o->ellipsis;
+
+   EINA_INLIST_FOREACH(o->paragraphs, par)
+     {
+        EINA_LIST_FOREACH(par->logical_items, l, it)
+          {
+             if (it->format)
+               return it->format->ellipsis;
+          }
+     }
+
+   return -1.0;
+}
+
+EAPI Evas_BiDi_Direction
+evas_textblock_cursor_paragraph_direction_get(const Evas_Textblock_Cursor *cur)
+{
+   if (!cur) return EVAS_BIDI_DIRECTION_NEUTRAL;
+   if (!cur->node)
+     {
+        ERR("There is no node information on the given cursor: %p", cur);
+        return EVAS_BIDI_DIRECTION_NEUTRAL;
+     }
+   if (!cur->node->par)
+     {
+        ERR("There is no paragraph information on the given cursor: %p, node: %p", cur, cur->node);
+        return EVAS_BIDI_DIRECTION_NEUTRAL;
+     }
+
+   return cur->node->par->direction;
+}
+/* END */
+
 /**
  * @}
  */