elm_label svn merge(add elm_util, slide duration time type, ...)
authorHyoyoung Chang <hyoyoung.chang@samsung.com>
Fri, 24 Dec 2010 05:02:12 +0000 (14:02 +0900)
committerHyoyoung Chang <hyoyoung.chang@samsung.com>
Fri, 24 Dec 2010 05:02:12 +0000 (14:02 +0900)
src/lib/Elementary.h.in
src/lib/Makefile.am
src/lib/elm_label.c

index 8ea86c4..b2e73e6 100644 (file)
@@ -563,8 +563,8 @@ extern "C" {
    EAPI void         elm_label_wrap_mode_set(Evas_Object *obj, Eina_Bool wrapmode);
    EAPI void         elm_label_slide_set(Evas_Object *obj, Eina_Bool slide);
    EAPI Eina_Bool    elm_label_slide_get(Evas_Object *obj);
-   EAPI void         elm_label_slide_duration_set(Evas_Object *obj, int duration);
-   EAPI int          elm_label_slide_duration_get(Evas_Object *obj);
+   EAPI void         elm_label_slide_duration_set(Evas_Object *obj, double duration);
+   EAPI double       elm_label_slide_duration_get(Evas_Object *obj);
    /* available styles:
     * default
     * marker
index 4f187ff..bad3571 100644 (file)
@@ -32,6 +32,7 @@ includesdir = $(includedir)/elementary-@VMAJ@
 libelementary_la_SOURCES = \
 elm_priv.h \
 elm_main.c \
+elm_util.c \
 elm_theme.c \
 elm_module.c \
 \
index a704449..8bb66f5 100644 (file)
@@ -15,56 +15,45 @@ struct _Widget_Data
 {
    Evas_Object *lbl;
    Evas_Object *bg;
-   const char  *label;
-   Evas_Coord   lastw;
-   Ecore_Job   *deferred_recalc_job;
-   Evas_Coord   wrap_w;
-   Evas_Coord   wrap_h;
-   Eina_Bool    linewrap : 1;
-   Eina_Bool    wrapmode : 1;
-   Eina_Bool    slidingmode : 1;
-   Eina_Bool    slidingellipsis : 1;
-   Eina_Bool    changed : 1;
-   Eina_Bool    bgcolor : 1;
-   Eina_Bool    ellipsis : 1;
-   int          slide_duration;
+   const char *label;
+   Ecore_Job *deferred_recalc_job;
+   double slide_duration;
+   Evas_Coord lastw;
+   Evas_Coord wrap_w;
+   Evas_Coord wrap_h;
+   Eina_Bool wrapmode : 1;
+   Eina_Bool linewrap : 1;
+   Eina_Bool changed : 1;
+   Eina_Bool bgcolor : 1;
+   Eina_Bool ellipsis : 1;
+   Eina_Bool slidingmode : 1;
+   Eina_Bool slidingellipsis : 1;
 };
 
 static const char *widtype = NULL;
 static void _del_hook(Evas_Object *obj);
 static void _theme_hook(Evas_Object *obj);
 static void _sizing_eval(Evas_Object *obj);
-static int  _get_value_in_key_string(const char *oldstring,
-                                     char       *key,
-                                     char      **value);
-static int _strbuf_key_value_replace(Eina_Strbuf *srcbuf,
-                                     char        *key,
-                                     const char  *value,
-                                     int          deleteflag);
-static int _stringshare_key_value_replace(const char **srcstring,
-                                          char        *key,
-                                          const char  *value,
-                                          int          deleteflag);
-static int  _is_width_over(Evas_Object *obj,
-                           int          linemode);
-static void _ellipsis_label_to_width(Evas_Object *obj,
-                                     int          linemode);
+static int _get_value_in_key_string(const char *oldstring, const char *key, char **value);
+static int _strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, const char *value, int deleteflag);
+static int _stringshare_key_value_replace(const char **srcstring, const char *key, const char *value, int deleteflag);
+static int _is_width_over(Evas_Object *obj, Eina_Bool multiline);
+static void _ellipsis_label_to_width(Evas_Object *obj, Eina_Bool multiline);
+static void _label_sliding_change(Evas_Object *obj);
 
 static void
 _elm_win_recalc_job(void *data)
 {
    Widget_Data *wd = elm_widget_data_get(data);
    Evas_Coord minw = -1, minh = -1, maxh = -1;
-   Evas_Coord resw, resh, minminw, minminh;
+   Evas_Coord resw, resh, minminw;
    if (!wd) return;
    wd->deferred_recalc_job = NULL;
    evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
    resh = 0;
-   minminw = 0;
    edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, 0, 0);
    minminw = minw;
-   minminh = minh;
-   if (wd->wrap_w >= resw)
+   if (wd->wrap_w >= resw) 
      {
         resw = wd->wrap_w;
         edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, resw, 0);
@@ -77,7 +66,8 @@ _elm_win_recalc_job(void *data)
         evas_object_size_hint_min_set(data, minminw, minh);
      }
 
-   if (wd->ellipsis && wd->linewrap && wd->wrap_h > 0 && _is_width_over(data, 1) == 1)
+   if ((wd->ellipsis) && (wd->linewrap) && (wd->wrap_h > 0) && 
+       (_is_width_over(data, 1) == 1))
      _ellipsis_label_to_width(data, 1);
 
    maxh = minh;
@@ -104,12 +94,15 @@ _theme_change(Evas_Object *obj)
    if (wd->linewrap)
      {
         if (wd->ellipsis)
-          _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap_ellipsis", elm_widget_style_get(obj));
+          _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap_ellipsis", 
+                                elm_widget_style_get(obj));
         else
-          _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap", elm_widget_style_get(obj));
+          _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap", 
+                                elm_widget_style_get(obj));
      }
    else
-     _elm_theme_object_set(obj, wd->lbl, "label", "base", elm_widget_style_get(obj));
+     _elm_theme_object_set(obj, wd->lbl, "label", "base", 
+                           elm_widget_style_get(obj));
 }
 
 static void
@@ -119,8 +112,9 @@ _theme_hook(Evas_Object *obj)
    if (!wd) return;
    _theme_change(obj);
    edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
-   edje_object_scale_set(wd->lbl, elm_widget_scale_get(obj) *
+   edje_object_scale_set(wd->lbl, elm_widget_scale_get(obj) * 
                          _elm_config->scale);
+   _label_sliding_change(obj);
    _sizing_eval(obj);
 }
 
@@ -138,7 +132,7 @@ _sizing_eval(Evas_Object *obj)
         wd->changed = EINA_FALSE;
         wd->lastw = resw;
         _elm_win_recalc_job(obj);
-// FIXME: works ok. but NOT for genlist. what should genlist do?
+// FIXME: works ok. but NOT for genlist. what should genlist do?        
 //        if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
 //        wd->deferred_recalc_job = ecore_job_add(_elm_win_recalc_job, obj);
      }
@@ -146,22 +140,17 @@ _sizing_eval(Evas_Object *obj)
      {
         evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
         edje_object_size_min_calc(wd->lbl, &minw, &minh);
-        if (wd->wrap_w > 0 && minw > wd->wrap_w)
-          minw = wd->wrap_w;
+        if (wd->wrap_w > 0 && minw > wd->wrap_w) minw = wd->wrap_w;
         evas_object_size_hint_min_set(obj, minw, minh);
         maxh = minh;
         evas_object_size_hint_max_set(obj, maxw, maxh);
-
-        if (wd->ellipsis && _is_width_over(obj, 0) == 1)
-          _ellipsis_label_to_width(obj, 0);
+        if ((wd->ellipsis) && (_is_width_over(obj, 0) == 1))
+           _ellipsis_label_to_width(obj, 0);
      }
 }
 
-static void
-_resize(void            *data,
-        Evas *e          __UNUSED__,
-        Evas_Object *obj __UNUSED__,
-        void *event_info __UNUSED__)
+static void 
+_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
 {
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return;
@@ -169,28 +158,26 @@ _resize(void            *data,
 }
 
 static int
-_get_value_in_key_string(const char *oldstring,
-                         char       *key,
-                         char      **value)
+_get_value_in_key_string(const char *oldstring, const char *key, char **value)
 {
    char *curlocater, *starttag, *endtag;
    int firstindex = 0, foundflag = -1;
-
+   
    curlocater = strstr(oldstring, key);
    if (curlocater)
      {
+        int key_len = strlen(key);
         starttag = curlocater;
-        endtag = curlocater + strlen(key);
-        if (endtag == NULL || *endtag != '=')
+        endtag = curlocater + key_len;
+        if ((!endtag) || (*endtag != '='))
           {
              foundflag = 0;
              return -1;
           }
-
         firstindex = abs(oldstring - curlocater);
-        firstindex += strlen(key) + 1; // strlen("key") + strlen("=")
-        *value = (char *)(oldstring + firstindex);
-
+        firstindex += key_len + 1; // strlen("key") + strlen("=")
+        *value = (char *)oldstring + firstindex;
+        
         while (oldstring != starttag)
           {
              if (*starttag == '>')
@@ -198,89 +185,84 @@ _get_value_in_key_string(const char *oldstring,
                   foundflag = 0;
                   break;
                }
-             if (*starttag == '<')
+             if (*starttag == '<') 
                break;
-             else
+             else 
                starttag--;
-             if (starttag == NULL) break;
+             if (!starttag) break;
           }
-
-        while (NULL != endtag)
+        
+        while (endtag)
           {
              if (*endtag == '<')
                {
                   foundflag = 0;
                   break;
                }
-             if (*endtag == '>')
+             if (*endtag == '>') 
                break;
-             else
+             else 
                endtag++;
-             if (endtag == NULL) break;
+             if (!endtag) break;
           }
-
-        if (foundflag != 0 && *starttag == '<' && *endtag == '>')
+        
+        if ((foundflag) && (*starttag == '<') && (*endtag == '>'))
           foundflag = 1;
-        else
+        else 
           foundflag = 0;
      }
    else
      {
         foundflag = 0;
      }
-
+   
    if (foundflag == 1) return 0;
-
+   
    return -1;
 }
 
+
 static int
-_strbuf_key_value_replace(Eina_Strbuf *srcbuf,
-                          char        *key,
-                          const char  *value,
-                          int          deleteflag)
+_strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, const char *value, int deleteflag)
 {
    const char *srcstring = NULL;
    Eina_Strbuf *repbuf = NULL, *diffbuf = NULL;
    char *curlocater, *replocater;
    char *starttag, *endtag;
    int tagtxtlen = 0, insertflag = 0;
-
+   
    srcstring = eina_strbuf_string_get(srcbuf);
    curlocater = strstr(srcstring, key);
-
-   if (curlocater == NULL)
-     {
-        insertflag = 1;
-     }
+   
+   if (!curlocater)
+     insertflag = 1;
    else
      {
-        do
+        int key_len = strlen(key);
+        do 
           {
              starttag = strchr(srcstring, '<');
              endtag = strchr(srcstring, '>');
              tagtxtlen = endtag - starttag;
              if (tagtxtlen <= 0) tagtxtlen = 0;
-             if (starttag < curlocater && curlocater < endtag) break;
-             if (endtag != NULL && endtag + 1 != NULL)
+             if ((starttag < curlocater) && (curlocater < endtag)) break;
+             if ((endtag) && ((endtag + 1)))
                srcstring = endtag + 1;
              else
                break;
           } while (strlen(srcstring) > 1);
-
-        if (starttag && endtag && tagtxtlen > strlen(key))
+        
+        if ((starttag) && (endtag) && (tagtxtlen > key_len))
           {
              repbuf = eina_strbuf_new();
              diffbuf = eina_strbuf_new();
              eina_strbuf_append_n(repbuf, starttag, tagtxtlen);
              srcstring = eina_strbuf_string_get(repbuf);
              curlocater = strstr(srcstring, key);
-
-             if (curlocater != NULL)
+             if (curlocater)
                {
-                  replocater = curlocater + strlen(key) + 1;
-
-                  while (*replocater == ' ' || *replocater == '=')
+                  replocater = curlocater + key_len + 1;
+                  while ((*replocater != '=') && (replocater))
                     replocater++;
 
                   while (*replocater && *replocater != ' ' && *replocater != '>')
@@ -289,26 +271,23 @@ _strbuf_key_value_replace(Eina_Strbuf *srcbuf,
                   if (replocater - curlocater > strlen(key) + 1)
                     {
                        replocater--;
-                       eina_strbuf_append_n(diffbuf, curlocater, replocater - curlocater + 1);
+                       eina_strbuf_append_n(diffbuf, curlocater, 
+                                            replocater-curlocater);
                     }
                   else
                     insertflag = 1;
                }
              else
-               {
-                  insertflag = 1;
-               }
+               insertflag = 1;
              eina_strbuf_reset(repbuf);
           }
         else
-          {
-             insertflag = 1;
-          }
+          insertflag = 1; 
      }
-
-   if (repbuf == NULL) repbuf = eina_strbuf_new();
-   if (diffbuf == NULL) diffbuf = eina_strbuf_new();
-
+   
+   if (!repbuf) repbuf = eina_strbuf_new();
+   if (!diffbuf) diffbuf = eina_strbuf_new();
+   
    if (insertflag)
      {
         eina_strbuf_append_printf(repbuf, "<%s=%s>", key, value);
@@ -331,18 +310,15 @@ _strbuf_key_value_replace(Eina_Strbuf *srcbuf,
 
    if (repbuf) eina_strbuf_free(repbuf);
    if (diffbuf) eina_strbuf_free(diffbuf);
-
-   return 0;
+  
+   return 0;           
 }
 
 static int
-_stringshare_key_value_replace(const char **srcstring,
-                               char        *key,
-                               const char  *value,
-                               int          deleteflag)
+_stringshare_key_value_replace(const char **srcstring, const char *key, const char *value, int deleteflag)
 {
-   Eina_Strbuf *sharebuf = NULL;
-
+   Eina_Strbuf *sharebuf = NULL;   
+   
    sharebuf = eina_strbuf_new();
    eina_strbuf_append(sharebuf, *srcstring);
    _strbuf_key_value_replace(sharebuf, key, value, deleteflag);
@@ -353,212 +329,28 @@ _stringshare_key_value_replace(const char **srcstring,
    return 0;
 }
 
-// FIXME: move to some where(such as elm_util??).
-//        copied from elm_entry for check pure text length w/o tags.
-static char *
-_str_append(char       *str,
-            const char *txt,
-            int        *len,
-            int        *alloc)
-{
-   int txt_len = strlen(txt);
-
-   if (txt_len <= 0) return str;
-   if ((*len + txt_len) >= *alloc)
-     {
-        char *str2;
-        int alloc2;
-
-        alloc2 = *alloc + txt_len + 128;
-        str2 = realloc(str, alloc2);
-        if (!str2) return str;
-        *alloc = alloc2;
-        str = str2;
-     }
-   strcpy(str + *len, txt);
-   *len += txt_len;
-   return str;
-}
-
-// FIXME: move to some where(such as elm_util??).
-//        copied from elm_entry for check pure text length w/o tags.
-static char *
-_strncpy(char       *dest,
-         const char *src,
-         size_t      count)
-{
-   if (!dest)
-     {
-        ERR("dest is NULL");
-        return NULL;
-     }
-   if (!src)
-     {
-        ERR("src is NULL");
-        return NULL;
-     }
-   if (count < 0)
-     {
-        ERR("count is smaller than 0");
-        return NULL;
-     }
-
-   return strncpy(dest, src, count);
-}
-
-// FIXME: move to some where(such as elm_util??).
-//        copied from elm_entry for check pure text length w/o tags.
-static char *
-_mkup_to_text(const char *mkup)
-{
-   char *str = NULL;
-   int str_len = 0, str_alloc = 0;
-   char *s, *p;
-   char *tag_start, *tag_end, *esc_start, *esc_end, *ts;
-
-   if (!mkup) return NULL;
-   s = p = NULL;
-   tag_start = tag_end = esc_start = esc_end = NULL;
-   p = (char *)mkup;
-   s = p;
-   for (;; )
-     {
-        if (((p != NULL) && (*p == 0)) ||
-            (tag_end) || (esc_end) ||
-            (tag_start) || (esc_start))
-          {
-             if (tag_end)
-               {
-                  char *ttag;
-
-                  ttag = malloc(tag_end - tag_start);
-                  if (ttag)
-                    {
-                       _strncpy(ttag, tag_start + 1, tag_end - tag_start - 1);
-                       ttag[tag_end - tag_start - 1] = 0;
-                       if (!strcmp(ttag, "br"))
-                         str = _str_append(str, "\n", &str_len, &str_alloc);
-                       else if (!strcmp(ttag, "\n"))
-                         str = _str_append(str, "\n", &str_len, &str_alloc);
-                       else if (!strcmp(ttag, "\\n"))
-                         str = _str_append(str, "\n", &str_len, &str_alloc);
-                       else if (!strcmp(ttag, "\t"))
-                         str = _str_append(str, "\t", &str_len, &str_alloc);
-                       else if (!strcmp(ttag, "\\t"))
-                         str = _str_append(str, "\t", &str_len, &str_alloc);
-                       else if (!strcmp(ttag, "ps")) /* Unicode paragraph separator */
-                         str = _str_append(str, "\xE2\x80\xA9", &str_len, &str_alloc);
-                       free(ttag);
-                    }
-                  tag_start = tag_end = NULL;
-               }
-             else if (esc_end)
-               {
-                  ts = malloc(esc_end - esc_start + 1);
-                  if (ts)
-                    {
-                       const char *esc;
-                       _strncpy(ts, esc_start, esc_end - esc_start);
-                       ts[esc_end - esc_start] = 0;
-                       esc = evas_textblock_escape_string_get(ts);
-                       if (esc)
-                         str = _str_append(str, esc, &str_len, &str_alloc);
-                       free(ts);
-                    }
-                  esc_start = esc_end = NULL;
-               }
-             else if ((p != NULL) && (*p == 0))
-               {
-                  ts = malloc(p - s + 1);
-                  if (ts)
-                    {
-                       _strncpy(ts, s, p - s);
-                       ts[p - s] = 0;
-                       str = _str_append(str, ts, &str_len, &str_alloc);
-                       free(ts);
-                    }
-                  break;
-               }
-          }
-        if ((p != NULL) && (*p == '<'))
-          {
-             if (!esc_start)
-               {
-                  tag_start = p;
-                  tag_end = NULL;
-                  ts = malloc(p - s + 1);
-                  if (ts)
-                    {
-                       _strncpy(ts, s, p - s);
-                       ts[p - s] = 0;
-                       str = _str_append(str, ts, &str_len, &str_alloc);
-                       free(ts);
-                    }
-                  s = NULL;
-               }
-          }
-        else if ((p != NULL) && (*p == '>'))
-          {
-             if (tag_start)
-               {
-                  tag_end = p;
-                  s = p + 1;
-               }
-          }
-        else if ((p != NULL) && (*p == '&'))
-          {
-             if (!tag_start)
-               {
-                  esc_start = p;
-                  esc_end = NULL;
-                  ts = malloc(p - s + 1);
-                  if (ts)
-                    {
-                       _strncpy(ts, s, p - s);
-                       ts[p - s] = 0;
-                       str = _str_append(str, ts, &str_len, &str_alloc);
-                       free(ts);
-                    }
-                  s = NULL;
-               }
-          }
-        else if ((p != NULL) && (*p == ';'))
-          {
-             if (esc_start)
-               {
-                  esc_end = p;
-                  s = p + 1;
-               }
-          }
-        p++;
-     }
-   return str;
-}
-
 static int
