diff options
author | Jean-Philippe Andre <jp.andre@samsung.com> | 2015-06-17 16:26:30 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2015-06-25 14:36:09 +0900 |
commit | 64fd278c62e3286c453885216d2d0c86a01ce9fc (patch) | |
tree | d4463d71e84454bb354b4da152a60d51b4f506c6 | |
parent | a18107309dc5233e76b77016b6eb3ef09ddf25ec (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.
-rw-r--r-- | doc/previews/preview_text_filter.c | 2 | ||||
-rw-r--r-- | src/Makefile_Efl.am | 4 | ||||
-rw-r--r-- | src/Makefile_Evas.am | 8 | ||||
-rw-r--r-- | src/lib/edje/edje_calc.c | 36 | ||||
-rw-r--r-- | src/lib/edje/edje_private.h | 2 | ||||
-rw-r--r-- | src/lib/edje/edje_text.c | 2 | ||||
-rw-r--r-- | src/lib/efl/Efl.h | 1 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_gfx_filter.eo | 73 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_interfaces_main.c | 2 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_filter.eo | 66 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_filter_mixin.c | 512 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_object_main.c | 2 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_object_text.c | 609 | ||||
-rw-r--r-- | src/lib/evas/canvas/evas_text.eo | 67 | ||||
-rw-r--r-- | src/lib/evas/include/evas_private.h | 3 | ||||
-rw-r--r-- | src/tests/evas/evas_test_filters.c | 8 |
16 files changed, 796 insertions, 601 deletions
diff --git a/doc/previews/preview_text_filter.c b/doc/previews/preview_text_filter.c index 864342b080..24c51cdaca 100644 --- a/doc/previews/preview_text_filter.c +++ b/doc/previews/preview_text_filter.c | |||
@@ -111,7 +111,7 @@ main(int argc, char **argv) | |||
111 | evas_object_color_set(o, 255, 255, 255, 255); | 111 | evas_object_color_set(o, 255, 255, 255, 255); |
112 | evas_object_show(o); | 112 | evas_object_show(o); |
113 | 113 | ||
114 | eo_do(o, evas_obj_text_filter_program_set(filter)); | 114 | eo_do(o, efl_gfx_filter_program_set(filter)); |
115 | 115 | ||
116 | ecore_evas_manual_render(wpd.ee); | 116 | ecore_evas_manual_render(wpd.ee); |
117 | evas_object_geometry_get(o, NULL, NULL, &w, &h); | 117 | evas_object_geometry_get(o, NULL, NULL, &w, &h); |
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am index 5d45ae03ae..ad49f47bb6 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 | ||
18 | efl_eolian_files_h = $(efl_eolian_files:%.eo=%.eo.h) | 20 | efl_eolian_files_h = $(efl_eolian_files:%.eo=%.eo.h) |
19 | efl_eolian_files_c = $(efl_eolian_files:%.eo=%.eo.c) | 21 | efl_eolian_files_c = $(efl_eolian_files:%.eo=%.eo.c) |
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index ef59a2f185..cfba9b61e3 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 | ||
45 | evas_eolian_type_files = \ | 47 | evas_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 | ||
523 | lib_evas_libevas_la_SOURCES += lib/evas/filters/evas_filter.c \ | 525 | lib_evas_libevas_la_SOURCES += \ |
526 | lib/evas/canvas/evas_filter_mixin.c \ | ||
527 | lib/evas/filters/evas_filter.c \ | ||
524 | lib/evas/filters/evas_filter_blend.c \ | 528 | lib/evas/filters/evas_filter_blend.c \ |
525 | lib/evas/filters/evas_filter_blur.c \ | 529 | lib/evas/filters/evas_filter_blur.c \ |
526 | lib/evas/filters/evas_filter_bump.c \ | 530 | lib/evas/filters/evas_filter_bump.c \ |
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index 30478a6ac8..a1cd9c1aff 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, | |||
2406 | static inline const char * | 2406 | static 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 6f209f8dfd..d8c0411507 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); |
2297 | Evas_Font_Size _edje_text_size_calc(Evas_Font_Size size, Edje_Text_Class *tc); | 2297 | Evas_Font_Size _edje_text_size_calc(Evas_Font_Size size, Edje_Text_Class *tc); |
2298 | const char * _edje_text_class_font_get(Edje *ed, | 2298 | const 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 0f65671b93..a49b661c9e 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 f8eb8eb1f9..7a2ea8fa70 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 0000000000..baa604696b --- /dev/null +++ b/src/lib/efl/interfaces/efl_gfx_filter.eo | |||
@@ -0,0 +1,73 @@ | |||
1 | interface 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 31a3aae616..5b044ff87e 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 | |||
23 | EAPI const Eo_Event_Description _EFL_GFX_CHANGED = | 25 | EAPI 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 0000000000..7f6bdcb096 --- /dev/null +++ b/src/lib/evas/canvas/evas_filter.eo | |||
@@ -0,0 +1,66 @@ | |||
1 | mixin 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 0000000000..20aa8cc72d --- /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 | |||
12 | typedef struct _Evas_Filter_Data Evas_Filter_Data; | ||
13 | struct _Evas_Filter_Data | ||
14 | { | ||
15 | const Evas_Object_Filter_Data *data; | ||
16 | }; | ||
17 | |||
18 | static 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 | |||
42 | static 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 | |||
77 | Eina_Bool | ||
78 | evas_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 | |||
265 | EOLIAN 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 | |||
311 | EOLIAN 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 | |||
317 | EOLIAN 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 | ||
389 | update: | ||
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 | |||
404 | EOLIAN 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 | |||
412 | EOLIAN 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 | |||
453 | EOLIAN 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 | |||
468 | EOLIAN 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 | |||
479 | EOLIAN 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 | |||
490 | EOLIAN 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 | |||
496 | EOLIAN 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 d047d96668..9552a44de4 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 80a7e75f46..65350462d2 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 | ||
71 | struct _Evas_Object_Text_Item | 73 | struct _Evas_Object_Text_Item |
@@ -368,13 +370,11 @@ evas_object_text_add(Evas *e) | |||
368 | } | 370 | } |
369 | 371 | ||
370 | EOLIAN static Eo * | 372 | EOLIAN 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 | |||
397 | EOLIAN static const char* | 397 | EOLIAN 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 | ||
404 | static 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 | |||
416 | EOLIAN static void | 403 | EOLIAN 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 | ||
656 | static 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 | ||
1347 | EOLIAN static void | 1344 | EOLIAN 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 | ||
1362 | EAPI int | 1350 | EAPI 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 | ||
1544 | EOLIAN static void | 1534 | EOLIAN 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 | ||
1608 | static 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 | 1584 | EOLIAN 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!"); | 1592 | EOLIAN 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 | ||
1638 | static void | 1612 | static 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 | |||
1922 | normal_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 | ||
2394 | EOLIAN 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 | |||
2441 | static 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 | |||
2476 | EOLIAN 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 | ||
2550 | update: | ||
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 | |||
2568 | EOLIAN 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 | |||
2610 | EAPI void | 2180 | EAPI void |
2611 | evas_object_text_font_source_set(Eo *obj, const char *font_source) | 2181 | evas_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 | |||
2222 | EOLIAN 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 | |||
2229 | EOLIAN 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 | |||
2236 | EOLIAN 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 | |||
2242 | EOLIAN 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 | |||
2248 | EOLIAN 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 25e02dd750..5991c0a56f 100644 --- a/src/lib/evas/canvas/evas_text.eo +++ b/src/lib/evas/canvas/evas_text.eo | |||
@@ -1,4 +1,4 @@ | |||
1 | class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties) | 1 | class 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 215e996581..33bfcd4285 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 | |||
1798 | void evas_model_set_from_surface_primitive(Evas_Canvas3D_Mesh *mesh, int frame, Evas_Canvas3D_Surface_Func func, int precision, Evas_Vec2 tex_scale); | 1798 | void evas_model_set_from_surface_primitive(Evas_Canvas3D_Mesh *mesh, int frame, Evas_Canvas3D_Surface_Func func, int precision, Evas_Vec2 tex_scale); |
1799 | void evas_model_set_from_terrain_primitive(Evas_Canvas3D_Mesh *mesh, int frame, int precision, Evas_Vec2 tex_scale); | 1799 | void evas_model_set_from_terrain_primitive(Evas_Canvas3D_Mesh *mesh, int frame, int precision, Evas_Vec2 tex_scale); |
1800 | 1800 | ||
1801 | /* Filter functions */ | ||
1802 | Eina_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 | |||
1801 | extern int _evas_alloc_error; | 1804 | extern int _evas_alloc_error; |
1802 | extern int _evas_event_counter; | 1805 | extern 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 d211114e06..0b72d7c77d 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); |