Edje: use textblock by default
authorDaniel Hirt <hirt.danny@gmail.com>
Sun, 15 Oct 2017 14:57:38 +0000 (17:57 +0300)
committerCedric BAIL <cedric@osg.samsung.com>
Fri, 10 Nov 2017 18:30:09 +0000 (10:30 -0800)
As most of you know, TEXT part was, up to this point, an Evas.Text
object.

This patch merges TEXT and TEXTBLOCK both to use Efl.Canvas.Text.
Code is added to emulate what TEXT did that TEXTBLOCK did not.

I believe we can move forward with TEXT, and deperacate TEXTBLOCK from
the EDC. You can also set markup to TEXT parts.

Exactness seems to show some differences, but further examination shows
that it's due to difference in how width is calculated in
Efl.Canvas.Text. The results seem correct.

Be sure to report of any breakage via Phabricator or contact me
directly.
I am running E with this and did not stumble upon any crashes or visual
bugs.

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
src/lib/edje/edje_calc.c
src/lib/edje/edje_load.c
src/lib/edje/edje_private.h
src/lib/edje/edje_textblock.c
src/lib/edje/edje_util.c

index 1442cb8..be7d9e4 100644 (file)
@@ -2401,7 +2401,7 @@ _edje_part_recalc_single_filter(Edje *ed,
    Eina_List *li1, *li2;
 
    /* handle TEXT, IMAGE, PROXY, SNAPSHOT part types here */
-   if (ep->part->type == EDJE_PART_TYPE_TEXT)
+   if (PART_IS_TEXT(ed, ep))
      {
         Edje_Part_Description_Text *chosen_edt = (Edje_Part_Description_Text *) chosen_desc;
         Edje_Part_Description_Text *edt = (Edje_Part_Description_Text *) desc;
@@ -2521,6 +2521,10 @@ _edje_part_recalc_single_filter(Edje *ed,
           }
      }
    efl_gfx_filter_program_set(obj, code, filter->name);
+   if (PART_IS_TEXT(ed, ep))
+     {
+        efl_text_gfx_filter_set(obj, filter->name);
+     }
    if (prev_sources != filter_sources)
      {
         /* remove sources that are not there anymore
@@ -2828,11 +2832,9 @@ _edje_part_recalc_single(Edje *ed,
      }
 
    /* if we have text that wants to make the min size the text size... */
-   if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
-     _edje_part_recalc_single_textblock(sc, ed, ep, (Edje_Part_Description_Text *)chosen_desc, params, &minw, &minh, &maxw, &maxh);
-   else if (ep->part->type == EDJE_PART_TYPE_TEXT)
+   if (PART_IS_TEXT(ed, ep))
      {
-        _edje_part_recalc_single_text(sc, ed, ep, (Edje_Part_Description_Text*) desc, (Edje_Part_Description_Text*) chosen_desc, params, &minw, &minh, &maxw, &maxh);
+        _edje_part_recalc_single_textblock(sc, ed, ep, (Edje_Part_Description_Text *)chosen_desc, params, &minw, &minh, &maxw, &maxh);
         _edje_part_recalc_single_filter(ed, ep, desc, chosen_desc, pos);
      }
 
@@ -4385,11 +4387,6 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
              break;
 
            case EDJE_PART_TYPE_TEXT:
-             _edje_calc_params_need_type_text(p3);
-             p3->type.text->size = INTP(p1->type.text->size, p2->type.text->size, pos);
-             EINA_FALLTHROUGH;
-
-             /* no break as we share code with the TEXTBLOCK type here. */
            case EDJE_PART_TYPE_TEXTBLOCK:
              _edje_calc_params_need_type_text(p3);
              p3->type.text->color2.r = INTP(p1->type.text->color2.r, p2->type.text->color2.r, pos2);
@@ -4601,6 +4598,8 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
              EINA_FALLTHROUGH;
            case EDJE_PART_TYPE_RECTANGLE:
              EINA_FALLTHROUGH;
+           case EDJE_PART_TYPE_TEXT:
+             EINA_FALLTHROUGH;
            case EDJE_PART_TYPE_TEXTBLOCK:
              EINA_FALLTHROUGH;
            case EDJE_PART_TYPE_BOX:
@@ -4610,11 +4609,18 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
            case EDJE_PART_TYPE_SNAPSHOT:
              EINA_FALLTHROUGH;
            case EDJE_PART_TYPE_VECTOR:
+             if (ep->part->type == EDJE_PART_TYPE_TEXT)
+               {
+                  evas_object_color_set(ep->object, 255, 255, 255, 255);
+               }
+             else
+               {
              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 */
@@ -4702,10 +4708,6 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
                }
              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();
@@ -4910,9 +4912,6 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
         /* 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);
@@ -4930,6 +4929,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
              _edje_table_recalc_apply(ed, ep, pf, (Edje_Part_Description_Table *)chosen_desc);
              break;
 
+           case EDJE_PART_TYPE_TEXT:
            case EDJE_PART_TYPE_TEXTBLOCK:
              _edje_textblock_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text *)chosen_desc);
              break;
index 94f8c0e..c2da41d 100644 (file)
@@ -1045,11 +1045,21 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
                        break;
 
                      case EDJE_PART_TYPE_TEXT:
-                       _edje_text_part_on_add(ed, rp);
-                       rp->object = evas_object_text_add(ed->base.evas);
-                       evas_object_text_font_source_set(rp->object, ed->path);
+                     case EDJE_PART_TYPE_TEXTBLOCK:
+                       _edje_textblock_styles_add(ed, rp);
+                       textblocks = eina_list_append(textblocks, rp);
+                       if (rp->part->type == EDJE_PART_TYPE_TEXT)
+                         {
+                            rp->object = efl_add(EFL_CANVAS_TEXT_CLASS,
+                                  ed->base.evas);
+                         }
+                       else
+                         {
+                            rp->object = evas_object_textblock_add(ed->base.evas);
+                         }
                        break;
 
+
                      case EDJE_PART_TYPE_GROUP:
                        sources = eina_list_append(sources, rp);
 
@@ -1067,12 +1077,6 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
                        _edje_callbacks_focus_add(rp->object, ed, rp);
                        break;
 
-                     case EDJE_PART_TYPE_TEXTBLOCK:
-                       _edje_textblock_styles_add(ed, rp);
-                       textblocks = eina_list_append(textblocks, rp);
-                       rp->object = evas_object_textblock_add(ed->base.evas);
-                       break;
-
                      case EDJE_PART_TYPE_BOX:
                        sources = eina_list_append(sources, rp);
                        rp->object = evas_object_box_add(ed->base.evas);
index 9f4d07e..f17abdf 100644 (file)
@@ -2547,6 +2547,11 @@ const char *   _edje_text_class_font_get(Edje *ed,
                                          int *size, char **free_later);
 const char *   _edje_text_font_get(const char *base, const char *new,
                                    char **free_later);
+const char *   _set_translated_string(Edje *ed, Edje_Real_Part *ep);
+
+#define PART_IS_TEXT(ed, ep) \
+   (((ep)->part->type == EDJE_PART_TYPE_TEXTBLOCK) || \
+     ((ep)->part->type == EDJE_PART_TYPE_TEXT))
 
 void
 _edje_part_recalc_single_textblock(FLOAT_T sc,
index 0451099..c46c2a9 100644 (file)
@@ -1,5 +1,17 @@
 #include "edje_private.h"
 
+#ifdef DEBUG_TEXT
+# define TPRN(...) do { printf(__VA_ARGS__); } while(0)
+#else
+# define TPRN(...)
+#endif
+
+#define COLOR_SET(color) \
+   (color).r * (color).a / 255, \
+   (color).g * (color).a / 255, \
+   (color).b * (color).a / 255, \
+   (color).a
+
 static double
 _edje_part_recalc_single_textblock_scale_range_adjust(Edje_Part_Description_Text *chosen_desc, double base_scale, double scale)
 {
@@ -20,6 +32,248 @@ _edje_part_recalc_single_textblock_scale_range_adjust(Edje_Part_Description_Text
    return scale;
 }
 
+static void
+_edje_part_recalc_textblock_font_get(Edje *ed, Edje_Real_Part *ep,
+      Edje_Part_Description_Text *chosen_desc,
+      const char **ret_font_source,
+      const char **ret_font, int *ret_size)
+
+{
+   Edje_Real_Part *source;
+   const char *font;
+   int size;
+   Eina_Bool inlined_font = EINA_FALSE;
+   const char *font_source = NULL;
+   char *sfont, *font2;
+
+   sfont = font2 = NULL;
+
+   source = ep->typedata.text->source;
+
+   if (source)
+      font = _edje_text_class_font_get(ed,
+            _edje_real_part_text_source_description_get(ep,
+               &source), &size, &sfont);
+   else
+      font = _edje_text_class_font_get(ed, chosen_desc, &size, &sfont);
+
+   if (size <= 0) size = 1;
+   if (!font) font = "";
+
+   if (source)
+     {
+        if (source->typedata.text->font) font = source->typedata.text->font;
+        if (source->typedata.text->size > 0) size = source->typedata.text->size;
+     }
+   else
+     {
+        if (ep->typedata.text->font) font = ep->typedata.text->font;
+        if (ep->typedata.text->size > 0) size = ep->typedata.text->size;
+     }
+
+   if (ed->file->fonts)
+     {
+        Edje_Font_Directory_Entry *fnt;
+
+        fnt = eina_hash_find(ed->file->fonts, font);
+
+        if (fnt)
+          {
+             size_t len = strlen(font) + sizeof("edje/fonts/") + 1;
+             font2 = alloca(len);
+             sprintf(font2, "edje/fonts/%s", font);
+             font = font2;
+             inlined_font = 1;
+             font2 = NULL; // so it is not freed at the end of the function
+          }
+     }
+   if (inlined_font)
+     {
+        font_source = ed->path;
+     }
+
+   if ((_edje_fontset_append) && (font))
+     {
+        font2 = malloc(strlen(font) + 1 + strlen(_edje_fontset_append) + 1);
+        if (font2)
+          {
+             strcpy(font2, font);
+             strcat(font2, ",");
+             strcat(font2, _edje_fontset_append);
+             font = font2; //font2 needs to be freed at the end of the
+             // function.
+          }
+     }
+   if (ret_font) *ret_font = font;
+   if (ret_size) *ret_size = size;
+   if (ret_font_source) *ret_font_source = font_source;
+
+   if (font2) free(font2);
+   if (sfont) free(sfont);
+}
+
+static inline Eina_Bool
+_edje_part_recalc_textblock_text_get(Edje *ed, Edje_Real_Part *ep,
+      Edje_Part_Description_Text *chosen_desc, const char **_ret)
+{
+   Eina_Bool same = EINA_FALSE;
+   const char *text = NULL;
+
+   if (chosen_desc->text.domain)
+     {
+        if (!chosen_desc->text.text.translated)
+           chosen_desc->text.text.translated = _set_translated_string(ed, ep);
+        if (chosen_desc->text.text.translated)
+           text = chosen_desc->text.text.translated;
+     }
+
+   if (!text)
+     {
+        text = edje_string_get(&chosen_desc->text.text);
+        if (ep->typedata.text->text) text = ep->typedata.text->text;
+     }
+
+   if (chosen_desc->text.id_text_source >= 0)
+     {
+        Edje_Part_Description_Text *et;
+        Edje_Real_Part *rp;
+        ep->typedata.text->text_source = ed->table_parts[chosen_desc->text.id_text_source % ed->table_parts_size];
+
+        et = _edje_real_part_text_text_source_description_get(ep, &rp);
+        text = edje_string_get(&(et->text.text));
+
+        if (rp->typedata.text->text) text = rp->typedata.text->text;
+     }
+
+   if ((text == ep->typedata.text->cache.in_str)
+       || (text && ep->typedata.text->cache.in_str && !strcmp(ep->typedata.text->cache.in_str, text)))
+     {
+        text = ep->typedata.text->cache.in_str;
+        same = EINA_TRUE;
+     }
+
+   if (!same)
+     {
+        eina_stringshare_replace(&ep->typedata.text->cache.in_str, text);
+     }
+
+   *_ret = text;
+   return same;
+}
+
+static inline Edje_Style *
+_edje_part_recalc_textblock_style_get(Edje *ed, Edje_Real_Part *ep,
+      Edje_Part_Description_Text *chosen_desc)
+{
+   Edje_Style *stl = NULL;
+   const char *tmp, *style = "";
+   Eina_List *l;
+
+   if (chosen_desc->text.id_source >= 0)
+     {
+        Edje_Part_Description_Text *et;
+
+        ep->typedata.text->source = ed->table_parts[chosen_desc->text.id_source % ed->table_parts_size];
+
+        et = _edje_real_part_text_source_description_get(ep, NULL);
+        tmp = edje_string_get(&et->text.style);
+        if (tmp) style = tmp;
+     }
+   else
+     {
+        ep->typedata.text->source = NULL;
+
+        tmp = edje_string_get(&chosen_desc->text.style);
+        if (tmp) style = tmp;
+     }
+
+   EINA_LIST_FOREACH(ed->file->styles, l, stl)
+     {
+        if ((stl->name) && (!strcmp(stl->name, style))) break;
+        stl = NULL;
+     }
+
+   return stl;
+}
+
+static inline void
+_edje_part_recalc_textblock_fit(Edje_Real_Part *ep,
+      Edje_Part_Description_Text *chosen_desc,
+      Edje_Calc_Params *params,
+      FLOAT_T sc, Evas_Coord *tw, Evas_Coord *th)
+{
+   double base_s = 1.0;
+   double orig_s;
+   double s = base_s;
+
+   if (ep->part->scale) base_s = TO_DOUBLE(sc);
+   efl_canvas_object_scale_set(ep->object, base_s);
+   efl_canvas_text_size_native_get(ep->object, tw, th);
+
+   orig_s = base_s;
+   /* Now make it bigger so calculations will be more accurate
+    * and less influenced by hinting... */
+     {
+        orig_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
+              orig_s * TO_INT(params->eval.w) / *tw);
+        efl_canvas_object_scale_set(ep->object, orig_s);
+        efl_canvas_text_size_native_get(ep->object, tw, th);
+     }
+   if (chosen_desc->text.fit_x)
+     {
+        if (*tw > 0)
+          {
+             s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
+                   orig_s * TO_INT(params->eval.w) / *tw);
+             efl_canvas_object_scale_set(ep->object, s);
+             efl_canvas_text_size_native_get(ep->object, NULL, NULL);
+          }
+     }
+   if (chosen_desc->text.fit_y)
+     {
+        if (*th > 0)
+          {
+             double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
+                   orig_s * TO_INT(params->eval.h) / *th);
+             /* If we already have X fit, restrict Y to be no bigger
+              * than what we got with X. */
+             if (!((chosen_desc->text.fit_x) && (tmp_s > s)))
+               {
+                  s = tmp_s;
+               }
+
+             efl_canvas_object_scale_set(ep->object, s);
+             efl_canvas_text_size_native_get(ep->object, NULL, NULL);
+          }
+     }
+
+   /* Final tuning, try going down 90% at a time, hoping it'll
+    * actually end up being correct. */
+     {
+        int i = 5;   /* Tries before we give up. */
+        Evas_Coord fw, fh;
+        efl_canvas_text_size_native_get(ep->object, &fw, &fh);
+
+        /* If we are still too big, try reducing the size to
+         * 95% each try. */
+        while ((i > 0) &&
+              ((chosen_desc->text.fit_x && (fw > TO_INT(params->eval.w))) ||
+               (chosen_desc->text.fit_y && (fh > TO_INT(params->eval.h)))))
+          {
+             double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s, s * 0.95);
+
+             /* Break if we are not making any progress. */
+             if (EQ(tmp_s, s))
+                break;
+             s = tmp_s;
+
+             efl_canvas_object_scale_set(ep->object, s);
+             efl_canvas_text_size_native_get(ep->object, &fw, &fh);
+             i--;
+          }
+     }
+}
+
 /*
  * Legacy function for min/max calculation of textblock part.
  * It can't calculate min/max properly in many cases.
@@ -35,6 +289,7 @@ _edje_part_recalc_single_textblock_min_max_calc_legacy(Edje_Real_Part *ep,
                                                        int *maxw, int *maxh)
 {
    Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b;
+   ins_l = ins_r = ins_t = ins_b = 0;
 
    /* Legacy code for Textblock min/max calculation */
    if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y))
