edje/style/optimization: keep the color value instead of color strings in style tags. 25/213025/2
authorsubhransu mohanty <sub.mohanty@samsung.com>
Thu, 29 Aug 2019 09:03:15 +0000 (18:03 +0900)
committerkim hosang <hosang12.kim@samsung.com>
Thu, 29 Aug 2019 09:27:10 +0000 (09:27 +0000)
During style_update we convert the string again back to integer and compute the final result
before converting back to string again. so just keep it as integer value for speedup.

Change-Id: I6aa986f3ab9318522a952d7763ef25bde0384fc7

src/lib/edje/edje_private.h
src/lib/edje/edje_textblock_styles.c

index 0bdb0f7..84e6cfe 100644 (file)
@@ -638,16 +638,19 @@ struct _Edje_Style_Tag
    const char                     *key;
    const char                     *value;
    const char                     *font;
+
    const char                     *text_class;
+   const char                     *color_class;
+
+
    double                          font_size;
 
    /***********************************************************************************
     * TIZEN_ONLY_FEATURE: apply Tizen's color_class features.                         *
     ***********************************************************************************/
-   const char                     *color_class;
-   const char                     *color;
-   const char                     *outline_color;
-   const char                     *shadow_color;
+   Edje_Color                     color;
+   Edje_Color                     outline_color;
+   Edje_Color                     shadow_color;
    /*******
     * END *
     *******/
index d48d785..c42d7ec 100644 (file)
  ***********************************************************************************/
 void _edje_textblock_style_update(Edje *ed, Edje_Style *stl);
 
-static int
-_hex_string_get(char ch)
+
+static unsigned char HEX_TABLE[128];
+static void
+_init_hex_table()
 {
-   if ((ch >= '0') && (ch <= '9')) return (ch - '0');
-   else if ((ch >= 'A') && (ch <= 'F')) return (ch - 'A' + 10);
-   else if ((ch >= 'a') && (ch <= 'f')) return (ch - 'a' + 10);
-   return 0;
+    HEX_TABLE['0'] = 0;
+    HEX_TABLE['1'] = 1;
+    HEX_TABLE['2'] = 2;
+    HEX_TABLE['3'] = 3;
+    HEX_TABLE['4'] = 4;
+    HEX_TABLE['5'] = 5;
+    HEX_TABLE['6'] = 6;
+    HEX_TABLE['7'] = 7;
+    HEX_TABLE['8'] = 8;
+    HEX_TABLE['9'] = 9;
+    HEX_TABLE['a'] = 10;
+    HEX_TABLE['A'] = 10;
+    HEX_TABLE['b'] = 11;
+    HEX_TABLE['B'] = 11;
+    HEX_TABLE['c'] = 12;
+    HEX_TABLE['C'] = 12;
+    HEX_TABLE['d'] = 13;
+    HEX_TABLE['D'] = 13;
+    HEX_TABLE['e'] = 14;
+    HEX_TABLE['E'] = 14;
+    HEX_TABLE['f'] = 15;
+    HEX_TABLE['F'] = 15;
 }
 
