From 93965db815d7ca1e3951b7cda9f74e821975d648 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Thu, 5 Jan 2017 17:56:04 +0900 Subject: [PATCH] evas: Implement filter sources support for textblock --- src/bin/elementary/test_gfx_filters.c | 24 +++++++++-- src/lib/evas/canvas/efl_canvas_text.eo | 1 + src/lib/evas/canvas/evas_filter_mixin.c | 6 +-- src/lib/evas/canvas/evas_object_textblock.c | 65 ++++++++++++++++++++++++++++- src/lib/evas/include/evas_filter.h | 3 ++ 5 files changed, 92 insertions(+), 7 deletions(-) diff --git a/src/bin/elementary/test_gfx_filters.c b/src/bin/elementary/test_gfx_filters.c index 1fc2cfd..755405e 100644 --- a/src/bin/elementary/test_gfx_filters.c +++ b/src/bin/elementary/test_gfx_filters.c @@ -25,7 +25,7 @@ static const Filter_Image images[] = { { "sky_01.jpg", "sky" }, { "sky_04.jpg", "cloud" }, { "wood_01.jpg", "wood" }, - { "icon_00.png", "love" }, + { "animated_logo.gif", "logo" }, { NULL, NULL } }; @@ -39,6 +39,11 @@ static const Filter_Image images_cloud[] = { { NULL, NULL }, }; +static const Filter_Image images_anim[] = { + { "animated_logo.gif", "logo" }, + { NULL, NULL }, +}; + /* builtin filter examples */ static const Filter templates[] = { { "Custom", NULL, NULL }, @@ -104,6 +109,13 @@ static const Filter templates[] = { { "Displaced cloud", "cloud = buffer { src = 'cloud' }\n" "displace { cloud, intensity = 10, fillmode = 'stretch' }", images_cloud }, + { "Animated ugliness", + "logo = buffer { src = 'logo' }\n" + "blend { logo, fillmode = 'repeat' }\n" + "a = buffer {}\n" + "grow { 5, dst = a }\n" + "blur { 5, src = a, color = 'darkblue' }\n" + "blend { color = 'yellow' }", images_anim } }; @@ -139,10 +151,11 @@ static void _spinner_cb(void *data, const Efl_Event *ev EINA_UNUSED) { Eo *win = data; - Eo *text, *code, *spinner; + Eo *text, *code, *spinner, *tb; int k; text = efl_key_wref_get(win, "text"); + tb = efl_key_wref_get(win, "textblock"); code = efl_key_wref_get(win, "code"); spinner = efl_key_wref_get(win, "spinner"); k = (int) round(elm_spinner_value_get(spinner)); @@ -160,6 +173,7 @@ _spinner_cb(void *data, const Efl_Event *ev EINA_UNUSED) const char *name = f->images[j].src_name; Eo *source_obj = efl_name_find(win, name); efl_gfx_filter_source_set(text, name, source_obj); + efl_gfx_filter_source_set(tb, name, source_obj); } } } @@ -228,7 +242,7 @@ _img_click(void *data, const Efl_Event *ev) Eina_Strbuf *buf; Eo *win = data; Eo *img = ev->object; - Eo *code, *text; + Eo *code, *text, *tb; const char *name; name = efl_name_get(img); @@ -236,6 +250,7 @@ _img_click(void *data, const Efl_Event *ev) code = efl_key_wref_get(win, "code"); text = efl_key_wref_get(win, "text"); + tb = efl_key_wref_get(win, "textblock"); buf = eina_strbuf_new(); eina_strbuf_append_printf(buf, "%s = buffer { src = '%s' }\n", name, name); @@ -245,6 +260,7 @@ _img_click(void *data, const Efl_Event *ev) eina_strbuf_free(buf); efl_gfx_filter_source_set(text, name, ev->object); + efl_gfx_filter_source_set(tb, name, ev->object); } static void @@ -369,6 +385,8 @@ test_gfx_filters(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve efl_name_set(efl_added, images[k].src_name), elm_object_tooltip_text_set(efl_added, images[k].src_name), efl_gfx_visible_set(efl_added, 1)); + if (efl_player_playable_get(o)) + efl_player_play_set(o, 1); efl_event_callback_add(o, EFL_UI_EVENT_CLICKED, _img_click, win); efl_pack(box2, o); } diff --git a/src/lib/evas/canvas/efl_canvas_text.eo b/src/lib/evas/canvas/efl_canvas_text.eo index e39544e..c018d11 100644 --- a/src/lib/evas/canvas/efl_canvas_text.eo +++ b/src/lib/evas/canvas/efl_canvas_text.eo @@ -369,6 +369,7 @@ class Efl.Canvas.Text (Efl.Canvas.Object, Efl.Text, Efl.Canvas.Filter.Internal) Efl.Text.text { get; set; } Efl.Gfx.Filter.filter_program { get; set; } Efl.Gfx.Filter.filter_data { get; set; } + Efl.Gfx.Filter.filter_source { get; set; } Efl.Canvas.Filter.Internal.filter_dirty; Efl.Canvas.Filter.Internal.filter_input_render; Efl.Canvas.Filter.Internal.filter_state_prepare; diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c index 1f6ea23..d28280b 100644 --- a/src/lib/evas/canvas/evas_filter_mixin.c +++ b/src/lib/evas/canvas/evas_filter_mixin.c @@ -107,8 +107,8 @@ _filter_cb(Evas_Filter_Context *ctx, void *data, Eina_Bool success) evas_post_render_job_add(obj->layer->evas, _filter_async_post_render_cb, post_data); } -static void -_filter_source_hash_free_cb(void *data) +void +_evas_filter_source_hash_free_cb(void *data) { Evas_Filter_Proxy_Binding *pb = data; Evas_Object_Protected_Data *proxy, *source; @@ -423,7 +423,7 @@ _efl_canvas_filter_internal_efl_gfx_filter_filter_source_set(Eo *eo_obj, Evas_Fi fcow = FCOW_BEGIN(pd); if (!fcow->sources) - fcow->sources = eina_hash_string_small_new(EINA_FREE_CB(_filter_source_hash_free_cb)); + fcow->sources = eina_hash_string_small_new(_evas_filter_source_hash_free_cb); else if (pb_old) eina_hash_del(fcow->sources, name, pb_old); diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c index bec6c88..ca0ef1a 100644 --- a/src/lib/evas/canvas/evas_object_textblock.c +++ b/src/lib/evas/canvas/evas_object_textblock.c @@ -598,6 +598,7 @@ struct _Evas_Object_Textblock struct { Efl_Canvas_Text_Filter_Program *programs; Evas_Filter_Data_Binding *data_bindings; + Eina_Hash *sources; } gfx_filter; Eina_Bool redraw : 1; Eina_Bool changed : 1; @@ -4378,6 +4379,7 @@ _format_filter_program_get(Efl_Canvas_Text_Data *o, Evas_Object_Textblock_Format { pgm = evas_filter_program_new(program->name, EINA_FALSE); evas_filter_program_data_set_all(pgm, EINA_INLIST_GET(o->gfx_filter.data_bindings)); + evas_filter_program_source_set_all(pgm, o->gfx_filter.sources); if (!evas_filter_program_parse(pgm, program->code)) { evas_filter_program_del(pgm); @@ -12875,6 +12877,7 @@ evas_object_textblock_free(Evas_Object *eo_obj) eina_stringshare_del(db->value); free(db); } + eina_hash_free(o->gfx_filter.sources); while (evas_object_textblock_style_user_peek(eo_obj)) { @@ -13285,7 +13288,6 @@ evas_object_textblock_render(Evas_Object *eo_obj EINA_UNUSED, filter->contexts = eina_array_new(8); filter_id = eina_array_count(filter->contexts); - // TODO: sources set ctx = evas_filter_context_new(obj->layer->evas, do_async, filter_id); evas_filter_state_prepare(eo_obj, &state, ti); evas_filter_program_state_set(pgm, &state); @@ -13309,6 +13311,7 @@ evas_object_textblock_render(Evas_Object *eo_obj EINA_UNUSED, evas_filter_program_padding_get(pgm, &filter->pad.l, &filter->pad.r, &filter->pad.t, &filter->pad.b); + evas_filter_context_proxy_render_all(ctx, eo_obj, EINA_FALSE); evas_filter_context_buffers_allocate_all(ctx); evas_filter_target_set(ctx, context, surface, obj->cur->geometry.x + ln->x + ti->parent.x + x - filter->pad.l, @@ -13776,6 +13779,66 @@ _efl_canvas_text_efl_gfx_filter_filter_data_get(Eo *obj EINA_UNUSED, Efl_Canvas_ if (execute) *execute = db->execute; } +EOLIAN static void +_efl_canvas_text_efl_gfx_filter_filter_source_set(Eo *eo_obj, Efl_Canvas_Text_Data *pd, const char *name, Efl_Gfx *eo_source) +{ + Evas_Object_Protected_Data *obj, *source; + Evas_Filter_Proxy_Binding *pb; + + if (!name) return; + + obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); + source = efl_data_scope_get(eo_source, EFL_CANVAS_OBJECT_CLASS); + evas_object_async_block(obj); + + pb = eina_hash_find(pd->gfx_filter.sources, name); + if (pb) + { + if (pb->eo_source == eo_source) return; + eina_hash_del(pd->gfx_filter.sources, name, pb); + } + else if (!eo_source) + { + return; + } + else + { + pb = calloc(1, sizeof(*pb)); + pb->eo_proxy = eo_obj; + pb->eo_source = eo_source; + pb->name = eina_stringshare_add(name); + } + + if (!pd->gfx_filter.sources) + pd->gfx_filter.sources = eina_hash_string_small_new(_evas_filter_source_hash_free_cb); + eina_hash_set(pd->gfx_filter.sources, name, pb); + + if (!eina_list_data_find(source->proxy->proxies, eo_obj)) + { + EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, Evas_Object_Proxy_Data, source_write) + source_write->proxies = eina_list_append(source_write->proxies, eo_obj); + EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write) + } + + if (!obj->proxy->is_proxy) + { + EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, Evas_Object_Proxy_Data, proxy_write) + proxy_write->is_proxy = EINA_TRUE; + EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write) + } + + pd->format_changed = EINA_TRUE; + _evas_textblock_invalidate_all(pd); + _evas_textblock_changed(pd, eo_obj); + evas_object_change(eo_obj, obj); +} + +EOLIAN static Efl_Gfx * +_efl_canvas_text_efl_gfx_filter_filter_source_get(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *pd, const char *name) +{ + return eina_hash_find(pd->gfx_filter.sources, name); +} + static void evas_object_textblock_coords_recalc(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h index 75a80a9..0ee3f30 100644 --- a/src/lib/evas/include/evas_filter.h +++ b/src/lib/evas/include/evas_filter.h @@ -157,6 +157,9 @@ Eina_Bool evas_filter_font_draw(Evas_Filter_Context *ctx, void *d Eina_Bool evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid, void *image, Eina_Bool do_async); Eina_Bool evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, void *surface, int x, int y); +// utility function +void _evas_filter_source_hash_free_cb(void *data); + /** * @brief Blend a source buffer into a destination buffer, allowing X,Y offsets, Alpha to RGBA conversion with color * @param ctx Current filter chain -- 2.7.4