summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-06-17 16:26:30 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2015-06-25 14:36:09 +0900
commit64fd278c62e3286c453885216d2d0c86a01ce9fc (patch)
treed4463d71e84454bb354b4da152a60d51b4f506c6 /src
parenta18107309dc5233e76b77016b6eb3ef09ddf25ec (diff)
Evas filters: EO-ify the filters API
This creates the new interface Efl.Gfx.Filter And the implementation is a mixin (evas_filter_mixin.c): Evas.Filter All the filter rendering code has now been moved to this new file. TODO: Merge image filtering.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Efl.am4
-rw-r--r--src/Makefile_Evas.am8
-rw-r--r--src/lib/edje/edje_calc.c36
-rw-r--r--src/lib/edje/edje_private.h2
-rw-r--r--src/lib/edje/edje_text.c2
-rw-r--r--src/lib/efl/Efl.h1
-rw-r--r--src/lib/efl/interfaces/efl_gfx_filter.eo73
-rw-r--r--src/lib/efl/interfaces/efl_interfaces_main.c2
-rw-r--r--src/lib/evas/canvas/evas_filter.eo66
-rw-r--r--src/lib/evas/canvas/evas_filter_mixin.c512
-rw-r--r--src/lib/evas/canvas/evas_object_main.c2
-rw-r--r--src/lib/evas/canvas/evas_object_text.c609
-rw-r--r--src/lib/evas/canvas/evas_text.eo67
-rw-r--r--src/lib/evas/include/evas_private.h3
-rw-r--r--src/tests/evas/evas_test_filters.c8
15 files changed, 795 insertions, 600 deletions
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index 5d45ae0..ad49f47 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -13,7 +13,9 @@ efl_eolian_files = \
13 lib/efl/interfaces/efl_gfx_gradient_base.eo \ 13 lib/efl/interfaces/efl_gfx_gradient_base.eo \
14 lib/efl/interfaces/efl_gfx_gradient_linear.eo \ 14 lib/efl/interfaces/efl_gfx_gradient_linear.eo \
15 lib/efl/interfaces/efl_gfx_gradient_radial.eo \ 15 lib/efl/interfaces/efl_gfx_gradient_radial.eo \
16 lib/efl/interfaces/efl_model_base.eo 16 lib/efl/interfaces/efl_gfx_filter.eo \
17 lib/efl/interfaces/efl_model_base.eo \
18 $(NULL)
17 19
18efl_eolian_files_h = $(efl_eolian_files:%.eo=%.eo.h) 20efl_eolian_files_h = $(efl_eolian_files:%.eo=%.eo.h)
19efl_eolian_files_c = $(efl_eolian_files:%.eo=%.eo.c) 21efl_eolian_files_c = $(efl_eolian_files:%.eo=%.eo.c)
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index ef59a2f..cfba9b6 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -40,7 +40,9 @@ evas_eolian_files = \
40 lib/evas/canvas/efl_vg_root_node.eo \ 40 lib/evas/canvas/efl_vg_root_node.eo \
41 lib/evas/canvas/efl_vg_gradient.eo \ 41 lib/evas/canvas/efl_vg_gradient.eo \
42 lib/evas/canvas/efl_vg_gradient_radial.eo \ 42 lib/evas/canvas/efl_vg_gradient_radial.eo \
43 lib/evas/canvas/efl_vg_gradient_linear.eo 43 lib/evas/canvas/efl_vg_gradient_linear.eo \
44 lib/evas/canvas/evas_filter.eo \
45 $(NULL)
44 46
45evas_eolian_type_files = \ 47evas_eolian_type_files = \
46 lib/evas/canvas/evas_types.eot 48 lib/evas/canvas/evas_types.eot
@@ -520,7 +522,9 @@ lib/evas/common/evas_op_sub/op_sub_pixel_mask_i386.c
520 522
521### Evas filters 523### Evas filters
522 524
523lib_evas_libevas_la_SOURCES += lib/evas/filters/evas_filter.c \ 525lib_evas_libevas_la_SOURCES += \
526lib/evas/canvas/evas_filter_mixin.c \
527lib/evas/filters/evas_filter.c \
524lib/evas/filters/evas_filter_blend.c \ 528lib/evas/filters/evas_filter_blend.c \
525lib/evas/filters/evas_filter_blur.c \ 529lib/evas/filters/evas_filter_blur.c \
526lib/evas/filters/evas_filter_bump.c \ 530lib/evas/filters/evas_filter_bump.c \
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c
index 30478a6..a1cd9c1 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,
1603 Edje_Part_Description_Text *chosen_desc, 1603 Edje_Part_Description_Text *chosen_desc,
1604 Edje_Calc_Params *params, 1604 Edje_Calc_Params *params,
1605 int *minw, int *minh, 1605 int *minw, int *minh,
1606 int *maxw, int *maxh, double pos) 1606 int *maxw, int *maxh)
1607#define RECALC_SINGLE_TEXT_USING_APPLY 1 1607#define RECALC_SINGLE_TEXT_USING_APPLY 1
1608#if RECALC_SINGLE_TEXT_USING_APPLY 1608#if RECALC_SINGLE_TEXT_USING_APPLY
1609/* 1609/*
@@ -1634,7 +1634,7 @@ _edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED,
1634 free(sfont); 1634 free(sfont);
1635 params->type.text.size = size; /* XXX TODO used by further calcs, go inside recalc_apply? */ 1635 params->type.text.size = size; /* XXX TODO used by further calcs, go inside recalc_apply? */
1636 1636
1637 _edje_text_recalc_apply(ed, ep, params, chosen_desc, EINA_TRUE, pos); 1637 _edje_text_recalc_apply(ed, ep, params, chosen_desc, EINA_TRUE);
1638 1638
1639 if ((!chosen_desc) || 1639 if ((!chosen_desc) ||
1640 ((!chosen_desc->text.min_x) && (!chosen_desc->text.min_y) && 1640 ((!chosen_desc->text.min_x) && (!chosen_desc->text.min_y) &&
@@ -2406,6 +2406,7 @@ _edje_part_recalc_single_map(Edje *ed,
2406static inline const char * 2406static inline const char *
2407_edje_filter_get(Edje *ed, Edje_Part_Description_Spec_Filter *filter) 2407_edje_filter_get(Edje *ed, Edje_Part_Description_Spec_Filter *filter)
2408{ 2408{
2409 if (!filter->code) return NULL;
2409 if (EINA_UNLIKELY(!filter->checked_data)) 2410 if (EINA_UNLIKELY(!filter->checked_data))
2410 { 2411 {
2411 Edje_String *st; 2412 Edje_String *st;
@@ -2433,7 +2434,6 @@ _edje_part_recalc_single_filter(Edje *ed,
2433 const char *src1, *src2, *part, *code; 2434 const char *src1, *src2, *part, *code;
2434 Evas_Object *obj = ep->object; 2435 Evas_Object *obj = ep->object;
2435 Eina_List *li1, *li2; 2436 Eina_List *li1, *li2;
2436 Eina_Bool im = 0;
2437 2437
2438 /* handle TEXT and IMAGE part types here */ 2438 /* handle TEXT and IMAGE part types here */
2439 if (ep->part->type == EDJE_PART_TYPE_TEXT) 2439 if (ep->part->type == EDJE_PART_TYPE_TEXT)
@@ -2446,19 +2446,6 @@ _edje_part_recalc_single_filter(Edje *ed,
2446 prev_sources = ep->typedata.text->filter.sources; 2446 prev_sources = ep->typedata.text->filter.sources;
2447 filter_sources = edt->text.filter.sources; 2447 filter_sources = edt->text.filter.sources;
2448 } 2448 }
2449#if 0
2450 // old form
2451 if (ep->typedata.text->filter.code)
2452 filter = &ep->typedata.text->filter;
2453 else
2454 filter = &chosen_edt->text.filter;
2455 if (ep->typedata.text->filter.sources != chosen_edt->text.filter.sources)
2456 {
2457 prev_sources = ep->typedata.text->filter.sources;
2458 filter_sources = chosen_edt->text.filter.sources;
2459 //ep->typedata.text->filter.sources = chosen_edt->text.filter.sources;
2460 }
2461#endif
2462 } 2449 }
2463 else if (ep->part->type == EDJE_PART_TYPE_IMAGE) 2450 else if (ep->part->type == EDJE_PART_TYPE_IMAGE)
2464 { 2451 {
@@ -2470,7 +2457,6 @@ _edje_part_recalc_single_filter(Edje *ed,
2470 prev_sources = edi->image.filter.sources; 2457 prev_sources = edi->image.filter.sources;
2471 filter_sources = chosen_edi->image.filter.sources; 2458 filter_sources = chosen_edi->image.filter.sources;
2472 } 2459 }
2473 im = 1;
2474 } 2460 }
2475 else 2461 else
2476 { 2462 {
@@ -2478,18 +2464,6 @@ _edje_part_recalc_single_filter(Edje *ed,
2478 return; 2464 return;
2479 } 2465 }
2480 2466
2481 // FIXME: Implement proper EO interface/mixin and remove this ugly thing
2482#define efl_gfx_filter_program_set(...) do { \
2483 if (!im) evas_obj_text_filter_program_set(__VA_ARGS__); \
2484 else evas_obj_text_filter_program_set(__VA_ARGS__); } while (0)
2485#define efl_gfx_filter_source_set(...) do { \
2486 if (!im) evas_obj_text_filter_source_set(__VA_ARGS__); \
2487 else evas_obj_image_filter_source_set(__VA_ARGS__); } while (0)
2488#define efl_gfx_filter_state_set(...) do { \
2489 if (!im) evas_obj_text_filter_state_set(__VA_ARGS__); \
2490 /* else evas_obj_image_filter_state_set(__VA_ARGS__); */ } while (0)
2491 // End of pure ugliness
2492
2493 /* common code below */ 2467 /* common code below */
2494 code = _edje_filter_get(ed, filter); 2468 code = _edje_filter_get(ed, filter);
2495 if (!code) 2469 if (!code)
@@ -2724,7 +2698,7 @@ _edje_part_recalc_single(Edje *ed,
2724 _edje_part_recalc_single_textblock(sc, ed, ep, (Edje_Part_Description_Text *)chosen_desc, params, &minw, &minh, &maxw, &maxh); 2698 _edje_part_recalc_single_textblock(sc, ed, ep, (Edje_Part_Description_Text *)chosen_desc, params, &minw, &minh, &maxw, &maxh);
2725 else if (ep->part->type == EDJE_PART_TYPE_TEXT) 2699 else if (ep->part->type == EDJE_PART_TYPE_TEXT)
2726 { 2700 {
2727 _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); 2701 _edje_part_recalc_single_text(sc, ed, ep, (Edje_Part_Description_Text*) desc, (Edje_Part_Description_Text*) chosen_desc, params, &minw, &minh, &maxw, &maxh);
2728 _edje_part_recalc_single_filter(ed, ep, desc, chosen_desc, pos); 2702 _edje_part_recalc_single_filter(ed, ep, desc, chosen_desc, pos);
2729 } 2703 }
2730 2704
@@ -4522,7 +4496,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
4522 switch (ep->part->type) 4496 switch (ep->part->type)
4523 { 4497 {
4524 case EDJE_PART_TYPE_TEXT: 4498 case EDJE_PART_TYPE_TEXT:
4525 _edje_text_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc, EINA_FALSE, pos); 4499 _edje_text_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc, EINA_FALSE);
4526 break; 4500 break;
4527 4501
4528 case EDJE_PART_TYPE_PROXY: 4502 case EDJE_PART_TYPE_PROXY:
diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h
index 6f209f8..d8c0411 100644
--- a/src/lib/edje/edje_private.h
+++ b/src/lib/edje/edje_private.h
@@ -2293,7 +2293,7 @@ void _edje_text_recalc_apply(Edje *ed,
2293 Edje_Real_Part *ep, 2293 Edje_Real_Part *ep,
2294 Edje_Calc_Params *params, 2294 Edje_Calc_Params *params,
2295 Edje_Part_Description_Text *chosen_desc, 2295 Edje_Part_Description_Text *chosen_desc,
2296 Eina_Bool calc_only, double state_val); 2296 Eina_Bool calc_only);
2297Evas_Font_Size _edje_text_size_calc(Evas_Font_Size size, Edje_Text_Class *tc); 2297Evas_Font_Size _edje_text_size_calc(Evas_Font_Size size, Edje_Text_Class *tc);
2298const char * _edje_text_class_font_get(Edje *ed, 2298const char * _edje_text_class_font_get(Edje *ed,
2299 Edje_Part_Description_Text *chosen_desc, 2299 Edje_Part_Description_Text *chosen_desc,
diff --git a/src/lib/edje/edje_text.c b/src/lib/edje/edje_text.c
index 0f65671..a49b661 100644
--- a/src/lib/edje/edje_text.c
+++ b/src/lib/edje/edje_text.c
@@ -197,7 +197,7 @@ void
197_edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep, 197_edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep,
198 Edje_Calc_Params *params, 198 Edje_Calc_Params *params,
199 Edje_Part_Description_Text *chosen_desc, 199 Edje_Part_Description_Text *chosen_desc,
200 Eina_Bool calc_only, double state_val) 200 Eina_Bool calc_only)
201{ 201{
202 const char *text = NULL; 202 const char *text = NULL;
203 const char *font; 203 const char *font;
diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h
index f8eb8eb..7a2ea8f 100644
--- a/src/lib/efl/Efl.h
+++ b/src/lib/efl/Efl.h
@@ -163,6 +163,7 @@ EAPI extern const Eo_Event_Description _EFL_GFX_PATH_CHANGED;
163#include "interfaces/efl_gfx_gradient_base.eo.h" 163#include "interfaces/efl_gfx_gradient_base.eo.h"
164#include "interfaces/efl_gfx_gradient_linear.eo.h" 164#include "interfaces/efl_gfx_gradient_linear.eo.h"
165#include "interfaces/efl_gfx_gradient_radial.eo.h" 165#include "interfaces/efl_gfx_gradient_radial.eo.h"
166#include "interfaces/efl_gfx_filter.eo.h"
166 167
167#endif 168#endif
168 169
diff --git a/src/lib/efl/interfaces/efl_gfx_filter.eo b/src/lib/efl/interfaces/efl_gfx_filter.eo
new file mode 100644
index 0000000..baa6046
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_gfx_filter.eo
@@ -0,0 +1,73 @@
1interface Efl.Gfx.Filter
2{
3 legacy_prefix: null;
4 /* @since 1.15 */
5 methods {
6 @property program {
7 set {
8 [[Set an evas filter program on this object.
9
10 Valid for Text and Image objects at the moment.
11
12 The argument passed to this function is a string
13 containing a valid Lua program based on the filters
14 API as described in the "Evas filters reference"
15 page.
16
17 Set to null to disable filtering.
18 ]]
19 }
20 get {
21 [[Gets the code of the filter program set on this object.
22 May be null.
23 ]]
24 }
25 values {
26 code: const(char)*; [[filter program source code]]
27 }
28 }
29 @property state {
30 set {
31 [[Set the current state of the filter (for use from Edje).]]
32 }
33 values {
34 cur_state: const(char)*;
35 cur_val: double(0.0);
36 next_state: const(char)*;
37 next_val: double(0.0);
38 pos: double(0.0);
39 }
40 }
41 @property padding {
42 get {
43 [[Gets the padding required to apply this filter.]]
44 }
45 values {
46 l: int;
47 r: int;
48 t: int;
49 b: int;
50 }
51 }
52 source_set {
53 [[Bind an object to use as a mask or texture with Evas Filters.
54
55 This will create automatically a new RGBA buffer containing
56 the source object's pixels (as it is rendered).
57 ]]
58 params {
59 @in name: const(char)*; [[buffer name as used in the program]]
60 @in source: Efl.Gfx.Base*; [[object to use as a proxy source]]
61 }
62 }
63 source_get @const {
64 [[Retrieve which object is attached to this filter given its
65 buffer name.
66 ]]
67 params {
68 @in name: const(char)*; [[buffer name as used in the program]]
69 @out source: Efl.Gfx.Base*; [[object used as a proxy source]]
70 }
71 }
72 }
73}
diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c
index 31a3aae..5b044ff 100644
--- a/src/lib/efl/interfaces/efl_interfaces_main.c
+++ b/src/lib/efl/interfaces/efl_interfaces_main.c
@@ -20,6 +20,8 @@
20#include "interfaces/efl_gfx_gradient_linear.eo.c" 20#include "interfaces/efl_gfx_gradient_linear.eo.c"
21#include "interfaces/efl_gfx_gradient_radial.eo.c" 21#include "interfaces/efl_gfx_gradient_radial.eo.c"
22 22
23#include "interfaces/efl_gfx_filter.eo.c"
24
23EAPI const Eo_Event_Description _EFL_GFX_CHANGED = 25EAPI const Eo_Event_Description _EFL_GFX_CHANGED =
24 EO_EVENT_DESCRIPTION("Graphics changed", "The visual representation of the object changed"); 26 EO_EVENT_DESCRIPTION("Graphics changed", "The visual representation of the object changed");
25 27
diff --git a/src/lib/evas/canvas/evas_filter.eo b/src/lib/evas/canvas/evas_filter.eo
new file mode 100644
index 0000000..7f6bdcb
--- /dev/null
+++ b/src/lib/evas/canvas/evas_filter.eo
@@ -0,0 +1,66 @@
1mixin Evas.Filter (Efl.Gfx.Filter)
2{
3 // Evas internal implementation
4 legacy_prefix: null;
5 methods {
6 @property changed {
7 set {
8 [[Marks this filter as changed.]]
9 }
10 values {
11 val: bool;
12 }
13 }
14 @property invalid {
15 set {
16 [[Marks this filter as invalid.]]
17 }
18 values {
19 val: bool;
20 }
21 }
22 constructor {
23 [[Initialize the Evas.Filter mixin.
24
25 Should be called in a parent's class constructor.
26 ]]
27 }
28 destructor {
29 [[Release all data held by this Evas.Filter.
30
31 This may include image buffers allocated by the Evas engine.
32 This should be called at the beginning of a parent's class destructor.
33 ]]
34 }
35 input_render {
36 [[Called by Evas.Filter when the parent class must render the input.
37 ;
38 ]]
39 params {
40 filter: void*; [[Evas_Filter_Context]]
41 drawctx: void*;
42 l: int;
43 r: int;
44 t: int;
45 b: int;
46 do_async: bool;
47 }
48 }
49 dirty {
50 [[Called when the filter changes must trigger a redraw of the object.
51
52 Virtual, to be implemented in the parent class.
53 ]]
54 }
55 }
56 implements {
57 Efl.Gfx.Filter.program.set;
58 Efl.Gfx.Filter.program.get;
59 Efl.Gfx.Filter.state.set;
60 Efl.Gfx.Filter.padding.get;
61 Efl.Gfx.Filter.source_set;
62 Efl.Gfx.Filter.source_get;
63 @virtual .input_render;
64 @virtual .dirty;
65 }
66}
diff --git a/src/lib/evas/canvas/evas_filter_mixin.c b/src/lib/evas/canvas/evas_filter_mixin.c
new file mode 100644
index 0000000..20aa8cc
--- /dev/null
+++ b/src/lib/evas/canvas/evas_filter_mixin.c
@@ -0,0 +1,512 @@
1#include "evas_common_private.h"
2#include "evas_private.h"
3#include "../../lib/efl/interfaces/efl_gfx_filter.eo.h"
4#include "evas_filter.eo.h"
5#include "evas_filter.h"
6
7#define MY_CLASS EVAS_FILTER_MIXIN
8
9#define ENFN obj->layer->evas->engine.func
10#define ENDT obj->layer->evas->engine.data.output
11
12typedef struct _Evas_Filter_Data Evas_Filter_Data;
13struct _Evas_Filter_Data
14{
15 const Evas_Object_Filter_Data *data;
16};
17
18static void
19_filter_cb(Evas_Filter_Context *ctx, void *data, Eina_Bool success)
20{
21 Eo *eo_obj = data;
22
23 // Destroy context as we won't reuse it.
24 evas_filter_context_destroy(ctx);
25
26 // Redraw text with normal styles in case of failure
27 if (!success)
28 {
29 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
30
31 ERR("Filter failed at runtime!");
32 eo_do(eo_obj,
33 evas_filter_invalid_set(EINA_TRUE);
34 evas_filter_dirty());
35 evas_object_change(eo_obj, obj);
36 evas_object_clip_dirty(eo_obj, obj);
37 evas_object_coords_recalc(eo_obj, obj);
38 evas_object_inform_call_resize(eo_obj);
39 }
40}
41
42static void
43_filter_source_hash_free_cb(void *data)
44{
45 Evas_Filter_Proxy_Binding *pb = data;
46 Evas_Object_Protected_Data *proxy, *source;
47 Evas_Filter_Data *pd;
48
49 proxy = eo_data_scope_get(pb->eo_proxy, EVAS_OBJECT_CLASS);
50 source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
51
52 if (source)
53 {
54 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy,
55 Evas_Object_Proxy_Data, source_write)
56 source_write->proxies = eina_list_remove(source_write->proxies, pb->eo_proxy);
57 EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write)
58 }
59
60 pd = eo_data_scope_get(pb->eo_proxy, MY_CLASS);
61
62 if (pd && proxy)
63 {
64 if (!eina_hash_population(pd->data->sources))
65 {
66 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, proxy->proxy,
67 Evas_Object_Proxy_Data, proxy_write)
68 proxy_write->is_proxy = EINA_FALSE;
69 EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, proxy_write)
70 }
71 }
72
73 eina_stringshare_del(pb->name);
74 free(pb);
75}
76
77Eina_Bool
78evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
79 void *output, void *context, void *surface,
80 int x, int y, Eina_Bool do_async, Eina_Bool alpha)
81{
82 Evas_Filter_Data *pd = eo_data_scope_get(eo_obj, MY_CLASS);
83
84 if (!pd->data->invalid && (pd->data->chain || pd->data->code))
85 {
86 int X, Y, W, H, l = 0, r = 0, t = 0, b = 0;
87 Evas_Filter_Context *filter;
88 void *drawctx;
89 Eina_Bool ok;
90 void *previous = pd->data->output;
91 Evas_Object_Filter_Data *fcow =
92 eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data));
93
94 /* NOTE: Filter rendering is now done ENTIRELY on CPU.
95 * So we rely on cache/cache2 to allocate a real image buffer,
96 * that we can draw to. The OpenGL texture will be created only
97 * after the rendering has been done, as we simply push the output
98 * image to GL.
99 */
100
101 W = obj->cur->geometry.w;
102 H = obj->cur->geometry.h;
103 X = obj->cur->geometry.x;
104 Y = obj->cur->geometry.y;
105
106 // Prepare color multiplier
107 ENFN->context_color_set(output, context,
108 obj->cur->cache.clip.r,
109 obj->cur->cache.clip.g,
110 obj->cur->cache.clip.b,
111 obj->cur->cache.clip.a);
112 if (obj->cur->clipper)
113 ENFN->context_multiplier_set(output, context,
114 obj->cur->clipper->cur->cache.clip.r,
115 obj->cur->clipper->cur->cache.clip.g,
116 obj->cur->clipper->cur->cache.clip.b,
117 obj->cur->clipper->cur->cache.clip.a);
118 else
119 ENFN->context_multiplier_unset(output, context);
120
121 if (!fcow->chain)
122 {
123 Evas_Filter_Program *pgm;
124 pgm = evas_filter_program_new(obj->name ? obj->name : obj->type, alpha);
125 evas_filter_program_source_set_all(pgm, fcow->sources);
126 evas_filter_program_state_set(pgm, eo_obj, obj,
127 fcow->state.cur.name, fcow->state.cur.value,
128 fcow->state.next.name, fcow->state.next.value,
129 fcow->state.pos);
130 if (!evas_filter_program_parse(pgm, fcow->code))
131 {
132 ERR("Filter program parsing failed");
133 evas_filter_program_del(pgm);
134 fcow->invalid = EINA_TRUE;
135
136 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
137 fcow, EINA_TRUE);
138 return EINA_FALSE;
139 }
140 fcow->chain = pgm;
141 fcow->invalid = EINA_FALSE;
142 }
143 else if (previous && !fcow->changed)
144 {
145 Eina_Bool redraw;
146
147 redraw = evas_filter_program_state_set(fcow->chain, eo_obj, obj,
148 fcow->state.cur.name, fcow->state.cur.value,
149 fcow->state.next.name, fcow->state.next.value,
150 fcow->state.pos);
151 if (redraw)
152 DBG("Filter redraw by state change!");
153
154 // Scan proxies to find if any changed
155 if (!redraw && fcow->sources)
156 {
157 Evas_Filter_Proxy_Binding *pb;
158 Evas_Object_Protected_Data *source;
159 Eina_Iterator *iter;
160
161 iter = eina_hash_iterator_data_new(fcow->sources);
162 EINA_ITERATOR_FOREACH(iter, pb)
163 {
164 source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
165 if (source->changed)
166 {
167 redraw = EINA_TRUE;
168 break;
169 }
170 }
171 eina_iterator_free(iter);
172 }
173
174 if (!redraw)
175 {
176 // Render this image only
177 ENFN->image_draw(ENDT, context,
178 surface, previous,
179 0, 0, W, H, // src
180 X + x, Y + y, W, H, // dst
181 EINA_FALSE, // smooth
182 do_async);
183
184 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
185 fcow, EINA_TRUE);
186 return EINA_TRUE;
187 }
188 }
189 else
190 evas_filter_program_state_set(fcow->chain, eo_obj, obj,
191 fcow->state.cur.name, fcow->state.cur.value,
192 fcow->state.next.name, fcow->state.next.value,
193 fcow->state.pos);
194
195 filter = evas_filter_context_new(obj->layer->evas, do_async);
196
197 // Run script
198 ok = evas_filter_context_program_use(filter, fcow->chain);
199 if (!filter || !ok)
200 {
201 ERR("Parsing failed?");
202 evas_filter_context_destroy(filter);
203
204 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
205 fcow, EINA_TRUE);
206 return EINA_FALSE;
207 }
208
209 // Proxies
210 evas_filter_context_proxy_render_all(filter, eo_obj, EINA_FALSE);
211
212 // Draw Context
213 drawctx = ENFN->context_new(ENDT);
214 ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
215
216 // Allocate all buffers now
217 evas_filter_context_buffers_allocate_all(filter);
218 evas_filter_target_set(filter, context, surface, X + x, Y + y);
219
220 // Steal output and release previous
221 fcow->output = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID);
222 if (fcow->output != previous)
223 evas_filter_buffer_backing_release(filter, previous);
224
225 evas_filter_program_padding_get(fcow->chain, &l, &r, &t, &b);
226 eo_do(eo_obj, evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
227#warning TODO: draw text into input buffer
228#if 0
229 // Render text to input buffer
230 EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), it)
231 if ((pd->font) && (it->text_props.len > 0))
232 {
233 evas_filter_font_draw(filter, drawctx, EVAS_FILTER_BUFFER_INPUT_ID, pd->font,
234 sl + it->x,
235 st + (int) pd->max_ascent,
236 &it->text_props,
237 do_async);
238 }
239#endif
240
241 ENFN->context_free(ENDT, drawctx);
242
243 // Add post-run callback and run filter
244 evas_filter_context_post_run_callback_set(filter, _filter_cb, eo_obj);
245 ok = evas_filter_run(filter);
246 fcow->changed = EINA_FALSE;
247 if (!ok) fcow->invalid = EINA_TRUE;
248
249 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data **) &(pd->data), fcow, EINA_TRUE);
250
251 if (ok)
252 {
253 DBG("Effect rendering done.");
254 return EINA_TRUE;
255 }
256 else
257 {
258 ERR("Rendering failed.");
259 return EINA_FALSE;
260 }
261 }
262 return EINA_FALSE;
263}
264
265EOLIAN void
266_evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
267 const char *code)
268{
269 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
270 Evas_Filter_Program *pgm = NULL;
271
272 if (!pd) return;
273 if (pd->data->code == code) return;
274 if (pd->data->code && code && !strcmp(code, pd->data->code)) return;
275
276 evas_object_async_block(obj);
277 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
278 {
279 // Parse filter program
280 evas_filter_program_del(fcow->chain);
281 if (code)
282 {
283 pgm = evas_filter_program_new("Evas_Text", EINA_TRUE);
284 evas_filter_program_source_set_all(pgm, fcow->sources);
285 evas_filter_program_state_set(pgm, eo_obj, obj,
286 fcow->state.cur.name, fcow->state.cur.value,
287 fcow->state.next.name, fcow->state.next.value,
288 fcow->state.pos);
289 if (!evas_filter_program_parse(pgm, code))
290 {
291 ERR("Parsing failed!");
292 evas_filter_program_del(pgm);
293 pgm = NULL;
294 }
295 }
296 fcow->chain = pgm;
297 fcow->changed = EINA_TRUE;
298 fcow->invalid = (pgm == NULL);
299 eina_stringshare_replace(&fcow->code, code);
300 }
301 EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
302
303 // Update object
304 eo_do(eo_obj, evas_filter_dirty());
305 evas_object_change(eo_obj, obj);
306 evas_object_clip_dirty(eo_obj, obj);
307 evas_object_coords_recalc(eo_obj, obj);
308 evas_object_inform_call_resize(eo_obj);
309}
310
311EOLIAN const char *
312_evas_filter_efl_gfx_filter_program_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd)
313{
314 return pd->data->code;
315}
316
317EOLIAN void
318_evas_filter_efl_gfx_filter_source_set(Eo *eo_obj, Evas_Filter_Data *pd,
319 const char *name, Efl_Gfx_Base *eo_source)
320{
321 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
322 Evas_Filter_Proxy_Binding *pb, *pb_old = NULL;
323 Evas_Object_Protected_Data *source = NULL;
324 Evas_Object_Filter_Data *fcow = NULL;
325
326 if (eo_source)
327 source = eo_data_scope_get(eo_source, EVAS_OBJECT_CLASS);
328
329 evas_object_async_block(obj);
330 if (!name)
331 {
332 if (!eo_source || !pd->data->sources) return;
333 if (eina_hash_del_by_data(pd->data->sources, eo_source))
334 goto update;
335 return;
336 }
337
338 if (!source && !pd->data->sources)
339 return;
340
341 if (pd->data->sources)
342 {
343 pb_old = eina_hash_find(pd->data->sources, name);
344 if (pb_old && (pb_old->eo_source == eo_source)) return;
345 }
346
347 fcow = eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data);
348
349 if (!fcow->sources)
350 fcow->sources = eina_hash_string_small_new(EINA_FREE_CB(_filter_source_hash_free_cb));
351 else if (pb_old)
352 eina_hash_del(fcow->sources, name, pb_old);
353
354 if (!source)
355 {
356 pb_old = eina_hash_find(fcow->sources, name);
357 if (!pb_old)
358 {
359 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data, fcow, EINA_TRUE);
360 return;
361 }
362 eina_hash_del_by_key(fcow->sources, name);
363 goto update;
364 }
365
366 pb = calloc(1, sizeof(*pb));
367 pb->eo_proxy = eo_obj;
368 pb->eo_source = eo_source;
369 pb->name = eina_stringshare_add(name);
370
371 if (!eina_list_data_find(source->proxy->proxies, eo_obj))
372 {
373 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, Evas_Object_Proxy_Data, source_write)
374 source_write->proxies = eina_list_append(source_write->proxies, eo_obj);
375 EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write)
376 }
377
378 if (!obj->proxy->is_proxy)
379 {
380 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, Evas_Object_Proxy_Data, proxy_write)
381 proxy_write->is_proxy = EINA_TRUE;
382 EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write)
383 }
384
385 eina_hash_add(fcow->sources, pb->name, pb);
386 evas_filter_program_source_set_all(fcow->chain, fcow->sources);
387
388 // Update object
389update:
390 if (fcow)
391 {
392 fcow->changed = EINA_TRUE;
393 fcow->invalid = EINA_FALSE;
394 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data, fcow, EINA_TRUE);
395 }
396
397 eo_do(eo_obj, evas_filter_dirty());
398 evas_object_change(eo_obj, obj);
399 evas_object_clip_dirty(eo_obj, obj);
400 evas_object_coords_recalc(eo_obj, obj);
401 evas_object_inform_call_resize(eo_obj);
402}
403
404EOLIAN void
405_evas_filter_efl_gfx_filter_source_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd,
406 const char *name, Efl_Gfx_Base **source)
407{
408 if (!source) return;
409 *source = eina_hash_find(pd->data->sources, name);
410}
411
412EOLIAN void
413_evas_filter_efl_gfx_filter_state_set(Eo *eo_obj, Evas_Filter_Data *pd,
414 const char *cur_state, double cur_val,
415 const char *next_state, double next_val,
416 double pos)
417{
418 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
419
420 evas_object_async_block(obj);
421 if ((cur_state != pd->data->state.cur.name) || (cur_val != pd->data->state.cur.value) ||
422 (next_state != pd->data->state.next.name) || (next_val != pd->data->state.next.value) ||
423 (pos != pd->data->state.pos))
424 {
425 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
426 {
427 fcow->changed = 1;
428 fcow->state.cur.name = cur_state;
429 fcow->state.cur.value = cur_val;
430 fcow->state.next.name = next_state;
431 fcow->state.next.value = next_val;
432 fcow->state.pos = pos;
433
434 if (pd->data->chain)
435 {
436 evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
437 fcow->state.cur.name, fcow->state.cur.value,
438 fcow->state.next.name, fcow->state.next.value,
439 fcow->state.pos);
440 }
441 }
442 EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
443
444 // Mark as changed
445 eo_do(eo_obj, evas_filter_dirty());
446 evas_object_change(eo_obj, obj);
447 evas_object_clip_dirty(eo_obj, obj);
448 evas_object_coords_recalc(eo_obj, obj);
449 evas_object_inform_call_resize(eo_obj);
450 }
451}
452
453EOLIAN void
454_evas_filter_efl_gfx_filter_padding_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd,
455 int *l, int *r, int *t, int *b)
456{
457 if (!pd->data->chain)
458 {
459 if (l) *l = 0;
460 if (r) *r = 0;
461 if (t) *t = 0;
462 if (b) *b = 0;
463 return;
464 }
465 evas_filter_program_padding_get(pd->data->chain, l, r, t, b);
466}
467
468EOLIAN void
469_evas_filter_changed_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool val)
470{
471 if ((evas_object_filter_cow_default != pd->data) && (pd->data->changed != val))
472 {
473 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
474 fcow->changed = val;
475 EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
476 }
477}
478
479EOLIAN void
480_evas_filter_invalid_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool val)
481{
482 if (pd->data->invalid != val)
483 {
484 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
485 fcow->invalid = val;
486 EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
487 }
488}
489
490EOLIAN void
491_evas_filter_constructor(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd)
492{
493 pd->data = eina_cow_alloc(evas_object_filter_cow);
494}
495
496EOLIAN void
497_evas_filter_destructor(Eo *eo_obj, Evas_Filter_Data *pd)
498{
499 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
500
501 if (!pd->data) return;
502 if (evas_object_filter_cow_default == pd->data) return;
503
504 if (pd->data->output)
505 ENFN->image_free(ENDT, pd->data->output);
506 eina_hash_free(pd->data->sources);
507 evas_filter_program_del(pd->data->chain);
508 eina_stringshare_del(pd->data->code);
509 eina_cow_free(evas_object_filter_cow, (const Eina_Cow_Data **) &pd->data);
510}
511
512#include "evas_filter.eo.c"
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c
index d047d96..9552a44 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -718,7 +718,7 @@ _evas_object_eo_base_destructor(Eo *eo_obj, Evas_Object_Protected_Data *obj)
718 if (eo_isa(proxy, EVAS_IMAGE_CLASS)) 718 if (eo_isa(proxy, EVAS_IMAGE_CLASS))
719 evas_object_image_source_unset(proxy); 719 evas_object_image_source_unset(proxy);
720 else if (eo_isa(proxy, EVAS_TEXT_CLASS)) 720 else if (eo_isa(proxy, EVAS_TEXT_CLASS))
721 eo_do(proxy, evas_obj_text_filter_source_set(NULL, eo_obj)); 721 eo_do(proxy, efl_gfx_filter_source_set(NULL, eo_obj));
722 } 722 }
723 723
724 /* Eina_Cow has no way to know if we are going to really change something 724 /* Eina_Cow has no way to know if we are going to really change something
diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c
index 80a7e75..6535046 100644
--- a/src/lib/evas/canvas/evas_object_text.c
+++ b/src/lib/evas/canvas/evas_object_text.c
@@ -1,5 +1,8 @@
1#include "evas_common_private.h" /* Includes evas_bidi_utils stuff. */ 1#include "evas_common_private.h" /* Includes evas_bidi_utils stuff. */
2#include "evas_private.h" 2#include "evas_private.h"
3
4#include "../efl/interfaces/efl_gfx_filter.eo.h"
5#include "evas_filter.eo.h"
3#include "evas_filter.h" 6#include "evas_filter.h"
4 7
5#define MY_CLASS EVAS_TEXT_CLASS 8#define MY_CLASS EVAS_TEXT_CLASS
@@ -42,8 +45,6 @@ struct _Evas_Text_Data
42 45
43 Evas_Font_Size size; 46 Evas_Font_Size size;
44 Evas_Text_Style_Type style; 47 Evas_Text_Style_Type style;
45
46 const Evas_Object_Filter_Data* filter; // cow
47 } cur, prev; 48 } cur, prev;
48 49
49 struct { 50 struct {
@@ -66,6 +67,7 @@ struct _Evas_Text_Data
66 67
67 Evas_BiDi_Direction bidi_dir : 2; 68 Evas_BiDi_Direction bidi_dir : 2;
68 char changed : 1; 69 char changed : 1;
70 char has_filter : 1;
69}; 71};
70 72
71struct _Evas_Object_Text_Item 73struct _Evas_Object_Text_Item
@@ -368,13 +370,11 @@ evas_object_text_add(Evas *e)
368} 370}
369 371
370EOLIAN static Eo * 372EOLIAN static Eo *
371_evas_text_eo_base_constructor(Eo *eo_obj, Evas_Text_Data *o) 373_evas_text_eo_base_constructor(Eo *eo_obj, Evas_Text_Data *o EINA_UNUSED)
372{ 374{
373 eo_obj = eo_do_super_ret(eo_obj, MY_CLASS, eo_obj, eo_constructor()); 375 eo_obj = eo_do_super_ret(eo_obj, MY_CLASS, eo_obj, eo_constructor());
374 evas_object_text_init(eo_obj); 376 evas_object_text_init(eo_obj);
375 377
376 o->cur.filter = eina_cow_alloc(evas_object_filter_cow);
377
378 return eo_obj; 378 return eo_obj;
379} 379}
380 380
@@ -397,22 +397,9 @@ _evas_text_efl_text_properties_font_source_set(Eo *eo_obj, Evas_Text_Data *o, co
397EOLIAN static const char* 397EOLIAN static const char*
398_evas_text_efl_text_properties_font_source_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o) 398_evas_text_efl_text_properties_font_source_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
399{ 399{
400
401 return o->cur.source; 400 return o->cur.source;
402} 401}
403 402
404static inline void
405_evas_text_filter_changed_set(Evas_Text_Data *o, Eina_Bool val)
406{
407 if ((evas_object_filter_cow_default != o->cur.filter)
408 && (o->cur.filter->changed != val))
409 {
410 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow)
411 fcow->changed = val;
412 EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow);
413 }
414}
415
416EOLIAN static void 403EOLIAN static void
417_evas_text_efl_text_properties_font_set(Eo *eo_obj, Evas_Text_Data *o, const char *font, Evas_Font_Size size) 404_evas_text_efl_text_properties_font_set(Eo *eo_obj, Evas_Text_Data *o, const char *font, Evas_Font_Size size)
418{ 405{
@@ -479,7 +466,8 @@ _evas_text_efl_text_properties_font_set(Eo *eo_obj, Evas_Text_Data *o, const cha
479 _evas_object_text_items_clear(o); 466 _evas_object_text_items_clear(o);
480 _evas_object_text_recalc(eo_obj, o->cur.text); 467 _evas_object_text_recalc(eo_obj, o->cur.text);
481 o->changed = 1; 468 o->changed = 1;
482 _evas_text_filter_changed_set(o, EINA_TRUE); 469 if (o->has_filter)
470 eo_do(eo_obj, evas_filter_changed_set(EINA_TRUE));
483 evas_object_change(eo_obj, obj); 471 evas_object_change(eo_obj, obj);
484 evas_object_clip_dirty(eo_obj, obj); 472 evas_object_clip_dirty(eo_obj, obj);
485 evas_object_coords_recalc(eo_obj, obj); 473 evas_object_coords_recalc(eo_obj, obj);
@@ -665,6 +653,19 @@ _layout_text_item_trim(Evas_Object_Protected_Data *obj, Evas_Text_Data *o, Evas_
665 return EINA_TRUE; 653 return EINA_TRUE;
666} 654}
667 655
656static void
657_evas_object_text_pad_get(Evas_Object *eo_obj, Evas_Text_Data *o, int *l, int *r, int *t, int *b)
658{
659 if (l) *l = 0;
660 if (r) *r = 0;
661 if (t) *t = 0;
662 if (b) *b = 0;
663 if (!o->has_filter)
664 evas_text_style_pad_get(o->cur.style, l, r, t, b);
665 else
666 eo_do(eo_obj, efl_gfx_filter_padding_get(l, r, t, b));
667}
668
668/** 669/**
669 * @internal 670 * @internal
670 * Populates o->items with the items of the text according to text 671 * Populates o->items with the items of the text according to text
@@ -767,10 +768,7 @@ _evas_object_text_layout(Evas_Object *eo_obj, Evas_Text_Data *o, Eina_Unicode *t
767 } 768 }
768 o->last_computed.advance_without_ellipsis = advance; 769 o->last_computed.advance_without_ellipsis = advance;
769 770
770 if (!o->cur.filter || !o->cur.filter->chain) 771 _evas_object_text_pad_get(eo_obj, o, &l, &r, NULL, NULL);
771 evas_text_style_pad_get(o->cur.style, &l, &r, NULL, NULL);
772 else
773 evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, NULL, NULL);
774 772
775 /* Handle ellipsis */ 773 /* Handle ellipsis */
776 if (pos && (o->cur.ellipsis >= 0.0) && (advance + l + r > obj->cur->geometry.w) && (obj->cur->geometry.w > 0)) 774 if (pos && (o->cur.ellipsis >= 0.0) && (advance + l + r > obj->cur->geometry.w) && (obj->cur->geometry.w > 0))
@@ -950,7 +948,8 @@ _evas_text_ellipsis_set(Eo *eo_obj, Evas_Text_Data *o, double ellipsis)
950 evas_object_async_block(obj); 948 evas_object_async_block(obj);
951 o->cur.ellipsis = ellipsis; 949 o->cur.ellipsis = ellipsis;
952 o->changed = 1; 950 o->changed = 1;
953 _evas_text_filter_changed_set(o, EINA_TRUE); 951 if (o->has_filter)
952 eo_do(eo_obj, evas_filter_changed_set(EINA_TRUE));
954 evas_object_change(eo_obj, obj); 953 evas_object_change(eo_obj, obj);
955 evas_object_clip_dirty(eo_obj, obj); 954 evas_object_clip_dirty(eo_obj, obj);
956} 955}
@@ -1008,7 +1007,8 @@ _evas_text_efl_text_text_set(Eo *eo_obj, Evas_Text_Data *o, const char *_text)
1008 if (o->cur.text != text) free(text); 1007 if (o->cur.text != text) free(text);
1009 1008
1010 o->changed = 1; 1009 o->changed = 1;
1011 _evas_text_filter_changed_set(o, EINA_TRUE); 1010 if (o->has_filter)
1011 eo_do(eo_obj, evas_filter_changed_set(EINA_TRUE));
1012 evas_object_change(eo_obj, obj); 1012 evas_object_change(eo_obj, obj);
1013 evas_object_clip_dirty(eo_obj, obj); 1013 evas_object_clip_dirty(eo_obj, obj);
1014 evas_object_coords_recalc(eo_obj, obj); 1014 evas_object_coords_recalc(eo_obj, obj);
@@ -1129,10 +1129,8 @@ _evas_text_char_pos_get(Eo *eo_obj, Evas_Text_Data *o, int pos, Evas_Coord *cx,
1129 1129
1130 Eina_Bool int_ret = _evas_object_text_char_coords_get(eo_obj, o, (size_t) pos, 1130 Eina_Bool int_ret = _evas_object_text_char_coords_get(eo_obj, o, (size_t) pos,
1131 &x, &y, &w, &h); 1131 &x, &y, &w, &h);
1132 if (!o->cur.filter || !o->cur.filter->chain) 1132
1133 evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b); 1133 _evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
1134 else
1135 evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, &t, &b);
1136 y += o->max_ascent - t; 1134 y += o->max_ascent - t;
1137 x -= l; 1135 x -= l;
1138 if (x < 0) 1136 if (x < 0)
@@ -1186,10 +1184,7 @@ _evas_text_char_coords_get(Eo *eo_obj, Evas_Text_Data *o, Evas_Coord x, Evas_Coo
1186 1184
1187 int int_ret = _evas_object_text_char_at_coords(eo_obj, o, x, y - o->max_ascent, 1185 int int_ret = _evas_object_text_char_at_coords(eo_obj, o, x, y - o->max_ascent,
1188 &rx, &ry, &rw, &rh); 1186 &rx, &ry, &rw, &rh);
1189 if (!o->cur.filter || !o->cur.filter->chain) 1187 _evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
1190 evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
1191 else
1192 evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, &t, &b);
1193 ry += o->max_ascent - t; 1188 ry += o->max_ascent - t;
1194 rx -= l; 1189 rx -= l;
1195 if (rx < 0) 1190 if (rx < 0)
@@ -1226,9 +1221,11 @@ _evas_text_style_set(Eo *eo_obj, Evas_Text_Data *o, Evas_Text_Style_Type style)
1226 if (o->cur.style == style) return; 1221 if (o->cur.style == style) return;
1227 evas_object_async_block(obj); 1222 evas_object_async_block(obj);
1228 1223
1229 evas_text_style_pad_get(o->cur.style, &pl, &pr, &pt, &pb); 1224 _evas_object_text_pad_get(eo_obj, o, &pl, &pr, &pt, &pb);
1225 //evas_text_style_pad_get(o->cur.style, &pl, &pr, &pt, &pb);
1230 o->cur.style = style; 1226 o->cur.style = style;
1231 evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b); 1227 _evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
1228 //evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
1232 1229
1233 if (o->items) w = obj->cur->geometry.w + (l - pl) + (r - pr); 1230 if (o->items) w = obj->cur->geometry.w + (l - pl) + (r - pr);
1234 h = obj->cur->geometry.h + (t - pt) + (b - pb); 1231 h = obj->cur->geometry.h + (t - pt) + (b - pb);
@@ -1345,18 +1342,9 @@ _evas_text_outline_color_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, int *r,
1345} 1342}
1346 1343
1347EOLIAN static void 1344EOLIAN static void
1348_evas_text_style_pad_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, int *l, int *r, int *t, int *b) 1345_evas_text_style_pad_get(Eo *eo_obj, Evas_Text_Data *o, int *l, int *r, int *t, int *b)
1349{ 1346{
1350 int sl = 0, sr = 0, st = 0, sb = 0; 1347 _evas_object_text_pad_get(eo_obj, o, l, r, t, b);
1351 /* use temps to be certain we have initialized values */
1352 if (!o->cur.filter || !o->cur.filter->chain)
1353 evas_text_style_pad_get(o->cur.style, &sl, &sr, &st, &sb);
1354 else
1355 evas_filter_program_padding_get(o->cur.filter->chain, &sl, &sr, &st, &sb);
1356 if (l) *l = sl;
1357 if (r) *r = sr;
1358 if (t) *t = st;
1359 if (b) *b = sb;
1360} 1348}
1361 1349
1362EAPI int 1350EAPI int
@@ -1539,6 +1527,8 @@ evas_object_text_init(Evas_Object *eo_obj)
1539#ifdef BIDI_SUPPORT 1527#ifdef BIDI_SUPPORT
1540 o->bidi_par_props = evas_bidi_paragraph_props_new(); 1528 o->bidi_par_props = evas_bidi_paragraph_props_new();
1541#endif 1529#endif
1530
1531 eo_do(eo_obj, evas_filter_constructor());
1542} 1532}
1543 1533
1544EOLIAN static void 1534EOLIAN static void
@@ -1554,24 +1544,8 @@ evas_object_text_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
1554{ 1544{
1555 Evas_Text_Data *o = eo_data_scope_get(eo_obj, MY_CLASS); 1545 Evas_Text_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
1556 1546
1557 /* free filter output */
1558 if (evas_object_filter_cow_default != o->cur.filter)
1559 {
1560 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow)
1561 if (fcow->output)
1562 ENFN->image_free(ENDT, fcow->output);
1563 eina_hash_free(fcow->sources);
1564 evas_filter_program_del(fcow->chain);
1565 eina_stringshare_del(fcow->code);
1566 fcow->output = NULL;
1567 fcow->chain = NULL;
1568 fcow->sources = NULL;
1569 fcow->code = NULL;
1570 EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow);
1571 eina_cow_free(evas_object_filter_cow, (const Eina_Cow_Data **) &o->cur.filter);
1572 }
1573
1574 /* free obj */ 1547 /* free obj */
1548 eo_do(eo_obj, evas_filter_destructor());
1575 _evas_object_text_items_clear(o); 1549 _evas_object_text_items_clear(o);
1576 if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text); 1550 if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
1577 if (o->cur.font) eina_stringshare_del(o->cur.font); 1551 if (o->cur.font) eina_stringshare_del(o->cur.font);
@@ -1605,34 +1579,34 @@ evas_font_draw_async_check(Evas_Object_Protected_Data *obj,
1605 } 1579 }
1606} 1580}
1607 1581
1608static void 1582/* ugly binding between evas_fitler_mixin.c and this object */
1609_filter_cb(Evas_Filter_Context *ctx, void *data, Eina_Bool success)
1610{
1611 Eo *eo_obj = data;
1612
1613 // Destroy context as we won't reuse it.
1614 evas_filter_context_destroy(ctx);
1615 1583
1616 // Redraw text with normal styles in case of failure 1584EOLIAN void
1617 if (!success) 1585_evas_text_evas_filter_dirty(Eo *eo_obj, Evas_Text_Data *o)
1618 { 1586{
1619 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); 1587 _evas_object_text_items_clear(o);
1620 Evas_Text_Data *o = (Evas_Text_Data *) obj->private_data; 1588 o->changed = 1;
1589 _evas_object_text_recalc(eo_obj, o->cur.text);
1590}
1621 1591
1622 ERR("Filter failed at runtime!"); 1592EOLIAN void
1623 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow) 1593_evas_text_evas_filter_input_render(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o,
1624 fcow->invalid = EINA_TRUE; 1594 void *_filter, void *drawctx,
1625 EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow); 1595 int l, int r, int t, int b, Eina_Bool do_async)
1596{
1597 Evas_Filter_Context *filter = _filter;
1598 Evas_Object_Text_Item *it;
1599 (void) r; (void) b;
1626 1600
1627 // Update object 1601 EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
1628 _evas_object_text_items_clear(o); 1602 if ((o->font) && (it->text_props.len > 0))
1629 o->changed = 1; 1603 {
1630 _evas_object_text_recalc(eo_obj, o->cur.text); 1604 evas_filter_font_draw(filter, drawctx, EVAS_FILTER_BUFFER_INPUT_ID, o->font,
1631 evas_object_change(eo_obj, obj); 1605 l + it->x,
1632 evas_object_clip_dirty(eo_obj, obj); 1606 t + (int) o->max_ascent,
1633 evas_object_coords_recalc(eo_obj, obj); 1607 &it->text_props,
1634 evas_object_inform_call_resize(eo_obj); 1608 do_async);
1635 } 1609 }
1636} 1610}
1637 1611
1638static void 1612static void
@@ -1657,10 +1631,7 @@ evas_object_text_render(Evas_Object *eo_obj,
1657 int shad_dst = 0, shad_sz = 0, dx = 0, dy = 0, haveshad = 0; 1631 int shad_dst = 0, shad_sz = 0, dx = 0, dy = 0, haveshad = 0;
1658 1632
1659 /* render object to surface with context, and offxet by x,y */ 1633 /* render object to surface with context, and offxet by x,y */
1660 if (!o->cur.filter->chain) 1634 _evas_object_text_pad_get(eo_obj, o, &sl, NULL, &st, NULL);
1661 evas_text_style_pad_get(o->cur.style, &sl, NULL, &st, NULL);
1662 else
1663 evas_filter_program_padding_get(o->cur.filter->chain, &sl, NULL, &st, NULL);
1664 ENFN->context_multiplier_unset(output, context); 1635 ENFN->context_multiplier_unset(output, context);
1665 ENFN->context_render_op_set(output, context, obj->cur->render_op); 1636 ENFN->context_render_op_set(output, context, obj->cur->render_op);
1666 /* FIXME: This clipping is just until we fix inset handling correctly. */ 1637 /* FIXME: This clipping is just until we fix inset handling correctly. */
@@ -1737,190 +1708,12 @@ evas_object_text_render(Evas_Object *eo_obj,
1737 &it->text_props, \ 1708 &it->text_props, \
1738 do_async); 1709 do_async);
1739 1710
1740 /* FIXME/WARNING 1711 if (o->has_filter)
1741 * The code below is EXPERIMENTAL, and not to be considered usable or even
1742 * remotely similar to its final form. You've been warned :)
1743 */
1744
1745 if (!o->cur.filter->invalid && (o->cur.filter->chain || o->cur.filter->code))
1746 { 1712 {
1747 int X, Y, W, H; 1713 if (evas_filter_object_render(eo_obj, obj, output, context, surface, x, y, do_async, EINA_TRUE))
1748 Evas_Filter_Context *filter; 1714 return;
1749 const int inbuf = 1;
1750 const int outbuf = 2;
1751 void *filter_ctx;
1752 Eina_Bool ok;
1753 int ox = 0, oy = 0;
1754 void *previous = o->cur.filter->output;
1755 Evas_Object_Filter_Data *fcow =
1756 eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter));
1757
1758 /* NOTE: Font effect rendering is now done ENTIRELY on CPU.
1759 * So we rely on cache/cache2 to allocate a real image buffer,
1760 * that we can draw to. The OpenGL texture will be created only
1761 * after the rendering has been done, as we simply push the output
1762 * image to GL.
1763 */
1764
1765 W = obj->cur->geometry.w;
1766 H = obj->cur->geometry.h;
1767 X = obj->cur->geometry.x;
1768 Y = obj->cur->geometry.y;
1769
1770 // Prepare color multiplier
1771 COLOR_ONLY_SET(obj, cur->cache, clip);
1772 if (obj->cur->clipper)
1773 ENFN->context_multiplier_set(output, context,
1774 obj->cur->clipper->cur->cache.clip.r,
1775 obj->cur->clipper->cur->cache.clip.g,
1776 obj->cur->clipper->cur->cache.clip.b,
1777 obj->cur->clipper->cur->cache.clip.a);
1778 else
1779 ENFN->context_multiplier_unset(output, context);
1780
1781 if (!fcow->chain)
1782 {
1783 Evas_Filter_Program *pgm;
1784 pgm = evas_filter_program_new("Evas_Text", EINA_TRUE);
1785 evas_filter_program_source_set_all(pgm, fcow->sources);
1786 evas_filter_program_state_set(pgm, eo_obj, obj,
1787 fcow->state.cur.name, fcow->state.cur.value,
1788 fcow->state.next.name, fcow->state.next.value,
1789 fcow->state.pos);
1790 if (!evas_filter_program_parse(pgm, fcow->code))
1791 {
1792 ERR("Filter program parsing failed");
1793 evas_filter_program_del(pgm);
1794 fcow->invalid = EINA_TRUE;
1795
1796 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter),
1797 fcow, EINA_TRUE);
1798 goto normal_render;
1799 }
1800 fcow->chain = pgm;
1801 fcow->invalid = EINA_FALSE;
1802 }
1803 else if (previous && !fcow->changed)
1804 {
1805 Eina_Bool redraw;
1806
1807 redraw = evas_filter_program_state_set(fcow->chain, eo_obj, obj,
1808 fcow->state.cur.name, fcow->state.cur.value,
1809 fcow->state.next.name, fcow->state.next.value,
1810 fcow->state.pos);
1811 if (redraw)
1812 DBG("Filter redraw by state change!");
1813
1814 // Scan proxies to find if any changed
1815 if (!redraw && fcow->sources)
1816 {
1817 Evas_Filter_Proxy_Binding *pb;
1818 Evas_Object_Protected_Data *source;
1819 Eina_Iterator *iter;
1820
1821 iter = eina_hash_iterator_data_new(fcow->sources);
1822 EINA_ITERATOR_FOREACH(iter, pb)
1823 {
1824 source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
1825 if (source->changed)
1826 {
1827 redraw = EINA_TRUE;
1828 break;
1829 }
1830 }
1831 eina_iterator_free(iter);
1832 }
1833
1834 if (!redraw)
1835 {
1836 // Render this image only
1837 ENFN->image_draw(ENDT, context,
1838 surface, previous,
1839 0, 0, W, H, // src
1840 X + x, Y + y, W, H, // dst
1841 EINA_FALSE, // smooth
1842 do_async);
1843
1844 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter),
1845 fcow, EINA_TRUE);
1846 return;
1847 }
1848 }
1849 else
1850 evas_filter_program_state_set(fcow->chain, eo_obj, obj,
1851 fcow->state.cur.name, fcow->state.cur.value,
1852 fcow->state.next.name, fcow->state.next.value,
1853 fcow->state.pos);
1854
1855 filter = evas_filter_context_new(obj->layer->evas, do_async);
1856
1857 // Run script
1858 ok = evas_filter_context_program_use(filter, fcow->chain);
1859 if (!filter || !ok)
1860 {
1861 ERR("Parsing failed?");
1862 evas_filter_context_destroy(filter);
1863
1864 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter),
1865 fcow, EINA_TRUE);
1866 goto normal_render;
1867 }
1868
1869 // Proxies
1870 evas_filter_context_proxy_render_all(filter, eo_obj, EINA_FALSE);
1871
1872 // Draw Context
1873 filter_ctx = ENFN->context_new(ENDT);
1874 ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255);
1875
1876 // Allocate all buffers now
1877 evas_filter_context_buffers_allocate_all(filter);
1878 evas_filter_target_set(filter, context, surface, X + x, Y + y);
1879
1880 // Steal output and release previous
1881 fcow->output = evas_filter_buffer_backing_steal(filter, outbuf);
1882 if (fcow->output != previous)
1883 evas_filter_buffer_backing_release(filter, previous);
1884
1885 // Render text to input buffer
1886 EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
1887 if ((o->font) && (it->text_props.len > 0))
1888 {
1889 evas_filter_font_draw(filter, filter_ctx, inbuf, o->font,
1890 sl + ox + it->x,
1891 st + oy + (int) o->max_ascent,
1892 &it->text_props,
1893 do_async);
1894 }
1895
1896 ENFN->context_free(ENDT, filter_ctx);
1897
1898 // Add post-run callback and run filter
1899 evas_filter_context_post_run_callback_set(filter, _filter_cb, eo_obj);
1900 ok = evas_filter_run(filter);
1901 fcow->changed = EINA_FALSE;
1902
1903 if (!ok) fcow->invalid = EINA_TRUE;
1904
1905 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter),
1906 fcow, EINA_TRUE);
1907
1908 if (ok)
1909 {
1910 DBG("Effect rendering done.");
1911 return;
1912 }
1913 else
1914 {
1915 ERR("Rendering failed");
1916 goto normal_render;
1917 }
1918 } 1715 }
1919 1716
1920 /* End of the EXPERIMENTAL code */
1921
1922normal_render:
1923
1924 /* shadows */ 1717 /* shadows */
1925 switch (o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC) 1718 switch (o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC)
1926 { 1719 {
@@ -2279,7 +2072,8 @@ _evas_object_text_rehint(Evas_Object *eo_obj)
2279 /* DO II */ 2072 /* DO II */
2280 _evas_object_text_recalc(eo_obj, o->cur.text); 2073 _evas_object_text_recalc(eo_obj, o->cur.text);
2281 o->changed = 1; 2074 o->changed = 1;
2282 _evas_text_filter_changed_set(o, EINA_TRUE); 2075 if (o->has_filter)
2076 eo_do(eo_obj, evas_filter_changed_set(EINA_TRUE));
2283 evas_object_change(eo_obj, obj); 2077 evas_object_change(eo_obj, obj);
2284 evas_object_clip_dirty(eo_obj, obj); 2078 evas_object_clip_dirty(eo_obj, obj);
2285 evas_object_coords_recalc(eo_obj, obj); 2079 evas_object_coords_recalc(eo_obj, obj);
@@ -2354,10 +2148,7 @@ _evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text)
2354 2148
2355 w = _evas_object_text_horiz_advance_without_ellipsis_get(o); 2149 w = _evas_object_text_horiz_advance_without_ellipsis_get(o);
2356 h = _evas_object_text_vert_advance_get(eo_obj, o); 2150 h = _evas_object_text_vert_advance_get(eo_obj, o);
2357 if (!o->cur.filter->chain) 2151 _evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
2358 evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
2359 else
2360 evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, &t, &b);
2361 2152
2362 if (o->cur.ellipsis >= 0.0) 2153 if (o->cur.ellipsis >= 0.0)
2363 { 2154 {
@@ -2377,12 +2168,7 @@ _evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text)
2377 else 2168 else
2378 { 2169 {
2379 int t = 0, b = 0, l = 0, r = 0; 2170 int t = 0, b = 0, l = 0, r = 0;
2380 2171 _evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
2381 if (!o->cur.filter->chain)
2382 evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
2383 else
2384 evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, &t, &b);
2385
2386 eo_do_super(eo_obj, MY_CLASS, 2172 eo_do_super(eo_obj, MY_CLASS,
2387 efl_gfx_size_set(0, o->max_ascent + o->max_descent + t + b)); 2173 efl_gfx_size_set(0, o->max_ascent + o->max_descent + t + b));
2388//// obj->cur->cache.geometry.validity = 0; 2174//// obj->cur->cache.geometry.validity = 0;
@@ -2391,222 +2177,6 @@ _evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text)
2391 o->last_computed.h = obj->cur->geometry.h; 2177 o->last_computed.h = obj->cur->geometry.h;
2392} 2178}
2393 2179
2394EOLIAN static void
2395_evas_text_filter_program_set(Eo *eo_obj, Evas_Text_Data *o, const char *arg)
2396{
2397 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
2398 Evas_Filter_Program *pgm = NULL;
2399
2400 if (!o) return;
2401 if (o->cur.filter->code == arg) return;
2402 if (o->cur.filter->code && arg && !strcmp(arg, o->cur.filter->code)) return;
2403
2404 evas_object_async_block(obj);
2405 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow)
2406 {
2407 // Parse filter program
2408 evas_filter_program_del(fcow->chain);
2409 if (arg)
2410 {
2411 pgm = evas_filter_program_new("Evas_Text", EINA_TRUE);
2412 evas_filter_program_source_set_all(pgm, fcow->sources);
2413 evas_filter_program_state_set(pgm, eo_obj, obj,
2414 fcow->state.cur.name, fcow->state.cur.value,
2415 fcow->state.next.name, fcow->state.next.value,
2416 fcow->state.pos);
2417 if (!evas_filter_program_parse(pgm, arg))
2418 {
2419 ERR("Parsing failed!");
2420 evas_filter_program_del(pgm);
2421 pgm = NULL;
2422 }
2423 }
2424 fcow->chain = pgm;
2425 fcow->changed = EINA_TRUE;
2426 fcow->invalid = (pgm == NULL);
2427 eina_stringshare_replace(&fcow->code, arg);
2428 }
2429 EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow);
2430
2431 // Update object
2432 _evas_object_text_items_clear(o);
2433 o->changed = 1;
2434 _evas_object_text_recalc(eo_obj, o->cur.text);
2435 evas_object_change(eo_obj, obj);
2436 evas_object_clip_dirty(eo_obj, obj);
2437 evas_object_coords_recalc(eo_obj, obj);
2438 evas_object_inform_call_resize(eo_obj);
2439}
2440
2441static void
2442_filter_source_hash_free_cb(void *data)
2443{
2444 Evas_Filter_Proxy_Binding *pb = data;
2445 Evas_Object_Protected_Data *proxy, *source;
2446 Evas_Text_Data *o;
2447
2448 proxy = eo_data_scope_get(pb->eo_proxy, EVAS_OBJECT_CLASS);
2449 source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
2450
2451 if (source)
2452 {
2453 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy,
2454 Evas_Object_Proxy_Data, source_write)
2455 source_write->proxies = eina_list_remove(source_write->proxies, pb->eo_proxy);
2456 EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write)
2457 }
2458
2459 o = eo_data_scope_get(pb->eo_proxy, MY_CLASS);
2460
2461 if (o && proxy)
2462 {
2463 if (!eina_hash_population(o->cur.filter->sources))
2464 {
2465 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, proxy->proxy,
2466 Evas_Object_Proxy_Data, proxy_write)
2467 proxy_write->is_proxy = EINA_FALSE;
2468 EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, proxy_write)
2469 }
2470 }
2471
2472 eina_stringshare_del(pb->name);
2473 free(pb);
2474}
2475
2476EOLIAN static void
2477_evas_text_filter_source_set(Eo *eo_obj, Evas_Text_Data *o, const char *name, Evas_Object *eo_source)
2478{
2479 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
2480 Evas_Filter_Proxy_Binding *pb, *pb_old = NULL;
2481 Evas_Object_Protected_Data *source = NULL;
2482 Evas_Object_Filter_Data *fcow = NULL;
2483
2484 if (eo_source) source = eo_data_scope_get(eo_source, EVAS_OBJECT_CLASS);
2485
2486 evas_object_async_block(obj);
2487 if (!name)
2488 {
2489 if (!eo_source || !o->cur.filter->sources) return;
2490 if (eina_hash_del_by_data(o->cur.filter->sources, eo_source))
2491 goto update;
2492 return;
2493 }
2494
2495 if (!source && !o->cur.filter->sources)
2496 return;
2497
2498 if (o->cur.filter->sources)
2499 {
2500 pb_old = eina_hash_find(o->cur.filter->sources, name);
2501 if (pb_old && (pb_old->eo_source == eo_source)) return;
2502 }
2503
2504 fcow = eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&o->cur.filter);
2505
2506 if (!fcow->sources)
2507 {
2508 fcow->sources = eina_hash_string_small_new
2509 (EINA_FREE_CB(_filter_source_hash_free_cb));
2510 }
2511 else if (pb_old)
2512 eina_hash_del(fcow->sources, name, pb_old);
2513
2514 if (!source)
2515 {
2516 pb_old = eina_hash_find(fcow->sources, name);
2517 if (!pb_old)
2518 {
2519 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&o->cur.filter,
2520 fcow, EINA_TRUE);
2521 return;
2522 }
2523 eina_hash_del_by_key(fcow->sources, name);
2524 goto update;
2525 }
2526
2527 pb = calloc(1, sizeof(*pb));
2528 pb->eo_proxy = eo_obj;
2529 pb->eo_source = eo_source;
2530 pb->name = eina_stringshare_add(name);
2531
2532 if (!eina_list_data_find(source->proxy->proxies, eo_obj))
2533 {
2534 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, Evas_Object_Proxy_Data, source_write)
2535 source_write->proxies = eina_list_append(source_write->proxies, eo_obj);
2536 EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write)
2537 }
2538
2539 if (!obj->proxy->is_proxy)
2540 {
2541 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, Evas_Object_Proxy_Data, proxy_write)
2542 proxy_write->is_proxy = EINA_TRUE;
2543 EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write)
2544 }
2545
2546 eina_hash_add(fcow->sources, pb->name, pb);
2547 evas_filter_program_source_set_all(fcow->chain, fcow->sources);
2548
2549 // Update object
2550update:
2551 if (fcow)
2552 {
2553 fcow->changed = EINA_TRUE;
2554 fcow->invalid = EINA_FALSE;
2555 eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&o->cur.filter,
2556 fcow, EINA_TRUE);
2557 }
2558
2559 _evas_object_text_items_clear(o);
2560 o->changed = 1;
2561 _evas_object_text_recalc(eo_obj, o->cur.text);
2562 evas_object_change(eo_obj, obj);
2563 evas_object_clip_dirty(eo_obj, obj);
2564 evas_object_coords_recalc(eo_obj, obj);
2565 evas_object_inform_call_resize(eo_obj);
2566}
2567
2568EOLIAN static void
2569_evas_text_filter_state_set(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o,
2570 const char *cur_state, double cur_val,
2571 const char *next_state, double next_val, double pos)
2572{
2573 Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
2574
2575 evas_object_async_block(obj);
2576 if ((cur_state != o->cur.filter->state.cur.name) || (cur_val != o->cur.filter->state.cur.value) ||
2577 (next_state != o->cur.filter->state.next.name) || (next_val != o->cur.filter->state.next.value) ||
2578 (pos != o->cur.filter->state.pos))
2579 {
2580 EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow)
2581 {
2582 fcow->changed = 1;
2583 fcow->state.cur.name = cur_state;
2584 fcow->state.cur.value = cur_val;
2585 fcow->state.next.name = next_state;
2586 fcow->state.next.value = next_val;
2587 fcow->state.pos = pos;
2588
2589 if (o->cur.filter->chain)
2590 {
2591 evas_filter_program_state_set(o->cur.filter->chain, eo_obj, obj,
2592 fcow->state.cur.name, fcow->state.cur.value,
2593 fcow->state.next.name, fcow->state.next.value,
2594 fcow->state.pos);
2595 }
2596 }
2597 EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow);
2598
2599 // Mark as changed
2600 _evas_object_text_items_clear(o);
2601 o->changed = 1;
2602 _evas_object_text_recalc(eo_obj, o->cur.text);
2603 evas_object_change(eo_obj, obj);
2604 evas_object_clip_dirty(eo_obj, obj);
2605 evas_object_coords_recalc(eo_obj, obj);
2606 evas_object_inform_call_resize(eo_obj);
2607 }
2608}
2609
2610EAPI void 2180EAPI void
2611evas_object_text_font_source_set(Eo *obj, const char *font_source) 2181evas_object_text_font_source_set(Eo *obj, const char *font_source)
2612{ 2182{
@@ -2646,4 +2216,43 @@ evas_object_text_text_get(const Eo *obj)
2646 return eo_do_ret((Eo *) obj, ret, efl_text_get()); 2216 return eo_do_ret((Eo *) obj, ret, efl_text_get());
2647} 2217}
2648 2218
2219
2220/* urgh. why are those needed? */
2221
2222EOLIAN void
2223_evas_text_efl_gfx_filter_program_set(Eo *obj, Evas_Text_Data *pd EINA_UNUSED, const char *code)
2224{
2225 pd->has_filter = (code != NULL);
2226 eo_do_super(obj, MY_CLASS, efl_gfx_filter_program_set(code));
2227}
2228
2229EOLIAN const char *
2230_evas_text_efl_gfx_filter_program_get(Eo *obj, Evas_Text_Data *pd EINA_UNUSED)
2231{
2232 const char *code;
2233 return eo_do_super_ret(obj, MY_CLASS, code, efl_gfx_filter_program_get());
2234}
2235
2236EOLIAN void
2237_evas_text_efl_gfx_filter_source_set(Eo *obj, Evas_Text_Data *pd EINA_UNUSED, const char *name, Efl_Gfx_Base *source)
2238{
2239 eo_do_super(obj, MY_CLASS, efl_gfx_filter_source_set(name, source));
2240}
2241
2242EOLIAN void
2243_evas_text_efl_gfx_filter_source_get(Eo *obj, Evas_Text_Data *pd EINA_UNUSED, const char *name, Efl_Gfx_Base **source)
2244{
2245 eo_do_super(obj, MY_CLASS, efl_gfx_filter_source_get(name, source));
2246}
2247
2248EOLIAN void
2249_evas_text_efl_gfx_filter_state_set(Eo *obj, Evas_Text_Data *pd EINA_UNUSED,
2250 const char *cur_state, double cur_val,
2251 const char *next_state, double next_val, double pos)
2252{
2253 eo_do_super(obj, MY_CLASS, efl_gfx_filter_state_set(cur_state, cur_val, next_state, next_val, pos));
2254}
2255
2256
2257
2649#include "canvas/evas_text.eo.c" 2258#include "canvas/evas_text.eo.c"
diff --git a/src/lib/evas/canvas/evas_text.eo b/src/lib/evas/canvas/evas_text.eo
index 25e02dd..5991c0a 100644
--- a/src/lib/evas/canvas/evas_text.eo
+++ b/src/lib/evas/canvas/evas_text.eo
@@ -1,4 +1,4 @@
1class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties) 1class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties, Evas.Filter)
2{ 2{
3 legacy_prefix: evas_object_text; 3 legacy_prefix: evas_object_text;
4 eo_prefix: evas_obj_text; 4 eo_prefix: evas_obj_text;
@@ -219,64 +219,6 @@ class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties)
219 a: int; /*@ The alpha component of the given color. */ 219 a: int; /*@ The alpha component of the given color. */
220 } 220 }
221 } 221 }
222 @property filter_program {
223 set {
224 /*@ Set an Evas filter program on this Text Object.
225
226 If the program fails to compile (syntax error, invalid
227 buffer name, etc...), the standard text effects will be
228 applied instead (SHADOW, etc...). switch back to the
229 standard text effects.
230
231 @since 1.9
232 @note EXPERIMENTAL FEATURE. This is an unstable API,
233 please use only for testing purposes.
234 @see @ref evasfiltersref "Evas filters reference"
235 */
236 legacy: null;
237 }
238 values {
239 program: const(char)*; /*@ The program code, as defined
240 by the @ref evasfiltersref "Evas filters script language".
241 Pass NULL to remove the former program and switch back
242 to the standard text effect */
243 }
244 }
245 @property filter_source {
246 set {
247 /*@ Bind an object to use as a mask or texture with Evas Filters.
248
249 This will create automatically a new RGBA buffer containing
250 the source object's pixels (as it is rendered).
251
252 @since 1.9
253 @note EXPERIMENTAL FEATURE. This is an unstable API,
254 please use only for testing purposes.
255 @see @ref evasfiltersref "Evas filters reference" */
256 legacy: null;
257 }
258 values {
259 name: const(char)*; /*@ Object name as used in the program code */
260 eobj: Evas.Object *; /*@ Eo object to use through proxy rendering */
261 }
262 }
263 @property filter_state {
264 set {
265 /*@ Set the current state of the filter (for use from Edje)
266
267 @internal
268 @since 1.15
269 */
270 legacy: null;
271 }
272 values {
273 cur_state: const(char)*;
274 cur_val: double(0.0);
275 next_state: const(char)*;
276 next_val: double(0.0);
277 animpos: double(0.0);
278 }
279 }
280 @property max_descent { 222 @property max_descent {
281 get { 223 get {
282 return: Evas.Coord; 224 return: Evas.Coord;
@@ -384,5 +326,12 @@ class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties)
384 Efl.Text_Properties.font.set; 326 Efl.Text_Properties.font.set;
385 Efl.Text_Properties.font_source.get; 327 Efl.Text_Properties.font_source.get;
386 Efl.Text_Properties.font_source.set; 328 Efl.Text_Properties.font_source.set;
329 Efl.Gfx.Filter.program.set;
330 Efl.Gfx.Filter.program.get;
331 Efl.Gfx.Filter.source_set;
332 Efl.Gfx.Filter.source_get;
333 Efl.Gfx.Filter.state.set;
334 Evas.Filter.dirty;
335 Evas.Filter.input_render;
387 } 336 }
388} 337}
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 215e996..33bfcd4 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1798,6 +1798,9 @@ void evas_model_set_from_torus_primitive(Evas_Canvas3D_Mesh *mesh, int frame, Ev
1798void evas_model_set_from_surface_primitive(Evas_Canvas3D_Mesh *mesh, int frame, Evas_Canvas3D_Surface_Func func, int precision, Evas_Vec2 tex_scale); 1798void evas_model_set_from_surface_primitive(Evas_Canvas3D_Mesh *mesh, int frame, Evas_Canvas3D_Surface_Func func, int precision, Evas_Vec2 tex_scale);
1799void evas_model_set_from_terrain_primitive(Evas_Canvas3D_Mesh *mesh, int frame, int precision, Evas_Vec2 tex_scale); 1799void evas_model_set_from_terrain_primitive(Evas_Canvas3D_Mesh *mesh, int frame, int precision, Evas_Vec2 tex_scale);
1800 1800
1801/* Filter functions */
1802Eina_Bool evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async, Eina_Bool alpha);
1803
1801extern int _evas_alloc_error; 1804extern int _evas_alloc_error;
1802extern int _evas_event_counter; 1805extern int _evas_event_counter;
1803 1806
diff --git a/src/tests/evas/evas_test_filters.c b/src/tests/evas/evas_test_filters.c
index d211114..0b72d7c 100644
--- a/src/tests/evas/evas_test_filters.c
+++ b/src/tests/evas/evas_test_filters.c
@@ -306,7 +306,7 @@ START_TEST(evas_filter_text_padding_test)
306 // Don't test proxy cases here. 306 // Don't test proxy cases here.
307 if (tc->source) continue; 307 if (tc->source) continue;
308 308
309 eo_do(to, evas_obj_text_filter_program_set(tc->code)); 309 eo_do(to, efl_gfx_filter_program_set(tc->code));
310 evas_object_text_style_pad_get(to, &l, &r, &t, &b); 310 evas_object_text_style_pad_get(to, &l, &r, &t, &b);
311 evas_object_geometry_get(to, NULL, NULL, &W, &H); 311 evas_object_geometry_get(to, NULL, NULL, &W, &H);
312 //fprintf(stderr, "Case %d: %dx%d for padding %d,%d,%d,%d\n", k, W, H, l, r, t, b); 312 //fprintf(stderr, "Case %d: %dx%d for padding %d,%d,%d,%d\n", k, W, H, l, r, t, b);
@@ -394,14 +394,14 @@ START_TEST(evas_filter_text_render_test)
394 evas_object_show(o); 394 evas_object_show(o);
395 eo_do(to, 395 eo_do(to,
396 efl_gfx_color_set(255, 255, 255, 255), 396 efl_gfx_color_set(255, 255, 255, 255),
397 evas_obj_text_filter_source_set(tc->source, o), 397 efl_gfx_filter_source_set(tc->source, o),
398 evas_obj_text_filter_program_set(tc->code)); 398 efl_gfx_filter_program_set(tc->code));
399 } 399 }
400 else 400 else
401 { 401 {
402 eo_do(to, 402 eo_do(to,
403 efl_gfx_color_set(255, 255, 255, 255), 403 efl_gfx_color_set(255, 255, 255, 255),
404 evas_obj_text_filter_program_set(tc->code)); 404 efl_gfx_filter_program_set(tc->code));
405 } 405 }
406 406
407 evas_object_geometry_get(to, NULL, NULL, &w, &h); 407 evas_object_geometry_get(to, NULL, NULL, &w, &h);