@@ -49,8 +304,10 @@ _edje_part_recalc_single_textblock_min_max_calc_legacy(Edje_Real_Part *ep,
           }
         else
           evas_object_textblock_size_native_get(ep->object, &tw, &th);
+
         evas_object_textblock_style_insets_get(ep->object, &ins_l,
-                                               &ins_r, &ins_t, &ins_b);
+              &ins_r, &ins_t, &ins_b);
+
         mw = ins_l + tw + ins_r;
         mh = ins_t + th + ins_b;
         if (minw && chosen_desc->text.min_x)
@@ -75,8 +332,10 @@ _edje_part_recalc_single_textblock_min_max_calc_legacy(Edje_Real_Part *ep,
           }
         else
           evas_object_textblock_size_native_get(ep->object, &tw, &th);
-        evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r,
-                                               &ins_t, &ins_b);
+
+        evas_object_textblock_style_insets_get(ep->object, &ins_l,
+              &ins_r, &ins_t, &ins_b);
+
         mw = ins_l + tw + ins_r;
         mh = ins_t + th + ins_b;
         if (maxw && chosen_desc->text.max_x)
@@ -101,19 +360,25 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep,
 {
    Evas_Coord tw, th, ins_l, ins_r, ins_t, ins_b;
    Evas_Coord min_calc_w = 0, min_calc_h = 0;
+   unsigned char dmin_x, dmin_y;
+
+   ins_l = ins_r = ins_t = ins_b = 0;
 
    /* min_calc_* values need to save calculated minumum size
     * for maximum size calculation */
    if (minw) min_calc_w = *minw;
    if (minh) min_calc_h = *minh;
 
-   if ((chosen_desc->text.min_x) || (chosen_desc->text.min_y))
+   dmin_x = chosen_desc->text.min_x;
+   dmin_y = chosen_desc->text.min_y;
+
+   if (dmin_x || dmin_y)
      {
         evas_object_textblock_style_insets_get(ep->object, &ins_l,
-                                               &ins_r, &ins_t, &ins_b);
+              &ins_r, &ins_t, &ins_b);
 
         tw = th = 0;
-        if (!chosen_desc->text.min_x)
+        if (!dmin_x)
           {
              /* text.min: 0 1
               * text.max: X X */
@@ -161,7 +426,7 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep,
           {
              /* text.min: 1 X
               * text.max: X X */
-             if (chosen_desc->text.min_y && (!chosen_desc->text.max_x) &&
+             if (dmin_y && (!chosen_desc->text.max_x) &&
                  maxw && (*maxw > -1))
                {
                   /* text.min: 1 1
@@ -222,14 +487,14 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep,
 
         if (tw > min_calc_w) min_calc_w = tw;
         if (th > min_calc_h) min_calc_h = th;
-        if (chosen_desc->text.min_x && minw) *minw = min_calc_w;
-        if (chosen_desc->text.min_y && minh) *minh = min_calc_h;
+        if (dmin_x && minw) *minw = min_calc_w;
+        if (dmin_y && minh) *minh = min_calc_h;
      }
 
    if ((chosen_desc->text.max_x) || (chosen_desc->text.max_y))
      {
-        evas_object_textblock_style_insets_get(ep->object, &ins_l, &ins_r,
-                                               &ins_t, &ins_b);
+        evas_object_textblock_style_insets_get(ep->object, &ins_l,
+              &ins_r, &ins_t, &ins_b);
 
         tw = th = 0;
         if (!chosen_desc->text.max_x)
@@ -284,7 +549,7 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep,
         else
           {
              /* text.max: 1 X */
-             if (chosen_desc->text.min_x)
+             if (dmin_x)
                {
                   /* text.min: 1 X
                    * text.max: 1 X
@@ -312,7 +577,7 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep,
                        if (min_calc_h > temp_h)
                          temp_h = min_calc_h;
 
-                       if (chosen_desc->text.min_y)
+                       if (dmin_y)
                          {
                             /* text.min: 0 1
                              * text.max: 1 1
@@ -383,6 +648,147 @@ _edje_part_recalc_single_textblock_min_max_calc(Edje_Real_Part *ep,
      }
 }
 
+static void
+_edje_textblock_colors_set(Edje *ed EINA_UNUSED,
+                           Edje_Real_Part *ep,
+                           Edje_Calc_Params *params,
+                           Eina_Bool styles)
+{
+
+   Edje_Text_Effect effect;
+   Efl_Text_Style_Effect_Type st;
+   Efl_Text_Style_Shadow_Direction dir;
+
+   if (ep->part->type == EDJE_PART_TYPE_TEXT)
+     {
+        efl_text_normal_color_set(ep->object, COLOR_SET(params->color));
+        evas_object_color_set(ep->object, 255, 255, 255, 255);
+     }
+
+   effect = ep->part->effect;
+   switch (effect & EDJE_TEXT_EFFECT_MASK_BASIC)
+     {
+      case EDJE_TEXT_EFFECT_NONE:
+      case EDJE_TEXT_EFFECT_PLAIN:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_NONE;
+         break;
+
+      case EDJE_TEXT_EFFECT_OUTLINE:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_OUTLINE;
+         if (styles) efl_text_outline_color_set(ep->object,
+               COLOR_SET(params->type.text->color2));
+         break;
+
+      case EDJE_TEXT_EFFECT_SOFT_OUTLINE:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_SOFT_OUTLINE;
+         if (styles) efl_text_outline_color_set(ep->object,
+               COLOR_SET(params->type.text->color2));
+         break;
+
+      case EDJE_TEXT_EFFECT_SHADOW:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_SHADOW;
+         if (styles) efl_text_shadow_color_set(ep->object,
+               COLOR_SET(params->type.text->color3));
+         break;
+
+      case EDJE_TEXT_EFFECT_SOFT_SHADOW:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_SOFT_SHADOW;
+         if (styles) efl_text_shadow_color_set(ep->object,
+               COLOR_SET(params->type.text->color3));
+         break;
+
+      case EDJE_TEXT_EFFECT_OUTLINE_SHADOW:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_OUTLINE_SHADOW;
+         if (styles)
+           {
+              efl_text_outline_color_set(ep->object,
+                    COLOR_SET(params->type.text->color2));
+              efl_text_shadow_color_set(ep->object,
+                    COLOR_SET(params->type.text->color3));
+           }
+         break;
+
+      case EDJE_TEXT_EFFECT_OUTLINE_SOFT_SHADOW:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_OUTLINE_SOFT_SHADOW;
+         if (styles)
+           {
+              efl_text_outline_color_set(ep->object,
+                    COLOR_SET(params->type.text->color2));
+              efl_text_shadow_color_set(ep->object,
+                    COLOR_SET(params->type.text->color3));
+           }
+         break;
+
+      case EDJE_TEXT_EFFECT_FAR_SHADOW:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_FAR_SHADOW;
+         if (styles) efl_text_shadow_color_set(ep->object,
+               COLOR_SET(params->type.text->color3));
+         break;
+
+      case EDJE_TEXT_EFFECT_FAR_SOFT_SHADOW:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_FAR_SOFT_SHADOW;
+         if (styles) efl_text_shadow_color_set(ep->object,
+               COLOR_SET(params->type.text->color3));
+         break;
+
+      case EDJE_TEXT_EFFECT_GLOW:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_GLOW;
+         if (styles)
+           {
+              efl_text_glow_color_set(ep->object,
+                    COLOR_SET(params->type.text->color2));
+              efl_text_glow2_color_set(ep->object,
+                    COLOR_SET(params->type.text->color3));
+           }
+         break;
+
+      default:
+         st = EFL_TEXT_STYLE_EFFECT_TYPE_NONE;
+         break;
+     }
+
+   switch (effect & EDJE_TEXT_EFFECT_MASK_SHADOW_DIRECTION)
+     {
+      case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_RIGHT:
+        dir = EFL_TEXT_STYLE_SHADOW_DIRECTION_RIGHT;
+        break;
+
+      case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM:
+        dir = EFL_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM;
+        break;
+
+      case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_LEFT:
+        dir = EFL_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT;
+         break;
+
+      case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_LEFT:
+        dir = EFL_TEXT_STYLE_SHADOW_DIRECTION_LEFT;
+         break;
+
+      case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_LEFT:
+        dir = EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT;
+         break;
+
+      case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP:
+        dir = EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP;
+         break;
+
+      case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_RIGHT:
+        dir = EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT;
+         break;
+
+      case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_RIGHT:
+        dir = EFL_TEXT_STYLE_SHADOW_DIRECTION_RIGHT;
+         break;
+
+      default:
+         dir = EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP;
+         break;
+     }
+   efl_text_effect_type_set(ep->object, st);
+   efl_text_shadow_direction_set(ep->object, dir);
+}
+
 void
 _edje_part_recalc_single_textblock(FLOAT_T sc,
                                    Edje *ed,
@@ -392,172 +798,97 @@ _edje_part_recalc_single_textblock(FLOAT_T sc,
                                    int *minw, int *minh,
                                    int *maxw, int *maxh)
 {
+   double align_y;
+
    if ((ep->type != EDJE_RP_TYPE_TEXT) ||
-       (!ep->typedata.text))
-     return;
+         (!ep->typedata.text))
+      return;
 
-   if (chosen_desc)
-     {
-        Evas_Coord tw, th;
-        const char *text = "";
-        const char *style = "";
-        Edje_Style *stl = NULL;
-        const char *tmp;
-        Eina_List *l;
+   align_y = TO_DOUBLE(params->type.text->align.y);
+   efl_text_valign_set(ep->object, align_y);
 
-        if (chosen_desc->text.id_source >= 0)
-          {
-             Edje_Part_Description_Text *et;
+   if (ep->part->type == EDJE_PART_TYPE_TEXT)
+     {
+        double align_x;
 
-             ep->typedata.text->source = ed->table_parts[chosen_desc->text.id_source % ed->table_parts_size];
+        align_x = TO_DOUBLE(params->type.text->align.x);
 
-             et = _edje_real_part_text_source_description_get(ep, NULL);
-             tmp = edje_string_get(&et->text.style);
-             if (tmp) style = tmp;
+        if (align_x < 0)
+          {
+             efl_text_halign_auto_type_set(ep->object,
+                   EFL_TEXT_HORIZONTAL_ALIGNMENT_AUTO_NORMAL);
           }
         else
           {
-             ep->typedata.text->source = NULL;
-
-             tmp = edje_string_get(&chosen_desc->text.style);
-             if (tmp) style = tmp;
+             efl_text_halign_set(ep->object, align_x);
           }
+     }
 
-        if (chosen_desc->text.id_text_source >= 0)
-          {
-             Edje_Part_Description_Text *et;
-             Edje_Real_Part *rp;
-
-             ep->typedata.text->text_source = ed->table_parts[chosen_desc->text.id_text_source % ed->table_parts_size];
+   if (chosen_desc)
+     {
+        const char *font, *font_source;
+        int size;
 
-             et = _edje_real_part_text_text_source_description_get(ep, &rp);
-             text = edje_string_get(&et->text.text);
+        Evas_Coord tw, th;
+        Edje_Style *stl = NULL;
+        const char *text;
 
-             if (rp->typedata.text->text) text = rp->typedata.text->text;
-          }
-        else
-          {
-             ep->typedata.text->text_source = NULL;
-             text = edje_string_get(&chosen_desc->text.text);
-             if (ep->typedata.text->text) text = ep->typedata.text->text;
-          }
+        _edje_part_recalc_textblock_text_get(ed, ep, chosen_desc,
+              &text);
 
-        EINA_LIST_FOREACH(ed->file->styles, l, stl)
-          {
-             if ((stl->name) && (!strcmp(stl->name, style))) break;
-             stl = NULL;
-          }
+        stl = _edje_part_recalc_textblock_style_get(ed, ep, chosen_desc);
 
         if (ep->part->scale)
           evas_object_scale_set(ep->object, TO_DOUBLE(sc));
 
         if ((chosen_desc->text.fit_x) || (chosen_desc->text.fit_y))
           {
-             double base_s = 1.0;
-             double orig_s;
-             double s = base_s;
-
-             if (ep->part->scale) base_s = TO_DOUBLE(sc);
-             efl_canvas_object_scale_set(ep->object, base_s);
-             efl_canvas_text_size_native_get(ep->object, &tw, &th);
-
-             orig_s = base_s;
-             /* Now make it bigger so calculations will be more accurate
-              * and less influenced by hinting... */
-             {
-                orig_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
-                                                                               orig_s * TO_INT(params->eval.w) / tw);
-                efl_canvas_object_scale_set(ep->object, orig_s);
-                efl_canvas_text_size_native_get(ep->object, &tw, &th);
-             }
-             if (chosen_desc->text.fit_x)
-               {
-                  if (tw > 0)
-                    {
-                       s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
-                                                                                 orig_s * TO_INT(params->eval.w) / tw);
-                       efl_canvas_object_scale_set(ep->object, s);
-                       efl_canvas_text_size_native_get(ep->object, NULL, NULL);
-                    }
-               }
-             if (chosen_desc->text.fit_y)
-               {
-                  if (th > 0)
-                    {
-                       double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
-                                                                                            orig_s * TO_INT(params->eval.h) / th);
-                       /* If we already have X fit, restrict Y to be no bigger
-                        * than what we got with X. */
-                       if (!((chosen_desc->text.fit_x) && (tmp_s > s)))
-                         {
-                            s = tmp_s;
-                         }
-
-                       efl_canvas_object_scale_set(ep->object, s);
-                       efl_canvas_text_size_native_get(ep->object, NULL, NULL);
-                    }
-               }
-
-             /* Final tuning, try going down 90% at a time, hoping it'll
-              * actually end up being correct. */
-             {
-                int i = 5;   /* Tries before we give up. */
-                Evas_Coord fw, fh;
-                efl_canvas_text_size_native_get(ep->object, &fw, &fh);
-
-                /* If we are still too big, try reducing the size to
-                 * 95% each try. */
-                while ((i > 0) &&
-                       ((chosen_desc->text.fit_x && (fw > TO_INT(params->eval.w))) ||
-                        (chosen_desc->text.fit_y && (fh > TO_INT(params->eval.h)))))
-                  {
-                     double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s, s * 0.95);
-
-                     /* Break if we are not making any progress. */
-                     if (EQ(tmp_s, s))
-                       break;
-                     s = tmp_s;
-
-                     efl_canvas_object_scale_set(ep->object, s);
-                     efl_canvas_text_size_native_get(ep->object, &fw, &fh);
-                     i--;
-                  }
-             }
+             _edje_part_recalc_textblock_fit(ep, chosen_desc, params, sc, &tw, &th);
           }
 
+        _edje_part_recalc_textblock_font_get(ed, ep, chosen_desc,
+              &font_source, &font, &size);
+
         if (stl)
           {
              if (evas_object_textblock_style_get(ep->object) != stl->style)
                evas_object_textblock_style_set(ep->object, stl->style);
-             // FIXME: need to account for editing
-             if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
-               {
-                  // do nothing - should be done elsewhere
-               }
-             else
-               {
-                  evas_object_textblock_text_markup_set(ep->object, text);
-               }
+          }
 
-             if ((ed->file->efl_version.major >= 1) && (ed->file->efl_version.minor >= 19))
-               {
-                  _edje_part_recalc_single_textblock_min_max_calc(ep,
-                                                                  chosen_desc,
-                                                                  params,
-                                                                  minw, minh,
-                                                                  maxw, maxh);
-               }
-             else
-               {
-                  _edje_part_recalc_single_textblock_min_max_calc_legacy(ep,
-                                                                         chosen_desc,
-                                                                         params,
-                                                                         minw, minh,
-                                                                         maxw, maxh);
-               }
+        if (ep->part->type == EDJE_PART_TYPE_TEXT)
+          {
+             FLOAT_T ellip = params->type.text->ellipsis;
+             efl_text_font_set(ep->object, font, size);
+             efl_text_ellipsis_set(ep->object, (ellip == -1.0) ? -1.0 : 1.0 - ellip);
+             _edje_textblock_colors_set(ed, ep, params, EINA_TRUE);
           }
 
-        evas_object_textblock_valign_set(ep->object, TO_DOUBLE(chosen_desc->text.align.y));
+        // FIXME: need to account for editing
+        if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
+          {
+             // do nothing - should be done elsewhere
+          }
+        else
+          {
+             evas_object_textblock_text_markup_set(ep->object, text);
+          }
+
+        if ((ed->file->efl_version.major >= 1) && (ed->file->efl_version.minor >= 19))
+          {
+             _edje_part_recalc_single_textblock_min_max_calc(ep,
+                   chosen_desc,
+                   params,
+                   minw, minh,
+                   maxw, maxh);
+          }
+        else
+          {
+             _edje_part_recalc_single_textblock_min_max_calc_legacy(ep,
+                   chosen_desc,
+                   params,
+                   minw, minh,
+                   maxw, maxh);
+          }
      }
 }
 
