Evas masking: Add clip_image_[un]set functions to draw context

This allows passing a mask image to the render functions.

@feature
This commit is contained in:
Jean-Philippe Andre 2014-11-13 10:31:41 +09:00
parent 9af60b1b04
commit a9630a77b6
4 changed files with 83 additions and 3 deletions

View File

@ -1537,6 +1537,9 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
ctx->target.b == 255 && ctx->target.a == 255)
ctx->target.color_use = EINA_FALSE;
ENFN->context_clip_image_get
(ENDT, draw_context, &ctx->target.mask, &ctx->target.mask_x, &ctx->target.mask_y);
if (ctx->gl_engine)
{
// Since GL has sync rendering, draw_context is safe to keep around
@ -1621,6 +1624,12 @@ _filter_target_render(Evas_Filter_Context *ctx)
ENFN->context_multiplier_unset(ENDT, drawctx);
}
if (ctx->target.mask)
ENFN->context_clip_image_set(ENDT, drawctx,
ctx->target.mask, ctx->target.mask_x, ctx->target.mask_y);
else
ENFN->context_clip_image_unset(ENDT, drawctx);
ENFN->image_draw(ENDT, drawctx, surface, image,
0, 0, src->w, src->h,
ctx->target.x, ctx->target.y, src->w, src->h,

View File

@ -101,6 +101,8 @@ struct _Evas_Filter_Context
int x, y;
int cx, cy, cw, ch; // clip
int r, g, b, a; // clip color
void *mask; // mask
int mask_x, mask_y; // mask offset
Eina_Bool clip_use : 1;
Eina_Bool color_use : 1;
} target;

View File

@ -1155,6 +1155,9 @@ struct _Evas_Func
Eina_Bool (*canvas_alpha_get) (void *data, void *context);
void (*context_free) (void *data, void *context);
void (*context_clip_set) (void *data, void *context, int x, int y, int w, int h);
void (*context_clip_image_set) (void *data, void *context, void *surface, int x, int y);
void (*context_clip_image_unset) (void *data, void *context);
void (*context_clip_image_get) (void *data, void *context, void **surface, int *x, int *y);
void (*context_clip_clip) (void *data, void *context, int x, int y, int w, int h);
void (*context_clip_unset) (void *data, void *context);
int (*context_clip_get) (void *data, void *context, int *x, int *y, int *w, int *h);

View File

@ -416,6 +416,60 @@ eng_context_clip_set(void *data EINA_UNUSED, void *context, int x, int y, int w,
evas_common_draw_context_set_clip(context, x, y, w, h);
}
static void
eng_context_clip_image_unset(void *data EINA_UNUSED, void *context)
{
RGBA_Draw_Context *ctx = context;
if (ctx->clip.mask)
{
Image_Entry *ie = ctx->clip.mask;
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
evas_cache2_image_close(ie);
else
#endif
evas_cache_image_drop(ie);
// Is the above code safe? Hmmm...
//evas_unref_queue_image_put(EVAS???, &ctx->clip.ie->cache_entry);
ctx->clip.mask = NULL;
}
}
static void
eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, int x, int y)
{
RGBA_Draw_Context *ctx = context;
if (ctx->clip.mask && ctx->clip.mask != surface)
eng_context_clip_image_unset(data, context);
ctx->clip.mask = surface;
ctx->clip.mask_x = x;
ctx->clip.mask_y = y;
if (surface)
{
Image_Entry *ie = surface;
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
evas_cache2_image_ref(ie);
else
#endif
evas_cache_image_ref(ie);
}
}
static void
eng_context_clip_image_get(void *data EINA_UNUSED, void *context, void **ie, int *x, int *y)
{
RGBA_Draw_Context *ctx = context;
if (ie) *ie = ctx->clip.mask;
if (x) *x = ctx->clip.mask_x;
if (y) *y = ctx->clip.mask_y;
}
static void
eng_context_clip_clip(void *data EINA_UNUSED, void *context, int x, int y, int w, int h)
{
@ -1296,14 +1350,23 @@ _image_draw_thread_cmd(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc,
clip_h = dst->cache_entry.h;
}
/* Set image mask, if any */
cr->mask = dc->clip.mask;
cr->mask_x = dc->clip.mask_x;
cr->mask_y = dc->clip.mask_y;
if (cr->mask)
{
Image_Entry *im = cr->mask;
RECTS_CLIP_TO_RECT(clip_x, clip_y, clip_w, clip_h,
cr->mask_x, cr->mask_y,
im->w, im->h);
}
EINA_RECTANGLE_SET(&cr->clip, clip_x, clip_y, clip_w, clip_h);
cr->mul_col = dc->mul.use ? dc->mul.col : 0xffffffff;
cr->render_op = dc->render_op;
cr->smooth = smooth;
cr->mask = dc->clip.mask;
cr->mask_x = dc->clip.mask_x;
cr->mask_y = dc->clip.mask_y;
evas_thread_cmd_enqueue(_draw_thread_image_draw, cr);
@ -3010,6 +3073,9 @@ static Evas_Func func =
eng_canvas_alpha_get,
eng_context_free,
eng_context_clip_set,
eng_context_clip_image_set,
eng_context_clip_image_unset,
eng_context_clip_image_get,
eng_context_clip_clip,
eng_context_clip_unset,
eng_context_clip_get,