-_is_width_over(Evas_Object *obj,
-               int          linemode)
+_is_width_over(Evas_Object *obj, Eina_Bool multiline)
 {
    Evas_Coord x, y, w, h;
    Evas_Coord vx, vy, vw, vh;
    Widget_Data *wd = elm_widget_data_get(obj);
-   const char *ellipsis_string = "...";
-   size_t ellen = strlen(ellipsis_string) + 1;
-
    if (!wd) return 0;
-
-   // too short to ellipsis
-   char *plaintxt = _mkup_to_text(edje_object_part_text_get(wd->lbl, "elm.text"));
+   const char *ellipsis_string = "...";
+   int mincount = sizeof(ellipsis_string) - 1;
+   char *plaintxt;
    int plainlen = 0;
-   if (plaintxt != NULL)
+
+   plaintxt = _elm_util_mkup_to_text(edje_object_part_text_get(wd->lbl, "elm.text"));
+   if (plaintxt)
      {
         plainlen = strlen(plaintxt);
         free(plaintxt);
      }
-   if (plainlen <= ellen) return 0;
+   // too short to ellipsis
+   if (plainlen <= mincount) return 0;
 
    edje_object_part_geometry_get(wd->lbl, "elm.text", &x, &y, &w, &h);
-
    evas_object_geometry_get(obj, &vx, &vy, &vw, &vh);
 
 /*
@@ -572,44 +364,35 @@ _is_width_over(Evas_Object *obj,
    fprintf(stderr, "## check str = %s\n", edje_object_part_text_get(wd->lbl, "elm.text"));
  */
 
-   if (linemode == 0) // single line
+   if (!multiline) // single line
      {
         // skip if too early to check widget size
-          if (w < 0 && h < 0)
-            return 0;
-          // if string fits at widget
-          if ((x >= 0) && (y >= 0))
-            {
-               if ((wd->wrap_w > 0) && (wd->wrap_w < w))
-                 {
-                    Evas_Coord minw, minh;
-                    edje_object_size_min_calc(wd->lbl, &minw, &minh);
-
-                    if (minw < wd->wrap_w) // min insufficient
-                      {
-                         return 0;
-                      }
-                    else
-                      return 1;
-                 }
-               else
-                 return 0;
-            }
-
-          if (0 < wd->wrap_w && w > wd->wrap_w) return 1;
+        if ((w < 0) && (h < 0)) return 0;
+        // if string fits at widget
+        if ((x >= 0) && (y >= 0))
+          {
+             if ((wd->wrap_w > 0) && (wd->wrap_w < w))
+               {
+                  Evas_Coord minw, minh;
+                  
+                  edje_object_size_min_calc(wd->lbl, &minw, &minh);
+                  if (minw < wd->wrap_w) return 0; // min insufficient
+                  else return 1;
+               }
+             else return 0;
+          }
+        if ((0 < wd->wrap_w) && (w > wd->wrap_w)) return 1;
      }
    else // multiline
      {
-//       if (vy > h && h > wd->wrap_h) return 1;
-          if ((x >= 0 || y >= 0) && h > wd->wrap_h) return 1;
+        if (((x >= 0) || (y >= 0)) && (h > wd->wrap_h)) return 1;
      }
-
+   
    return 0;
 }
 
 static void
-_ellipsis_fontsize_set(Evas_Object *obj,
-                       int          fontsize)
+_ellipsis_fontsize_set(Evas_Object *obj, int fontsize)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
@@ -627,15 +410,12 @@ _ellipsis_fontsize_set(Evas_Object *obj,
 }
 
 static Eina_Bool
-_ellipsis_cut_chars_to_widget(Evas_Object *obj,
-                              int          fontsize,
-                              int          linemode)
+_ellipsis_cut_chars_to_widget(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return EINA_FALSE;
-
    const char *ellipsis_string = "...";
-   int minshowcount = strlen(ellipsis_string);
+   int mincount = sizeof(ellipsis_string) - 1; 
    Evas_Coord w, h;
    Evas_Textblock_Cursor *tc1, *tc2;
    char *cutstr, *elstr;
@@ -644,70 +424,61 @@ _ellipsis_cut_chars_to_widget(Evas_Object *obj,
    int i = 0;
 
    edje_object_part_geometry_get(wd->lbl, "elm.text", NULL, NULL, &w, &h);
-   if (w <= 0)
-     return EINA_FALSE;
+   if (w <= 0) return EINA_FALSE;
    tc1 = evas_object_textblock_cursor_new((Evas_Object *)edje_object_part_object_get(wd->lbl, "elm.text"));
    tc2 = evas_object_textblock_cursor_new((Evas_Object *)edje_object_part_object_get(wd->lbl, "elm.text"));
 
-   if (wd->wrap_w > 0 && wd->wrap_w < w)
-     limitw = wd->wrap_w;
-   else
-     limitw = w;
+   if ((wd->wrap_w > 0) && (wd->wrap_w < w)) limitw = wd->wrap_w;
+   else limitw = w;
    evas_textblock_cursor_pos_set(tc1, 0);
    evas_textblock_cursor_char_coord_set(tc2, limitw, 0);
 
    // if too small to cut,(is it bug? or any other reasons?)
    // then fallback to one step mode
-   if (evas_textblock_cursor_pos_get(tc2) < minshowcount)
+   if (evas_textblock_cursor_pos_get(tc2) < mincount)
      {
-        int eolpos = evas_textblock_cursor_paragraph_text_length_get(tc1);
         Evas_Coord cx, cy, cw, ch;
-        for (i = eolpos; i > minshowcount; i--)
+        int eolpos = evas_textblock_cursor_paragraph_text_length_get(tc1);
+        
+        for (i = eolpos; i > mincount; i--)
           {
              evas_textblock_cursor_pos_set(tc2, i);
              evas_textblock_cursor_char_geometry_get(tc2, &cx, &cy, &cw, &ch);
-             if (cx <= limitw)
-               break;
+             if (cx <= limitw) break;
           }
 
-        if (evas_textblock_cursor_pos_get(tc2) < minshowcount)
+        if (evas_textblock_cursor_pos_get(tc2) < mincount)
           {
              evas_textblock_cursor_free(tc1);
              evas_textblock_cursor_free(tc2);
-
              return EINA_FALSE;
           }
      }
 
-   for (i = 0; i <= minshowcount; i++)
-     evas_textblock_cursor_char_prev(tc2);
+   for (i = 0; i <= mincount; i++) evas_textblock_cursor_char_prev(tc2);
    cutstr = evas_textblock_cursor_range_text_get(tc1, tc2, EVAS_TEXTBLOCK_TEXT_PLAIN);
-
-   // FIXME: consider other unicode encoding, currently only care about utf-8
+   if (!cutstr) return EINA_FALSE;
+   
    lencutstr = strlen(cutstr);
-   elstr = malloc(sizeof(char) * (lencutstr + minshowcount + 1));
+   elstr = alloca(sizeof(char) * (lencutstr + mincount + 1));
    strcpy(elstr, cutstr);
+   free(cutstr);
    strcat(elstr, ellipsis_string);
-
    edje_object_part_text_set(wd->lbl, "elm.text", elstr);
 
-   free(elstr);
    evas_textblock_cursor_free(tc1);
    evas_textblock_cursor_free(tc2);
-
+   
    return EINA_TRUE;
 }
 
 static Eina_Bool
-_ellipsis_cut_lines_to_widget(Evas_Object *obj,
-                              int          fontsize,
-                              int          linemode)
+_ellipsis_cut_lines_to_widget(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return EINA_FALSE;
-
    const char *ellipsis_string = "...";
-   int minshowcount = strlen(ellipsis_string);
+   int mincount = sizeof(ellipsis_string) - 1; 
    Evas_Coord w, h;
    Evas_Textblock_Cursor *tc1, *tc2;
    int linenum = 0, cutline = 0;
@@ -722,36 +493,31 @@ _ellipsis_cut_lines_to_widget(Evas_Object *obj,
    tc1 = evas_object_textblock_cursor_new((Evas_Object *)edje_object_part_object_get(wd->lbl, "elm.text"));
    tc2 = evas_object_textblock_cursor_new((Evas_Object *)edje_object_part_object_get(wd->lbl, "elm.text"));
    // goto last paragraph
-   while (evas_textblock_cursor_paragraph_next(tc2) == EINA_TRUE)
-     ;
+   while (evas_textblock_cursor_paragraph_next(tc2) == EINA_TRUE);
+   
    evas_textblock_cursor_paragraph_last(tc2);
    // get total linenumber
    linenum = evas_textblock_cursor_line_geometry_get(tc2, NULL, NULL, NULL, NULL);
-   lineheight = h / linenum * 1.0;
-   if (wd->wrap_h > 0 && wd->wrap_h < h)
-     limith = wd->wrap_h;
-   else
-     limith = h;
+   lineheight = (double)h / (double)linenum;
+   if ((wd->wrap_h > 0) && (wd->wrap_h < h)) limith = wd->wrap_h;
+   else limith = h;
    cutline = limith / lineheight;
-   if (cutline < 1)
-     cutline = 1;
-
+   if (cutline < 1) cutline = 1;
+   
    evas_textblock_cursor_pos_set(tc1, 0);
    evas_textblock_cursor_line_set(tc2, cutline - 1);
    evas_textblock_cursor_line_char_last(tc2);
-   for (i = 0; i <= minshowcount; i++)
-     evas_textblock_cursor_char_prev(tc2);
+   for (i = 0; i <= mincount; i++) evas_textblock_cursor_char_prev(tc2);
    cutstr = evas_textblock_cursor_range_text_get(tc1, tc2, EVAS_TEXTBLOCK_TEXT_PLAIN);
-
-   // FIXME: consider other unicode encoding, currently only care about utf-8
+   if (!cutstr) return EINA_FALSE;
+   
    lencutstr = strlen(cutstr);
-   elstr = malloc(sizeof(char) * (lencutstr + minshowcount + 1));
+   elstr = alloca(sizeof(char) * (lencutstr + mincount + 1));
    strcpy(elstr, cutstr);
+   free(cutstr);
    strcat(elstr, ellipsis_string);
-
    edje_object_part_text_set(wd->lbl, "elm.text", elstr);
 
-   free(elstr);
    evas_textblock_cursor_free(tc1);
    evas_textblock_cursor_free(tc2);
 
@@ -759,12 +525,10 @@ _ellipsis_cut_lines_to_widget(Evas_Object *obj,
 }
 
 static void
-_ellipsis_label_to_width(Evas_Object *obj,
-                         int          linemode)
+_ellipsis_label_to_width(Evas_Object *obj, Eina_Bool multiline)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-
    int cur_fontsize = 0;
    char *kvalue;
    const char *minfont, *deffont, *maxfont;
@@ -781,31 +545,30 @@ _ellipsis_label_to_width(Evas_Object *obj,
    else cur_fontsize = 1;
    if (minfontsize > maxfontsize || cur_fontsize == 1) return;  // theme is not ready for ellipsis
    if (eina_stringshare_strlen(wd->label) <= 0) return;
-
+   
    if (_get_value_in_key_string(wd->label, "font_size", &kvalue) == 0)
      {
         if (kvalue != NULL) cur_fontsize = atoi(kvalue);
      }
-
-   while (_is_width_over(obj, linemode))
+   
+   while (_is_width_over(obj, multiline))
      {
         if (cur_fontsize > minfontsize)
           {
              cur_fontsize -= 3;
-             if (cur_fontsize < minfontsize)
-               cur_fontsize = minfontsize;
+             if (cur_fontsize < minfontsize) cur_fontsize = minfontsize;
              _ellipsis_fontsize_set(obj, cur_fontsize);
           }
         else
           {
-             if (linemode == 0) // single line
+             if (!multiline) // single line
                {
-                  _ellipsis_cut_chars_to_widget(obj, cur_fontsize, linemode);
+                  _ellipsis_cut_chars_to_widget(obj);
                   break;
                }
              else // multiline
                {
-                  _ellipsis_cut_lines_to_widget(obj, cur_fontsize, linemode);
+                  _ellipsis_cut_lines_to_widget(obj);
                   break;
                }
           }
@@ -832,48 +595,48 @@ _label_state_change(Evas_Object *obj)
      }
 }
 
-void
+static void
 _label_sliding_change(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-
+   char *plaintxt;
+   int plainlen = 0;
+   
+   // dosen't support multiline sliding effect
    if (wd->linewrap)
-     {
+     { 
         wd->slidingmode = EINA_FALSE;
-        fprintf(stderr, "ERR: elm_label dosen't support multiline sliding effect!!!\n");
-        fprintf(stderr, "ERR: elm_label dosen't support multiline sliding effect!!!\n");
-        fprintf(stderr, "ERR: elm_label dosen't support multiline sliding effect!!!\n");
         return;
      }
 
-   char *plaintxt = _mkup_to_text(edje_object_part_text_get(wd->lbl, "elm.text"));
-   int plainlen = 0;
+   plaintxt = _elm_util_mkup_to_text(edje_object_part_text_get(wd->lbl, "elm.text"));
    if (plaintxt != NULL)
      {
         plainlen = strlen(plaintxt);
         free(plaintxt);
      }
+   // too short to slide label
    if (plainlen < 1)
      {
         wd->slidingmode = EINA_TRUE;
-        fprintf(stderr, "ERR: too short to slide label!!!\n");
         return;
      }
 
    if (wd->slidingmode)
      {
+        Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
+        
         if (wd->ellipsis)
           {
              wd->slidingellipsis = EINA_TRUE;
              elm_label_ellipsis_set(obj, EINA_FALSE);
           }
-        Edje_Message_Int_Set *msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
-
+        
         msg->count = 1;
-        msg->val[0] = (int)wd->slide_duration;
+        msg->val[0] = wd->slide_duration;
 
-        edje_object_message_send(wd->lbl, EDJE_MESSAGE_INT_SET, 0, msg);
+        edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_SET, 0, msg);
         edje_object_signal_emit(wd->lbl, "elm,state,slide,start", "elm");
      }
    else
@@ -902,8 +665,12 @@ elm_label_add(Evas_Object *parent)
    Evas *e;
    Widget_Data *wd;
 
+   EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
+
    wd = ELM_NEW(Widget_Data);
    e = evas_object_evas_get(parent);
+   if (!e) return NULL;
+   wd->bgcolor = EINA_FALSE;
    wd->bg = evas_object_rectangle_add(e);
    evas_object_color_set(wd->bg, 0, 0, 0, 0);
    obj = elm_widget_add(e);
@@ -913,10 +680,9 @@ elm_label_add(Evas_Object *parent)
    elm_widget_data_set(obj, wd);
    elm_widget_del_hook_set(obj, _del_hook);
    elm_widget_theme_hook_set(obj, _theme_hook);
-   elm_widget_can_focus_set(obj, 0);
+   elm_widget_can_focus_set(obj, EINA_FALSE);
 
    wd->linewrap = EINA_FALSE;
-   wd->bgcolor = EINA_FALSE;
    wd->ellipsis = EINA_FALSE;
    wd->wrapmode = EINA_FALSE;
    wd->slidingmode = EINA_FALSE;
@@ -930,9 +696,9 @@ elm_label_add(Evas_Object *parent)
    wd->label = eina_stringshare_add("<br>");
    edje_object_part_text_set(wd->lbl, "elm.text", "<br>");
    elm_widget_resize_object_set(obj, wd->lbl);
-
+   
    evas_object_event_callback_add(wd->lbl, EVAS_CALLBACK_RESIZE, _resize, obj);
-
+   
    wd->changed = 1;
    _sizing_eval(obj);
    return obj;
@@ -947,8 +713,7 @@ elm_label_add(Evas_Object *parent)
  * @ingroup Label
  */
 EAPI void
-elm_label_label_set(Evas_Object *obj,
-                    const char  *label)
+elm_label_label_set(Evas_Object *obj, const char *label)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -984,8 +749,7 @@ elm_label_label_get(const Evas_Object *obj)
  * @ingroup Label
  */
 EAPI void
-elm_label_line_wrap_set(Evas_Object *obj,
-                        Eina_Bool    wrap)
+elm_label_line_wrap_set(Evas_Object *obj, Eina_Bool wrap)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -1025,8 +789,7 @@ elm_label_line_wrap_get(const Evas_Object *obj)
  * @ingroup Label
  */
 EAPI void
-elm_label_wrap_width_set(Evas_Object *obj,
-                         Evas_Coord   w)
+elm_label_wrap_width_set(Evas_Object *obj, Evas_Coord w)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -1092,7 +855,11 @@ elm_label_wrap_height_get(const Evas_Object *obj)
 }
 
 /**
- * Set the font size on the label object
+ * Set the font size on the label object.
+ * 
+ * NEVER use this. It is for hyper-special cases only. use styles instead. e.g.
+ * "big", "medium", "small" - or better name them by use:
+ * "title", "footnote", "quote" etc.
  *
  * @param obj The label object
  * @param size font size
@@ -1100,8 +867,7 @@ elm_label_wrap_height_get(const Evas_Object *obj)
  * @ingroup Label
  */
 EAPI void
-elm_label_fontsize_set(Evas_Object *obj,
-                       int          fontsize)
+elm_label_fontsize_set(Evas_Object *obj, int fontsize)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -1109,6 +875,7 @@ elm_label_fontsize_set(Evas_Object *obj,
    int len, removeflag = 0;
 
    if (!wd) return;
+   _elm_dangerous_call_check(__FUNCTION__);
    len = strlen(wd->label);
    if (len <= 0) return;
    fontbuf = eina_strbuf_new();
@@ -1128,20 +895,24 @@ elm_label_fontsize_set(Evas_Object *obj,
 /**
  * Set the text align on the label object
  *
+ * NEVER use this. It is for hyper-special cases only. use styles instead. e.g.
+ * "big", "medium", "small" - or better name them by use:
+ * "title", "footnote", "quote" etc.
+ *
  * @param obj The label object
  * @param align align mode ("left", "center", "right")
  *
  * @ingroup Label
  */
 EAPI void
-elm_label_text_align_set(Evas_Object *obj,
-                         const char  *alignmode)
+elm_label_text_align_set(Evas_Object *obj, const char *alignmode)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    int len;
 
    if (!wd) return;
+   _elm_dangerous_call_check(__FUNCTION__);
    len = strlen(wd->label);
    if (len <= 0) return;
 
@@ -1176,6 +947,7 @@ elm_label_text_color_set(Evas_Object *obj,
    int len;
 
    if (!wd) return;
+   _elm_dangerous_call_check(__FUNCTION__);
    len = strlen(wd->label);
    if (len <= 0) return;
    colorbuf = eina_strbuf_new();
@@ -1193,11 +965,16 @@ elm_label_text_color_set(Evas_Object *obj,
 /**
  * Set background color of the label
  *
+ * NEVER use this. It is for hyper-special cases only. use styles instead. e.g.
+ * "big", "medium", "small" - or better name them by use:
+ * "title", "footnote", "quote" etc.
+ *
  * @param obj The label object
- * @param r Red property background color of The label object
- * @param g Green property background color of The label object
- * @param b Blue property background color of The label object
- * @param a Alpha property background color of The label object
+ * @param r Red property background color of The label object 
+ * @param g Green property background color of The label object 
+ * @param b Blue property background color of The label object 
+ * @param a Alpha property background alpha of The label object 
+ *
  * @ingroup Label
  */
 EAPI void
@@ -1212,6 +989,8 @@ elm_label_background_color_set(Evas_Object *obj,
    if (!wd) return;
    evas_object_color_set(wd->bg, r, g, b, a);
 
+   if (!wd) return;
+   _elm_dangerous_call_check(__FUNCTION__);
    if (wd->bgcolor == EINA_FALSE)
      {
         wd->bgcolor = 1;
@@ -1227,8 +1006,7 @@ elm_label_background_color_set(Evas_Object *obj,
  * @ingroup Label
  */
 EAPI void
-elm_label_ellipsis_set(Evas_Object *obj,
-                       Eina_Bool    ellipsis)
+elm_label_ellipsis_set(Evas_Object *obj, Eina_Bool ellipsis)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -1297,7 +1075,6 @@ elm_label_slide_get(Evas_Object *obj)
    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return EINA_FALSE;
-
    return wd->slidingmode;
 }
 
@@ -1309,20 +1086,17 @@ elm_label_slide_get(Evas_Object *obj)
  * @ingroup Label
  */
 EAPI void
-elm_label_slide_duration_set(Evas_Object *obj,
-                             int          duration)
+elm_label_slide_duration_set(Evas_Object *obj, double duration)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
-   Edje_Message_Int_Set *msg = alloca(sizeof(Edje_Message_Int_Set) + (sizeof(int)));
+   Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
 
    if (!wd) return;
    wd->slide_duration = duration;
-
    msg->count = 1;
-   msg->val[0] = (int)wd->slide_duration;
-
-   edje_object_message_send(wd->lbl, EDJE_MESSAGE_INT_SET, 0, msg);
+   msg->val[0] = wd->slide_duration;
+   edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_SET, 0, msg);
 }
 
 /**
@@ -1332,10 +1106,10 @@ elm_label_slide_duration_set(Evas_Object *obj,
  * @return The duration time in moving text from slide begin position to slide end position
  * @ingroup Label
  */
-EAPI int
+EAPI double
 elm_label_slide_duration_get(Evas_Object *obj)
 {
-   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return 0;
    return wd->slide_duration;