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
This commit is contained in:
abdulleh Ghujeh 2019-11-28 13:14:15 +09:00 committed by WooHyun Jung
parent 2ca6c301e4
commit f6caca1d70
6 changed files with 647 additions and 63 deletions

View File

@ -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)
);

View File

@ -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 {

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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);
}