-/**
- * @internal
- * Calculate the color string according to the given RGBA color.
- * @detail It returns a multiplied color string.
- * Return string should be free'd manually.
- *
- * @param color The existing color string from Textblock style.
- * @param r     Red color
- * @param g     Green color
- * @param b     Blue color
- * @param a     Alpha value
- * @return multiplied color string. It should be free'd manually.
- */
-char *
-_edje_textblock_color_calc(const char *color, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+static inline uint8_t
+_hexhi(int ch)
+{
+   return (uint8_t)(HEX_TABLE[ch] << 4);
+}
+
+static inline uint8_t
+_hex(int ch)
 {
-   int cr, cg, cb, ca;
-   int nr, ng, nb, na;
-   int len;
-   char *ret;
+   return HEX_TABLE[ch];
+}
 
+static void
+_parse_color(const char *str, Edje_Color *out)
+{
+   static Eina_Bool init_table = EINA_TRUE;
+   if (init_table)
+     {
+        _init_hex_table();
+        init_table = EINA_FALSE;
+     }
+   uint8_t cr, cg, cb, ca;
    cr = cg = cb = ca = 0;
-   len = strlen(color);
+   size_t len = strlen(str);
 
    if (len == 7) /* #RRGGBB */
      {
-        cr = (_hex_string_get(color[1]) << 4) | (_hex_string_get(color[2]));
-        cg = (_hex_string_get(color[3]) << 4) | (_hex_string_get(color[4]));
-        cb = (_hex_string_get(color[5]) << 4) | (_hex_string_get(color[6]));
+        cr = _hexhi(str[1]) | _hex(str[2]);
+        cg = _hexhi(str[3]) | _hex(str[4]);
+        cb = _hexhi(str[5]) | _hex(str[6]);
         ca = 0xff;
      }
    else if (len == 9) /* #RRGGBBAA */
      {
-        cr = (_hex_string_get(color[1]) << 4) | (_hex_string_get(color[2]));
-        cg = (_hex_string_get(color[3]) << 4) | (_hex_string_get(color[4]));
-        cb = (_hex_string_get(color[5]) << 4) | (_hex_string_get(color[6]));
-        ca = (_hex_string_get(color[7]) << 4) | (_hex_string_get(color[8]));
+       cr = _hexhi(str[1]) | _hex(str[2]);
+       cg = _hexhi(str[3]) | _hex(str[4]);
+       cb = _hexhi(str[5]) | _hex(str[6]);
+       ca = _hexhi(str[7]) | _hex(str[8]);
      }
    else if (len == 4) /* #RGB */
      {
-        cr = _hex_string_get(color[1]);
-        cr = (cr << 4) | cr;
-        cg = _hex_string_get(color[2]);
-        cg = (cg << 4) | cg;
-        cb = _hex_string_get(color[3]);
-        cb = (cb << 4) | cb;
+        cr = _hexhi(str[1]) | _hex(str[1]);
+        cg = _hexhi(str[2]) | _hex(str[2]);
+        cb = _hexhi(str[3]) | _hex(str[3]);
         ca = 0xff;
      }
    else if (len == 5) /* #RGBA */
      {
-        cr = _hex_string_get(color[1]);
-        cr = (cr << 4) | cr;
-        cg = _hex_string_get(color[2]);
-        cg = (cg << 4) | cg;
-        cb = _hex_string_get(color[3]);
-        cb = (cb << 4) | cb;
-        ca = _hex_string_get(color[4]);
-        ca = (ca << 4) | ca;
+       cr = _hexhi(str[1]) | _hex(str[1]);
+       cg = _hexhi(str[2]) | _hex(str[2]);
+       cb = _hexhi(str[3]) | _hex(str[3]);
+       ca = _hexhi(str[4]) | _hex(str[4]);
      }
+   out->r = cr;
+   out->g = cg;
+   out->b = cb;
+   out->a = ca;
+}
 
-     nr = (((int)r + 1) * cr) >> 8;
-     ng = (((int)g + 1) * cg) >> 8;
-     nb = (((int)b + 1) * cb) >> 8;
-     na = (((int)a + 1) * ca) >> 8;
+/**
+ * @internal
+ * Calculate the color string according to the given RGBA color.
+ * @detail It returns a multiplied color string.
+ */
+Eina_Bool
+_edje_textblock_color_calc(Edje_Color *color, unsigned char r, unsigned char g, unsigned char b, unsigned char a, char *result)
+{
+   unsigned int nr, ng, nb, na;
+   nr = (((unsigned int)r + 1) * color->r) >> 8;
+   ng = (((unsigned int)g + 1) * color->g) >> 8;
+   nb = (((unsigned int)b + 1) * color->b) >> 8;
+   na = (((unsigned int)a + 1) * color->a) >> 8;
 
-     ret = malloc(10);
-     snprintf(ret, 10, "#%02x%02x%02x%02x", nr, ng, nb, na);
+   if (nr == color->r && ng == color->g && nb == color->b && na == color->a)
+       return EINA_FALSE;
 
-     return ret;
+   snprintf(result, 10, "#%02x%02x%02x%02x", nr, ng, nb, na);
+
+   return EINA_TRUE;
 }
 
 void _edje_textblock_style_all_update(Edje *ed)
@@ -290,7 +320,7 @@ _edje_format_parse(const char **s)
 }
 
 static void