@@ -566,15 +897,11 @@ _edje_textblock_recalc_apply(Edje *ed, Edje_Real_Part *ep,
                              Edje_Calc_Params *params,
                              Edje_Part_Description_Text *chosen_desc)
 {
-   /* FIXME: this is just an hack. */
    FLOAT_T sc;
 
-#if 0
-   _get_text(ep);
-#endif
-
    sc = DIV(ed->scale, ed->file->base_scale);
    if (EQ(sc, ZERO)) sc = DIV(_edje_scale, ed->file->base_scale);
+   _edje_textblock_colors_set(ed, ep, params, EINA_FALSE);
    if (chosen_desc->text.fit_x || chosen_desc->text.fit_y)
      {
         _edje_part_recalc_single_textblock(sc, ed, ep, chosen_desc, params,
index da5c3cb..deea925 100644 (file)
@@ -2078,7 +2078,7 @@ _edje_efl_text_get(Eo *obj EINA_UNUSED, Edje *ed, const char *part,
                     return desc->text.text.str;
                }
           }
-        if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
+        else
           {
              const char *entry;
              if (legacy)
@@ -3496,7 +3496,7 @@ again:
              //width
              if (!ep->chosen_description->fixed.w)
                {
-                  if ((legacy_calc) && (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK))
+                  if ((legacy_calc) && PART_IS_TEXT(ed, ep))
                     {
                        //We care textblock width size specially.
                        Evas_Coord tb_mw;
@@ -3524,9 +3524,8 @@ again:
                {
                   if (legacy_calc)
                     {
-                       if ((ep->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
-                           ((Edje_Part_Description_Text *)ep->chosen_description)->text.min_x ||
-                           !skip_h)
+                       if (!PART_IS_TEXT(ed, ep) ||
+                           ((Edje_Part_Description_Text *)ep->chosen_description)->text.min_x || !skip_h)
                          {
                             if (over_h > max_over_h)
                               {
@@ -3536,7 +3535,7 @@ again:
                               }
                          }
 
-                       if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK)
+                       if (PART_IS_TEXT(ed, ep))
                          has_fixed_tb = EINA_FALSE;
                     }
                   else if (over_h > max_over_h)