cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=a821eb456a8c89943f306286669093e2a43aa1f1
commit a821eb456a8c89943f306286669093e2a43aa1f1 Author: ali <ali198...@gmail.com> Date: Thu Aug 1 23:00:07 2019 +0000 evas_common: parse color in rgb()/rgba() format evas_common_format_color_parse: support rgb()/rgba() format efl user can now specify colors in text formats and styles as rgb(0-255,0-255,0-255) & rgba(0-255,0-255,0-255,0-255) format. This is related to task: T8068 Reviewed-by: Cedric BAIL <cedric.b...@free.fr> Differential Revision: https://phab.enlightenment.org/D9309 --- src/bin/elementary/test_label.c | 2 + src/lib/evas/canvas/evas_object_textblock.c | 20 ++++++ src/lib/evas/common/evas_text_utils.c | 98 ++++++++++++++++++++++++----- 3 files changed, 104 insertions(+), 16 deletions(-) diff --git a/src/bin/elementary/test_label.c b/src/bin/elementary/test_label.c index c00ae7986e..233ce015b4 100644 --- a/src/bin/elementary/test_label.c +++ b/src/bin/elementary/test_label.c @@ -393,6 +393,8 @@ test_label_colors(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *ev elm_object_text_set(lb, "<color=red>this is red color line(color = red)<color><br>" "<color=#0000FF>this is blue color line (color = #0000FF)<color><br>" + "<color=rgb(0,255,0)>this is green color line (color = rgb(0,255,0))<color><br>" + "<color=rgba(0,255,0,255)>this is blue color line (color = rgba(0,255,0,255))<color><br>" ); evas_object_size_hint_weight_set(lb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(win, lb); diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index 0ffcaf72e9..6299e3f195 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -1953,6 +1953,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * color=<color> @@ -1972,6 +1974,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * underline_color=<color> @@ -1992,6 +1996,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * underline2_color=<color> @@ -2011,6 +2017,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * underline_dash_color=<color> @@ -2031,6 +2039,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * outline_color=<color> @@ -2051,6 +2061,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * shadow_color=<color> @@ -2071,6 +2083,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * glow_color=<color> @@ -2091,6 +2105,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * glow2_color=<color> @@ -2111,6 +2127,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * backing_color=<color> @@ -2131,6 +2149,8 @@ _format_command(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const ch * @li "#RRGGBBAA" * @li "#RGB" * @li "#RGBA" + * @li "rgb(r,g,b)" + * @li "rgba(r,g,b,a)" * @li "color_name" like "red" * @code * strikethrough_color=<color> diff --git a/src/lib/evas/common/evas_text_utils.c b/src/lib/evas/common/evas_text_utils.c index b7cbe1b219..e9c5cc2c94 100644 --- a/src/lib/evas/common/evas_text_utils.c +++ b/src/lib/evas/common/evas_text_utils.c @@ -1299,7 +1299,7 @@ _hex_string_get(char ch, Eina_Bool *ok) * * @param source source buffer * @param dest destination buffer - * @param max maximum number of chars to be copyed + * @param max maximum number of chars to be copied * @return number of spaces removed */ @@ -1323,6 +1323,36 @@ size_t remove_spaces_lowercase(const char* source,char * dest,size_t max) return spaces; } +/** + * @internal + * read color component from string + * + * @param source source string + * @param[out] next position after the color compnent + * @param byte store color value read from string + * @return if read success + */ + +Eina_Bool read_byte_color_component(const char* source,char ** next,unsigned char * byte) +{ + const char *p_start = source; + char *p_stop = NULL; + Eina_Bool b_ret = EINA_TRUE; + long value = 0; + value = strtol(p_start, &p_stop, 10); + if ( value > 255 || value < 0 || p_start == p_stop ) + { + b_ret = EINA_FALSE; + } + + if (next) + *next = p_stop; + if (byte) + *byte = (unsigned char) value; + + return b_ret; +} + /** * @internal @@ -1332,12 +1362,11 @@ size_t remove_spaces_lowercase(const char* source,char * dest,size_t max) * 3. "#RGB" * 4. "#RGBA" * 5. "color names" + * 6. "rgb(r,g,b)" + * 7. "rgba(r,g,b,a)" * TODO (we may use specific color parser) - * 6. "rgb(RR,GG,BB)" - * 7. "rgba(RR,GG,BB,AA)" - * 8. "rgb(%R,%G,%B)" - * 9. "rgba(%R,%G,%B,%A)" - * 10."hsv(HH,SS,VV)" + * 8. "hsl(H,S,L)" + * 9. "hsla(H,S,L,A)" * To the rgba values. * * @param[in] str The string to parse - NOT NULL. @@ -1393,24 +1422,61 @@ evas_common_format_color_parse(const char *str, int slen, } else v = EINA_FALSE; } - else + else if (slen <= 21)/* search for rgb(),hsv(),colorname, 20 is length of rgba(255,255,255,255) */ { /*remove spaces and convert name to lowercase*/ char color_name[0xFF] = {0}; slen = slen - (int) remove_spaces_lowercase(str,color_name,0xFF); - static size_t color_array_length = sizeof(color_name_value_sorted)/sizeof(Color_Name_Value); - Color_Name_Value* pcolor = (Color_Name_Value*) bsearch(color_name, color_name_value_sorted, color_array_length, sizeof(Color_Name_Value),_color_name_search); - if (pcolor) + + if ((strncmp(color_name,"rgb(",4) == 0) && color_name[slen-1] == ')'&& slen >= 10 && slen <=16) /* rgb() */ { - *r = pcolor->r; - *g = pcolor->g; - *b = pcolor->b; - *a = 0xff; + char * p_color = &color_name[3]; + + if ( + (!read_byte_color_component(++p_color,&p_color,r) || !p_color || *p_color != ',') || + (!read_byte_color_component(++p_color,&p_color,g) || !p_color || *p_color != ',') || + (!read_byte_color_component(++p_color,&p_color,b) || !p_color || *p_color != ')') + ) + { + *r = *g = *b = *a = 0; + v = EINA_FALSE; + } + else + { + *a = 0xff; + } } - else + else if ((strncmp(color_name,"rgba(",4) == 0) && color_name[slen-1] == ')'&& slen >= 13 && slen <=21) /* rgba() */ { - v = EINA_FALSE; + char * p_color = &color_name[4]; + + if ( + (!read_byte_color_component(++p_color,&p_color,r) || !p_color || *p_color != ',') || + (!read_byte_color_component(++p_color,&p_color,g) || !p_color || *p_color != ',') || + (!read_byte_color_component(++p_color,&p_color,b) || !p_color || *p_color != ',') || + (!read_byte_color_component(++p_color,&p_color,a) || !p_color || *p_color != ')') + ) + { + *r = *g = *b = *a = 0; + v = EINA_FALSE; + } } + else + { + static size_t color_array_length = sizeof(color_name_value_sorted)/sizeof(Color_Name_Value); + Color_Name_Value* pcolor = (Color_Name_Value*) bsearch(color_name, color_name_value_sorted, color_array_length, sizeof(Color_Name_Value),_color_name_search); + if (pcolor) + { + *r = pcolor->r; + *g = pcolor->g; + *b = pcolor->b; + *a = 0xff; + } + else + { + v = EINA_FALSE; + } + } } if(*a != 0xFF) --