woohyun pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=f6caca1d70b750dcb73329fabcd8da01876d7a2f

commit f6caca1d70b750dcb73329fabcd8da01876d7a2f
Author: abdulleh Ghujeh <[email protected]>
Date:   Thu Nov 28 13:14:15 2019 +0900

    Efl Canvas Text : Modify Style Property
    
    Summary:
    This patch defines the way style property will work at canvas_text object
    
    1- Changing canvas_text style property using Font/Format/Style interfaces 
or with efl_canvas_text style property are the same.
         Example:
    
    ```
    efl_text_font_set(tb, "Arial", 30);
    //is same as
    efl_canvas_text_style_set(tb, "font=Arial font_size=30");
    
    //which means calling
    char * font;
    int size;
    int font_size;
    efl_text_font_get(tb, &font, &size);
    // calling this after any of the top two functions will return same result
    ```
    
    2- style_get_property
         Will return string that contains full details about all the current 
applied style at canvas_text  level.
    
    3- style_set_property
         Will only override passed styles and leave everything else as it is
    
    ```
    efl_canvas_text_style_set(tb, "font=Arial");  // overrider font name to 
Arial and leave everthing else
    efl_canvas_text_style_set(tb, "font_size=30");  // overrider font size to 
30 and leave everthing else (font name will stay arial)
    ```
    
    Reviewers: ali.alzyod, woohyun, tasn, segfaultxavi, bu5hm4n, zmike
    
    Reviewed By: woohyun
    
    Subscribers: zmike, bu5hm4n, segfaultxavi, a.srour, cedric, #reviewers, 
#committers
    
    Tags: #efl
    
    Differential Revision: https://phab.enlightenment.org/D10607
---
 src/bin/elementary/test_photocam.c          |   3 +-
 src/lib/evas/canvas/efl_canvas_text.eo      |  29 +-
 src/lib/evas/canvas/evas_font_dir.c         |  42 +-
 src/lib/evas/canvas/evas_object_textblock.c | 574 ++++++++++++++++++++++++++--
 src/lib/evas/common/evas_font.h             |   3 +-
 src/tests/evas/evas_test_textblock.c        |  59 ++-
 6 files changed, 647 insertions(+), 63 deletions(-)

diff --git a/src/bin/elementary/test_photocam.c 
b/src/bin/elementary/test_photocam.c
index eb068e663c..78aa528aaa 100644
--- a/src/bin/elementary/test_photocam.c
+++ b/src/bin/elementary/test_photocam.c
@@ -817,7 +817,8 @@ test_image_zoomable_animated(void *data EINA_UNUSED, 
Evas_Object *obj EINA_UNUSE
            efl_text_set(efl_added, "Clicking the image will play/pause 
animation."),
            efl_text_interactive_editable_set(efl_added, EINA_FALSE),
            efl_gfx_hint_weight_set(efl_added, 1, 0),
-           efl_canvas_text_style_set(efl_added, NULL, "DEFAULT='align=center 
font=Sans font_size=10 color=#fff wrap=word'"),
+           efl_text_font_set(efl_added, "Sans", 10),
+           efl_text_normal_color_set(efl_added, 255, 255, 255, 255),
            efl_pack(bx, efl_added)
           );
 
diff --git a/src/lib/evas/canvas/efl_canvas_text.eo 
b/src/lib/evas/canvas/efl_canvas_text.eo
index 10c43c71e8..f5e6af118f 100644
--- a/src/lib/evas/canvas/efl_canvas_text.eo
+++ b/src/lib/evas/canvas/efl_canvas_text.eo
@@ -75,26 +75,19 @@ class @beta Efl.Canvas.Text extends Efl.Canvas.Object 
implements Efl.Text,
             mode: bool; [[$true for legacy mode, $false otherwise]]
          }
       }
