jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=0e8f890dfbdb188d02857b2bcf64d35089f3a297

commit 0e8f890dfbdb188d02857b2bcf64d35089f3a297
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Mon Jun 22 21:52:16 2015 +0900

    Edje & evas filters: Add extra data from EDC to Lua program
    
    This also supports color classes (really rough implementation for
    now, but the API should remain stable).
    
    @feature
---
 src/bin/edje/edje_cc_handlers.c           | 52 ++++++++++++++++++++++++++
 src/lib/edje/edje_calc.c                  | 61 +++++++++++++++++++++++++++++++
 src/lib/edje/edje_data.c                  |  2 +
 src/lib/edje/edje_private.h               |  1 +
 src/lib/efl/interfaces/efl_gfx_filter.eo  |  9 +++++
 src/lib/evas/canvas/evas_filter_mixin.c   | 30 +++++++++++++++
 src/lib/evas/canvas/evas_object_main.c    |  2 +-
 src/lib/evas/filters/evas_filter_parser.c | 26 +++++++++++++
 src/lib/evas/include/evas_filter.h        |  1 +
 src/lib/evas/include/evas_private.h       |  1 +
 10 files changed, 184 insertions(+), 1 deletion(-)

diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c
index 8954f08..f6458f8 100644
--- a/src/bin/edje/edje_cc_handlers.c
+++ b/src/bin/edje/edje_cc_handlers.c
@@ -396,6 +396,7 @@ static void 
st_collections_group_parts_part_description_mesh_assembly(void);
 static void st_collections_group_parts_part_description_mesh_geometry(void);
 static void st_collections_group_parts_part_description_filter_code(void);
 static void st_collections_group_parts_part_description_filter_source(void);
+static void st_collections_group_parts_part_description_filter_data(void);
 
 #ifdef HAVE_EPHYSICS
 static void st_collections_group_parts_part_description_physics_mass(void);
@@ -849,6 +850,7 @@ New_Statement_Handler statement_handlers[] =
      {"collections.group.parts.part.description.mesh.geometry", 
st_collections_group_parts_part_description_mesh_geometry},
      {"collections.group.parts.part.description.filter.code", 
st_collections_group_parts_part_description_filter_code},
      {"collections.group.parts.part.description.filter.source", 
st_collections_group_parts_part_description_filter_source},
+     {"collections.group.parts.part.description.filter.data", 
st_collections_group_parts_part_description_filter_data},
 
 #ifdef HAVE_EPHYSICS
      {"collections.group.parts.part.description.physics.mass", 
st_collections_group_parts_part_description_physics_mass},
@@ -11649,6 +11651,56 @@ 
st_collections_group_parts_part_description_filter_source(void)
    free(name);
 }
 
+/**
+    @page edcref
+
+    @property
+        filter.data
+    @parameters
+        [name] [content]
+    @effect
+        Pass extra data to the Lua filter program. This can be used to pass
+        extra colors from a color_class using the following syntax:
+          filter.data: "mycc" "color_class('my_color_class')";
+        If not a color class, the data will simply be set as a string attached
+        to the global variable 'name' in the Lua program.
+        For more information, please refer to the page "Evas filters 
reference".
+        @see evasfiltersref
+    @endproperty
+*/
+static void
+st_collections_group_parts_part_description_filter_data(void)
+{
+   Edje_Part_Description_Spec_Filter *filter;
+   char *name, *value;
+
+   if (current_part->type == EDJE_PART_TYPE_TEXT)
+     filter = &(((Edje_Part_Description_Text *)current_desc)->text.filter);
+   else if (current_part->type == EDJE_PART_TYPE_IMAGE)
+     filter = &(((Edje_Part_Description_Image *)current_desc)->image.filter);
+   else
+     {
+        ERR("parse error %s:%i. filter set for non-TEXT and non-IMAGE part.",
+            file_in, line - 1);
+        exit(-1);
+     }
+
+   check_arg_count(2);
+
+   if (!filter->data)
+     filter->data = eina_hash_string_small_new(EINA_FREE_CB(free));
+
+   name = parse_str(0);
+   value = parse_str(1);
+   if (eina_hash_find(filter->data, name))
+     {
+        ERR("parse error %s:%i. filter.data '%s' already exists in this 
context",
+            file_in, line - 1, name);
+        exit(-1);
+     }
+
+   eina_hash_add(filter->data, name, value);
+}
 
 /** @edcsubsection{collections_group_parts_descriptions_params,
  *                 Group.Parts.Part.Description.Params} */
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c
index 48a4d81..b506ef1 100644
--- a/src/lib/edje/edje_calc.c
+++ b/src/lib/edje/edje_calc.c
@@ -2535,6 +2535,67 @@ _edje_part_recalc_single_filter(Edje *ed,
               efl_gfx_filter_state_set(chosen_desc->state.name, 
chosen_desc->state.value,
                                        NULL, 0.0, pos);
            }
+         /* pass extra data items */
+         if (filter->data)
+           {
+              Eina_Iterator *it = eina_hash_iterator_tuple_new(filter->data);
+              Eina_Hash_Tuple *tup;
+              EINA_ITERATOR_FOREACH(it, tup)
+                {
+                   const char *name = tup->key;
+                   char *value = tup->data;
+                   if (!value)
+                     {
+                        efl_gfx_filter_data_set(name, NULL);
+                     }
+                   else if (!strncmp(value, "color_class('", 
sizeof("color_class('") - 1))
+                     {
+                        /* special handling for color classes even tho they're 
not that great */
+                        char *ccname, *buffer, *r;
+                        Edje_Color_Class *cc;
+
+                        ccname = strdup(value + sizeof("color_class('") - 1);
+                        if (ccname)
+                          {
+                             r = strchr(ccname, '\'');
+                             if (r)
+                               {
+                                  *r = '\0';
+                                  cc = _edje_color_class_find(ed, ccname);
+                                  if (cc)
+                                    {
+                                       static const char *fmt =
+                                             "%s={r=%d,g=%d,b=%d,a=%d,"
+                                             "r2=%d,g2=%d,b2=%d,a2=%d,"
+                                             "r3=%d,g3=%d,b3=%d,a3=%d}";
+                                       int len = sizeof(fmt);
+                                       len += strlen(ccname);
+                                       buffer = alloca(len);
+                                       snprintf(buffer, len - 1, fmt, ccname,
+                                                cc->r, cc->g, cc->b, cc->a,
+                                                cc->r2, cc->g2, cc->b2, cc->a2,
+                                                cc->r3, cc->g3, cc->b3, 
cc->a3);
+                                       efl_gfx_filter_data_set(name, buffer);
+                                    }
+                                  else
+                                    {
+                                       ERR("Unknown color class: %s", ccname);
+                                       eina_hash_del(filter->data, tup->key, 
tup->data);
+                                    }
+                               }
+                             else
+                               {
+                                  ERR("Failed to parse color class: %s", 
value);
+                                  eina_hash_del(filter->data, tup->key, 
tup->data);
+                               }
+                             free(ccname);
+                          }
+                     }
+                   else
+                     efl_gfx_filter_data_set(name, value);
+                }
+              eina_iterator_free(it);
+           }
          );
 }
 
diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c
index c85dcd8..d6a08f7 100644
--- a/src/lib/edje/edje_data.c
+++ b/src/lib/edje/edje_data.c
@@ -959,6 +959,7 @@ _edje_edd_init(void)
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_image, 
Edje_Part_Description_Image, "image.fill.type", image.fill.type, EET_T_CHAR);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_image, 
Edje_Part_Description_Image, "image.filter.code", image.filter.code, 
EET_T_STRING);
    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(_edje_edd_edje_part_description_image, 
Edje_Part_Description_Image, "image.filter.sources", image.filter.sources);
+   EET_DATA_DESCRIPTOR_ADD_HASH_STRING(_edje_edd_edje_part_description_image, 
Edje_Part_Description_Image, "image.filter.data", image.filter.data);
 
    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Proxy);
    eddc.func.mem_free = mem_free_proxy;
@@ -1017,6 +1018,7 @@ _edje_edd_init(void)
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.ellipsis", text.ellipsis, EET_T_DOUBLE);
    EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.filter", text.filter.code, EET_T_STRING);
    EET_DATA_DESCRIPTOR_ADD_LIST_STRING(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.filter_sources", text.filter.sources);
+   EET_DATA_DESCRIPTOR_ADD_HASH_STRING(_edje_edd_edje_part_description_text, 
Edje_Part_Description_Text, "text.filter.data", text.filter.data); // @since 
1.15
 
    EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Text);
    eddc.func.mem_free = mem_free_textblock;
diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h
index fcc463c..21d156c 100644
--- a/src/lib/edje/edje_private.h
+++ b/src/lib/edje/edje_private.h
@@ -1283,6 +1283,7 @@ struct _Edje_Part_Description_Spec_Filter
    const char    *code;
    const char    *name;
    Eina_List     *sources; /* "part" or "buffer:part" */
+   Eina_Hash     *data; /* "name" --> "data" */
    Eina_Bool      checked_data : 1; // checked whether this is a data item or 
embedded string
    Eina_Bool      no_free : 1;
 };
diff --git a/src/lib/efl/interfaces/efl_gfx_filter.eo 
b/src/lib/efl/interfaces/efl_gfx_filter.eo
index ed8bedc..2140acf 100644
--- a/src/lib/efl/interfaces/efl_gfx_filter.eo
+++ b/src/lib/efl/interfaces/efl_gfx_filter.eo
@@ -70,5 +70,14 @@ interface Efl.Gfx.Filter
             @out source: Efl.Gfx.Base*; [[object used as a proxy source]]
          }
       }
+      data_set {
+         [[Pass extra data to the filter program.
+
+         This sets a global value as a string.]]
+         params {
+            @in name: const(char)*; [[name of the global variable]]
+            @in value: const(char)*; [[string value to use as data]]
+         }
+      }
    }
 }
diff --git a/src/lib/evas/canvas/evas_filter_mixin.c 
b/src/lib/evas/canvas/evas_filter_mixin.c
index 87454a7..5a76b1e 100644
--- a/src/lib/evas/canvas/evas_filter_mixin.c
+++ b/src/lib/evas/canvas/evas_filter_mixin.c
@@ -123,6 +123,7 @@ evas_filter_object_render(Eo *eo_obj, 
Evas_Object_Protected_Data *obj,
              Evas_Filter_Program *pgm;
              pgm = evas_filter_program_new(fcow->name, alpha);
              evas_filter_program_source_set_all(pgm, fcow->sources);
+             evas_filter_program_data_set_all(pgm, fcow->data);
              evas_filter_program_state_set(pgm, eo_obj, obj,
                                            fcow->state.cur.name, 
fcow->state.cur.value,
                                            fcow->state.next.name, 
fcow->state.next.value,
@@ -274,6 +275,7 @@ _evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, 
Evas_Filter_Data *pd,
              alpha = eo_do_ret(eo_obj, alpha, evas_filter_input_alpha());
              pgm = evas_filter_program_new(fcow->name, alpha);
              evas_filter_program_source_set_all(pgm, fcow->sources);
+             evas_filter_program_data_set_all(pgm, fcow->data);
              evas_filter_program_state_set(pgm, eo_obj, obj,
                                            fcow->state.cur.name, 
fcow->state.cur.value,
                                            fcow->state.next.name, 
fcow->state.next.value,
@@ -377,6 +379,7 @@ _evas_filter_efl_gfx_filter_source_set(Eo *eo_obj, 
Evas_Filter_Data *pd,
 
    eina_hash_add(fcow->sources, pb->name, pb);
    evas_filter_program_source_set_all(fcow->chain, fcow->sources);
+   evas_filter_program_data_set_all(fcow->chain, fcow->data);
 
    // Update object
 update:
@@ -497,9 +500,36 @@ _evas_filter_destructor(Eo *eo_obj, Evas_Filter_Data *pd)
    if (pd->data->output)
      ENFN->image_free(ENDT, pd->data->output);
    eina_hash_free(pd->data->sources);
+   eina_hash_free(pd->data->data);
    evas_filter_program_del(pd->data->chain);
    eina_stringshare_del(pd->data->code);
    eina_cow_free(evas_object_filter_cow, (const Eina_Cow_Data **) &pd->data);
 }
 
+EOLIAN void
+_evas_filter_efl_gfx_filter_data_set(Eo *obj EINA_UNUSED, Evas_Filter_Data *pd,
+                                     const char *name, const char *value)
+{
+   const char *check = NULL;
+
+   if (!pd->data) return;
+
+   if (pd->data->data && ((check = eina_hash_find(pd->data->data, name)) != 
NULL))
+     {
+        if (!strcmp(check, value))
+          return;
+     }
+
+   EINA_COW_WRITE_BEGIN(evas_object_filter_cow, fcow, Evas_Object_Filter_Data, 
fcow)
+     {
+        if (!fcow->data)
+          fcow->data = eina_hash_string_small_new(free);
+        eina_hash_set(fcow->data, name, value ? strdup(value) : NULL);
+        if (fcow->chain)
+          evas_filter_program_data_set_all(fcow->chain, fcow->data);
+        fcow->changed = 1;
+     }
+   EINA_COW_WRITE_END(evas_object_filter_cow, fcow, fcow);
+}
+
 #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 8330f2e..936e54d 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -33,7 +33,7 @@ static const Evas_Object_Protected_State default_state = {
   1.0, 0, EVAS_RENDER_BLEND, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, 
EINA_FALSE, EINA_FALSE
 };
 static const Evas_Object_Filter_Data default_filter = {
-  NULL, NULL, NULL, NULL, NULL, { { "default", 0.0 }, { "default", 0.0 }, 0.0 
}, EINA_FALSE, EINA_FALSE
+  NULL, NULL, NULL, NULL, NULL, NULL, { { "default", 0.0 }, { "default", 0.0 
}, 0.0 }, EINA_FALSE, EINA_FALSE
 };
 const void * const evas_object_filter_cow_default = &default_filter;
 static const Evas_Object_Mask_Data default_mask = {
diff --git a/src/lib/evas/filters/evas_filter_parser.c 
b/src/lib/evas/filters/evas_filter_parser.c
index f25f82a..6b4b8d3 100644
--- a/src/lib/evas/filters/evas_filter_parser.c
+++ b/src/lib/evas/filters/evas_filter_parser.c
@@ -341,6 +341,7 @@ struct _Evas_Filter_Program
       int l, r, t, b;
    } pad;
    Evas_Filter_Program_State state;
+   Eina_Hash /* str -> str */ *data;
    lua_State *L;
    int       lua_func;
    int       last_bufid;
@@ -2620,6 +2621,24 @@ _filter_program_state_set(Evas_Filter_Program *pgm)
    }
    lua_setglobal(L, "state");
 
+   /* now push all extra data */
+   if (pgm->data)
+     {
+        Eina_Iterator *it = eina_hash_iterator_tuple_new(pgm->data);
+        Eina_Hash_Tuple *tup;
+        EINA_ITERATOR_FOREACH(it, tup)
+          {
+             const char *name = tup->key;
+             const char *value = tup->data;
+             if (value)
+               lua_pushstring(L, value);
+             else
+               lua_pushnil(L);
+             lua_setglobal(L, name);
+          }
+        eina_iterator_free(it);
+     }
+
 #undef JOINC
 #undef SETFIELD
 #undef SETCOLOR
@@ -2905,6 +2924,13 @@ evas_filter_program_source_set_all(Evas_Filter_Program 
*pgm,
    pgm->proxies = proxies;
 }
 
+void
+evas_filter_program_data_set_all(Evas_Filter_Program *pgm, Eina_Hash *data)
+{
+   if (!pgm) return;
+   pgm->data = data;
+}
+
 /** Glue with Evas' filters */
 
 #define CA(color) ((color >> 24) & 0xFF)
diff --git a/src/lib/evas/include/evas_filter.h 
b/src/lib/evas/include/evas_filter.h
index e72738a..6784a0d 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -133,6 +133,7 @@ Eina_Bool                
evas_filter_context_program_use(Evas_Filter_Context *ct
 EAPI Eina_Bool           evas_filter_program_padding_get(Evas_Filter_Program 
*pgm, int *l, int *r, int *t, int *b);
 EAPI void                
evas_filter_program_source_set_all(Evas_Filter_Program *pgm, Eina_Hash 
*sources);
 void                     
evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, 
Eina_Bool do_async);
+void                     evas_filter_program_data_set_all(Evas_Filter_Program 
*pgm, Eina_Hash *data);
 
 /* Filter context (low level) */
 Evas_Filter_Context     *evas_filter_context_new(Evas_Public_Data *evas, 
Eina_Bool async);
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index 925aa52..c94c5ed 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1178,6 +1178,7 @@ struct _Evas_Object_Filter_Data
    Eina_Stringshare    *code;
    Evas_Filter_Program *chain;
    Eina_Hash           *sources; // Evas_Filter_Proxy_Binding
+   Eina_Hash           *data; // str -> str
    void                *output;
    struct {
       struct {

-- 


Reply via email to