forked from enlightenment/efl
Evas filters: Implement fill with padding
Add parameters l, r, t, b to clip the fill area. While l=x and t=y, the width and height of the clip are determined at filter run-time, since we don't know the buffer size before.
This commit is contained in:
parent
b5b6f6ef3c
commit
2da17927da
|
@ -24,7 +24,7 @@ static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
|
|||
#define CLAMP(a,b,c) MIN(MAX((b),(a)),(c))
|
||||
|
||||
#define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0)
|
||||
#define DRAW_CLIP_SET(x, y, w, h) do { cmd->draw.clipx = x; cmd->draw.clipy = y; cmd->draw.clipw = w; cmd->draw.cliph = h; } while (0)
|
||||
#define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0)
|
||||
#define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0)
|
||||
|
||||
typedef struct _Evas_Filter_Thread_Command Evas_Filter_Thread_Command;
|
||||
|
@ -791,8 +791,8 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
|
|||
cmd->draw.ox = ox;
|
||||
cmd->draw.oy = oy;
|
||||
cmd->draw.render_op = ENFN->context_render_op_get(ENDT, drawctx);
|
||||
ENFN->context_clip_get(ENDT, drawctx, &cmd->draw.clipx, &cmd->draw.clipy,
|
||||
&cmd->draw.clipw, &cmd->draw.cliph);
|
||||
ENFN->context_clip_get(ENDT, drawctx, &cmd->draw.clip.x, &cmd->draw.clip.y,
|
||||
&cmd->draw.clip.w, &cmd->draw.clip.h);
|
||||
|
||||
return cmd->id;
|
||||
}
|
||||
|
@ -1057,19 +1057,29 @@ _fill_cpu(Evas_Filter_Command *cmd)
|
|||
{
|
||||
Evas_Filter_Buffer *fb = cmd->output;
|
||||
int step = fb->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
|
||||
int x = MAX(0, cmd->draw.clipx);
|
||||
int y = MAX(0, cmd->draw.clipy);
|
||||
int x = MAX(0, cmd->draw.clip.x);
|
||||
int y = MAX(0, cmd->draw.clip.y);
|
||||
DATA8 *ptr = ((RGBA_Image *) fb->backing)->mask.data;
|
||||
int w, h, k, j;
|
||||
|
||||
if (cmd->draw.clipw)
|
||||
w = MIN(cmd->draw.clipw, fb->w);
|
||||
if (!cmd->draw.clip_mode_lrtb)
|
||||
{
|
||||
if (cmd->draw.clip.w)
|
||||
w = MIN(cmd->draw.clip.w, fb->w - x);
|
||||
else
|
||||
w = fb->w - x;
|
||||
if (cmd->draw.clip.h)
|
||||
h = MIN(cmd->draw.clip.h, fb->h - y);
|
||||
else
|
||||
h = fb->h - y;
|
||||
}
|
||||
else
|
||||
w = fb->w - x;
|
||||
if (cmd->draw.cliph)
|
||||
h = MIN(cmd->draw.cliph, fb->h);
|
||||
else
|
||||
h = fb->h - y;
|
||||
{
|
||||
x = MAX(0, cmd->draw.clip.l);
|
||||
y = MAX(0, cmd->draw.clip.t);
|
||||
w = CLAMP(0, fb->w - x - cmd->draw.clip.r, fb->w - x);
|
||||
h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y);
|
||||
}
|
||||
|
||||
ptr += y * step * fb->w;
|
||||
if ((fb->alpha_only)
|
||||
|
@ -1091,7 +1101,7 @@ _fill_cpu(Evas_Filter_Command *cmd)
|
|||
{
|
||||
for (j = 0; j < w; j++)
|
||||
*dst++ = color;
|
||||
dst += fb->w;
|
||||
dst += fb->w - w;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1187,7 +1197,8 @@ _filter_command_run(Evas_Filter_Command *cmd)
|
|||
cmd->id, _filter_name_get(cmd->mode),
|
||||
cmd->input->id, cmd->mask ? cmd->mask->id : 0, cmd->output->id);
|
||||
|
||||
if (!cmd->input->w && !cmd->input->h)
|
||||
if (!cmd->input->w && !cmd->input->h
|
||||
&& (cmd->mode != EVAS_FILTER_MODE_FILL))
|
||||
{
|
||||
DBG("Skipping processing of empty input buffer (size 0x0)");
|
||||
return EINA_TRUE;
|
||||
|
|
|
@ -92,8 +92,8 @@ _filter_blend_cpu_rgba(Evas_Filter_Command *cmd)
|
|||
cmd->ENFN->context_color_set(cmd->ENDT, drawctx, cmd->draw.R, cmd->draw.G,
|
||||
cmd->draw.B, cmd->draw.A);
|
||||
cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, cmd->draw.render_op);
|
||||
cmd->ENFN->context_clip_set(cmd->ENDT, drawctx, cmd->draw.clipx,
|
||||
cmd->draw.clipy, cmd->draw.clipw, cmd->draw.cliph);
|
||||
cmd->ENFN->context_clip_set(cmd->ENDT, drawctx, cmd->draw.clip.x,
|
||||
cmd->draw.clip.y, cmd->draw.clip.w, cmd->draw.clip.h);
|
||||
|
||||
cmd->ENFN->image_draw(cmd->ENDT, drawctx, out, in,
|
||||
0, 0, w, h, // src
|
||||
|
|
|
@ -926,13 +926,22 @@ _fill_instruction_prepare(Evas_Filter_Instruction *instr)
|
|||
EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "fill"), EINA_FALSE);
|
||||
|
||||
/*
|
||||
* fill [dst=]BUFFER [color=COLOR]
|
||||
* fill [dst=BUFFER] [color=COLOR] (l=INT) (r=INT) (t=INT) (b=INT)
|
||||
*
|
||||
* Works with both Alpha and RGBA.
|
||||
*
|
||||
* The geometry is defined by l, r, t, b, offsets from the edges of the buffer
|
||||
* These offsets always go INWARDS, which means b > 0 goes UP, while t > 0
|
||||
* goes DOWN.
|
||||
*/
|
||||
|
||||
instr->type = EVAS_FILTER_MODE_FILL;
|
||||
_instruction_param_seq_add(instr, "dst", VT_BUFFER, NULL);
|
||||
_instruction_param_seq_add(instr, "dst", VT_BUFFER, "output");
|
||||
_instruction_param_seq_add(instr, "color", VT_COLOR, 0x0);
|
||||
_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;
|
||||
}
|
||||
|
@ -1308,6 +1317,12 @@ evas_filter_program_proxy_source_get(Evas_Filter_Program *pgm, const char *name)
|
|||
#define SETCOLOR(c) do { ENFN->context_color_get(ENDT, dc, &R, &G, &B, &A); \
|
||||
ENFN->context_color_set(ENDT, dc, CR(c), CG(c), CB(c), CA(c)); } while (0)
|
||||
#define RESETCOLOR() do { ENFN->context_color_set(ENDT, dc, R, G, B, A); } while (0)
|
||||
|
||||
#define SETCLIP(l, r, t, b) int _l = 0, _r = 0, _t = 0, _b = 0; \
|
||||
do { ENFN->context_clip_get(ENDT, dc, &_l, &_r, &_t, &_b); \
|
||||
ENFN->context_clip_set(ENDT, dc, l, r, t, b); } while (0)
|
||||
#define RESETCLIP() do { ENFN->context_clip_set(ENDT, dc, _l, _r, _t, _b); } while (0)
|
||||
|
||||
int A, R, G, B;
|
||||
|
||||
static Evas_Filter_Fill_Mode
|
||||
|
@ -1473,13 +1488,17 @@ _instr2cmd_fill(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
|
|||
{
|
||||
const char *bufname;
|
||||
Buffer *buf;
|
||||
int R, G, B, A;
|
||||
int R, G, B, A, l, r, t, b;
|
||||
Evas_Filter_Command *cmd;
|
||||
DATA32 color;
|
||||
int cmdid;
|
||||
|
||||
bufname = _instruction_param_gets(instr, "dst", NULL);
|
||||
color = _instruction_param_getc(instr, "color", NULL);
|
||||
// TODO/FIXME: Add clip info
|
||||
l = _instruction_param_geti(instr, "l", NULL);
|
||||
r = _instruction_param_geti(instr, "r", NULL);
|
||||
t = _instruction_param_geti(instr, "t", NULL);
|
||||
b = _instruction_param_geti(instr, "b", NULL);
|
||||
|
||||
buf = _buffer_get(pgm, bufname);
|
||||
|
||||
|
@ -1487,6 +1506,13 @@ _instr2cmd_fill(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm,
|
|||
cmdid = evas_filter_command_fill_add(ctx, dc, buf->cid);
|
||||
RESETCOLOR();
|
||||
|
||||
cmd = EINA_INLIST_CONTAINER_GET(eina_inlist_last(ctx->commands), Evas_Filter_Command);
|
||||
cmd->draw.clip.l = l;
|
||||
cmd->draw.clip.r = r;
|
||||
cmd->draw.clip.t = t;
|
||||
cmd->draw.clip.b = b;
|
||||
cmd->draw.clip_mode_lrtb = EINA_TRUE;
|
||||
|
||||
return cmdid;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,8 +106,16 @@ struct _Evas_Filter_Command
|
|||
int render_op;
|
||||
int R, G, B, A;
|
||||
int ox, oy;
|
||||
int clipx, clipy, clipw, cliph;
|
||||
union {
|
||||
struct {
|
||||
int x, y, w, h;
|
||||
};
|
||||
struct {
|
||||
int l, r, t, b;
|
||||
};
|
||||
} clip;
|
||||
Evas_Filter_Fill_Mode fillmode;
|
||||
Eina_Bool clip_mode_lrtb : 1;
|
||||
} draw;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue