forked from enlightenment/efl
Evas filters: Add offset parameter to vflip
It is not possible to logically handle padding and offset at the same time for a proper mirror effect, unless this is handled directly at the transformation level. Also, add support for blend() operation padding computation.
This commit is contained in:
parent
d9fb0cdc34
commit
209a7077a0
|
@ -1048,9 +1048,11 @@ end:
|
|||
}
|
||||
|
||||
int
|
||||
evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context,
|
||||
evas_filter_command_transform_add(Evas_Filter_Context *ctx,
|
||||
void *draw_context EINA_UNUSED,
|
||||
int inbuf, int outbuf,
|
||||
Evas_Filter_Transform_Flags flags)
|
||||
Evas_Filter_Transform_Flags flags,
|
||||
int ox, int oy)
|
||||
{
|
||||
Evas_Filter_Command *cmd;
|
||||
Evas_Filter_Buffer *in, *out;
|
||||
|
@ -1076,6 +1078,8 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context,
|
|||
if (!cmd) return -1;
|
||||
|
||||
cmd->transform.flags = flags;
|
||||
cmd->draw.ox = ox;
|
||||
cmd->draw.oy = oy;
|
||||
|
||||
return cmd->id;
|
||||
}
|
||||
|
|
|
@ -684,6 +684,38 @@ _buffer_del(Buffer *buf)
|
|||
|
||||
/* Instruction definitions */
|
||||
|
||||
static void
|
||||
_blend_padding_update(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr,
|
||||
int *padl, int *padr, int *padt, int *padb)
|
||||
{
|
||||
const char *outbuf;
|
||||
Buffer *out;
|
||||
int ox, oy, l = 0, r = 0, t = 0, b = 0;
|
||||
|
||||
ox = _instruction_param_geti(instr, "ox", NULL);
|
||||
oy = _instruction_param_geti(instr, "oy", NULL);
|
||||
|
||||
outbuf = _instruction_param_gets(instr, "dst", NULL);
|
||||
out = _buffer_get(pgm, outbuf);
|
||||
EINA_SAFETY_ON_NULL_RETURN(out);
|
||||
|
||||
if (ox < 0) l = (-ox);
|
||||
else r = ox;
|
||||
|
||||
if (oy < 0) t = (-oy);
|
||||
else b = oy;
|
||||
|
||||
if (out->pad.l < l) out->pad.l = l;
|
||||
if (out->pad.r < r) out->pad.r = r;
|
||||
if (out->pad.t < t) out->pad.t = t;
|
||||
if (out->pad.b < b) out->pad.b = b;
|
||||
|
||||
if (padl) *padl = l;
|
||||
if (padr) *padr = r;
|
||||
if (padt) *padt = t;
|
||||
if (padb) *padb = b;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_blend_instruction_prepare(Evas_Filter_Instruction *instr)
|
||||
{
|
||||
|
@ -696,6 +728,7 @@ _blend_instruction_prepare(Evas_Filter_Instruction *instr)
|
|||
*/
|
||||
|
||||
instr->type = EVAS_FILTER_MODE_BLEND;
|
||||
instr->pad.update = _blend_padding_update;
|
||||
_instruction_param_seq_add(instr, "src", VT_BUFFER, "input");
|
||||
_instruction_param_seq_add(instr, "dst", VT_BUFFER, "output");
|
||||
_instruction_param_seq_add(instr, "ox", VT_INT, 0);
|
||||
|
@ -1024,6 +1057,62 @@ _mask_instruction_prepare(Evas_Filter_Instruction *instr)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_transform_padding_update(Evas_Filter_Program *pgm,
|
||||
Evas_Filter_Instruction *instr,
|
||||
int *padl, int *padr, int *padt, int *padb)
|
||||
{
|
||||
const char *outbuf;
|
||||
Buffer *out;
|
||||
int ox, oy, l = 0, r = 0, t = 0, b = 0;
|
||||
|
||||
//ox = _instruction_param_geti(instr, "ox", NULL);
|
||||
ox = 0;
|
||||
oy = _instruction_param_geti(instr, "oy", NULL);
|
||||
|
||||
outbuf = _instruction_param_gets(instr, "dst", NULL);
|
||||
out = _buffer_get(pgm, outbuf);
|
||||
EINA_SAFETY_ON_NULL_RETURN(out);
|
||||
|
||||
if (ox < 0) l = (-ox) * 2;
|
||||
else r = ox * 2;
|
||||
|
||||
if (oy < 0) t = (-oy) * 2;
|
||||
else b = oy * 2;
|
||||
|
||||
if (out->pad.l < l) out->pad.l = l;
|
||||
if (out->pad.r < r) out->pad.r = r;
|
||||
if (out->pad.t < t) out->pad.t = t;
|
||||
if (out->pad.b < b) out->pad.b = b;
|
||||
|
||||
if (padl) *padl = l;
|
||||
if (padr) *padr = r;
|
||||
if (padt) *padt = t;
|
||||
if (padb) *padb = b;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_transform_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, "transform"), EINA_FALSE);
|
||||
|
||||
/*
|
||||
* mask [op=]STRING [input=BUFFER] [output=BUFFER] (oy=INT)
|
||||
*/
|
||||
|
||||
instr->type = EVAS_FILTER_MODE_TRANSFORM;
|
||||
instr->pad.update = _transform_padding_update;
|
||||
_instruction_param_seq_add(instr, "op", VT_STRING, "vflip");
|
||||
_instruction_param_seq_add(instr, "src", VT_BUFFER, "input");
|
||||
_instruction_param_seq_add(instr, "dst", VT_BUFFER, "output");
|
||||
//_instruction_param_name_add(instr, "ox", VT_INT, 0);
|
||||
_instruction_param_name_add(instr, "oy", VT_INT, 0);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Evas_Filter_Instruction *
|
||||
_instruction_create(const char *name)
|
||||
{
|
||||
|
@ -1048,6 +1137,8 @@ _instruction_create(const char *name)
|
|||
prepare = _grow_instruction_prepare;
|
||||
else if (!strcasecmp(name, "mask"))
|
||||
prepare = _mask_instruction_prepare;
|
||||
else if (!strcasecmp(name, "transform"))
|
||||
prepare = _transform_instruction_prepare;
|
||||
|
||||
if (!prepare)
|
||||
{
|
||||
|
@ -1647,6 +1738,34 @@ interpolated:
|
|||
return cmdid;
|
||||
}
|
||||
|
||||
static int
|
||||
_instr2cmd_transform(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
|
||||
Evas_Filter_Instruction *instr, void *dc)
|
||||
{
|
||||
Evas_Filter_Transform_Flags flags;
|
||||
const char *src, *dst, *op;
|
||||
Buffer *in, *out;
|
||||
int ox = 0, oy;
|
||||
|
||||
op = _instruction_param_gets(instr, "op", NULL);
|
||||
src = _instruction_param_gets(instr, "src", NULL);
|
||||
dst = _instruction_param_gets(instr, "dst", NULL);
|
||||
// ox = _instruction_param_geti(instr, "ox", NULL);
|
||||
oy = _instruction_param_geti(instr, "oy", NULL);
|
||||
|
||||
if (!strcasecmp(op, "vflip"))
|
||||
flags = EVAS_FILTER_TRANSFORM_VFLIP;
|
||||
else
|
||||
{
|
||||
ERR("Invalid transform '%s'", op);
|
||||
return -1;
|
||||
}
|
||||
|
||||
in = _buffer_get(pgm, src);
|
||||
out = _buffer_get(pgm, dst);
|
||||
return evas_filter_command_transform_add(ctx, dc, in->cid, out->cid, flags, ox, oy);
|
||||
}
|
||||
|
||||
static int
|
||||
_command_from_instruction(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
|
||||
Evas_Filter_Instruction *instr, void *dc)
|
||||
|
@ -1680,6 +1799,9 @@ _command_from_instruction(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
|
|||
case EVAS_FILTER_MODE_CURVE:
|
||||
instr2cmd = _instr2cmd_curve;
|
||||
break;
|
||||
case EVAS_FILTER_MODE_TRANSFORM:
|
||||
instr2cmd = _instr2cmd_transform;
|
||||
break;
|
||||
default:
|
||||
CRI("Invalid instruction type: %d", instr->type);
|
||||
return -1;
|
||||
|
|
|
@ -5,7 +5,8 @@ _vflip_cpu(Evas_Filter_Command *cmd)
|
|||
{
|
||||
size_t datasize, stride;
|
||||
DATA8 *in, *out, *span;
|
||||
int w, h, sy, dy;
|
||||
int w, h, sy, dy, oy, center, t, b, objh;
|
||||
int s0, s1, d0, d1;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
|
||||
|
@ -24,23 +25,43 @@ _vflip_cpu(Evas_Filter_Command *cmd)
|
|||
datasize = cmd->input->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
|
||||
stride = w * datasize;
|
||||
|
||||
oy = cmd->draw.oy;
|
||||
t = cmd->ctx->padt;
|
||||
b = cmd->ctx->padb;
|
||||
objh = h - t - b;
|
||||
center = t + objh / 2 + oy;
|
||||
|
||||
s0 = t;
|
||||
s1 = h - b - 1;
|
||||
if (oy >= 0)
|
||||
{
|
||||
d0 = center + (objh / 2) + oy;
|
||||
d1 = center - (objh / 2) - oy;
|
||||
}
|
||||
else
|
||||
{
|
||||
d0 = center + (objh / 2) - oy;
|
||||
d1 = center - (objh / 2) + oy;
|
||||
}
|
||||
|
||||
if (in == out)
|
||||
{
|
||||
span = malloc(stride);
|
||||
if (!span) return EINA_FALSE;
|
||||
}
|
||||
|
||||
for (sy = 0, dy = h - 1; dy >= 0; sy++, dy--)
|
||||
for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
|
||||
{
|
||||
DATA8* src = in + stride * sy;
|
||||
DATA8* dst = out + stride * dy;
|
||||
|
||||
if (in == out)
|
||||
{
|
||||
if (src == dst) break;
|
||||
memcpy(span, dst, stride);
|
||||
memcpy(dst, src, stride);
|
||||
memcpy(src, span, stride);
|
||||
if (sy >= (h / 2)) break;
|
||||
if (sy >= center) break;
|
||||
}
|
||||
else
|
||||
memcpy(dst, src, stride);
|
||||
|
|
|
@ -227,9 +227,11 @@ int evas_filter_command_bump_map_add(Evas_Filter_Context *c
|
|||
* @param inbuf Input buffer (Alpha or RGBA)
|
||||
* @param outbuf Output buffer (Alpha or RGBA), same size as inbuf
|
||||
* @param flags Specifies the operation to apply (eg. vflip)
|
||||
* @param ox X offset
|
||||
* @param oy Y offset
|
||||
* @return Filter command ID or -1 in case of error
|
||||
*/
|
||||
int evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags);
|
||||
int evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags, int ox, int oy);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue