From 225c0f937a3a5c40aaf9cb39ba73bfa65dd32d64 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Thu, 28 May 2015 17:59:59 +0900 Subject: [PATCH] Evas filters: Pass edje state name & value to the filters From Edje, pass the current state info (name and value) as well as the next state and the transition position when applicable. --- src/lib/edje/edje_calc.c | 8 +-- src/lib/edje/edje_private.h | 2 +- src/lib/edje/edje_text.c | 36 +++++++++---- src/lib/evas/canvas/evas_object_image.c | 7 +-- src/lib/evas/canvas/evas_object_main.c | 2 +- src/lib/evas/canvas/evas_object_text.c | 62 +++++++++++++++++++++-- src/lib/evas/canvas/evas_text.eo | 17 +++++++ src/lib/evas/filters/evas_filter_parser.c | 41 ++++++++++++++- src/lib/evas/include/evas_filter.h | 2 +- src/lib/evas/include/evas_private.h | 11 ++++ 10 files changed, 162 insertions(+), 26 deletions(-) diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index 898e0dabeb..c1e7e1b618 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -1603,7 +1603,7 @@ _edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED, Edje_Part_Description_Text *chosen_desc, Edje_Calc_Params *params, int *minw, int *minh, - int *maxw, int *maxh) + int *maxw, int *maxh, double pos) #define RECALC_SINGLE_TEXT_USING_APPLY 1 #if RECALC_SINGLE_TEXT_USING_APPLY /* @@ -1634,7 +1634,7 @@ _edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED, free(sfont); params->type.text.size = size; /* XXX TODO used by further calcs, go inside recalc_apply? */ - _edje_text_recalc_apply(ed, ep, params, chosen_desc, EINA_TRUE); + _edje_text_recalc_apply(ed, ep, params, chosen_desc, EINA_TRUE, pos); if ((!chosen_desc) || ((!chosen_desc->text.min_x) && (!chosen_desc->text.min_y) && @@ -2564,7 +2564,7 @@ _edje_part_recalc_single(Edje *ed, if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) _edje_part_recalc_single_textblock(sc, ed, ep, (Edje_Part_Description_Text *)chosen_desc, params, &minw, &minh, &maxw, &maxh); else if (ep->part->type == EDJE_PART_TYPE_TEXT) - _edje_part_recalc_single_text(sc, ed, ep, (Edje_Part_Description_Text *)desc, (Edje_Part_Description_Text *)chosen_desc, params, &minw, &minh, &maxw, &maxh); + _edje_part_recalc_single_text(sc, ed, ep, (Edje_Part_Description_Text*) desc, (Edje_Part_Description_Text*) chosen_desc, params, &minw, &minh, &maxw, &maxh, pos); if ((ep->part->type == EDJE_PART_TYPE_TABLE) && (((((Edje_Part_Description_Table *)chosen_desc)->table.min.h) || @@ -4358,7 +4358,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta switch (ep->part->type) { case EDJE_PART_TYPE_TEXT: - _edje_text_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text *)chosen_desc, EINA_FALSE); + _edje_text_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc, EINA_FALSE, pos); break; case EDJE_PART_TYPE_PROXY: diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 44c8be785a..b5ac256d0c 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -2286,7 +2286,7 @@ void _edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *params, Edje_Part_Description_Text *chosen_desc, - Eina_Bool calc_only); + Eina_Bool calc_only, double state_val); Evas_Font_Size _edje_text_size_calc(Evas_Font_Size size, Edje_Text_Class *tc); const char * _edje_text_class_font_get(Edje *ed, Edje_Part_Description_Text *chosen_desc, diff --git a/src/lib/edje/edje_text.c b/src/lib/edje/edje_text.c index b91db6b42d..2edf614528 100644 --- a/src/lib/edje/edje_text.c +++ b/src/lib/edje/edje_text.c @@ -197,7 +197,7 @@ void _edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *params, Edje_Part_Description_Text *chosen_desc, - Eina_Bool calc_only) + Eina_Bool calc_only, double state_val) { const char *text = NULL; const char *font; @@ -529,16 +529,32 @@ arrange_text: part_get_geometry(ep, &tw, &th); /* filters */ - eo_do(ep->object, - EINA_LIST_FOREACH(prev_sources, li, source_name) - evas_obj_text_filter_source_set(source_name, NULL); + if (filter) + { + eo_do(ep->object, + EINA_LIST_FOREACH(prev_sources, li, source_name) + evas_obj_text_filter_source_set(source_name, NULL); - EINA_LIST_FOREACH(filter_sources, li, source_name) - { - Edje_Real_Part *rp = _edje_real_part_get(ed, source_name); - evas_obj_text_filter_source_set(source_name, rp ? rp->object : NULL); - } - evas_obj_text_filter_program_set(filter)); + EINA_LIST_FOREACH(filter_sources, li, source_name) + { + Edje_Real_Part *rp = _edje_real_part_get(ed, source_name); + evas_obj_text_filter_source_set(source_name, rp ? rp->object : NULL); + }; + if (ep->param2) + { + evas_obj_text_filter_state_set(chosen_desc->common.state.name, chosen_desc->common.state.value, + ep->param2->description->state.name, ep->param2->description->state.value, + state_val); + } + else + { + evas_obj_text_filter_state_set(chosen_desc->common.state.name, chosen_desc->common.state.value, + NULL, 0.0, state_val); + } + evas_obj_text_filter_program_set(filter)); + } + else + eo_do(ep->object, evas_obj_text_filter_program_set(NULL)); /* Handle alignment */ { diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index bca2af5393..bbf5c80217 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -3268,7 +3268,8 @@ start_draw: W = obj->cur->geometry.w; H = obj->cur->geometry.h; - if (pgm && evas_filter_program_state_set(pgm, eo_obj, obj)) +#warning implement state_set from edje + if (pgm && evas_filter_program_state_set(pgm, eo_obj, obj, NULL, 0.0, NULL, 0.0, 0.0)) redraw = EINA_TRUE; if (!redraw && o->cur->filter->output) @@ -3309,7 +3310,7 @@ start_draw: { pgm = evas_filter_program_new("Image", EINA_FALSE); evas_filter_program_source_set_all(pgm, o->cur->filter->sources); - evas_filter_program_state_set(pgm, eo_obj, obj); + evas_filter_program_state_set(pgm, eo_obj, obj, NULL, 0.0, NULL, 0.0, 0.0); ok = evas_filter_program_parse(pgm, o->cur->filter->code); if (!ok) goto state_write; } @@ -4840,7 +4841,7 @@ _evas_image_filter_program_set(Eo *eo_obj, Evas_Image_Data *o, const char *arg) { pgm = evas_filter_program_new("Evas_Text: Filter Program", EINA_FALSE); evas_filter_program_source_set_all(pgm, fcow->sources); - evas_filter_program_state_set(pgm, eo_obj, obj); + evas_filter_program_state_set(pgm, eo_obj, obj, NULL, 0.0, NULL, 0.0, 0.0); if (!evas_filter_program_parse(pgm, arg)) { ERR("Parsing failed!"); diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c index d82b7b43ad..d047d96668 100644 --- a/src/lib/evas/canvas/evas_object_main.c +++ b/src/lib/evas/canvas/evas_object_main.c @@ -33,7 +33,7 @@ static const Evas_Object_Protected_State default_state = { 1.0, 0, EVAS_RENDER_BLEND, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE }; static const Evas_Object_Filter_Data default_filter = { - NULL, NULL, NULL, NULL, EINA_FALSE, EINA_FALSE + NULL, NULL, NULL, NULL, { { "default", 0.0 }, { "default", 0.0 }, 0.0 }, EINA_FALSE, EINA_FALSE }; const void * const evas_object_filter_cow_default = &default_filter; static const Evas_Object_Mask_Data default_mask = { diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c index 6fb4335d23..f517a97562 100644 --- a/src/lib/evas/canvas/evas_object_text.c +++ b/src/lib/evas/canvas/evas_object_text.c @@ -1783,7 +1783,10 @@ evas_object_text_render(Evas_Object *eo_obj, Evas_Filter_Program *pgm; pgm = evas_filter_program_new("Evas_Text", EINA_TRUE); evas_filter_program_source_set_all(pgm, fcow->sources); - evas_filter_program_state_set(pgm, eo_obj, obj); + evas_filter_program_state_set(pgm, eo_obj, obj, + fcow->state.cur.name, fcow->state.cur.value, + fcow->state.next.name, fcow->state.next.value, + fcow->state.pos); if (!evas_filter_program_parse(pgm, fcow->code)) { ERR("Filter program parsing failed"); @@ -1801,7 +1804,10 @@ evas_object_text_render(Evas_Object *eo_obj, { Eina_Bool redraw; - redraw = evas_filter_program_state_set(fcow->chain, eo_obj, obj); + redraw = evas_filter_program_state_set(fcow->chain, eo_obj, obj, + fcow->state.cur.name, fcow->state.cur.value, + fcow->state.next.name, fcow->state.next.value, + fcow->state.pos); if (redraw) DBG("Filter redraw by state change!"); @@ -1841,7 +1847,10 @@ evas_object_text_render(Evas_Object *eo_obj, } } else - evas_filter_program_state_set(fcow->chain, eo_obj, obj); + evas_filter_program_state_set(fcow->chain, eo_obj, obj, + fcow->state.cur.name, fcow->state.cur.value, + fcow->state.next.name, fcow->state.next.value, + fcow->state.pos); filter = evas_filter_context_new(obj->layer->evas, do_async); @@ -2401,7 +2410,10 @@ _evas_text_filter_program_set(Eo *eo_obj, Evas_Text_Data *o, const char *arg) { pgm = evas_filter_program_new("Evas_Text", EINA_TRUE); evas_filter_program_source_set_all(pgm, fcow->sources); - evas_filter_program_state_set(pgm, eo_obj, obj); + evas_filter_program_state_set(pgm, eo_obj, obj, + fcow->state.cur.name, fcow->state.cur.value, + fcow->state.next.name, fcow->state.next.value, + fcow->state.pos); if (!evas_filter_program_parse(pgm, arg)) { ERR("Parsing failed!"); @@ -2551,6 +2563,48 @@ update: evas_object_inform_call_resize(eo_obj); } +EOLIAN static void +_evas_text_filter_state_set(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, + const char *cur_state, double cur_val, + const char *next_state, double next_val, double pos) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + + evas_object_async_block(obj); + if ((cur_state != o->cur.filter->state.cur.name) || (cur_val != o->cur.filter->state.cur.value) || + (next_state != o->cur.filter->state.next.name) || (next_val != o->cur.filter->state.next.value) || + (pos != o->cur.filter->state.pos)) + { + EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow) + { + fcow->changed = 1; + fcow->state.cur.name = cur_state; + fcow->state.cur.value = cur_val; + fcow->state.next.name = next_state; + fcow->state.next.value = next_val; + fcow->state.pos = pos; + + if (o->cur.filter->chain) + { + evas_filter_program_state_set(o->cur.filter->chain, eo_obj, obj, + fcow->state.cur.name, fcow->state.cur.value, + fcow->state.next.name, fcow->state.next.value, + fcow->state.pos); + } + } + EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow); + + // Mark as changed + _evas_object_text_items_clear(o); + o->changed = 1; + _evas_object_text_recalc(eo_obj, o->cur.text); + evas_object_change(eo_obj, obj); + evas_object_clip_dirty(eo_obj, obj); + evas_object_coords_recalc(eo_obj, obj); + evas_object_inform_call_resize(eo_obj); + } +} + EAPI void evas_object_text_font_source_set(Eo *obj, const char *font_source) { diff --git a/src/lib/evas/canvas/evas_text.eo b/src/lib/evas/canvas/evas_text.eo index 62a27ee08c..25e02dd750 100644 --- a/src/lib/evas/canvas/evas_text.eo +++ b/src/lib/evas/canvas/evas_text.eo @@ -260,6 +260,23 @@ class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties) eobj: Evas.Object *; /*@ Eo object to use through proxy rendering */ } } + @property filter_state { + set { + /*@ Set the current state of the filter (for use from Edje) + + @internal + @since 1.15 + */ + legacy: null; + } + values { + cur_state: const(char)*; + cur_val: double(0.0); + next_state: const(char)*; + next_val: double(0.0); + animpos: double(0.0); + } + } @property max_descent { get { return: Evas.Coord; diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c index c27569dccb..294cd1eff7 100644 --- a/src/lib/evas/filters/evas_filter_parser.c +++ b/src/lib/evas/filters/evas_filter_parser.c @@ -340,9 +340,20 @@ struct _Evas_Filter_Program_State struct { int a, r, g, b; } glow; struct { int a, r, g, b; } glow2; } text; - struct { int a, r, g, b; } color; + struct { + int a, r, g, b; + } color; + struct { + const char *name; + double value; + } cur; + struct { + const char *name; + double value; + } next; int w, h; double scale; + double pos; }; struct _Evas_Filter_Program @@ -2545,6 +2556,24 @@ _filter_program_state_set(Evas_Filter_Program *pgm) { SETFIELD("color", JOINC(color)); SETFIELD("scale", pgm->state.scale); + SETFIELD("pos", pgm->state.pos); + lua_newtable(L); // "cur" + { + SETFIELD("value", pgm->state.cur.value); + lua_pushstring(L, pgm->state.cur.name); + lua_setfield(L, -2, "name"); + lua_setfield(L, -2, "cur"); + } + lua_newtable(L); // "next" + { + if (pgm->state.next.name) + { + SETFIELD("value", pgm->state.next.value); + lua_pushstring(L, pgm->state.next.name); + lua_setfield(L, -2, "name"); + } + lua_setfield(L, -2, "next"); + } lua_newtable(L); // "text" { SETFIELD("outline", JOINC(text.outline)); @@ -2774,7 +2803,10 @@ evas_filter_program_new(const char *name, Eina_Bool input_alpha) EAPI Eina_Bool evas_filter_program_state_set(Evas_Filter_Program *pgm, Evas_Object *eo_obj, - Evas_Object_Protected_Data *obj) + Evas_Object_Protected_Data *obj, + const char *cur_state, double cur_val, + const char *next_state, double next_val, + double pos) { Evas_Filter_Program_State old_state; @@ -2785,6 +2817,11 @@ evas_filter_program_state_set(Evas_Filter_Program *pgm, Evas_Object *eo_obj, pgm->state.w = obj->cur->geometry.w; pgm->state.h = obj->cur->geometry.h; pgm->state.scale = obj->cur->scale; + pgm->state.pos = pos; + pgm->state.cur.name = cur_state; + pgm->state.cur.value = cur_val; + pgm->state.next.name = next_state; + pgm->state.next.value = next_val; eo_do(eo_obj, efl_gfx_color_get(&pgm->state.color.r, diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h index 2d238438df..e72738a089 100644 --- a/src/lib/evas/include/evas_filter.h +++ b/src/lib/evas/include/evas_filter.h @@ -126,7 +126,7 @@ enum _Evas_Filter_Transform_Flags /* Parser stuff (high level API) */ EAPI Evas_Filter_Program *evas_filter_program_new(const char *name, Eina_Bool input_alpha); -EAPI Eina_Bool evas_filter_program_state_set(Evas_Filter_Program *pgm, Evas_Object *eo_obj, Evas_Object_Protected_Data *obj); +EAPI Eina_Bool evas_filter_program_state_set(Evas_Filter_Program *pgm, Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, const char *cur_state, double cur_val, const char *next_state, double next_val, double pos); EAPI Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str); EAPI void evas_filter_program_del(Evas_Filter_Program *pgm); Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm); diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 05de77c56c..474e3ca4a1 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1178,6 +1178,17 @@ struct _Evas_Object_Filter_Data Evas_Filter_Program *chain; Eina_Hash *sources; // Evas_Filter_Proxy_Binding void *output; + struct { + struct { + const char *name; + double value; + } cur; + struct { + const char *name; + double value; + } next; + double pos; + } state; Eina_Bool changed : 1; Eina_Bool invalid : 1; // Code parse failed };