summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-05-26 19:37:21 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2015-06-25 14:36:08 +0900
commitffea07a0493df3423d633d4ef3ce401fc15c0fd4 (patch)
tree5a524bf9c3d9b3aae676d4908e27288c41e5031d /src
parentd148c0f0d233900061ba27691881af073b4f0f63 (diff)
Evas filters: Pass text colors to the parser
This does not implement the full feature yet (Lua variable is not set). This commit also brings various fixes.
Diffstat (limited to 'src')
-rw-r--r--src/lib/evas/canvas/evas_object_text.c38
-rw-r--r--src/lib/evas/filters/evas_filter.c6
-rw-r--r--src/lib/evas/filters/evas_filter_parser.c491
-rw-r--r--src/lib/evas/include/evas_filter.h3
4 files changed, 329 insertions, 209 deletions
diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c
index ba63da4..39e6c62 100644
--- a/src/lib/evas/canvas/evas_object_text.c
+++ b/src/lib/evas/canvas/evas_object_text.c
@@ -13,6 +13,8 @@
13/* save typing */ 13/* save typing */
14#define ENFN obj->layer->evas->engine.func 14#define ENFN obj->layer->evas->engine.func
15#define ENDT obj->layer->evas->engine.data.output 15#define ENDT obj->layer->evas->engine.data.output
16#define COL_OBJECT(obj, sub) ARGB_JOIN(obj->sub->color.a, obj->sub->color.r, obj->sub->color.g, obj->sub->color.b)
17#define COL_JOIN(o, sub, color) ARGB_JOIN(o->sub.color.a, o->sub.color.r, o->sub.color.g, o->sub.color.b)
16 18
17/* private magic number for text objects */ 19/* private magic number for text objects */
18static const char o_type[] = "text"; 20static const char o_type[] = "text";
@@ -1766,16 +1768,15 @@ evas_object_text_render(Evas_Object *eo_obj,
1766 Y = obj->cur->geometry.y; 1768 Y = obj->cur->geometry.y;
1767 1769
1768 // Prepare color multiplier 1770 // Prepare color multiplier
1769 ENFN->context_color_set(ENDT, context, 255, 255, 255, 255); 1771 COLOR_ONLY_SET(obj, cur->cache, clip);
1770 if ((obj->cur->cache.clip.r == 255) && (obj->cur->cache.clip.g == 255) && 1772 if (obj->cur->clipper)
1771 (obj->cur->cache.clip.b == 255) && (obj->cur->cache.clip.a == 255)) 1773 ENFN->context_multiplier_set(output, context,
1772 ENFN->context_multiplier_unset(ENDT, 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);
1773 else 1778 else
1774 ENFN->context_multiplier_set(ENDT, context, 1779 ENFN->context_multiplier_unset(output, context);
1775 obj->cur->cache.clip.r,
1776 obj->cur->cache.clip.g,
1777 obj->cur->cache.clip.b,
1778 obj->cur->cache.clip.a);
1779 1780
1780 if (!fcow->chain) 1781 if (!fcow->chain)
1781 { 1782 {
@@ -1794,10 +1795,15 @@ evas_object_text_render(Evas_Object *eo_obj,
1794 } 1795 }
1795 fcow->chain = pgm; 1796 fcow->chain = pgm;
1796 fcow->invalid = EINA_FALSE; 1797 fcow->invalid = EINA_FALSE;
1798 evas_filter_program_state_set(fcow->chain, eo_obj, obj);
1797 } 1799 }
1798 else if (previous) 1800 else if (previous && !fcow->changed)
1799 { 1801 {
1800 Eina_Bool redraw = fcow->changed; 1802 Eina_Bool redraw;
1803
1804 redraw = evas_filter_program_state_set(fcow->chain, eo_obj, obj);
1805 if (redraw)
1806 DBG("Filter redraw by state change!");
1801 1807
1802 // Scan proxies to find if any changed 1808 // Scan proxies to find if any changed
1803 if (!redraw && fcow->sources) 1809 if (!redraw && fcow->sources)
@@ -1834,8 +1840,12 @@ evas_object_text_render(Evas_Object *eo_obj,
1834 return; 1840 return;
1835 } 1841 }
1836 } 1842 }
1843 else
1844 evas_filter_program_state_set(fcow->chain, eo_obj, obj);
1837 1845
1838 filter = evas_filter_context_new(obj->layer->evas, do_async); 1846 filter = evas_filter_context_new(obj->layer->evas, do_async);
1847
1848 // Run script
1839 ok = evas_filter_context_program_use(filter, fcow->chain); 1849 ok = evas_filter_context_program_use(filter, fcow->chain);
1840 if (!filter || !ok) 1850 if (!filter || !ok)
1841 { 1851 {
@@ -2372,8 +2382,6 @@ _evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text)
2372 o->last_computed.h = obj->cur->geometry.h; 2382 o->last_computed.h = obj->cur->geometry.h;
2373} 2383}
2374 2384
2375/* EXPERIMENTAL CODE BEGIN */
2376
2377EOLIAN static void 2385EOLIAN static void
2378_evas_text_filter_program_set(Eo *eo_obj, Evas_Text_Data *o, const char *arg) 2386_evas_text_filter_program_set(Eo *eo_obj, Evas_Text_Data *o, const char *arg)
2379{ 2387{
@@ -2393,7 +2401,7 @@ _evas_text_filter_program_set(Eo *eo_obj, Evas_Text_Data *o, const char *arg)
2393 { 2401 {
2394 pgm = evas_filter_program_new("Evas_Text", EINA_TRUE); 2402 pgm = evas_filter_program_new("Evas_Text", EINA_TRUE);
2395 evas_filter_program_source_set_all(pgm, fcow->sources); 2403 evas_filter_program_source_set_all(pgm, fcow->sources);
2396 evas_filter_program_state_set(pgm, obj->cur->geometry.w, obj->cur->geometry.h); 2404 evas_filter_program_state_set(pgm, eo_obj, obj);
2397 if (!evas_filter_program_parse(pgm, arg)) 2405 if (!evas_filter_program_parse(pgm, arg))
2398 { 2406 {
2399 ERR("Parsing failed!"); 2407 ERR("Parsing failed!");
@@ -2543,8 +2551,6 @@ update:
2543 evas_object_inform_call_resize(eo_obj); 2551 evas_object_inform_call_resize(eo_obj);
2544} 2552}
2545 2553
2546/* EXPERIMENTAL CODE END */
2547
2548EAPI void 2554EAPI void
2549evas_object_text_font_source_set(Eo *obj, const char *font_source) 2555evas_object_text_font_source_set(Eo *obj, const char *font_source)
2550{ 2556{
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index f8aebb8..1a8c2ed 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -493,6 +493,7 @@ evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only)
493 493
494 fb->transient = EINA_FALSE; 494 fb->transient = EINA_FALSE;
495 495
496 DBG("Created context buffer %d", fb->id);
496 return fb->id; 497 return fb->id;
497} 498}
498 499
@@ -741,12 +742,8 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
741 Evas_Filter_Buffer *buf = NULL; 742 Evas_Filter_Buffer *buf = NULL;
742 Eina_List *l; 743 Eina_List *l;
743 744
744 DBG("Want temp buffer: %dx%d %s", w, h, alpha_only ? "alpha" : "rgba");
745 EINA_LIST_FOREACH(ctx->buffers, l, buf) 745 EINA_LIST_FOREACH(ctx->buffers, l, buf)
746 { 746 {
747 DBG("Try buffer #%d: temp:%d %dx%d %s (lock:%d)",
748 buf->id, buf->transient,
749 buf->w, buf->h, buf->alpha_only ? "alpha" : "rgba", buf->locked);
750 if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only)) 747 if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only))
751 { 748 {
752 if ((!w || (w == buf->w)) 749 if ((!w || (w == buf->w))
@@ -766,7 +763,6 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
766 763
767 buf = _buffer_new(ctx, w, h, alpha_only); 764 buf = _buffer_new(ctx, w, h, alpha_only);
768 buf->locked = EINA_TRUE; 765 buf->locked = EINA_TRUE;
769 DBG("Created temporary buffer: %d (%s)", buf->id, alpha_only ? "Alpha" : "RGBA");
770 return buf; 766 return buf;
771} 767}
772 768
diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c
index 426e31c..e1a59d2 100644
--- a/src/lib/evas/filters/evas_filter_parser.c
+++ b/src/lib/evas/filters/evas_filter_parser.c
@@ -18,6 +18,10 @@
18#define EVAS_FILTER_MODE_GROW (EVAS_FILTER_MODE_LAST+1) 18#define EVAS_FILTER_MODE_GROW (EVAS_FILTER_MODE_LAST+1)
19#define EVAS_FILTER_MODE_BUFFER (EVAS_FILTER_MODE_LAST+2) 19#define EVAS_FILTER_MODE_BUFFER (EVAS_FILTER_MODE_LAST+2)
20 20
21#define INSTR_PARAM_CHECK(a) do { if (!(a)) { \
22 ERR("Argument %s can not be nil in %s!", #a, instr->name); return -1; } \
23 } while (0)
24
21/* Note on the documentation: 25/* Note on the documentation:
22 * To keep it simple, I'm not using any fancy features, only <ul>/<li> lists 26 * To keep it simple, I'm not using any fancy features, only <ul>/<li> lists
23 * and @a, @b, @c flags from Doxygen. 27 * and @a, @b, @c flags from Doxygen.
@@ -286,6 +290,7 @@ typedef struct _Buffer
286 } pad; 290 } pad;
287 int w, h; 291 int w, h;
288 Eina_Bool alpha : 1; 292 Eina_Bool alpha : 1;
293 Eina_Bool manual : 1; // created by "buffer" instruction
289} Buffer; 294} Buffer;
290 295
291typedef struct _Instruction_Param 296typedef struct _Instruction_Param
@@ -316,11 +321,23 @@ struct _Evas_Filter_Instruction
316 Eina_Bool (* parse_run) (lua_State *L, Evas_Filter_Program *, Evas_Filter_Instruction *); 321 Eina_Bool (* parse_run) (lua_State *L, Evas_Filter_Program *, Evas_Filter_Instruction *);
317 struct 322 struct
318 { 323 {
319 void (* update) (Evas_Filter_Program *, Evas_Filter_Instruction *, int *, int *, int *, int *); 324 int (* update) (Evas_Filter_Program *, Evas_Filter_Instruction *, int *, int *, int *, int *);
320 } pad; 325 } pad;
321 Eina_Bool valid : 1; 326 Eina_Bool valid : 1;
322}; 327};
323 328
329struct _Evas_Filter_Program_State
330{
331 struct {
332 struct { int a, r, g, b; } outline;
333 struct { int a, r, g, b; } shadow;
334 struct { int a, r, g, b; } glow;
335 struct { int a, r, g, b; } glow2;
336 } text;
337 struct { int a, r, g, b; } color;
338 int w, h;
339};
340
324struct _Evas_Filter_Program 341struct _Evas_Filter_Program
325{ 342{
326 Eina_Stringshare *name; // Optional for now 343 Eina_Stringshare *name; // Optional for now
@@ -328,11 +345,13 @@ struct _Evas_Filter_Program
328 Eina_Inlist /* Evas_Filter_Instruction */ *instructions; 345 Eina_Inlist /* Evas_Filter_Instruction */ *instructions;
329 Eina_Inlist /* Buffer */ *buffers; 346 Eina_Inlist /* Buffer */ *buffers;
330 struct { 347 struct {
348 // Note: padding can't be in the state as it's calculated after running Lua
331 int l, r, t, b; 349 int l, r, t, b;
332 } pad; 350 } pad;
333 int w, h; 351 Evas_Filter_Program_State state;
334 lua_State *L; 352 lua_State *L;
335 int lua_func; 353 int lua_func;
354 int last_bufid;
336 Eina_Bool valid : 1; 355 Eina_Bool valid : 1;
337 Eina_Bool padding_calc : 1; // Padding has been calculated 356 Eina_Bool padding_calc : 1; // Padding has been calculated
338 Eina_Bool padding_set : 1; // Padding has been forced 357 Eina_Bool padding_set : 1; // Padding has been forced
@@ -602,7 +621,6 @@ static Buffer *
602_buffer_get(Evas_Filter_Program *pgm, const char *name) 621_buffer_get(Evas_Filter_Program *pgm, const char *name)
603{ 622{
604 Buffer *buf; 623 Buffer *buf;
605 Evas_Object *source;
606 624
607 EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, NULL); 625 EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, NULL);
608 EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); 626 EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
@@ -611,22 +629,6 @@ _buffer_get(Evas_Filter_Program *pgm, const char *name)
611 if (!strcmp(buf->name, name)) 629 if (!strcmp(buf->name, name))
612 return buf; 630 return buf;
613 631
614 // Auto proxies
615 if (pgm->proxies)
616 {
617 source = eina_hash_find(pgm->proxies, name);
618 if (!source) return NULL;
619
620 buf = calloc(1, sizeof(Buffer));
621 if (!buf) return NULL;
622
623 buf->name = eina_stringshare_add(name);
624 buf->proxy = eina_stringshare_add(name);
625 buf->alpha = EINA_FALSE;
626 pgm->buffers = eina_inlist_append(pgm->buffers, EINA_INLIST_GET(buf));
627 return buf;
628 }
629
630 return NULL; 632 return NULL;
631} 633}
632 634
@@ -636,18 +638,11 @@ _lua_buffer_push(lua_State *L, Buffer *buf)
636 Buffer **ptr; 638 Buffer **ptr;
637 639
638 lua_getglobal(L, buf->name); 640 lua_getglobal(L, buf->name);
639 if (lua_isnil(L, -1)) 641 ptr = lua_newuserdata(L, sizeof(Buffer **));
640 { 642 *ptr = buf;
641 ptr = lua_newuserdata(L, sizeof(Buffer **)); 643 luaL_getmetatable(L, _lua_buffer_meta);
642 *ptr = buf; 644 lua_setmetatable(L, -2);
643 luaL_getmetatable(L, _lua_buffer_meta); 645 lua_setglobal(L, buf->name);
644 lua_setmetatable(L, -2);
645 lua_setglobal(L, buf->name);
646 }
647 else
648 {
649 ERR("to do");
650 }
651 646
652 return EINA_TRUE; 647 return EINA_TRUE;
653} 648}
@@ -727,7 +722,7 @@ _lua_buffer_source(lua_State *L)
727 722
728static Buffer * 723static Buffer *
729_buffer_add(Evas_Filter_Program *pgm, const char *name, Eina_Bool alpha, 724_buffer_add(Evas_Filter_Program *pgm, const char *name, Eina_Bool alpha,
730 const char *src) 725 const char *src, Eina_Bool manual)
731{ 726{
732 Buffer *buf; 727 Buffer *buf;
733 728
@@ -746,11 +741,20 @@ _buffer_add(Evas_Filter_Program *pgm, const char *name, Eina_Bool alpha,
746 buf = calloc(1, sizeof(Buffer)); 741 buf = calloc(1, sizeof(Buffer));
747 if (!buf) return NULL; 742 if (!buf) return NULL;
748 743
749 buf->name = eina_stringshare_add(name); 744 buf->manual = manual;
745 if (!name)
746 {
747 char bufname[32];
748 snprintf(bufname, sizeof(bufname), "__buffer%02d", ++pgm->last_bufid);
749 buf->name = eina_stringshare_add(bufname);
750 }
751 else
752 buf->name = eina_stringshare_add(name);
750 buf->proxy = eina_stringshare_add(src); 753 buf->proxy = eina_stringshare_add(src);
751 buf->alpha = alpha; 754 buf->alpha = alpha;
752 buf->w = pgm->w; 755 buf->w = pgm->state.w;
753 buf->h = pgm->h; 756 buf->h = pgm->state.h;
757
754 pgm->buffers = eina_inlist_append(pgm->buffers, EINA_INLIST_GET(buf)); 758 pgm->buffers = eina_inlist_append(pgm->buffers, EINA_INLIST_GET(buf));
755 _lua_buffer_push(pgm->L, buf); 759 _lua_buffer_push(pgm->L, buf);
756 760
@@ -810,7 +814,6 @@ _buffer_instruction_parse_run(lua_State *L,
810 char bufname[32] = {0}; 814 char bufname[32] = {0};
811 const char *src, *rgba; 815 const char *src, *rgba;
812 Eina_Bool ok, alpha = EINA_FALSE; 816 Eina_Bool ok, alpha = EINA_FALSE;
813 int cnt;
814 817
815 EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE); 818 EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
816 EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE); 819 EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
@@ -823,9 +826,8 @@ _buffer_instruction_parse_run(lua_State *L,
823 826
824 alpha = (rgba && !strcasecmp(rgba, "alpha")); 827 alpha = (rgba && !strcasecmp(rgba, "alpha"));
825 828
826 cnt = (pgm->buffers ? eina_inlist_count(pgm->buffers) : 0) + 1; 829 snprintf(bufname, sizeof(bufname), "__buffer%02d", ++pgm->last_bufid);
827 snprintf(bufname, sizeof(bufname), "__buffer%02d", cnt); 830 ok = (_buffer_add(pgm, bufname, alpha, src, EINA_TRUE) != NULL);
828 ok = (_buffer_add(pgm, bufname, alpha, src) != NULL);
829 831
830 if (!ok) return EINA_FALSE; 832 if (!ok) return EINA_FALSE;
831 833
@@ -851,45 +853,44 @@ _buffer_instruction_prepare(Evas_Filter_Program *pgm EINA_UNUSED,
851 return EINA_TRUE; 853 return EINA_TRUE;
852} 854}
853 855
854static void 856static int
855_blend_padding_update(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr, 857_blend_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
858 Evas_Filter_Instruction *instr,
856 int *padl, int *padr, int *padt, int *padb) 859 int *padl, int *padr, int *padt, int *padb)
857{ 860{
858 const char *inbuf, *outbuf;
859 Evas_Filter_Fill_Mode fillmode; 861 Evas_Filter_Fill_Mode fillmode;
860 Buffer *in, *out; 862 Buffer *src, *dst;
861 int ox, oy, l = 0, r = 0, t = 0, b = 0; 863 int ox, oy, l = 0, r = 0, t = 0, b = 0;
862 864
863 ox = _instruction_param_geti(instr, "ox", NULL); 865 ox = _instruction_param_geti(instr, "ox", NULL);
864 oy = _instruction_param_geti(instr, "oy", NULL); 866 oy = _instruction_param_geti(instr, "oy", NULL);
865 867
866 inbuf = _instruction_param_gets(instr, "src", NULL); 868 src = _instruction_param_getbuf(instr, "src", NULL);
867 in = _buffer_get(pgm, inbuf); 869 dst = _instruction_param_getbuf(instr, "dst", NULL);
868 EINA_SAFETY_ON_NULL_RETURN(in); 870 INSTR_PARAM_CHECK(src);
869 871 INSTR_PARAM_CHECK(dst);
870 outbuf = _instruction_param_gets(instr, "dst", NULL);
871 out = _buffer_get(pgm, outbuf);
872 EINA_SAFETY_ON_NULL_RETURN(out);
873 872
874 fillmode = _fill_mode_get(instr); 873 fillmode = _fill_mode_get(instr);
875 if (fillmode & (EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_REPEAT_X)) ox = 0; 874 if (fillmode & (EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_REPEAT_X)) ox = 0;
876 if (fillmode & (EVAS_FILTER_FILL_MODE_STRETCH_Y | EVAS_FILTER_FILL_MODE_REPEAT_Y)) oy = 0; 875 if (fillmode & (EVAS_FILTER_FILL_MODE_STRETCH_Y | EVAS_FILTER_FILL_MODE_REPEAT_Y)) oy = 0;
877 876
878 if (ox < 0) l = (-ox) + in->pad.l; 877 if (ox < 0) l = (-ox) + src->pad.l;
879 else r = ox + in->pad.r; 878 else r = ox + src->pad.r;
880 879
881 if (oy < 0) t = (-oy) + in->pad.t; 880 if (oy < 0) t = (-oy) + src->pad.t;
882 else b = oy + in->pad.b; 881 else b = oy + src->pad.b;
883 882
884 if (out->pad.l < l) out->pad.l = l; 883 if (dst->pad.l < l) dst->pad.l = l;
885 if (out->pad.r < r) out->pad.r = r; 884 if (dst->pad.r < r) dst->pad.r = r;
886 if (out->pad.t < t) out->pad.t = t; 885 if (dst->pad.t < t) dst->pad.t = t;
887 if (out->pad.b < b) out->pad.b = b; 886 if (dst->pad.b < b) dst->pad.b = b;
888 887
889 if (padl) *padl = l; 888 if (padl) *padl = l;
890 if (padr) *padr = r; 889 if (padr) *padr = r;
891 if (padt) *padt = t; 890 if (padt) *padt = t;
892 if (padb) *padb = b; 891 if (padb) *padb = b;
892
893 return 0;
893} 894}
894 895
895/** 896/**
@@ -955,33 +956,32 @@ _blend_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction *in
955 return EINA_TRUE; 956 return EINA_TRUE;
956} 957}
957 958
958static void 959static int
959_blur_padding_update(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr, 960_blur_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
961 Evas_Filter_Instruction *instr,
960 int *padl, int *padr, int *padt, int *padb) 962 int *padl, int *padr, int *padt, int *padb)
961{ 963{
962 Eina_Bool yset = EINA_FALSE; 964 Eina_Bool yset = EINA_FALSE;
963 int rx, ry, ox, oy, l, r, t, b, count; 965 int rx, ry, ox, oy, l, r, t, b, count;
964 const char *inbuf, *outbuf, *typestr; 966 const char *typestr;
965 Evas_Filter_Blur_Type type = EVAS_FILTER_BLUR_DEFAULT; 967 Evas_Filter_Blur_Type type = EVAS_FILTER_BLUR_DEFAULT;
966 Buffer *in, *out; 968 Buffer *src, *dst;
967 969
968 rx = _instruction_param_geti(instr, "rx", NULL); 970 rx = _instruction_param_geti(instr, "rx", NULL);
969 ry = _instruction_param_geti(instr, "ry", &yset); 971 ry = _instruction_param_geti(instr, "ry", &yset);
970 ox = _instruction_param_geti(instr, "ox", NULL); 972 ox = _instruction_param_geti(instr, "ox", NULL);
971 oy = _instruction_param_geti(instr, "oy", NULL); 973 oy = _instruction_param_geti(instr, "oy", NULL);
972 inbuf = _instruction_param_gets(instr, "src", NULL);
973 outbuf = _instruction_param_gets(instr, "dst", NULL);
974 count = _instruction_param_geti(instr, "count", NULL); 974 count = _instruction_param_geti(instr, "count", NULL);
975 typestr = _instruction_param_gets(instr, "type", NULL); 975 typestr = _instruction_param_gets(instr, "type", NULL);
976 976
977 src = _instruction_param_getbuf(instr, "src", NULL);
978 dst = _instruction_param_getbuf(instr, "dst", NULL);
979 INSTR_PARAM_CHECK(src);
980 INSTR_PARAM_CHECK(dst);
981
977 if (typestr && !strcasecmp(typestr, "box")) 982 if (typestr && !strcasecmp(typestr, "box"))
978 type = EVAS_FILTER_BLUR_BOX; 983 type = EVAS_FILTER_BLUR_BOX;
979 984
980 in = _buffer_get(pgm, inbuf);
981 out = _buffer_get(pgm, outbuf);
982 EINA_SAFETY_ON_NULL_RETURN(in);
983 EINA_SAFETY_ON_NULL_RETURN(out);
984
985 if (!yset) ry = rx; 985 if (!yset) ry = rx;
986 if (rx < 0) rx = 0; 986 if (rx < 0) rx = 0;
987 if (ry < 0) ry = 0; 987 if (ry < 0) ry = 0;
@@ -997,20 +997,22 @@ _blur_padding_update(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr,
997 rx *= count; 997 rx *= count;
998 ry *= count; 998 ry *= count;
999 999
1000 l = rx + in->pad.l + ((ox < 0) ? (-ox) : 0); 1000 l = rx + src->pad.l + ((ox < 0) ? (-ox) : 0);
1001 r = rx + in->pad.r + ((ox > 0) ? ox : 0); 1001 r = rx + src->pad.r + ((ox > 0) ? ox : 0);
1002 t = ry + in->pad.t + ((oy < 0) ? (-oy) : 0); 1002 t = ry + src->pad.t + ((oy < 0) ? (-oy) : 0);
1003 b = ry + in->pad.b + ((oy > 0) ? oy : 0); 1003 b = ry + src->pad.b + ((oy > 0) ? oy : 0);
1004 1004
1005 if (out->pad.l < l) out->pad.l = l; 1005 if (dst->pad.l < l) dst->pad.l = l;
1006 if (out->pad.r < r) out->pad.r = r; 1006 if (dst->pad.r < r) dst->pad.r = r;
1007 if (out->pad.t < t) out->pad.t = t; 1007 if (dst->pad.t < t) dst->pad.t = t;
1008 if (out->pad.b < b) out->pad.b = b; 1008 if (dst->pad.b < b) dst->pad.b = b;
1009 1009
1010 if (padl) *padl = l; 1010 if (padl) *padl = l;
1011 if (padr) *padr = r; 1011 if (padr) *padr = r;
1012 if (padt) *padt = t; 1012 if (padt) *padt = t;
1013 if (padb) *padb = b; 1013 if (padb) *padb = b;
1014
1015 return 0;
1014} 1016}
1015 1017
1016/** 1018/**
@@ -1212,39 +1214,37 @@ _curve_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction *in
1212 return EINA_TRUE; 1214 return EINA_TRUE;
1213} 1215}
1214 1216
1215static void 1217static int
1216_displace_padding_update(Evas_Filter_Program *pgm, 1218_displace_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
1217 Evas_Filter_Instruction *instr, 1219 Evas_Filter_Instruction *instr,
1218 int *padl, int *padr, int *padt, int *padb) 1220 int *padl, int *padr, int *padt, int *padb)
1219{ 1221{
1220 int intensity = 0; 1222 int intensity = 0;
1221 int l, r, t, b; 1223 int l, r, t, b;
1222 const char *inbuf, *outbuf; 1224 Buffer *src, *dst;
1223 Buffer *in, *out;
1224 1225
1225 intensity = _instruction_param_geti(instr, "intensity", NULL); 1226 intensity = _instruction_param_geti(instr, "intensity", NULL);
1226 inbuf = _instruction_param_gets(instr, "src", NULL); 1227 src = _instruction_param_getbuf(instr, "src", NULL);
1227 outbuf = _instruction_param_gets(instr, "dst", NULL); 1228 dst = _instruction_param_getbuf(instr, "dst", NULL);
1228 1229 INSTR_PARAM_CHECK(src);
1229 in = _buffer_get(pgm, inbuf); 1230 INSTR_PARAM_CHECK(dst);
1230 out = _buffer_get(pgm, outbuf);
1231 EINA_SAFETY_ON_NULL_RETURN(in);
1232 EINA_SAFETY_ON_NULL_RETURN(out);
1233 1231
1234 l = intensity + in->pad.l; 1232 l = intensity + src->pad.l;
1235 r = intensity + in->pad.r; 1233 r = intensity + src->pad.r;
1236 t = intensity + in->pad.t; 1234 t = intensity + src->pad.t;
1237 b = intensity + in->pad.b; 1235 b = intensity + src->pad.b;
1238 1236
1239 if (out->pad.l < l) out->pad.l = l; 1237 if (dst->pad.l < l) dst->pad.l = l;
1240 if (out->pad.r < r) out->pad.r = r; 1238 if (dst->pad.r < r) dst->pad.r = r;
1241 if (out->pad.t < t) out->pad.t = t; 1239 if (dst->pad.t < t) dst->pad.t = t;
1242 if (out->pad.b < b) out->pad.b = b; 1240 if (dst->pad.b < b) dst->pad.b = b;
1243 1241
1244 if (padl) *padl = l; 1242 if (padl) *padl = l;
1245 if (padr) *padr = r; 1243 if (padr) *padr = r;
1246 if (padt) *padt = t; 1244 if (padt) *padt = t;
1247 if (padb) *padb = b; 1245 if (padb) *padb = b;
1246
1247 return 0;
1248} 1248}
1249 1249
1250/** 1250/**
@@ -1361,40 +1361,39 @@ _fill_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction *ins
1361 return EINA_TRUE; 1361 return EINA_TRUE;
1362} 1362}
1363 1363
1364static void 1364static int
1365_grow_padding_update(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr, 1365_grow_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
1366 Evas_Filter_Instruction *instr,
1366 int *padl, int *padr, int *padt, int *padb) 1367 int *padl, int *padr, int *padt, int *padb)
1367{ 1368{
1368 const char *inbuf, *outbuf; 1369 Buffer *src, *dst;
1369 Buffer *in, *out;
1370 int l, r, t, b; 1370 int l, r, t, b;
1371 int radius; 1371 int radius;
1372 1372
1373 radius = _instruction_param_geti(instr, "radius", NULL); 1373 radius = _instruction_param_geti(instr, "radius", NULL);
1374 inbuf = _instruction_param_gets(instr, "src", NULL); 1374 src = _instruction_param_getbuf(instr, "src", NULL);
1375 outbuf = _instruction_param_gets(instr, "dst", NULL); 1375 dst = _instruction_param_getbuf(instr, "dst", NULL);
1376 1376 INSTR_PARAM_CHECK(src);
1377 in = _buffer_get(pgm, inbuf); 1377 INSTR_PARAM_CHECK(dst);
1378 out = _buffer_get(pgm, outbuf);
1379 EINA_SAFETY_ON_NULL_RETURN(in);
1380 EINA_SAFETY_ON_NULL_RETURN(out);
1381 1378
1382 if (radius < 0) radius = 0; 1379 if (radius < 0) radius = 0;
1383 1380
1384 l = radius + in->pad.l; 1381 l = radius + src->pad.l;
1385 r = radius + in->pad.r; 1382 r = radius + src->pad.r;
1386 t = radius + in->pad.t; 1383 t = radius + src->pad.t;
1387 b = radius + in->pad.b; 1384 b = radius + src->pad.b;
1388 1385
1389 if (padl) *padl = l; 1386 if (padl) *padl = l;
1390 if (padr) *padr = r; 1387 if (padr) *padr = r;
1391 if (padt) *padt = t; 1388 if (padt) *padt = t;
1392 if (padb) *padb = b; 1389 if (padb) *padb = b;
1393 1390
1394 if (out->pad.l < l) out->pad.l = l; 1391 if (dst->pad.l < l) dst->pad.l = l;
1395 if (out->pad.r < r) out->pad.r = r; 1392 if (dst->pad.r < r) dst->pad.r = r;
1396 if (out->pad.t < t) out->pad.t = t; 1393 if (dst->pad.t < t) dst->pad.t = t;
1397 if (out->pad.b < b) out->pad.b = b; 1394 if (dst->pad.b < b) dst->pad.b = b;
1395
1396 return 0;
1398} 1397}
1399 1398
1400/** 1399/**
@@ -1494,22 +1493,19 @@ _mask_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction *ins
1494 return EINA_TRUE; 1493 return EINA_TRUE;
1495} 1494}
1496 1495
1497static void 1496static int
1498_transform_padding_update(Evas_Filter_Program *pgm, 1497_transform_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
1499 Evas_Filter_Instruction *instr, 1498 Evas_Filter_Instruction *instr,
1500 int *padl, int *padr, int *padt, int *padb) 1499 int *padl, int *padr, int *padt, int *padb)
1501{ 1500{
1502 const char *outbuf; 1501 Buffer *dst;
1503 Buffer *out;
1504 int ox, oy, l = 0, r = 0, t = 0, b = 0; 1502 int ox, oy, l = 0, r = 0, t = 0, b = 0;
1505 1503
1506 //ox = _instruction_param_geti(instr, "ox", NULL); 1504 //ox = _instruction_param_geti(instr, "ox", NULL);
1507 ox = 0; 1505 ox = 0;
1508 oy = _instruction_param_geti(instr, "oy", NULL); 1506 oy = _instruction_param_geti(instr, "oy", NULL);
1509 1507 dst = _instruction_param_getbuf(instr, "dst", NULL);
1510 outbuf = _instruction_param_gets(instr, "dst", NULL); 1508 INSTR_PARAM_CHECK(dst);
1511 out = _buffer_get(pgm, outbuf);
1512 EINA_SAFETY_ON_NULL_RETURN(out);
1513 1509
1514 if (ox < 0) l = (-ox) * 2; 1510 if (ox < 0) l = (-ox) * 2;
1515 else r = ox * 2; 1511 else r = ox * 2;
@@ -1517,15 +1513,17 @@ _transform_padding_update(Evas_Filter_Program *pgm,
1517 if (oy < 0) t = (-oy) * 2; 1513 if (oy < 0) t = (-oy) * 2;
1518 else b = oy * 2; 1514 else b = oy * 2;
1519 1515
1520 if (out->pad.l < l) out->pad.l = l; 1516 if (dst->pad.l < l) dst->pad.l = l;
1521 if (out->pad.r < r) out->pad.r = r; 1517 if (dst->pad.r < r) dst->pad.r = r;
1522 if (out->pad.t < t) out->pad.t = t; 1518 if (dst->pad.t < t) dst->pad.t = t;
1523 if (out->pad.b < b) out->pad.b = b; 1519 if (dst->pad.b < b) dst->pad.b = b;
1524 1520
1525 if (padl) *padl = l; 1521 if (padl) *padl = l;
1526 if (padr) *padr = r; 1522 if (padr) *padr = r;
1527 if (padt) *padt = t; 1523 if (padt) *padt = t;
1528 if (padb) *padb = b; 1524 if (padb) *padb = b;
1525
1526 return 0;
1529} 1527}
1530 1528
1531/** 1529/**
@@ -1580,7 +1578,7 @@ _transform_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction
1580 return EINA_TRUE; 1578 return EINA_TRUE;
1581} 1579}
1582 1580
1583static void 1581static int
1584_padding_set_padding_update(Evas_Filter_Program *pgm, 1582_padding_set_padding_update(Evas_Filter_Program *pgm,
1585 Evas_Filter_Instruction *instr, 1583 Evas_Filter_Instruction *instr,
1586 int *padl, int *padr, int *padt, int *padb) 1584 int *padl, int *padr, int *padt, int *padb)
@@ -1614,6 +1612,8 @@ _padding_set_padding_update(Evas_Filter_Program *pgm,
1614 if (padt) *padt = t; 1612 if (padt) *padt = t;
1615 if (padb) *padb = b; 1613 if (padb) *padb = b;
1616 pgm->padding_set = EINA_TRUE; 1614 pgm->padding_set = EINA_TRUE;
1615
1616 return 0;
1617} 1617}
1618 1618
1619/** 1619/**
@@ -1717,6 +1717,7 @@ _lua_program_get(lua_State *L)
1717 1717
1718static Eina_Bool 1718static Eina_Bool
1719_lua_parameter_parse(Evas_Filter_Program *pgm, lua_State *L, 1719_lua_parameter_parse(Evas_Filter_Program *pgm, lua_State *L,
1720 Evas_Filter_Instruction *instr,
1720 Instruction_Param *param, int i) 1721 Instruction_Param *param, int i)
1721{ 1722{
1722 if (!param) return EINA_FALSE; 1723 if (!param) return EINA_FALSE;
@@ -1761,22 +1762,33 @@ _lua_parameter_parse(Evas_Filter_Program *pgm, lua_State *L,
1761 param->value.s = strdup(lua_tostring(L, i)); 1762 param->value.s = strdup(lua_tostring(L, i));
1762 break; 1763 break;
1763 case VT_COLOR: 1764 case VT_COLOR:
1764 if (lua_isnumber(L, i)) 1765 if ((lua_isnumber(L, i)) || (lua_type(L, i) == LUA_TSTRING))
1765 { 1766 {
1766 DATA32 color = (DATA32) lua_tonumber(L, i); 1767 int A, R, G, B;
1767 int A = A_VAL(&color); 1768 DATA32 color;
1768 int R = R_VAL(&color); 1769
1769 int G = G_VAL(&color); 1770 if (lua_isnumber(L, i))
1770 int B = B_VAL(&color); 1771 color = (DATA32) lua_tonumber(L, i);
1771 if (!A && (R || B || G)) A = 0xFF; 1772 else
1772 evas_color_argb_premul(A, &R, &G, &B); 1773 {
1774 if (!_color_parse(lua_tostring(L, i), &color))
1775 goto fail;
1776 }
1777
1778 A = A_VAL(&color);
1779 R = R_VAL(&color);
1780 G = G_VAL(&color);
1781 B = B_VAL(&color);
1782 if (!A && (R || G || B)) A = 0xFF;
1783 if ((A < R) || (A < G) || (A < B))
1784 {
1785 ERR("Argument '%s' of function '%s' is not a valid premultiplied RGBA value!",
1786 param->name, instr->name);
1787 evas_color_argb_premul(A, &R, &G, &B);
1788 //goto fail;
1789 }
1773 param->value.c = ARGB_JOIN(A, R, G, B); 1790 param->value.c = ARGB_JOIN(A, R, G, B);
1774 } 1791 }
1775 else if (lua_type(L, i) == LUA_TSTRING)
1776 {
1777 if (!_color_parse(lua_tostring(L, i), &param->value.c))
1778 goto fail;
1779 }
1780 else 1792 else
1781 goto fail; 1793 goto fail;
1782 break; 1794 break;
@@ -1889,7 +1901,7 @@ _lua_instruction_run(lua_State *L, Evas_Filter_Instruction *instr)
1889 goto fail; 1901 goto fail;
1890 } 1902 }
1891 1903
1892 if (!_lua_parameter_parse(pgm, L, param, -1)) 1904 if (!_lua_parameter_parse(pgm, L, instr, param, -1))
1893 goto fail; 1905 goto fail;
1894 lua_pop(L, 1); 1906 lua_pop(L, 1);
1895 } 1907 }
@@ -1899,7 +1911,7 @@ _lua_instruction_run(lua_State *L, Evas_Filter_Instruction *instr)
1899 EINA_INLIST_FOREACH(instr->params, param) 1911 EINA_INLIST_FOREACH(instr->params, param)
1900 { 1912 {
1901 if ((++i) > argc) break; 1913 if ((++i) > argc) break;
1902 if (!_lua_parameter_parse(pgm, L, param, i)) 1914 if (!_lua_parameter_parse(pgm, L, instr, param, i))
1903 goto fail; 1915 goto fail;
1904 } 1916 }
1905 } 1917 }
@@ -2043,11 +2055,30 @@ static const luaL_Reg buffer_meta[] = {
2043 { NULL, NULL } 2055 { NULL, NULL }
2044}; 2056};
2045 2057
2058static void
2059_filter_program_buffers_set(Evas_Filter_Program *pgm)
2060{
2061 // Standard buffers
2062 _buffer_add(pgm, "input", pgm->input_alpha, NULL, EINA_FALSE);
2063 _buffer_add(pgm, "output", EINA_FALSE, NULL, EINA_FALSE);
2064
2065 // Register proxies
2066 if (pgm->proxies)
2067 {
2068 Eina_Iterator *it = eina_hash_iterator_key_new(pgm->proxies);
2069 const char *source;
2070
2071 EINA_ITERATOR_FOREACH(it, source)
2072 _buffer_add(pgm, source, EINA_FALSE, source, EINA_FALSE);
2073
2074 eina_iterator_free(it);
2075 }
2076}
2077
2046static lua_State * 2078static lua_State *
2047_lua_state_create(Evas_Filter_Program *pgm) 2079_lua_state_create(Evas_Filter_Program *pgm)
2048{ 2080{
2049 lua_State *L; 2081 lua_State *L;
2050 Buffer *buf;
2051 2082
2052 pgm->L = L = luaL_newstate(); 2083 pgm->L = L = luaL_newstate();
2053 if (!L) 2084 if (!L)
@@ -2136,29 +2167,6 @@ _lua_state_create(Evas_Filter_Program *pgm)
2136 lua_rawset(L, -3); 2167 lua_rawset(L, -3);
2137 lua_pop(L, 1); 2168 lua_pop(L, 1);
2138 2169
2139 _buffer_add(pgm, "input", pgm->input_alpha, NULL);
2140 _buffer_add(pgm, "output", EINA_FALSE, NULL);
2141
2142 // Register proxies
2143 if (pgm->proxies)
2144 {
2145 Eina_Iterator *it = eina_hash_iterator_key_new(pgm->proxies);
2146 const char *source;
2147
2148 EINA_ITERATOR_FOREACH(it, source)
2149 {
2150 buf = calloc(1, sizeof(Buffer));
2151 if (!buf) break;
2152
2153 buf->name = eina_stringshare_add(source);
2154 buf->proxy = eina_stringshare_ref(buf->name);
2155 buf->alpha = EINA_FALSE;
2156 pgm->buffers = eina_inlist_append(pgm->buffers, EINA_INLIST_GET(buf));
2157 _lua_buffer_push(L, buf);
2158 }
2159 eina_iterator_free(it);
2160 }
2161
2162 return L; 2170 return L;
2163} 2171}
2164 2172
@@ -2284,6 +2292,78 @@ _legacy_strdup(const char *str)
2284} 2292}
2285#endif 2293#endif
2286 2294
2295static void
2296_filter_program_state_set(Evas_Filter_Program *pgm)
2297{
2298 lua_State *L = pgm->L;
2299
2300 // TODO:
2301 // text properties: colors, font size, ascent/descent, style (enum)
2302
2303 /* State is defined as follow:
2304 * state = {
2305 * text = {
2306 * outline = COL
2307 * shadow = COL
2308 * glow = COL
2309 * glow2 = COL
2310 * }
2311 * color = COL
2312 * }
2313 */
2314
2315#define JOINC(k) ARGB_JOIN(pgm->state.k.a, pgm->state.k.r, pgm->state.k.g, pgm->state.k.b)
2316#define SETFIELD(name, val) do { lua_pushinteger(L, val); lua_setfield(L, -2, name); } while(0)
2317
2318 lua_newtable(L); // "state"
2319 {
2320 SETFIELD("color", JOINC(color));
2321 lua_newtable(L); // "text"
2322 {
2323 SETFIELD("outline", JOINC(text.outline));
2324 SETFIELD("shadow", JOINC(text.shadow));
2325 SETFIELD("glow", JOINC(text.glow));
2326 SETFIELD("glow2", JOINC(text.glow2));
2327 lua_setfield(L, -2, "text");
2328 }
2329 }
2330 lua_setglobal(L, "state");
2331
2332#undef JOINC
2333#undef SETFIELD
2334}
2335
2336static void
2337_filter_program_reset(Evas_Filter_Program *pgm)
2338{
2339 Evas_Filter_Instruction *instr;
2340 lua_State *L = pgm->L;
2341 Eina_Inlist *il;
2342 Buffer *buf;
2343
2344 // Clear out commands
2345 EINA_INLIST_FREE(pgm->instructions, instr)
2346 {
2347 pgm->instructions = eina_inlist_remove(pgm->instructions, EINA_INLIST_GET(instr));
2348 _instruction_del(instr);
2349 }
2350
2351 // Clear out buffers
2352 EINA_INLIST_FOREACH_SAFE(pgm->buffers, il, buf)
2353 {
2354 lua_pushnil(L);
2355 lua_setglobal(L, buf->name);
2356 pgm->buffers = eina_inlist_remove(pgm->buffers, EINA_INLIST_GET(buf));
2357 _buffer_del(buf);
2358 }
2359
2360 // Re-create buffers
2361 _filter_program_buffers_set(pgm);
2362
2363 // Reset state table
2364 _filter_program_state_set(pgm);
2365}
2366
2287/** Parse a style program */ 2367/** Parse a style program */
2288 2368
2289EAPI Eina_Bool 2369EAPI Eina_Bool
@@ -2314,6 +2394,7 @@ evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str)
2314 if (ok) 2394 if (ok)
2315 { 2395 {
2316 pgm->lua_func = luaL_ref(L, LUA_REGISTRYINDEX); 2396 pgm->lua_func = luaL_ref(L, LUA_REGISTRYINDEX);
2397 _filter_program_reset(pgm);
2317 lua_rawgeti(L, LUA_REGISTRYINDEX, pgm->lua_func); 2398 lua_rawgeti(L, LUA_REGISTRYINDEX, pgm->lua_func);
2318 ok = !lua_pcall(L, 0, LUA_MULTRET, 0); 2399 ok = !lua_pcall(L, 0, LUA_MULTRET, 0);
2319 } 2400 }
@@ -2334,6 +2415,7 @@ evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str)
2334 } 2415 }
2335 pgm->valid = ok; 2416 pgm->valid = ok;
2336 pgm->padding_calc = EINA_FALSE; 2417 pgm->padding_calc = EINA_FALSE;
2418 pgm->changed = EINA_FALSE;
2337 2419
2338 return ok; 2420 return ok;
2339} 2421}
@@ -2371,12 +2453,12 @@ _buffers_update(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm)
2371 } 2453 }
2372 else 2454 else
2373 { 2455 {
2374 if ((buf->w != pgm->w) || (buf->h != pgm->h)) 2456 if ((buf->w != pgm->state.w) || (buf->h != pgm->state.h))
2375 pgm->changed = EINA_TRUE; 2457 pgm->changed = EINA_TRUE;
2376 buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha); 2458 buf->cid = evas_filter_buffer_empty_new(ctx, buf->alpha);
2377 fb = _filter_buffer_get(ctx, buf->cid); 2459 fb = _filter_buffer_get(ctx, buf->cid);
2378 fb->w = buf->w = pgm->w; 2460 fb->w = buf->w = pgm->state.w;
2379 fb->h = buf->h = pgm->h; 2461 fb->h = buf->h = pgm->state.h;
2380 } 2462 }
2381 } 2463 }
2382} 2464}
@@ -2450,23 +2532,61 @@ evas_filter_program_new(const char *name, Eina_Bool input_alpha)
2450 if (!pgm) return NULL; 2532 if (!pgm) return NULL;
2451 pgm->name = eina_stringshare_add(name); 2533 pgm->name = eina_stringshare_add(name);
2452 pgm->input_alpha = input_alpha; 2534 pgm->input_alpha = input_alpha;
2535 pgm->state.color.r = 255;
2536 pgm->state.color.g = 255;
2537 pgm->state.color.b = 255;
2538 pgm->state.color.a = 255;
2453 2539
2454 return pgm; 2540 return pgm;
2455} 2541}
2456 2542
2457EAPI void 2543EAPI Eina_Bool
2458evas_filter_program_state_set(Evas_Filter_Program *pgm, int w, int h) 2544evas_filter_program_state_set(Evas_Filter_Program *pgm, Evas_Object *eo_obj,
2545 Evas_Object_Protected_Data *obj)
2459{ 2546{
2460 Eina_Bool changed = EINA_FALSE; 2547 Evas_Filter_Program_State old_state;
2461#define SET(a) do { if (pgm->a != a) { changed = 1; pgm->a = a; } } while (0)
2462 2548
2463 EINA_SAFETY_ON_NULL_RETURN(pgm); 2549 EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
2464 2550
2465 SET(w); 2551 memcpy(&old_state, &pgm->state, sizeof(Evas_Filter_Program_State));
2466 SET(h); 2552
2467 pgm->changed |= changed; 2553 pgm->state.w = obj->cur->geometry.w;
2554 pgm->state.h = obj->cur->geometry.h;
2555
2556 eo_do(eo_obj,
2557 efl_gfx_color_get(&pgm->state.color.r,
2558 &pgm->state.color.g,
2559 &pgm->state.color.b,
2560 &pgm->state.color.a));
2561
2562 if (eo_isa(eo_obj, EVAS_TEXT_CLASS))
2563 {
2564 eo_do(eo_obj,
2565 evas_obj_text_shadow_color_get(&pgm->state.text.shadow.r,
2566 &pgm->state.text.shadow.g,
2567 &pgm->state.text.shadow.b,
2568 &pgm->state.text.shadow.a),
2569 evas_obj_text_outline_color_get(&pgm->state.text.outline.r,
2570 &pgm->state.text.outline.g,
2571 &pgm->state.text.outline.b,
2572 &pgm->state.text.outline.a),
2573 evas_obj_text_glow_color_get(&pgm->state.text.glow.r,
2574 &pgm->state.text.glow.g,
2575 &pgm->state.text.glow.b,
2576 &pgm->state.text.glow.a),
2577 evas_obj_text_glow2_color_get(&pgm->state.text.glow2.r,
2578 &pgm->state.text.glow2.g,
2579 &pgm->state.text.glow2.b,
2580 &pgm->state.text.glow2.a));
2581 }
2468 2582
2469#undef SET 2583 if (memcmp(&old_state, &pgm->state, sizeof(Evas_Filter_Program_State)) != 0)
2584 pgm->changed = EINA_TRUE;
2585
2586 if (pgm->changed)
2587 pgm->padding_calc = EINA_FALSE;
2588
2589 return pgm->changed;
2470} 2590}
2471 2591
2472/** Bind objects for proxy rendering */ 2592/** Bind objects for proxy rendering */
@@ -2494,10 +2614,6 @@ evas_filter_program_source_set_all(Evas_Filter_Program *pgm,
2494 ENFN->context_clip_set(ENDT, dc, l, r, t, b); } while (0) 2614 ENFN->context_clip_set(ENDT, dc, l, r, t, b); } while (0)
2495#define RESETCLIP() do { ENFN->context_clip_set(ENDT, dc, _l, _r, _t, _b); } while (0) 2615#define RESETCLIP() do { ENFN->context_clip_set(ENDT, dc, _l, _r, _t, _b); } while (0)
2496 2616
2497#define INSTR_PARAM_CHECK(a) do { if (!(a)) { \
2498 ERR("Argument %s can not be nil in %s!", #a, instr->name); return -1; } \
2499 } while (0)
2500
2501static Evas_Filter_Fill_Mode 2617static Evas_Filter_Fill_Mode
2502_fill_mode_get(Evas_Filter_Instruction *instr) 2618_fill_mode_get(Evas_Filter_Instruction *instr)
2503{ 2619{
@@ -3006,15 +3122,16 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
3006 DBG("Using program '%s' for context %p", pgm->name, ctx); 3122 DBG("Using program '%s' for context %p", pgm->name, ctx);
3007 3123
3008 // Copy current state (size, edje state val, color class, etc...) 3124 // Copy current state (size, edje state val, color class, etc...)
3009 ctx->w = pgm->w; 3125 ctx->w = pgm->state.w;
3010 ctx->h = pgm->h; 3126 ctx->h = pgm->state.h;
3011 3127
3012 // Create empty context with all required buffers 3128 // Create empty context with all required buffers
3013 evas_filter_context_clear(ctx); 3129 evas_filter_context_clear(ctx);
3014 _buffers_update(ctx, pgm);
3015 3130
3016 if (pgm->changed) 3131 if (pgm->changed)
3017 { 3132 {
3133 pgm->changed = EINA_FALSE;
3134 _filter_program_reset(pgm);
3018 lua_rawgeti(pgm->L, LUA_REGISTRYINDEX, pgm->lua_func); 3135 lua_rawgeti(pgm->L, LUA_REGISTRYINDEX, pgm->lua_func);
3019 success = !lua_pcall(pgm->L, 0, LUA_MULTRET, 0); 3136 success = !lua_pcall(pgm->L, 0, LUA_MULTRET, 0);
3020 if (!success) 3137 if (!success)
@@ -3024,7 +3141,7 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
3024 goto end; 3141 goto end;
3025 } 3142 }
3026 } 3143 }
3027 pgm->changed = EINA_FALSE; 3144 _buffers_update(ctx, pgm);
3028 3145
3029 // Compute and save padding info 3146 // Compute and save padding info
3030 evas_filter_program_padding_get(pgm, &ctx->padl, &ctx->padr, &ctx->padt, &ctx->padb); 3147 evas_filter_program_padding_get(pgm, &ctx->padl, &ctx->padr, &ctx->padt, &ctx->padb);
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h
index d4f9f47..2d23843 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -35,6 +35,7 @@ typedef struct _Evas_Filter_Command Evas_Filter_Command;
35typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction; 35typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction;
36typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer; 36typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer;
37typedef struct _Evas_Filter_Proxy_Binding Evas_Filter_Proxy_Binding; 37typedef struct _Evas_Filter_Proxy_Binding Evas_Filter_Proxy_Binding;
38typedef struct _Evas_Filter_Program_State Evas_Filter_Program_State;
38typedef enum _Evas_Filter_Mode Evas_Filter_Mode; 39typedef enum _Evas_Filter_Mode Evas_Filter_Mode;
39typedef enum _Evas_Filter_Blur_Type Evas_Filter_Blur_Type; 40typedef enum _Evas_Filter_Blur_Type Evas_Filter_Blur_Type;
40typedef enum _Evas_Filter_Channel Evas_Filter_Channel; 41typedef enum _Evas_Filter_Channel Evas_Filter_Channel;
@@ -125,7 +126,7 @@ enum _Evas_Filter_Transform_Flags
125 126
126/* Parser stuff (high level API) */ 127/* Parser stuff (high level API) */
127EAPI Evas_Filter_Program *evas_filter_program_new(const char *name, Eina_Bool input_alpha); 128EAPI Evas_Filter_Program *evas_filter_program_new(const char *name, Eina_Bool input_alpha);
128EAPI void evas_filter_program_state_set(Evas_Filter_Program *pgm, int w, int h); 129EAPI Eina_Bool evas_filter_program_state_set(Evas_Filter_Program *pgm, Evas_Object *eo_obj, Evas_Object_Protected_Data *obj);
129EAPI Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str); 130EAPI Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str);
130EAPI void evas_filter_program_del(Evas_Filter_Program *pgm); 131EAPI void evas_filter_program_del(Evas_Filter_Program *pgm);
131Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm); 132Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm);