jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=91a471b4dc72cdb621f782b54eba21188989f402

commit 91a471b4dc72cdb621f782b54eba21188989f402
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Fri Mar 21 11:52:52 2014 +0900

    Evas filters: Add new instruction padding_set
    
    This will allow forcing a specific value for the filter padding,
    instead of relying on auto calculation.
    
    Two advantages:
    - Auto calculation can't be perfect, since it will add as much
      padding as required for the full blur effect
    - This prepares the path for animations with effects, where the
      object size does not change over time
---
 src/lib/evas/filters/evas_filter_parser.c | 127 ++++++++++++++++++++++++++++--
 src/lib/evas/include/evas_filter.h        |   1 +
 2 files changed, 120 insertions(+), 8 deletions(-)

diff --git a/src/lib/evas/filters/evas_filter_parser.c 
b/src/lib/evas/filters/evas_filter_parser.c
index ce7e45d..aaa9e7b 100644
--- a/src/lib/evas/filters/evas_filter_parser.c
+++ b/src/lib/evas/filters/evas_filter_parser.c
@@ -316,7 +316,12 @@ struct _Evas_Filter_Program
    Eina_Hash /* const char * : Evas_Filter_Proxy_Binding */ *proxies;
    Eina_Inlist /* Evas_Filter_Instruction */ *instructions;
    Eina_Inlist /* Buffer */ *buffers;
+   struct {
+      int l, r, t, b;
+   } pad;
    Eina_Bool valid : 1;
+   Eina_Bool padding_calc : 1; // Padding has been calculated
+   Eina_Bool padding_set : 1; // Padding has been forced
 };
 
 /* Instructions */
@@ -1635,6 +1640,85 @@ _transform_instruction_prepare(Evas_Filter_Instruction 
*instr)
    return EINA_TRUE;
 }
 
+static void
+_padding_set_padding_update(Evas_Filter_Program *pgm,
+                            Evas_Filter_Instruction *instr,
+                            int *padl, int *padr, int *padt, int *padb)
+{
+   int l = 0, r = 0, t = 0, b = 0;
+   Eina_Bool lset = EINA_FALSE;
+   Eina_Bool rset = EINA_FALSE;
+   Eina_Bool tset = EINA_FALSE;
+   Eina_Bool bset = EINA_FALSE;
+
+   l = _instruction_param_geti(instr, "l", &lset);
+   r = _instruction_param_geti(instr, "r", &rset);
+   t = _instruction_param_geti(instr, "t", &tset);
+   b = _instruction_param_geti(instr, "b", &bset);
+
+   if (!lset && !rset && !bset && !tset)
+     DBG("padding_set() called without specifying any of l,r,t,b resets to 0");
+
+   if (l < 0 || r < 0 || t < 0 || b < 0)
+     {
+        WRN("invalid padding values in padding_set(%d, %d, %d, %d), resets to 
0", l, r, t, b);
+        l = r = t = b = 0;
+     }
+
+   if (!rset) r = l;
+   if (!tset) t = r;
+   if (!bset) b = t;
+
+   if (padl) *padl = l;
+   if (padr) *padr = r;
+   if (padt) *padt = t;
+   if (padb) *padb = b;
+   pgm->padding_set = EINA_TRUE;
+}
+
+/**
+  @page evasfiltersref
+
+  @subsection sec_commands_padding_set Padding_Set
+
+  Forcily set a specific padding for this filter.
+
+  @code
+    padding_set (l, r = [l], t = [r], b = [t]);
+  @endcode
+
+  @param l        Padding on the left side in pixels.
+  @param r        Padding on the right side in pixels. If unset, defaults to 
@a l.
+  @param t        Padding on the top in pixels. If unset, defaults to @a r.
+  @param b        Padding on the bottom in pixels. If unset, defaults to @a t.
+
+  All values must be >= 0. When filtering 'filled' images, some values may be 
too high
+  and would result in completely hiding the image.
+
+  It is not possible to set only one of those without forcing the others as 
well.
+  A common use case will be when changing a blur size during an animation, or
+  when applying a mask that will hide most of the (blurred) text.
+
+  @since 1.10
+ */
+
+static Eina_Bool
+_padding_set_instruction_prepare(Evas_Filter_Instruction *instr)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "padding_set"), 
EINA_FALSE);
+
+   instr->type = EVAS_FILTER_MODE_PADDING_SET;
+   instr->pad.update = _padding_set_padding_update;
+   _instruction_param_seq_add(instr, "l", VT_INT, 0);
+   _instruction_param_seq_add(instr, "r", VT_INT, 0);
+   _instruction_param_seq_add(instr, "t", VT_INT, 0);
+   _instruction_param_seq_add(instr, "b", VT_INT, 0);
+
+   return EINA_TRUE;
+}
+
 static Evas_Filter_Instruction *
 _instruction_create(const char *name)
 {
@@ -1661,6 +1745,8 @@ _instruction_create(const char *name)
      prepare = _mask_instruction_prepare;
    else if (!strcasecmp(name, "transform"))
      prepare = _transform_instruction_prepare;
+   else if (!strcasecmp(name, "padding_set"))
+     prepare = _padding_set_instruction_prepare;
 
    if (!prepare)
      {
@@ -1825,6 +1911,7 @@ evas_filter_program_parse(Evas_Filter_Program *pgm, const 
char *str)
 
              // Add to the queue
              pgm->instructions = eina_inlist_append(pgm->instructions, 
EINA_INLIST_GET(instr));
+             pgm->padding_calc = EINA_FALSE;
              instr = NULL;
              count++;
           }
@@ -1859,20 +1946,42 @@ evas_filter_program_padding_get(Evas_Filter_Program 
*pgm,
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
 
+   if (pgm->padding_calc || pgm->padding_set)
+     {
+        if (l) *l = pgm->pad.l;
+        if (r) *r = pgm->pad.r;
+        if (t) *t = pgm->pad.t;
+        if (b) *b = pgm->pad.b;
+        return EINA_TRUE;
+     }
+
    // Reset all paddings
    EINA_INLIST_FOREACH(pgm->buffers, buf)
      buf->pad.l = buf->pad.r = buf->pad.t = buf->pad.b = 0;
 
    // Accumulate paddings
    EINA_INLIST_FOREACH(pgm->instructions, instr)
-     if (instr->pad.update)
-       {
-          instr->pad.update(pgm, instr, &pl, &pr, &pt, &pb);
-          if (pl > maxl) maxl = pl;
-          if (pr > maxr) maxr = pr;
-          if (pt > maxt) maxt = pt;
-          if (pb > maxb) maxb = pb;
-       }
+     {
+        if (instr->type == EVAS_FILTER_MODE_PADDING_SET)
+          {
+             instr->pad.update(pgm, instr, &maxl, &maxr, &maxt, &maxb);
+             break;
+          }
+        else if (instr->pad.update)
+          {
+             instr->pad.update(pgm, instr, &pl, &pr, &pt, &pb);
+             if (pl > maxl) maxl = pl;
+             if (pr > maxr) maxr = pr;
+             if (pt > maxt) maxt = pt;
+             if (pb > maxb) maxb = pb;
+          }
+     }
+
+   pgm->pad.l = maxl;
+   pgm->pad.r = maxr;
+   pgm->pad.t = maxt;
+   pgm->pad.b = maxb;
+   pgm->padding_calc = EINA_TRUE;
 
    if (l) *l = maxl;
    if (r) *r = maxr;
@@ -2350,6 +2459,8 @@ _command_from_instruction(Evas_Filter_Context *ctx, 
Evas_Filter_Program *pgm,
       case EVAS_FILTER_MODE_TRANSFORM:
         instr2cmd = _instr2cmd_transform;
         break;
+      case EVAS_FILTER_MODE_PADDING_SET:
+        return EINA_TRUE;
       default:
         CRI("Invalid instruction type: %d", instr->type);
         return -1;
diff --git a/src/lib/evas/include/evas_filter.h 
b/src/lib/evas/include/evas_filter.h
index 052617e..09b7bd4 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -37,6 +37,7 @@ enum _Evas_Filter_Mode
    EVAS_FILTER_MODE_MASK,         /**< Apply Alpha or RGBA texture on image */
    EVAS_FILTER_MODE_BUMP,         /**< Apply bump mapping (light effect) */
    EVAS_FILTER_MODE_TRANSFORM,    /**< Apply a simple geometrical 
transformation */
+   EVAS_FILTER_MODE_PADDING_SET,  /**< Special padding_set instruction to 
force a specific padding value */
    EVAS_FILTER_MODE_LAST
 };
 

-- 


Reply via email to