-_edje_format_reparse(Edje_File *edf, const char *str, Edje_Style_Tag *tag_ret, Eina_Strbuf *result)
+_edje_format_reparse(Edje_File *edf, const char *str, Edje_Style_Tag *tag, Eina_Strbuf *result)
 {
    char *s2, *item;
    const char *s;
@@ -311,8 +341,7 @@ _edje_format_reparse(Edje_File *edf, const char *str, Edje_Style_Tag *tag_ret, E
                }
              else if ((key_len == 10) && !strncmp(key, "text_class", key_len))
                {
-                  if (tag_ret)
-                    tag_ret->text_class = eina_stringshare_add(val);
+                  tag->text_class = eina_stringshare_add(val);
 
                   // no need to add text_class tag to style
                   // as evas_textblock_style has no idea about
@@ -322,59 +351,43 @@ _edje_format_reparse(Edje_File *edf, const char *str, Edje_Style_Tag *tag_ret, E
                }
              else if ((key_len == 9) && !strncmp(key, "font_size", key_len))
                {
-                  if (tag_ret)
-                    tag_ret->font_size = atof(val);
+                  tag->font_size = atof(val);
                }
              else if ((key_len == 4) && !strncmp(key, "font", key_len)) /* Fix fonts */
                {
-                  if (tag_ret)
-                    {
-                       if (_edje_font_is_embedded(edf, val))
-                         {
-                            char buffer[120];
-                            snprintf(buffer, sizeof(buffer), "edje/fonts/%s", val);
-                            tag_ret->font = eina_stringshare_add(buffer);
-                         }
-                       else
-                         {
-                            tag_ret->font = eina_stringshare_add(val);
-                         }
-                    }
+                  if (_edje_font_is_embedded(edf, val))
+                   {
+                      char buffer[120];
+                      snprintf(buffer, sizeof(buffer), "edje/fonts/%s", val);
+                      tag->font = eina_stringshare_add(buffer);
+                   }
+                  else
+                   {
+                      tag->font = eina_stringshare_add(val);
+                   }
                }
              /***********************************************************************************
               * TIZEN_ONLY_FEATURE: apply Tizen's color_class features.                         *
               ***********************************************************************************/
              else if ((key_len == 11) && !strncmp(key, "color_class", key_len))
                {
-                  if (tag_ret)
-                    tag_ret->color_class = eina_stringshare_add(val);
+                  tag->color_class = eina_stringshare_add(val);
 
                   free(item);
                   continue;
                }
              else if ((key_len == 5) && !strncmp(key, "color", key_len))
                {
-                  if (tag_ret)
-                    tag_ret->color = eina_stringshare_add(val);
-
-                  free(item);
-                  continue;
+                  _parse_color(val, &(tag->color));
                }
              else if ((key_len == 13) && !strncmp(key, "outline_color", key_len))
                {
-                  if (tag_ret)
-                    tag_ret->outline_color = eina_stringshare_add(val);
-
-                  free(item);
-                  continue;
+                  _parse_color(val, &(tag->outline_color));
                }
              else if ((key_len == 12) && !strncmp(key, "shadow_color", key_len))
                {
-                  if (tag_ret)
-                    tag_ret->shadow_color = eina_stringshare_add(val);
+                  _parse_color(val, &(tag->shadow_color));
 
-                  free(item);
-                  continue;
                }
              /*******
               * END *
@@ -504,61 +517,35 @@ _edje_textblock_style_update(Edje *ed, Edje_Style *stl)
         /***********************************************************************************
          * TIZEN_ONLY_FEATURE: apply Tizen's color_class features.                         *
          ***********************************************************************************/
-        if (tag->color)
+        char color[11];
+        if (cc && tag->color.a)
           {
-             eina_strbuf_append(txt, " ");
-             eina_strbuf_append(txt, "color=");
-
-             if (cc)
+             Eina_Bool result = _edje_textblock_color_calc(&(tag->color),
+                                        cc->r, cc->g, cc->b, cc->a, color);
+             if (result)
                {
-                  char *color;
-
-                  color = _edje_textblock_color_calc(tag->color,
-                                                     cc->r, cc->g, cc->b, cc->a);
-                  eina_strbuf_append_escaped(txt, (const char *)color);
-                  if (color) free(color);
-               }
-             else
-               {
-                  eina_strbuf_append_escaped(txt, tag->color);
+                  eina_strbuf_append(txt, " color=");
+                  eina_strbuf_append(txt, color);
                }
           }
-        if (tag->outline_color)
+        if (cc && tag->outline_color.a)
           {
-             eina_strbuf_append(txt, " ");
-             eina_strbuf_append(txt, "outline_color=");
-
-             if (cc)
+             Eina_Bool result = _edje_textblock_color_calc(&(tag->outline_color),
+                                              cc->r2, cc->g2, cc->b2, cc->a2, color);
+             if (result)
                {
-                  char *color;
-
-                  color = _edje_textblock_color_calc(tag->outline_color,
-                                                     cc->r2, cc->g2, cc->b2, cc->a2);
-                  eina_strbuf_append_escaped(txt, (const char *)color);
-                  if (color) free(color);
-               }
-             else
-               {
-                  eina_strbuf_append_escaped(txt, tag->outline_color);
+                  eina_strbuf_append(txt, " outline_color=");
+                  eina_strbuf_append(txt, color);
                }
           }
-        if (tag->shadow_color)
+        if (cc && tag->shadow_color.a)
           {
-             eina_strbuf_append(txt, " ");
-             eina_strbuf_append(txt, "shadow_color=");
-
-             if (cc)
-               {
-                  char *color;
-
-                  color = _edje_textblock_color_calc(tag->shadow_color,
-                                                     cc->r3, cc->g3, cc->b3, cc->a3);
-                  eina_strbuf_append_escaped(txt, (const char *)color);
-                  if (color) free(color);
-               }
-             else
+             Eina_Bool result = _edje_textblock_color_calc(&(tag->shadow_color),
+                                        cc->r3, cc->g3, cc->b3, cc->a3, color);
+             if (result)
                {
-                  eina_strbuf_append_escaped(txt, tag->shadow_color);
+                  eina_strbuf_append(txt, " shadow_color=");
+                  eina_strbuf_append(txt, color);
                }
           }
         /*******
@@ -919,9 +906,6 @@ _edje_file_textblock_style_cleanup(Edje_File *edf)
                    * TIZEN_ONLY_FEATURE: apply Tizen's color_class features.                         *
                    ***********************************************************************************/
                   if (tag->color_class) eina_stringshare_del(tag->color_class);
-                  if (tag->color) eina_stringshare_del(tag->color);
-                  if (tag->outline_color) eina_stringshare_del(tag->outline_color);
-                  if (tag->shadow_color) eina_stringshare_del(tag->shadow_color);
                   /*******
                    * END *
                    *******/