#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;
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;
}
{
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);
- else
- w = fb->w - x;
- if (cmd->draw.cliph)
- h = MIN(cmd->draw.cliph, fb->h);
+ 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
- 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)
{
for (j = 0; j < w; j++)
*dst++ = color;
- dst += fb->w;
+ dst += fb->w - w;
}
}
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;
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
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;
}
#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
{
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);
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;
}