-      @property style {
-         [[The text style of the object.
-
-           $key is how you reference the style (for deletion or fetching). 
$NULL
-           as key indicates the style has the highest priority (default style).
-           The style priority is the order of creation, styles created first
-           are applied first with the exception of $NULL which is implicitly
-           first.
-
-           Set $style to $NULL to delete it.
-         ]]
-         set {
-         }
-         get {
-         }
-         keys {
-            key: string; [[The name to the style. $NULL is the default style]]
+      style_apply {
+         [[apply the style for this object, sent style member will override 
old ones, other styles will not be affected.
+         similar to setting style using functions (for example font_slant_set, 
wrap_set).]]
+         params {
+            @in style: string; [[A whitespace-separated list of 
$[property=value] pairs, for example, $[font=sans size=30].]]
          }
+      }
+      @property all_styles {
+         [[Get all styles belong to this object as string (default styles plus 
styles 
+         from style_apply or style functions (for example font_slant_set, 
wrap_set).]]
+         get {}
          values {
-            style: string; [[The style]]
+            style: string; [[All styles, should not be freed.]]
          }
       }
       @property size_formatted {
diff --git a/src/lib/evas/canvas/evas_font_dir.c 
b/src/lib/evas/canvas/evas_font_dir.c
index b1bbb6b155..5b945dcb27 100644
--- a/src/lib/evas/canvas/evas_font_dir.c
+++ b/src/lib/evas/canvas/evas_font_dir.c
@@ -429,12 +429,50 @@ static Style_Map _style_spacing_map[] =
 };
 
 #define _STYLE_MAP_LEN(x) (sizeof(x) / sizeof(*(x)))
+
+/**
+ * @internal
+ * Find the string from the map at a style
+ * @return the string at a style type
+ */
+static const char*
+_evas_font_style_find_str_internal(int type, Style_Map _map[], size_t map_len)
+{
+   size_t i;
+   for ( i = 0; i < map_len; i++ )
+     {
+        if (_map[i].type == type)
+          return _map[i].name;
+     }
+   return NULL;
+}
+
+const char*
+evas_font_style_find_str(int type, Evas_Font_Style style)
+{
+#define _RET_STYLE(x) \
+   return _evas_font_style_find_str_internal(type, \
+                   _style_##x##_map, _STYLE_MAP_LEN(_style_##x##_map));
+   switch (style)
+     {
+        case EVAS_FONT_STYLE_SLANT:
+           _RET_STYLE(slant);
+        case EVAS_FONT_STYLE_WEIGHT:
+           _RET_STYLE(weight);
+        case EVAS_FONT_STYLE_WIDTH:
+           _RET_STYLE(width);
+        default:
+           return NULL;
+     }
+#undef _RET_STYLE
+}
+
 /**
  * @internal
  * Find a certain attribute from the map in the style.
  * @return the index of the found one.
  */
-static int
+static unsigned int
 _evas_font_style_find_internal(const char *style, const char *style_end,
       Style_Map _map[], size_t map_len)
 {
@@ -462,7 +500,7 @@ _evas_font_style_find_internal(const char *style, const 
char *style_end,
    return 0;
 }
 
-int
+unsigned int
 evas_font_style_find(const char *start, const char *end,
       Evas_Font_Style style)
 {
diff --git a/src/lib/evas/canvas/evas_object_textblock.c 
b/src/lib/evas/canvas/evas_object_textblock.c
index 98cfc9f1f2..68115a6116 100644
--- a/src/lib/evas/canvas/evas_object_textblock.c
+++ b/src/lib/evas/canvas/evas_object_textblock.c
@@ -476,6 +476,7 @@ struct _Evas_Object_Textblock
          Efl_Text_Format_Wrap            wrap;
          Efl_Text_Font_Bitmap_Scalable   bitmap_scalable;
       } info;
+      char * default_style_str;
    } default_format;
    double                              valign;
    Eina_Stringshare                   *markup_text;
@@ -551,6 +552,7 @@ static int evas_object_textblock_was_opaque(Evas_Object 
*eo_obj,
 static void evas_object_textblock_coords_recalc(Evas_Object *eo_obj,
                                                Evas_Object_Protected_Data *obj,
                                                void *type_private_data);
+static void _canvas_text_format_changed(Eo *eo_obj, Efl_Canvas_Text_Data *o);
 
 static const Evas_Object_Func object_func =
 {
@@ -2702,6 +2704,230 @@ _format_command(Evas_Object *eo_obj, 
Evas_Object_Textblock_Format *fmt, const ch
      }
 }
 
+//FIXME Create common function for both _default _format_command & 
_format_command
+/**
+ * @internal
+ * Parses the cmd and parameter and adds the parsed format to fmt and fmt info.
+ *
+ * @param obj the evas object - should not be NULL.
+ * @param fmt The format to populate - should not be NULL.
+ * @param[in] cmd the command to process, should be stringshared.
+ * @param[in] param the parameter of the command. may modify the string.
+ */
+static Eina_Bool
+_default_format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format 
*fmt, const char *cmd, char *param)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(param, EINA_FALSE);
+
+   Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+   int len = _format_clean_param(param);
+   Eina_Bool changed = EINA_FALSE;
+   const char * font_prefix = "font_";
+
+   ASYNC_BLOCK;
+
+   if (cmd == fontstr)
+     {
+        char *end = strchr(param, ':');
+
+        if (!end)
+        changed = eina_stringshare_replace(&(_FMT_INFO(font)), param);
+        else
+        changed = eina_stringshare_replace_length(&(_FMT_INFO(font)), param, 
end - param);
+
+        while (end)
+        {
+           const char *tend;
+           param = end;
+           end = strchr(end + 1, ':');
+           if (!end)
+              tend = param + strlen(param);
+           else
+              tend = end;
+
+           char *equal = strchr(param, '=');
+           if (equal)
+              {
+                 char font_param[strlen(font_prefix) + (equal - param)];
+                 font_param[0] = '\0';
+                 strcat(font_param, font_prefix);
+                 strncat(font_param, &param[1], equal - param -1);
+                 const char *key = eina_stringshare_add(font_param);
+
+                 char val[tend - equal];
+                 val[0] = '\0';
+                 strncat(val, &equal[1], tend - equal -1);
+
+                 _default_format_command(eo_obj, fmt, key, val);
+                 eina_stringshare_del(key);
+              }
+        }
+     }
+   else if (cmd == font_fallbacksstr)
+     {
+        changed = eina_stringshare_replace(&(_FMT_INFO(font_fallbacks)), 
param);
+     }
+   else if (cmd == font_sizestr)
+     {
+        int size;
+
+        size = atoi(param);
+        if (size > 0 && _FMT_INFO(size) != size)
+          {
+             _FMT_INFO(size) = size;
+             changed = EINA_TRUE;
+          }
+     }
+   else if (cmd == font_sourcestr)
+     {
+        Eina_Stringshare *font_source = _FMT_INFO(font_source);
+        if ((!font_source) ||
+              ((font_source) && (strcmp(font_source, param))))
+          {
+             changed = eina_stringshare_replace(&(_FMT_INFO(font_source)), 
param);
+          }
+     }
+   else if (cmd == font_weightstr)
+     {
+        unsigned int weight = evas_font_style_find(param,
+                                                   param + len,
+                                                   EVAS_FONT_STYLE_WEIGHT);
+
+        if (_FMT_INFO(font_weight) != weight)
+          {
+             _FMT_INFO(font_weight) = weight;
+             changed = EINA_TRUE;
+          }
+     }
+   else if (cmd == font_stylestr)
+     {
+        unsigned int slant = evas_font_style_find(param,
+                                                  param + len,
+                                                  EVAS_FONT_STYLE_SLANT);
+
+        if (_FMT_INFO(font_slant) != slant)
+          {
+             _FMT_INFO(font_slant) = slant;
+             changed = EINA_TRUE;
+          }
+     }
+   else if (cmd == font_widthstr)
+     {
+        unsigned int width = evas_font_style_find(param,
+                                                  param + len,
+                                                  EVAS_FONT_STYLE_WIDTH);
+
+        if (_FMT_INFO(font_width) != width)
+          {
+             _FMT_INFO(font_width) = width;
+             changed = EINA_TRUE;
+          }
+     }
+   else if (cmd == langstr)
+     {
+        changed = eina_stringshare_replace(&(_FMT_INFO(font_lang)),
+                                           evas_font_lang_normalize(param));
+     }
+   else if (cmd == gfx_filterstr)
+     {
+        if (!fmt->gfx_filter)
+          fmt->gfx_filter = calloc(1, sizeof(Efl_Canvas_Text_Filter));
+        eina_stringshare_replace(&fmt->gfx_filter->name, param);
+        eina_stringshare_replace(&(_FMT_INFO(gfx_filter_name)), param);
+     }
+   else if (cmd == wrapstr)
+     {
+        Efl_Text_Format_Wrap wrap = _FMT_INFO(wrap);
+
+        if (!strcmp("word", param))
+          wrap = EFL_TEXT_FORMAT_WRAP_WORD;
+        else if (!strcmp("char", param))
+          wrap = EFL_TEXT_FORMAT_WRAP_CHAR;
+        else if (!strcmp("mixed", param))
+          wrap = EFL_TEXT_FORMAT_WRAP_MIXED;
+        else if (!strcmp("hyphenation", param))
+          wrap = EFL_TEXT_FORMAT_WRAP_HYPHENATION;
+
+        if (_FMT_INFO(wrap) != wrap)
+          {
+             _FMT_INFO(wrap) = wrap;
+             _FMT(wrap_word) = (wrap == EFL_TEXT_FORMAT_WRAP_WORD);
+             _FMT(wrap_char) = (wrap == EFL_TEXT_FORMAT_WRAP_CHAR);
+             _FMT(wrap_mixed) = (wrap == EFL_TEXT_FORMAT_WRAP_MIXED);
+             _FMT(wrap_hyphenation) = (wrap == 
EFL_TEXT_FORMAT_WRAP_HYPHENATION);
+             changed = EINA_TRUE;
+          }
+     }
+   else if (cmd == stylestr)
+     {
+        const char *p;
+        char *p1, *p2, *pp;
+
+        p2 = alloca(len + 1);
+        *p2 = 0;
+        /* no comma */
+        if (!strstr(param, ",")) p1 = (char*) param;
+        else
+          {
+             p1 = alloca(len + 1);
+             *p1 = 0;
+
+             /* split string "str1,str2" into p1 and p2 (if we have more than
+              * 1 str2 eg "str1,str2,str3,str4" then we don't care. p2 just
+              * ends up being the last one as right now it's only valid to have
+              * 1 comma and 2 strings */
+             pp = p1;
+             for (p = param; *p; p++)
+               {
+                  if (*p == ',')
+                    {
+                       *pp = 0;
+                       pp = p2;
+                       continue;
+                    }
+                  *pp = *p;
+                  pp++;
+               }
+             *pp = 0;
+          }
+
+        if      (!strcmp(p1, "off"))                 {fmt->style = 
EVAS_TEXT_STYLE_PLAIN;               _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_NONE;}
+        else if (!strcmp(p1, "none"))                {fmt->style = 
EVAS_TEXT_STYLE_PLAIN;               _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_NONE;}
+        else if (!strcmp(p1, "plain"))               {fmt->style = 
EVAS_TEXT_STYLE_PLAIN;               _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_NONE;}
+        else if (!strcmp(p1, "shadow"))              {fmt->style = 
EVAS_TEXT_STYLE_SHADOW;              _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_SHADOW;}
+        else if (!strcmp(p1, "outline"))             {fmt->style = 
EVAS_TEXT_STYLE_OUTLINE;             _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_OUTLINE;}
+        else if (!strcmp(p1, "soft_outline"))        {fmt->style = 
EVAS_TEXT_STYLE_SOFT_OUTLINE;        _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_SOFT_OUTLINE;}
+        else if (!strcmp(p1, "outline_shadow"))      {fmt->style = 
EVAS_TEXT_STYLE_OUTLINE_SHADOW;      _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_OUTLINE_SHADOW;}
+        else if (!strcmp(p1, "outline_soft_shadow")) {fmt->style = 
EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW; _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_OUTLINE_SOFT_SHADOW;}
+        else if (!strcmp(p1, "glow"))                {fmt->style = 
EVAS_TEXT_STYLE_GLOW;                _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_GLOW;}
+        else if (!strcmp(p1, "far_shadow"))          {fmt->style = 
EVAS_TEXT_STYLE_FAR_SHADOW;          _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_FAR_SHADOW;}
+        else if (!strcmp(p1, "soft_shadow"))         {fmt->style = 
EVAS_TEXT_STYLE_SOFT_SHADOW;         _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_SOFT_SHADOW;}
+        else if (!strcmp(p1, "far_soft_shadow"))     {fmt->style = 
EVAS_TEXT_STYLE_FAR_SOFT_SHADOW;     _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_FAR_SOFT_SHADOW;}
+        else                                         {fmt->style = 
EVAS_TEXT_STYLE_PLAIN;               _FMT_INFO(effect) = 
EFL_TEXT_STYLE_EFFECT_TYPE_NONE;}
+        if (*p2)
+          {
+             if      (!strcmp(p2, "bottom_right"))  
{EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, 
EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT); _FMT_INFO(shadow_direction) = 
EFL_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT;}
+             else if (!strcmp(p2, "bottom"))        
{EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, 
EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM);       _FMT_INFO(shadow_direction) = 
EFL_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM;}
+             else if (!strcmp(p2, "bottom_left"))   
{EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, 
EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT);  _FMT_INFO(shadow_direction) = 
EFL_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT;}
+             else if (!strcmp(p2, "left"))          
{EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, 
EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT);         _FMT_INFO(shadow_direction) = 
EFL_TEXT_STYLE_SHADOW_DIRECTION_LEFT;}
+             else if (!strcmp(p2, "top_left"))      
{EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, 
EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT);     _FMT_INFO(shadow_direction) = 
EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT;}
+             else if (!strcmp(p2, "top"))           
{EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, 
EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP);          _FMT_INFO(shadow_direction) = 
EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP;}
+             else if (!strcmp(p2, "top_right"))     
{EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, 
EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT);    _FMT_INFO(shadow_direction) = 
EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT;}
+             else if (!strcmp(p2, "right"))         
{EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, 
EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT);        _FMT_INFO(shadow_direction) = 
EFL_TEXT_STYLE_SHADOW_DIRECTION_RIGHT;}
+             else                                   
{EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(fmt->style, 
EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT); _FMT_INFO(shadow_direction) = 
EFL_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT;}
+          }
+     }
+   else
+     {
+        /* Update reset of formats like color, ...etc*/
+        _format_command(eo_obj, fmt, cmd, param);
+        /*FIXME update only when change happened*/
+        changed = EINA_TRUE;
+     }
+
+  return changed;
+}
+
 /* 
  * @internal
  * just to create a constant without using marco
@@ -2924,12 +3150,16 @@ _format_parse(const char **s)
  * @param obj The evas object - Not NULL.
  * @param[out] fmt The format to populate - Not NULL.
  * @param[in] str the string to parse.- Not NULL.
+ * @param[in] is_default_format if this is default format true else false.
  */
 static void
-_format_fill(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const 
char *str)
+_format_fill(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const 
char *str, Eina_Bool is_default_format)
 {
    const char *s;
    const char *item;
+   Eina_Bool changed = EINA_FALSE;
+
+   if (!str) return;
 
    s = str;
 
@@ -2945,7 +3175,16 @@ _format_fill(Evas_Object *eo_obj, 
Evas_Object_Textblock_Format *fmt, const char
         char *val = NULL;
         if (_format_param_parse(item, &key, &val, &allocator))
           {
-             if ((key) && (val)) _format_command(eo_obj, fmt, key, val);
+             if ((key) && (val))
+               {
+                  if (is_default_format == EINA_TRUE)
+                    {
+                       if (_default_format_command(eo_obj, fmt, key, val))
+                         changed = EINA_TRUE;
+                    }
+                  else
+                    _format_command(eo_obj, fmt, key, val);
+               }
              eina_stringshare_del(key);
           }
         else
@@ -2954,9 +3193,292 @@ _format_fill(Evas_Object *eo_obj, 
Evas_Object_Textblock_Format *fmt, const char
           }
      }
 
+   if (is_default_format == EINA_TRUE && changed)
+     {
+        Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+        _canvas_text_format_changed(eo_obj, o);
+     }
+
    _allocator_reset(&allocator);
 }
 
+#define PRINTF_APPEND_STR(name, val) eina_strbuf_append_printf(format_buffer, 
"%s=%s ", name, val)
+#define PRINTF_APPEND_INT(name, val) eina_strbuf_append_printf(format_buffer, 
"%s=%i ", name, val)
+#define PRINTF_APPEND_COLOR(name, r, g, b, a) 
eina_strbuf_append_printf(format_buffer, "%s=rgba(%i,%i,%i,%i) ", name, r, g, 
b, a)
+#define PRINTF_APPEND_FLOAT(name, val) 
eina_strbuf_append_printf(format_buffer, "%s=%f ", name, val)
+#define PRINTF_APPEND_PERCENT_FLOAT(name, val) 
eina_strbuf_append_printf(format_buffer, "%s=%f%% ", name, val)
+
+/**
+ * @internal
+ * get all formats in one string
+ *
+ * @param obj The evas object - Not NULL.
+ * @param[out] fmt The format to convert to string - Not NULL.
+ * @return the format as string, must be freed by the user.
+ */
+static char *
+_format_string_get(const Eo *eo_obj, Evas_Object_Textblock_Format *fmt)
+{
+   Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+   Eina_Strbuf *format_buffer = eina_strbuf_new();
+
+   //format info
+
+   if (_FMT_INFO(font))
+     PRINTF_APPEND_STR(fontstr, _FMT_INFO(font));
+
+   if (_FMT_INFO(font_fallbacks))
+     PRINTF_APPEND_STR(font_fallbacksstr, _FMT_INFO(font_fallbacks));
+
+   PRINTF_APPEND_INT(font_sizestr, _FMT_INFO(size));
+
+   if (_FMT_INFO(font_source))
+     PRINTF_APPEND_STR(font_sourcestr, _FMT_INFO(font_source));
+
+   const char *weight_value_str = 
evas_font_style_find_str(_FMT_INFO(font_weight), EVAS_FONT_STYLE_WEIGHT);
+   if (!weight_value_str)
+     weight_value_str = "normal";
+
+   PRINTF_APPEND_STR(font_weightstr, weight_value_str);
+
+   const char *slant_value_str = 
evas_font_style_find_str(_FMT_INFO(font_slant), EVAS_FONT_STYLE_SLANT);
+   if (!slant_value_str)
+     slant_value_str = "normal";
+
+   PRINTF_APPEND_STR(font_stylestr, slant_value_str);
+
+   const char *width_value_str = 
evas_font_style_find_str(_FMT_INFO(font_width), EVAS_FONT_STYLE_WIDTH);
+   if (!width_value_str)
+     width_value_str = "normal";
+
+   PRINTF_APPEND_STR(font_widthstr, width_value_str);
+
+   if (_FMT_INFO(font_lang))
+     PRINTF_APPEND_STR(langstr, _FMT_INFO(font_lang));
+
+   if (_FMT_INFO(gfx_filter_name))
+     PRINTF_APPEND_STR(gfx_filterstr, _FMT_INFO(gfx_filter_name));
+
+   char *wrap_value_str;
+   Efl_Text_Format_Wrap wrap = _FMT_INFO(wrap);
+
+   switch (wrap)
+     {
+        case EFL_TEXT_FORMAT_WRAP_CHAR:
+          wrap_value_str = "char";
+          break;
+        case EFL_TEXT_FORMAT_WRAP_MIXED:
+          wrap_value_str = "mixed";
+          break;
+        case EFL_TEXT_FORMAT_WRAP_HYPHENATION:
+          wrap_value_str = "hyphenation";
+          break;
+        default:
+          wrap_value_str = "word";
+          break;
+     }
+
+   PRINTF_APPEND_STR(wrapstr, wrap_value_str);
+
+   //format
+   PRINTF_APPEND_COLOR(colorstr, fmt->color.normal.r, fmt->color.normal.g,
+                             fmt->color.normal.b, fmt->color.normal.a);
+
+   PRINTF_APPEND_COLOR(underline_colorstr, fmt->color.underline.r, 
fmt->color.underline.g,
+                             fmt->color.underline.b, fmt->color.underline.a);
+
+   PRINTF_APPEND_COLOR(underline2_colorstr, fmt->color.underline2.r, 
fmt->color.underline2.g,
+                             fmt->color.underline2.b, fmt->color.underline2.a);
+
+   PRINTF_APPEND_COLOR(underline_dash_colorstr, fmt->color.underline_dash.r, 
fmt->color.underline_dash.g,
+                             fmt->color.underline_dash.b, 
fmt->color.underline_dash.a);
+
+   PRINTF_APPEND_COLOR(outline_colorstr, fmt->color.outline.r, 
fmt->color.outline.g,
+                             fmt->color.outline.b, fmt->color.outline.a);
+
+   PRINTF_APPEND_COLOR(shadow_colorstr, fmt->color.shadow.r, 
fmt->color.shadow.g,
+                             fmt->color.shadow.b, fmt->color.shadow.a);
+
+   PRINTF_APPEND_COLOR(glow_colorstr, fmt->color.glow.r, fmt->color.glow.g,
+                             fmt->color.glow.b, fmt->color.glow.a);
+
+   PRINTF_APPEND_COLOR(glow2_colorstr, fmt->color.glow2.r, fmt->color.glow2.g,
+                             fmt->color.glow2.b, fmt->color.glow2.a);
+
+   PRINTF_APPEND_COLOR(backing_colorstr, fmt->color.backing.r, 
fmt->color.backing.g,
+                             fmt->color.backing.b, fmt->color.backing.a);
+
+   PRINTF_APPEND_COLOR(strikethrough_colorstr, fmt->color.strikethrough.r, 
fmt->color.strikethrough.g,
+                             fmt->color.strikethrough.b, 
fmt->color.strikethrough.a);
+
+   char *halign_value_str = NULL;
+   Evas_Textblock_Align_Auto halign = fmt->halign_auto;
+
+   switch (halign)
+     {
+        case EVAS_TEXTBLOCK_ALIGN_AUTO_NORMAL:
+          halign_value_str = "auto";
+          break;
+        case EVAS_TEXTBLOCK_ALIGN_AUTO_END:
+          halign_value_str = "end";
+          break;
+        case EVAS_TEXTBLOCK_ALIGN_AUTO_LOCALE:
+          halign_value_str = "locale";
+          break;
+        case EVAS_TEXTBLOCK_ALIGN_AUTO_NONE:
+          if (fmt->halign == 0.5)
+            halign_value_str = "center";
+          else if (fmt->halign == 0.0)
+            halign_value_str = "left";
+          else if (fmt->halign == 1.0)
+            halign_value_str = "right";
+
+          break;
+     }
+
+   if (halign_value_str != NULL)
+     PRINTF_APPEND_STR(alignstr, halign_value_str);
+   else
+     PRINTF_APPEND_FLOAT(alignstr, fmt->halign);
+
+
+   char *valign_value_str = NULL;
+
+   if (fmt->valign == 0.5)
+     valign_value_str = "center";
+   else if (fmt->valign == 0.0)
+     valign_value_str = "top";
+   else if (fmt->valign == 1.0)
+     valign_value_str = "bottom";
+   else if (fmt->valign == -1.0)
+     valign_value_str = "baseline";
+
+   if (valign_value_str != NULL)
+     PRINTF_APPEND_STR(valignstr, valign_value_str);
+   else
+     PRINTF_APPEND_FLOAT(valignstr, fmt->valign);
+
+   PRINTF_APPEND_FLOAT(text_valignstr, o->valign);
+   PRINTF_APPEND_INT(left_marginstr, fmt->margin.l);
+   PRINTF_APPEND_INT(right_marginstr, fmt->margin.r);
+
+
+   char *underline_value_str = "off";
+
+   if (fmt->underline == EINA_TRUE && fmt->underline2 == EINA_TRUE)
+     underline_value_str = "double";
+   else if (fmt->underline == EINA_TRUE)
+     underline_value_str = "single";
+   else if (fmt->underline_dash == EINA_TRUE)
+     underline_value_str = "dashed";
+
+   PRINTF_APPEND_STR(underlinestr, underline_value_str);
+   PRINTF_APPEND_STR(strikethroughstr, (fmt->strikethrough == 0 ? "off" : 
"on"));
+   PRINTF_APPEND_STR(backingstr, (fmt->backing == 0 ? "off" : "on"));
+
+   char *style_value_str_1 = "off";
+   char *style_value_str_2 = NULL;
+   Efl_Text_Style_Effect_Type style1 = _FMT_INFO(effect);
+   Efl_Text_Style_Effect_Type style2 = _FMT_INFO(shadow_direction);
+
+   switch (style1)
+     {
+        case EFL_TEXT_STYLE_EFFECT_TYPE_NONE:
+          style_value_str_1 = "plain";
+          break;
+        case EFL_TEXT_STYLE_EFFECT_TYPE_SHADOW:
+          style_value_str_1 = "shadow";
+          break;
+        case EFL_TEXT_STYLE_EFFECT_TYPE_OUTLINE:
+          style_value_str_1 = "outline";
+          break;
+        case EFL_TEXT_STYLE_EFFECT_TYPE_SOFT_OUTLINE:
+          style_value_str_1 = "soft_outline";
+          break;
+        case EFL_TEXT_STYLE_EFFECT_TYPE_OUTLINE_SHADOW:
+          style_value_str_1 = "outline_shadow";
+          break;
+        case EFL_TEXT_STYLE_EFFECT_TYPE_OUTLINE_SOFT_SHADOW:
+          style_value_str_1 = "outline_soft_shadow";
+          break;
+        case EFL_TEXT_STYLE_EFFECT_TYPE_GLOW:
+          style_value_str_1 = "glow";
+          break;
+        case EFL_TEXT_STYLE_EFFECT_TYPE_FAR_SHADOW:
+          style_value_str_1 = "far_shadow";
+          break;
+        case EFL_TEXT_STYLE_EFFECT_TYPE_SOFT_SHADOW:
+          style_value_str_1 = "soft_shadow";
+          break;
+        case EFL_TEXT_STYLE_EFFECT_TYPE_FAR_SOFT_SHADOW:
+          style_value_str_1 = "far_soft_shadow";
+          break;
+        default:
+          style_value_str_1 = "off";
+          break;
+     }
+
+   switch (style2)
+     {
+        case EFL_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT:
+          style_value_str_2 = "bottom_right";
+          break;
+        case EFL_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM:
+          style_value_str_2 = "bottom";
+          break;
+        case EFL_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT:
+          style_value_str_2 = "bottom_left";
+          break;
+        case EFL_TEXT_STYLE_SHADOW_DIRECTION_LEFT:
+          style_value_str_2 = "left";
+          break;
+        case EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT:
+          style_value_str_2 = "top_left";
+          break;
+        case EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP:
+          style_value_str_2 = "top";
+          break;
+        case EFL_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT:
+          style_value_str_2 = "top_right";
+          break;
+        case EFL_TEXT_STYLE_SHADOW_DIRECTION_RIGHT:
+          style_value_str_2 = "right";
+          break;
+        default:
+          style_value_str_2 = NULL;
+          break;
+     }
+
+   if (style_value_str_2 != NULL)
+     eina_strbuf_append_printf(format_buffer, "%s=%s,%s ", stylestr, 
style_value_str_1, style_value_str_2);
+   else
+     PRINTF_APPEND_STR(stylestr, style_value_str_1);
+
+   PRINTF_APPEND_INT(tabstopsstr, fmt->tabstops);
+   PRINTF_APPEND_INT(linesizestr, fmt->linesize);
+   PRINTF_APPEND_PERCENT_FLOAT(linerelsizestr, (fmt->linerelsize*100));
+   PRINTF_APPEND_INT(linegapstr, fmt->linegap);
+   PRINTF_APPEND_PERCENT_FLOAT(linerelgapstr, (fmt->linerelgap*100));
+   PRINTF_APPEND_PERCENT_FLOAT(linefillstr, (fmt->linefill*100));
+   PRINTF_APPEND_FLOAT(ellipsisstr, fmt->ellipsis);
+   PRINTF_APPEND_STR(passwordstr, (fmt->password == 0 ? "off" : "on"));
+
+   if (o->repch)
+     PRINTF_APPEND_STR(replacement_charstr, o->repch);
+
+   PRINTF_APPEND_INT(underline_dash_widthstr, fmt->underline_dash_width);
+   PRINTF_APPEND_INT(underline_dash_gapstr, fmt->underline_dash_gap);
+   PRINTF_APPEND_FLOAT(underline_heightstr, fmt->underline_height);
+
+   const char *temp = eina_strbuf_string_get(format_buffer);
+   size_t len = strlen(temp);
+   char *format_str = malloc(len+1);
+   strcpy(format_str, temp);
+   eina_strbuf_free(format_buffer);
+
+   return format_str;
+}
+
 /**
  * @internal
  * Duplicate a format and return the duplicate.
@@ -6839,7 +7361,7 @@ _layout_setup(Ctxt *c, const Eo *eo_obj, Evas_Coord w, 
Evas_Coord h)
           }
         if ((c->o->style) && (c->o->style->default_tag))
           {
-             _format_fill(c->obj, c->fmt, c->o->style->default_tag);
+             _format_fill(c->obj, c->fmt, c->o->style->default_tag, 
EINA_FALSE);
              finalize = EINA_TRUE;
           }
 
@@ -6847,7 +7369,7 @@ _layout_setup(Ctxt *c, const Eo *eo_obj, Evas_Coord w, 
Evas_Coord h)
           {
              if ((use->st) && (use->st->default_tag))
                {
-                  _format_fill(c->obj, c->fmt, use->st->default_tag);
+                  _format_fill(c->obj, c->fmt, use->st->default_tag, 
EINA_FALSE);
                   finalize = EINA_TRUE;
                }
           }
@@ -7452,41 +7974,12 @@ _style_by_key_find(Efl_Canvas_Text_Data *o, const char 
*key)
    return NULL;
 }
 
-static Evas_Textblock_Style *
-_style_fetch(const char *style)
-{
-   Evas_Textblock_Style *ts = NULL;
-   Eina_List *i;
-
-   if (!style) return NULL;
-
-   EINA_LIST_FOREACH(_style_cache, i, ts)
-     {
-        if (ts->style_text == style) break;
-     }
-
-   if (!ts)
-     {
-        ts = evas_textblock_style_new();
-        ts->legacy = EINA_FALSE;
-        evas_textblock_style_set(ts, style);
-        _style_cache = eina_list_append(_style_cache, ts);
-     }
-   return ts;
-}
-
 EOLIAN static void
-_efl_canvas_text_style_set(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, 
const char *key, const char *style)
+_efl_canvas_text_style_apply(Eo *eo_obj, Efl_Canvas_Text_Data *o, const char 
*style)
 {
-   // FIXME: Make key value behaviour.
    Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, 
EFL_CANVAS_OBJECT_CLASS);
    evas_object_async_block(obj);
-
-   Evas_Textblock_Style *ts;
-
-   ts = _style_fetch(style);
-
-   _textblock_style_generic_set(eo_obj, ts, key);
+   _format_fill(eo_obj, &(o->default_format.format), style, EINA_TRUE);
 }
 
 EAPI Evas_Textblock_Style *
@@ -7500,11 +7993,13 @@ evas_object_textblock_style_get(const Eo *eo_obj)
 }
 
 EOLIAN static const char *
-_efl_canvas_text_style_get(const Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data 
*o, const char *key)
+_efl_canvas_text_all_styles_get(const Eo *eo_obj EINA_UNUSED, 
Efl_Canvas_Text_Data *o)
 {
-   Evas_Textblock_Style *ts = _style_by_key_find(o, key);
+   if (o->default_format.default_style_str)
+     free(o->default_format.default_style_str);
 
-   return ts ? ts->style_text : NULL;
+   o->default_format.default_style_str = _format_string_get(eo_obj, 
&(o->default_format.format));
+   return o->default_format.default_style_str;
 }
 
 EOLIAN static void
@@ -13767,6 +14262,9 @@ evas_object_textblock_free(Evas_Object *eo_obj)
    if (o->bidi_delimiters) eina_stringshare_del(o->bidi_delimiters);
    _format_command_shutdown();
 
+   if (o->default_format.default_style_str)
+     free(o->default_format.default_style_str);
+
    /* remove obstacles */
    _obstacles_free(eo_obj, o);
 
diff --git a/src/lib/evas/common/evas_font.h b/src/lib/evas/common/evas_font.h
index e16785520d..4588a31f0d 100644
--- a/src/lib/evas/common/evas_font.h
+++ b/src/lib/evas/common/evas_font.h
@@ -410,7 +410,8 @@ void evas_font_free(void *font);
 void evas_fonts_zero_free();
 void evas_fonts_zero_pressure();
 void evas_font_name_parse(Evas_Font_Description *fdesc, const char *name);
-int evas_font_style_find(const char *start, const char *end, Evas_Font_Style 
style);
+unsigned int evas_font_style_find(const char *start, const char *end, 
Evas_Font_Style style);
+const char *evas_font_style_find_str(int type, Evas_Font_Style style);
 Evas_Font_Description *evas_font_desc_new(void);
 Evas_Font_Description *evas_font_desc_dup(const Evas_Font_Description *fdesc);
 void evas_font_desc_unref(Evas_Font_Description *fdesc);
diff --git a/src/tests/evas/evas_test_textblock.c 
b/src/tests/evas/evas_test_textblock.c
index 163d403ef2..fbeba499f7 100644
--- a/src/tests/evas/evas_test_textblock.c
+++ b/src/tests/evas/evas_test_textblock.c
@@ -4350,6 +4350,9 @@ EFL_START_TEST(evas_textblock_annotation)
 }
 EFL_END_TEST;
 
+static const char *efl_style_buf =
+   "" TEST_FONT " font_size=10 color=#000 text_class=entry";
+
 #define START_EFL_CANVAS_TEXT_TEST() \
    Evas *evas; \
    Eo *txt; \
@@ -4360,9 +4363,8 @@ EFL_END_TEST;
    txt = efl_add(EFL_CANVAS_TEXT_CLASS, evas); \
    fail_if(!txt); \
    efl_canvas_text_newline_as_paragraph_separator_set(txt, EINA_FALSE); \
-   efl_canvas_text_style_set(txt, NULL, style_buf); \
-   fail_if(!efl_canvas_text_style_get(txt, NULL) || \
-         strcmp(style_buf, efl_canvas_text_style_get(txt, NULL))); \
+   efl_canvas_text_style_apply(txt, efl_style_buf); \
+   fail_if(!efl_canvas_text_all_styles_get(txt)); \
    cur_obj = efl_canvas_text_cursor_create(txt);\
    cur = evas_object_textblock_cursor_new(txt); \
    fail_if(!cur); \
@@ -4547,6 +4549,56 @@ EFL_START_TEST(efl_text_font)
 }
 EFL_END_TEST
 
+EFL_START_TEST(efl_canvas_text_style)
+{
+   START_EFL_CANVAS_TEXT_TEST();
+   unsigned char r, g, b, a;
+   const char *style;
+
+   efl_text_password_set(txt, EINA_FALSE);
+   efl_text_underline_type_set(txt, EFL_TEXT_STYLE_UNDERLINE_TYPE_DOUBLE);
+   efl_text_font_weight_set(txt, EFL_TEXT_FONT_WEIGHT_EXTRABOLD);
+   efl_text_font_slant_set(txt, EFL_TEXT_FONT_SLANT_OBLIQUE);
+   efl_text_tabstops_set(txt, 20);
+
+   efl_canvas_text_style_apply(txt, "color=#90E135");
+
+   style = efl_canvas_text_all_styles_get(txt);
+
+   // from efl_style_buf
+   fail_if(!strstr(style, "font=DejaVuSans,UnDotum,malayalam"));
+   // default value
+   fail_if(!strstr(style, "font_width=normal"));
+
+   // from functions
+   fail_if(!strstr(style, "font_weight=extrabold"));
+   fail_if(!strstr(style, "tabstops=20"));
+   fail_if(!strstr(style, "color=rgba(144,225,53,255)"));
+   fail_if(!strstr(style, "password=off"));
+   efl_text_password_set(txt, EINA_TRUE);
+   style = efl_canvas_text_all_styles_get(txt);
+   fail_if(!strstr(style, "password=on"));
+
+   efl_canvas_text_style_apply(txt, "font_width=ultracondensed");
+   ck_assert_int_eq(efl_text_font_width_get(txt), 
EFL_TEXT_FONT_WIDTH_ULTRACONDENSED);
+
+   efl_canvas_text_style_apply(txt, "wrap=none");
+   ck_assert_int_eq(efl_text_wrap_get(txt), EFL_TEXT_FORMAT_WRAP_NONE);
+
+   efl_canvas_text_style_apply(txt, "backing=on");
+   ck_assert_int_eq(efl_text_backing_type_get(txt), 
EFL_TEXT_STYLE_BACKING_TYPE_ENABLED);
+
+   efl_canvas_text_style_apply(txt, "color=#EF596C");
+   efl_text_normal_color_get(txt, &r, &g, &b, &a);
+   ck_assert_int_eq(r, 0xEF);
+   ck_assert_int_eq(g, 0x59);
+   ck_assert_int_eq(b, 0x6C);
+   ck_assert_int_eq(a, 0xFF);
+
+   END_EFL_CANVAS_TEXT_TEST();
+}
+EFL_END_TEST
+
 void evas_test_textblock(TCase *tc)
 {
    tcase_add_test(tc, evas_textblock_simple);
@@ -4581,5 +4633,6 @@ void evas_test_textblock(TCase *tc)
    tcase_add_test(tc, efl_canvas_text_markup);
    tcase_add_test(tc, efl_canvas_text_markup_invalid_escape);
    tcase_add_test(tc, efl_text_font);
+   tcase_add_test(tc, efl_canvas_text_style);
 }
 

-- 


Reply via email to