2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2008-07-10 15:53:33 -07:00
|
|
|
#include "evas_convert_main.h"
|
2010-02-25 07:10:05 -08:00
|
|
|
#include "evas_private.h"
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2015-09-23 22:06:40 -07:00
|
|
|
EAPI Cutout_Rects *
|
2007-09-13 07:14:37 -07:00
|
|
|
evas_common_draw_context_cutouts_new(void)
|
2007-04-04 02:55:40 -07:00
|
|
|
{
|
|
|
|
Cutout_Rects *rects;
|
|
|
|
|
2010-03-01 18:10:48 -08:00
|
|
|
rects = calloc(1, sizeof(Cutout_Rects));
|
2007-04-04 02:55:40 -07:00
|
|
|
return rects;
|
|
|
|
}
|
|
|
|
|
2015-09-02 20:03:23 -07:00
|
|
|
static void
|
|
|
|
evas_common_draw_context_cutouts_dup(Cutout_Rects *rects2, const Cutout_Rects *rects)
|
|
|
|
{
|
|
|
|
if (!rects) return;
|
|
|
|
rects2->active = rects->active;
|
2015-10-13 12:10:34 -07:00
|
|
|
rects2->max = rects->active;
|
2015-09-23 22:06:40 -07:00
|
|
|
rects2->last_add = rects->last_add;
|
2015-10-13 12:10:34 -07:00
|
|
|
if (rects2->max > 0)
|
2015-09-02 20:03:23 -07:00
|
|
|
{
|
2015-10-13 12:10:34 -07:00
|
|
|
const size_t sz = sizeof(Cutout_Rect) * rects2->max;
|
2015-09-02 20:03:23 -07:00
|
|
|
rects2->rects = malloc(sz);
|
|
|
|
memcpy(rects2->rects, rects->rects, sz);
|
2017-01-30 21:50:52 -08:00
|
|
|
return;
|
2015-09-02 20:03:23 -07:00
|
|
|
}
|
2017-01-30 21:50:52 -08:00
|
|
|
else rects2->rects = NULL;
|
2015-09-02 20:03:23 -07:00
|
|
|
}
|
|
|
|
|
2007-04-04 02:55:40 -07:00
|
|
|
EAPI void
|
|
|
|
evas_common_draw_context_cutouts_free(Cutout_Rects* rects)
|
|
|
|
{
|
2013-06-20 04:28:18 -07:00
|
|
|
if (!rects) return;
|
2007-04-04 02:55:40 -07:00
|
|
|
rects->active = 0;
|
2015-09-23 22:06:40 -07:00
|
|
|
rects->last_add.w = 0;
|
2007-04-04 02:55:40 -07:00
|
|
|
}
|
|
|
|
|
2016-04-01 01:37:37 -07:00
|
|
|
EAPI void
|
|
|
|
evas_common_draw_context_cutouts_real_free(Cutout_Rects* rects)
|
|
|
|
{
|
|
|
|
if (!rects) return;
|
|
|
|
free(rects->rects);
|
|
|
|
free(rects);
|
|
|
|
}
|
|
|
|
|
2007-04-04 02:55:40 -07:00
|
|
|
EAPI void
|
2011-05-26 18:44:10 -07:00
|
|
|
evas_common_draw_context_cutouts_del(Cutout_Rects* rects, int idx)
|
2007-04-04 02:55:40 -07:00
|
|
|
{
|
2011-05-26 18:44:10 -07:00
|
|
|
if ((idx >= 0) && (idx < rects->active))
|
2007-04-04 02:55:40 -07:00
|
|
|
{
|
2011-05-26 18:44:10 -07:00
|
|
|
Cutout_Rect *rect;
|
2008-07-10 15:53:33 -07:00
|
|
|
|
2015-09-23 22:06:40 -07:00
|
|
|
rect = rects->rects + idx;
|
2008-07-10 15:53:33 -07:00
|
|
|
memmove(rect, rect + 1,
|
2015-09-23 22:06:40 -07:00
|
|
|
sizeof(Cutout_Rect) * (rects->active - idx - 1));
|
2007-04-04 02:55:40 -07:00
|
|
|
rects->active--;
|
2015-09-23 22:06:40 -07:00
|
|
|
rects->last_add.w = 0;
|
2007-04-04 02:55:40 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-23 02:36:03 -08:00
|
|
|
static int _init_count = 0;
|
2017-02-10 13:40:44 -08:00
|
|
|
static Eina_Trash *_ctxt_spares = NULL;
|
2017-01-30 21:50:52 -08:00
|
|
|
static int _ctxt_spares_count = 0;
|
|
|
|
static SLK(_ctx_spares_lock);
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_common_draw_context_real_free(RGBA_Draw_Context *dc)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_PIXMAN
|
|
|
|
# if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY)
|
|
|
|
if (dc->col.pixman_color_image)
|
|
|
|
pixman_image_unref(dc->col.pixman_color_image);
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
evas_common_draw_context_apply_clean_cutouts(&dc->cutout);
|
|
|
|
evas_common_draw_context_cutouts_real_free(dc->cache.rects);
|
|
|
|
free(dc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_common_draw_context_stash(RGBA_Draw_Context *dc)
|
|
|
|
{
|
2017-02-10 13:40:44 -08:00
|
|
|
if (_ctxt_spares_count >= 8)
|
2017-01-30 21:50:52 -08:00
|
|
|
{
|
2017-02-10 13:40:44 -08:00
|
|
|
_evas_common_draw_context_real_free(dc);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
2017-01-30 21:50:52 -08:00
|
|
|
#ifdef HAVE_PIXMAN
|
|
|
|
# if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY)
|
2017-02-10 13:40:44 -08:00
|
|
|
if (dc->col.pixman_color_image)
|
|
|
|
{
|
|
|
|
pixman_image_unref(dc->col.pixman_color_image);
|
|
|
|
dc->col.pixman_color_image = NULL;
|
|
|
|
}
|
2017-01-30 21:50:52 -08:00
|
|
|
# endif
|
|
|
|
#endif
|
2017-02-10 13:40:44 -08:00
|
|
|
evas_common_draw_context_apply_clean_cutouts(&dc->cutout);
|
|
|
|
evas_common_draw_context_cutouts_real_free(dc->cache.rects);
|
|
|
|
SLKL(_ctx_spares_lock);
|
|
|
|
eina_trash_push(&_ctxt_spares, dc);
|
|
|
|
_ctxt_spares_count++;
|
|
|
|
SLKU(_ctx_spares_lock);
|
2017-01-30 21:50:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static RGBA_Draw_Context *
|
|
|
|
_evas_common_draw_context_find(void)
|
|
|
|
{
|
|
|
|
RGBA_Draw_Context *dc;
|
|
|
|
|
2017-02-10 13:40:44 -08:00
|
|
|
if (!_ctxt_spares)
|
|
|
|
{
|
|
|
|
dc = malloc(sizeof(RGBA_Draw_Context));
|
|
|
|
}
|
|
|
|
else
|
2017-01-30 21:50:52 -08:00
|
|
|
{
|
|
|
|
SLKL(_ctx_spares_lock);
|
2017-02-10 13:40:44 -08:00
|
|
|
dc = eina_trash_pop(&_ctxt_spares);
|
2017-01-30 21:50:52 -08:00
|
|
|
_ctxt_spares_count--;
|
|
|
|
SLKU(_ctx_spares_lock);
|
|
|
|
}
|
2017-02-10 13:40:44 -08:00
|
|
|
|
2017-01-30 21:50:52 -08:00
|
|
|
return dc;
|
|
|
|
}
|
2015-02-23 02:36:03 -08:00
|
|
|
|
2015-02-20 06:04:52 -08:00
|
|
|
EAPI void
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_common_init(void)
|
|
|
|
{
|
2017-01-30 21:50:52 -08:00
|
|
|
if (_init_count++) return;
|
2015-02-23 02:36:03 -08:00
|
|
|
|
2017-01-30 21:50:52 -08:00
|
|
|
SLKI(_ctx_spares_lock);
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_common_cpu_init();
|
|
|
|
|
|
|
|
evas_common_blend_init();
|
|
|
|
evas_common_image_init();
|
|
|
|
evas_common_convert_init();
|
|
|
|
evas_common_scale_init();
|
2015-02-20 08:11:44 -08:00
|
|
|
evas_common_scale_sample_init();
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_common_rectangle_init();
|
|
|
|
evas_common_polygon_init();
|
|
|
|
evas_common_line_init();
|
|
|
|
evas_common_font_init();
|
|
|
|
evas_common_draw_init();
|
|
|
|
evas_common_tilebuf_init();
|
|
|
|
}
|
|
|
|
|
2015-02-20 06:04:52 -08:00
|
|
|
EAPI void
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_common_shutdown(void)
|
|
|
|
{
|
2017-01-30 21:50:52 -08:00
|
|
|
if (--_init_count) return;
|
2015-02-23 02:36:03 -08:00
|
|
|
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_font_dir_cache_free();
|
2015-02-23 02:35:29 -08:00
|
|
|
evas_common_font_shutdown();
|
|
|
|
evas_common_image_shutdown();
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_common_image_cache_free();
|
2015-02-20 08:11:44 -08:00
|
|
|
evas_common_scale_sample_shutdown();
|
2017-01-30 21:50:52 -08:00
|
|
|
// just in case any thread is still doing things... don't del this here
|
|
|
|
// RGBA_Draw_Context *dc;
|
|
|
|
// SLKL(_ctx_spares_lock);
|
|
|
|
// EINA_LIST_FREE(_ctxt_spares, dc) _evas_common_draw_context_real_free(dc);
|
|
|
|
// _ctxt_spares_count = 0;
|
|
|
|
// SLKU(_ctx_spares_lock);
|
|
|
|
// SLKD(_ctx_spares_lock);
|
2005-12-03 01:27:53 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_init(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI RGBA_Draw_Context *
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_new(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
RGBA_Draw_Context *dc;
|
2017-01-30 21:50:52 -08:00
|
|
|
dc = _evas_common_draw_context_find();
|
|
|
|
if (!dc) return NULL;
|
|
|
|
memset(dc, 0, sizeof(RGBA_Draw_Context));
|
2002-11-08 00:02:15 -08:00
|
|
|
return dc;
|
|
|
|
}
|
|
|
|
|
2015-09-02 20:03:23 -07:00
|
|
|
EAPI RGBA_Draw_Context *
|
|
|
|
evas_common_draw_context_dup(RGBA_Draw_Context *dc)
|
|
|
|
{
|
2017-01-30 21:50:52 -08:00
|
|
|
RGBA_Draw_Context *dc2 = _evas_common_draw_context_find();
|
2015-09-02 20:03:23 -07:00
|
|
|
|
2017-01-30 21:50:52 -08:00
|
|
|
if (!dc) return dc2;
|
2015-09-02 20:03:23 -07:00
|
|
|
memcpy(dc2, dc, sizeof(RGBA_Draw_Context));
|
|
|
|
evas_common_draw_context_cutouts_dup(&dc2->cutout, &dc->cutout);
|
2015-10-04 00:50:58 -07:00
|
|
|
#ifdef HAVE_PIXMAN
|
2017-01-30 21:50:52 -08:00
|
|
|
# if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY)
|
|
|
|
dc2->col.pixman_color_image = NULL;
|
|
|
|
# endif
|
2015-10-04 00:50:58 -07:00
|
|
|
#endif
|
2016-11-16 16:05:56 -08:00
|
|
|
dc2->cache.rects = NULL;
|
|
|
|
dc2->cache.used = 0;
|
2015-09-02 20:03:23 -07:00
|
|
|
return dc2;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_free(RGBA_Draw_Context *dc)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2007-04-29 21:23:47 -07:00
|
|
|
if (!dc) return;
|
2017-01-30 21:50:52 -08:00
|
|
|
_evas_common_draw_context_stash(dc);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2007-04-04 02:55:40 -07:00
|
|
|
EAPI void
|
|
|
|
evas_common_draw_context_clear_cutouts(RGBA_Draw_Context *dc)
|
|
|
|
{
|
2012-07-04 02:39:23 -07:00
|
|
|
evas_common_draw_context_cutouts_free(&dc->cutout);
|
2007-04-04 02:55:40 -07:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2003-09-08 22:51:03 -07:00
|
|
|
evas_common_draw_context_font_ext_set(RGBA_Draw_Context *dc,
|
2015-03-19 03:02:02 -07:00
|
|
|
void *data,
|
|
|
|
void *(*gl_new) (void *data, RGBA_Font_Glyph *fg),
|
|
|
|
void (*gl_free) (void *ext_dat),
|
2017-09-25 02:34:22 -07:00
|
|
|
void (*gl_draw) (void *data, void *dest, void *context, RGBA_Font_Glyph *fg, int x, int y, int w, int h),
|
2017-03-08 02:33:15 -08:00
|
|
|
void *(*gl_image_new) (void *gc, RGBA_Font_Glyph *fg, int alpha, Evas_Colorspace cspace),
|
2015-03-19 03:02:02 -07:00
|
|
|
void (*gl_image_free) (void *image),
|
2017-03-08 02:33:15 -08:00
|
|
|
void (*gl_image_draw) (void *gc, void *im, int dx, int dy, int dw, int dh, int smooth))
|
2003-09-08 22:51:03 -07:00
|
|
|
{
|
|
|
|
dc->font_ext.data = data;
|
|
|
|
dc->font_ext.func.gl_new = gl_new;
|
|
|
|
dc->font_ext.func.gl_free = gl_free;
|
|
|
|
dc->font_ext.func.gl_draw = gl_draw;
|
2017-03-08 02:33:15 -08:00
|
|
|
dc->font_ext.func.gl_image_new = gl_image_new;
|
2015-03-19 03:02:02 -07:00
|
|
|
dc->font_ext.func.gl_image_free = gl_image_free;
|
|
|
|
dc->font_ext.func.gl_image_draw = gl_image_draw;
|
2003-09-08 22:51:03 -07:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_clip_clip(RGBA_Draw_Context *dc, int x, int y, int w, int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
if (dc->clip.use)
|
|
|
|
{
|
2005-05-21 19:49:50 -07:00
|
|
|
RECTS_CLIP_TO_RECT(dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h,
|
2002-11-08 00:02:15 -08:00
|
|
|
x, y, w, h);
|
|
|
|
}
|
|
|
|
else
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_set_clip(dc, x, y, w, h);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_set_clip(RGBA_Draw_Context *dc, int x, int y, int w, int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
dc->clip.use = 1;
|
|
|
|
dc->clip.x = x;
|
|
|
|
dc->clip.y = y;
|
|
|
|
dc->clip.w = w;
|
|
|
|
dc->clip.h = h;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_unset_clip(RGBA_Draw_Context *dc)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
dc->clip.use = 0;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_set_color(RGBA_Draw_Context *dc, int r, int g, int b, int a)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
R_VAL(&(dc->col.col)) = (DATA8)r;
|
|
|
|
G_VAL(&(dc->col.col)) = (DATA8)g;
|
|
|
|
B_VAL(&(dc->col.col)) = (DATA8)b;
|
|
|
|
A_VAL(&(dc->col.col)) = (DATA8)a;
|
2011-12-23 03:50:29 -08:00
|
|
|
#ifdef HAVE_PIXMAN
|
2013-03-11 19:56:40 -07:00
|
|
|
#if defined(PIXMAN_FONT) || defined(PIXMAN_RECT) || defined(PIXMAN_LINE) || defined(PIXMAN_POLY)
|
2014-05-27 19:24:56 -07:00
|
|
|
if (dc->col.pixman_color_image)
|
2011-12-23 03:50:29 -08:00
|
|
|
pixman_image_unref(dc->col.pixman_color_image);
|
|
|
|
|
|
|
|
pixman_color_t pixman_color;
|
|
|
|
|
|
|
|
pixman_color.alpha = (dc->col.col & 0xff000000) >> 16;
|
|
|
|
pixman_color.red = (dc->col.col & 0x00ff0000) >> 8;
|
|
|
|
pixman_color.green = (dc->col.col & 0x0000ff00);
|
|
|
|
pixman_color.blue = (dc->col.col & 0x000000ff) << 8;
|
|
|
|
|
|
|
|
dc->col.pixman_color_image = pixman_image_create_solid_fill(&pixman_color);
|
2013-03-11 19:56:40 -07:00
|
|
|
#endif
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_set_multiplier(RGBA_Draw_Context *dc, int r, int g, int b, int a)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
dc->mul.use = 1;
|
|
|
|
R_VAL(&(dc->mul.col)) = (DATA8)r;
|
|
|
|
G_VAL(&(dc->mul.col)) = (DATA8)g;
|
|
|
|
B_VAL(&(dc->mul.col)) = (DATA8)b;
|
|
|
|
A_VAL(&(dc->mul.col)) = (DATA8)a;
|
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_unset_multiplier(RGBA_Draw_Context *dc)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
dc->mul.use = 0;
|
|
|
|
}
|
|
|
|
|
2011-04-05 22:38:38 -07:00
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_draw_context_add_cutout(RGBA_Draw_Context *dc, int x, int y, int w, int h)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2010-11-13 22:00:35 -08:00
|
|
|
// if (dc->cutout.rects > 512) return;
|
2007-10-01 20:40:14 -07:00
|
|
|
if (dc->clip.use)
|
|
|
|
{
|
2009-10-12 08:22:38 -07:00
|
|
|
#if 1 // this is a bit faster
|
2015-09-23 22:06:40 -07:00
|
|
|
int x1, x2, y1, y2;
|
|
|
|
int cx1, cx2, cy1, cy2;
|
|
|
|
|
|
|
|
x2 = x + w;
|
|
|
|
cx1 = dc->clip.x;
|
|
|
|
if (x2 <= cx1) return;
|
|
|
|
x1 = x;
|
|
|
|
cx2 = cx1 + dc->clip.w;
|
|
|
|
if (x1 >= cx2) return;
|
|
|
|
|
|
|
|
if (x1 < cx1) x1 = cx1;
|
|
|
|
if (x2 > cx2) x2 = cx2;
|
|
|
|
|
|
|
|
y2 = y + h;
|
|
|
|
cy1 = dc->clip.y;
|
|
|
|
if (y2 <= cy1) return;
|
|
|
|
y1 = y;
|
|
|
|
cy2 = cy1 + dc->clip.h;
|
|
|
|
if (y1 >= cy2) return;
|
|
|
|
|
|
|
|
if (y1 < cy1) y1 = cy1;
|
|
|
|
if (y2 > cy2) y2 = cy2;
|
|
|
|
|
|
|
|
x = x1;
|
|
|
|
y = y1;
|
|
|
|
w = x2 - x1;
|
|
|
|
h = y2 - y1;
|
2011-12-23 03:50:29 -08:00
|
|
|
#else
|
2007-10-01 20:40:14 -07:00
|
|
|
RECTS_CLIP_TO_RECT(x, y, w, h,
|
2015-09-23 22:06:40 -07:00
|
|
|
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
|
2011-12-23 03:50:29 -08:00
|
|
|
#endif
|
2007-10-01 20:40:14 -07:00
|
|
|
}
|
2015-09-23 22:06:40 -07:00
|
|
|
if ((w * h) <= (8 * 8)) return;
|
|
|
|
if (dc->cutout.last_add.w > 0)
|
|
|
|
{
|
|
|
|
if ((dc->cutout.last_add.x == x) && (dc->cutout.last_add.y == y) &&
|
|
|
|
(dc->cutout.last_add.w == w) && (dc->cutout.last_add.h == h)) return;
|
|
|
|
}
|
|
|
|
dc->cutout.last_add.x = x;
|
|
|
|
dc->cutout.last_add.y = y;
|
|
|
|
dc->cutout.last_add.w = w;
|
|
|
|
dc->cutout.last_add.h = h;
|
2007-04-04 02:55:40 -07:00
|
|
|
evas_common_draw_context_cutouts_add(&dc->cutout, x, y, w, h);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2015-09-23 22:06:40 -07:00
|
|
|
static int
|
|
|
|
evas_common_draw_context_cutout_split(Cutout_Rects *res, int idx, Cutout_Rect *split)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
/* 1 input rect, multiple out */
|
2011-05-26 18:44:10 -07:00
|
|
|
Cutout_Rect in = res->rects[idx];
|
2002-11-08 00:02:15 -08:00
|
|
|
|
|
|
|
/* this is to save me a LOT of typing */
|
2007-04-04 02:55:40 -07:00
|
|
|
#define INX1 (in.x)
|
|
|
|
#define INX2 (in.x + in.w)
|
2002-11-08 00:02:15 -08:00
|
|
|
#define SPX1 (split->x)
|
2005-05-21 19:49:50 -07:00
|
|
|
#define SPX2 (split->x + split->w)
|
2007-04-04 02:55:40 -07:00
|
|
|
#define INY1 (in.y)
|
|
|
|
#define INY2 (in.y + in.h)
|
2002-11-08 00:02:15 -08:00
|
|
|
#define SPY1 (split->y)
|
2005-05-21 19:49:50 -07:00
|
|
|
#define SPY2 (split->y + split->h)
|
2007-04-04 02:55:40 -07:00
|
|
|
#define X1_IN (in.x < split->x)
|
|
|
|
#define X2_IN ((in.x + in.w) > (split->x + split->w))
|
|
|
|
#define Y1_IN (in.y < split->y)
|
|
|
|
#define Y2_IN ((in.y + in.h) > (split->y + split->h))
|
|
|
|
#define R_NEW(_r, _x, _y, _w, _h) { evas_common_draw_context_cutouts_add(_r, _x, _y, _w, _h); }
|
|
|
|
if (!RECTS_INTERSECT(in.x, in.y, in.w, in.h,
|
2002-11-08 00:02:15 -08:00
|
|
|
split->x, split->y, split->w, split->h))
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
/* No colision => no clipping, don't touch it. */
|
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* S = split (ie cut out rect) */
|
|
|
|
/* +--+ = in (rect to be cut) */
|
2005-05-21 19:49:50 -07:00
|
|
|
|
|
|
|
/*
|
2002-11-08 00:02:15 -08:00
|
|
|
* +---+
|
|
|
|
* | |
|
|
|
|
* | S |
|
|
|
|
* | |
|
|
|
|
* +---+
|
2005-05-21 19:49:50 -07:00
|
|
|
*
|
2002-11-08 00:02:15 -08:00
|
|
|
*/
|
|
|
|
if (X1_IN && X2_IN && Y1_IN && Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, in.x, in.y, in.w, SPY1 - in.y);
|
|
|
|
R_NEW(res, in.x, SPY1, SPX1 - in.x, SPY2 - SPY1);
|
|
|
|
R_NEW(res, SPX2, SPY1, INX2 - SPX2, SPY2 - SPY1);
|
|
|
|
/* out => (in.x, SPY2, in.w, INY2 - SPY2) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = INY2 - SPY2;
|
|
|
|
res->rects[idx].y = SPY2;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
/* SSSSSSS
|
|
|
|
* S+---+S
|
|
|
|
* S|SSS|S
|
|
|
|
* S|SSS|S
|
|
|
|
* S|SSS|S
|
|
|
|
* S+---+S
|
|
|
|
* SSSSSSS
|
|
|
|
*/
|
|
|
|
if (!X1_IN && !X2_IN && !Y1_IN && !Y2_IN)
|
|
|
|
{
|
2011-05-26 18:44:10 -07:00
|
|
|
evas_common_draw_context_cutouts_del(res, idx);
|
2007-04-04 02:55:40 -07:00
|
|
|
return 0;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
/* SSS
|
|
|
|
* S+---+
|
|
|
|
* S|S |
|
|
|
|
* S|S |
|
|
|
|
* S|S |
|
|
|
|
* S+---+
|
|
|
|
* SSS
|
|
|
|
*/
|
|
|
|
if (!X1_IN && X2_IN && !Y1_IN && !Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
/* in => (SPX2, in.y, INX2 - SPX2, in.h) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].w = INX2 - SPX2;
|
|
|
|
res->rects[idx].x = SPX2;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
/* S
|
|
|
|
* +---+
|
|
|
|
* | S |
|
|
|
|
* | S |
|
|
|
|
* | S |
|
|
|
|
* +---+
|
|
|
|
* S
|
|
|
|
*/
|
|
|
|
if (X1_IN && X2_IN && !Y1_IN && !Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, in.x, in.y, SPX1 - in.x, in.h);
|
|
|
|
/* in => (SPX2, in.y, INX2 - SPX2, in.h) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].w = INX2 - SPX2;
|
|
|
|
res->rects[idx].x = SPX2;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
/* SSS
|
|
|
|
* +---+S
|
|
|
|
* | S|S
|
|
|
|
* | S|S
|
|
|
|
* | S|S
|
|
|
|
* +---+S
|
|
|
|
* SSS
|
|
|
|
*/
|
|
|
|
if (X1_IN && !X2_IN && !Y1_IN && !Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
/* in => (in.x, in.y, SPX1 - in.x, in.h) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].w = SPX1 - in.x;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
/* SSSSSSS
|
|
|
|
* S+---+S
|
|
|
|
* S|SSS|S
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* +---+
|
2005-05-21 19:49:50 -07:00
|
|
|
*
|
2002-11-08 00:02:15 -08:00
|
|
|
*/
|
|
|
|
if (!X1_IN && !X2_IN && !Y1_IN && Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
/* in => (in.x, SPY2, in.w, INY2 - SPY2) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = INY2 - SPY2;
|
|
|
|
res->rects[idx].y = SPY2;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
/*
|
2002-11-08 00:02:15 -08:00
|
|
|
* +---+
|
|
|
|
* | |
|
|
|
|
* S|SSS|S
|
|
|
|
* | |
|
|
|
|
* +---+
|
2005-05-21 19:49:50 -07:00
|
|
|
*
|
2002-11-08 00:02:15 -08:00
|
|
|
*/
|
|
|
|
if (!X1_IN && !X2_IN && Y1_IN && Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, in.x, SPY2, in.w, INY2 - SPY2);
|
|
|
|
/* in => (in.x, in.y, in.w, SPY1 - in.y) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = SPY1 - in.y;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
/*
|
2002-11-08 00:02:15 -08:00
|
|
|
* +---+
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* S|SSS|S
|
|
|
|
* S+---+S
|
|
|
|
* SSSSSSS
|
|
|
|
*/
|
|
|
|
if (!X1_IN && !X2_IN && Y1_IN && !Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
/* in => (in.x, in.y, in.w, SPY1 - in.y) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = SPY1 - in.y;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
/* SSS
|
|
|
|
* S+---+
|
|
|
|
* S|S |
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* +---+
|
2005-05-21 19:49:50 -07:00
|
|
|
*
|
2002-11-08 00:02:15 -08:00
|
|
|
*/
|
|
|
|
if (!X1_IN && X2_IN && !Y1_IN && Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, SPX2, in.y, INX2 - SPX2, SPY2 - in.y);
|
|
|
|
/* in => (in.x, SPY2, in.w, INY2 - SPY2) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = INY2 - SPY2;
|
|
|
|
res->rects[idx].y = SPY2;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
/* S
|
|
|
|
* +---+
|
|
|
|
* | S |
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* +---+
|
2005-05-21 19:49:50 -07:00
|
|
|
*
|
2002-11-08 00:02:15 -08:00
|
|
|
*/
|
|
|
|
if (X1_IN && X2_IN && !Y1_IN && Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, in.x, in.y, SPX1 - in.x, SPY2 - in.y);
|
|
|
|
R_NEW(res, SPX2, in.y, INX2 - SPX2, SPY2 - in.y);
|
|
|
|
/* in => (in.x, SPY2, in.w, INY2 - SPY2) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = INY2 - SPY2;
|
|
|
|
res->rects[idx].y = SPY2;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
/* SSS
|
|
|
|
* +---+S
|
|
|
|
* | S|S
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* +---+
|
2005-05-21 19:49:50 -07:00
|
|
|
*
|
2002-11-08 00:02:15 -08:00
|
|
|
*/
|
|
|
|
if (X1_IN && !X2_IN && !Y1_IN && Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, in.x, in.y, SPX1 - in.x, SPY2 - in.y);
|
|
|
|
/* in => (in.x, SPY2, in.w, INY2 - SPY2) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = INY2 - SPY2;
|
|
|
|
res->rects[idx].y = SPY2;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
/*
|
2002-11-08 00:02:15 -08:00
|
|
|
* +---+
|
|
|
|
* | |
|
|
|
|
* S|S |
|
|
|
|
* | |
|
|
|
|
* +---+
|
2005-05-21 19:49:50 -07:00
|
|
|
*
|
2002-11-08 00:02:15 -08:00
|
|
|
*/
|
|
|
|
if (!X1_IN && X2_IN && Y1_IN && Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, in.x, SPY2, in.w, INY2 - SPY2);
|
|
|
|
R_NEW(res, SPX2, SPY1, INX2 - SPX2, SPY2 - SPY1);
|
|
|
|
/* in => (in.x, SPY2, in.w, INY2 - SPY2) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = SPY1 - in.y;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
/*
|
2002-11-08 00:02:15 -08:00
|
|
|
* +---+
|
|
|
|
* | |
|
|
|
|
* | S|S
|
|
|
|
* | |
|
|
|
|
* +---+
|
2005-05-21 19:49:50 -07:00
|
|
|
*
|
2002-11-08 00:02:15 -08:00
|
|
|
*/
|
|
|
|
if (X1_IN && !X2_IN && Y1_IN && Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, in.x, SPY2, in.w, INY2 - SPY2);
|
|
|
|
R_NEW(res, in.x, SPY1, SPX1 - in.x, SPY2 - SPY1);
|
|
|
|
/* in => (in.x, in.y, in.w, SPY1 - in.y) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = SPY1 - in.y;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
/*
|
2002-11-08 00:02:15 -08:00
|
|
|
* +---+
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* S|S |
|
|
|
|
* S+---+
|
|
|
|
* SSS
|
|
|
|
*/
|
|
|
|
if (!X1_IN && X2_IN && Y1_IN && !Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, SPX2, SPY1, INX2 - SPX2, INY2 - SPY1);
|
|
|
|
/* in => (in.x, in.y, in.w, SPY1 - in.y) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = SPY1 - in.y;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
/*
|
2002-11-08 00:02:15 -08:00
|
|
|
* +---+
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* | S |
|
|
|
|
* +---+
|
|
|
|
* S
|
|
|
|
*/
|
|
|
|
if (X1_IN && X2_IN && Y1_IN && !Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, in.x, SPY1, SPX1 - in.x, INY2 - SPY1);
|
|
|
|
R_NEW(res, SPX2, SPY1, INX2 - SPX2, INY2 - SPY1);
|
|
|
|
/* in => (in.x, in.y, in.w, SPY1 - in.y) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = SPY1 - in.y;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
/*
|
2002-11-08 00:02:15 -08:00
|
|
|
* +---+
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* | S|S
|
|
|
|
* +---+S
|
|
|
|
* SSS
|
|
|
|
*/
|
|
|
|
if (X1_IN && !X2_IN && Y1_IN && !Y2_IN)
|
|
|
|
{
|
2007-04-04 02:55:40 -07:00
|
|
|
R_NEW(res, in.x, SPY1, SPX1 - in.x, INY2 - SPY1);
|
|
|
|
/* in => (in.x, in.y, in.w, SPY1 - in.y) */
|
2011-05-26 18:44:10 -07:00
|
|
|
res->rects[idx].h = SPY1 - in.y;
|
2007-04-04 02:55:40 -07:00
|
|
|
return 1;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2011-05-26 18:44:10 -07:00
|
|
|
evas_common_draw_context_cutouts_del(res, idx);
|
2007-04-04 02:55:40 -07:00
|
|
|
return 0;
|
2005-02-04 18:30:13 -08:00
|
|
|
#undef INX1
|
|
|
|
#undef INX2
|
|
|
|
#undef SPX1
|
|
|
|
#undef SPX2
|
|
|
|
#undef INY1
|
|
|
|
#undef INY2
|
|
|
|
#undef SPY1
|
|
|
|
#undef SPY2
|
|
|
|
#undef X1_IN
|
|
|
|
#undef X2_IN
|
|
|
|
#undef Y1_IN
|
|
|
|
#undef Y2_IN
|
|
|
|
#undef R_NEW
|
|
|
|
}
|
|
|
|
|
2016-12-30 01:55:55 -08:00
|
|
|
EAPI void
|
|
|
|
evas_common_draw_context_target_set(RGBA_Draw_Context *dc, int x, int y, int w, int h)
|
|
|
|
{
|
|
|
|
dc->cutout_target.x = x;
|
|
|
|
dc->cutout_target.y = y;
|
|
|
|
dc->cutout_target.w = w;
|
|
|
|
dc->cutout_target.h = h;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_srt_y(const void *d1, const void *d2)
|
|
|
|
{
|
|
|
|
const Cutout_Rect *r1 = d1, *r2 = d2;
|
|
|
|
if (r1->y == r2->y) return r1->x - r2->x;
|
|
|
|
return r1->y - r2->y;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_srt_x(const void *d1, const void *d2)
|
|
|
|
{
|
|
|
|
const Cutout_Rect *r1 = d1, *r2 = d2;
|
|
|
|
if (r1->x == r2->x) return r1->y - r2->y;
|
|
|
|
return r1->x - r2->x;
|
|
|
|
}
|
|
|
|
|
2015-09-23 22:06:40 -07:00
|
|
|
EAPI Cutout_Rects *
|
2012-07-04 02:39:23 -07:00
|
|
|
evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reuse)
|
2005-02-04 18:30:13 -08:00
|
|
|
{
|
2015-09-23 22:06:40 -07:00
|
|
|
Cutout_Rects *res = NULL;
|
2016-12-30 01:55:55 -08:00
|
|
|
int i, j, active, found = 0;
|
2005-02-04 18:30:13 -08:00
|
|
|
|
2007-04-04 02:55:40 -07:00
|
|
|
if (!dc->clip.use) return NULL;
|
|
|
|
if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) return NULL;
|
2011-12-23 03:50:29 -08:00
|
|
|
|
2016-12-30 01:55:55 -08:00
|
|
|
if (!reuse) res = evas_common_draw_context_cutouts_new();
|
2012-07-04 02:39:23 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
evas_common_draw_context_cutouts_free(reuse);
|
|
|
|
res = reuse;
|
|
|
|
}
|
2016-12-30 01:55:55 -08:00
|
|
|
// this avoids a nasty case of O(n^2)/2 below with lots of rectangles
|
|
|
|
// to merge so only do this merging if the number of rects is small enough
|
|
|
|
// not to blow out into insanity
|
2007-04-04 02:55:40 -07:00
|
|
|
evas_common_draw_context_cutouts_add(res, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
|
2016-12-30 01:55:55 -08:00
|
|
|
for (i = 0; i < dc->cutout.active; i++)
|
2007-04-04 02:55:40 -07:00
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
if ((dc->cutout_target.w != 0) &&
|
|
|
|
(!RECTS_INTERSECT(dc->cutout.rects[i].x, dc->cutout.rects[i].y,
|
|
|
|
dc->cutout.rects[i].w, dc->cutout.rects[i].h,
|
|
|
|
dc->cutout_target.x, dc->cutout_target.y,
|
|
|
|
dc->cutout_target.w, dc->cutout_target.h)))
|
|
|
|
continue;
|
|
|
|
// Don't loop on the element just added to the list as they are
|
|
|
|
// already correctly clipped.
|
|
|
|
active = res->active;
|
2007-04-04 02:55:40 -07:00
|
|
|
for (j = 0; j < active; )
|
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
if (evas_common_draw_context_cutout_split
|
|
|
|
(res, j, dc->cutout.rects + i)) j++;
|
|
|
|
else active--;
|
2007-04-04 02:55:40 -07:00
|
|
|
}
|
2005-02-04 18:30:13 -08:00
|
|
|
}
|
2012-02-20 23:01:39 -08:00
|
|
|
/* merge rects */
|
|
|
|
#define RI res->rects[i]
|
|
|
|
#define RJ res->rects[j]
|
|
|
|
if (res->active > 1)
|
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
if (res->active > 5)
|
2012-02-20 23:01:39 -08:00
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
// fast path for larger numbers of rects to merge by using
|
|
|
|
// qsort to sort by y and x to limit the number of rects
|
|
|
|
// we have to walk as rects that have a different y cannot
|
|
|
|
// be merged anyway (or x).
|
|
|
|
qsort(res->rects, res->active, sizeof(res->rects[0]), _srt_y);
|
2012-02-20 23:01:39 -08:00
|
|
|
for (i = 0; i < res->active; i++)
|
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
if (RI.w == 0) continue; // skip empty rect
|
2012-02-20 23:01:39 -08:00
|
|
|
for (j = i + 1; j < res->active; j++)
|
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
if (RJ.y != RI.y) break; // new line, sorted thus skip
|
|
|
|
if (RJ.w == 0) continue; // skip empty rect
|
|
|
|
// if J is the same height (could be merged)
|
|
|
|
if (RJ.h == RI.h)
|
2012-02-20 23:01:39 -08:00
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
// if J is immediately to the right of I
|
|
|
|
if (RJ.x == (RI.x + RI.w))
|
2012-02-20 23:01:39 -08:00
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
RI.w = (RJ.x + RJ.w) - RI.x; // expand RI
|
|
|
|
RJ.w = 0; // invalidate
|
|
|
|
found++;
|
2012-02-20 23:01:39 -08:00
|
|
|
}
|
2016-12-30 01:55:55 -08:00
|
|
|
// since we sort y and THEN x, if height matches
|
|
|
|
// but it's not immediately adjacent, no more
|
|
|
|
// rects exists that can be merged
|
|
|
|
else break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qsort(res->rects, res->active, sizeof(res->rects[0]), _srt_x);
|
|
|
|
for (i = 0; i < res->active; i++)
|
|
|
|
{
|
|
|
|
if (RI.w == 0) continue; // skip empty rect
|
|
|
|
for (j = i + 1; j < res->active; j++)
|
|
|
|
{
|
|
|
|
if (RJ.x != RI.x) break; // new line, sorted thus skip
|
|
|
|
if (RJ.w == 0) continue; // skip empty rect
|
|
|
|
// if J is the same height (could be merged)
|
|
|
|
if (RJ.w == RI.w)
|
|
|
|
{
|
|
|
|
// if J is immediately to the right of I
|
|
|
|
if (RJ.y == (RI.y + RI.h))
|
2012-02-20 23:01:39 -08:00
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
RI.h = (RJ.y + RJ.h) - RI.y; // expand RI
|
|
|
|
RJ.w = 0; // invalidate
|
|
|
|
found++;
|
2012-02-20 23:01:39 -08:00
|
|
|
}
|
2016-12-30 01:55:55 -08:00
|
|
|
// since we sort y and THEN x, if height matches
|
|
|
|
// but it's not immediately adjacent, no more
|
|
|
|
// rects exists that can be merged
|
|
|
|
else break;
|
2012-02-20 23:01:39 -08:00
|
|
|
}
|
2016-12-30 01:55:55 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// for a small number of rects, keep things simple as the count
|
|
|
|
// is small and big-o complexity isnt a problem yet
|
|
|
|
found = 1;
|
|
|
|
while (found)
|
|
|
|
{
|
|
|
|
found = 0;
|
|
|
|
for (i = 0; i < res->active; i++)
|
|
|
|
{
|
|
|
|
for (j = i + 1; j < res->active; j++)
|
2012-02-20 23:01:39 -08:00
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
// skip empty rects we are removing
|
|
|
|
if (RJ.w == 0) continue;
|
|
|
|
// check if its same width, immediately above or below
|
|
|
|
if ((RJ.w == RI.w) && (RJ.x == RI.x))
|
2012-02-20 23:01:39 -08:00
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
if ((RJ.y + RJ.h) == RI.y) // above
|
|
|
|
{
|
|
|
|
RI.y = RJ.y;
|
|
|
|
RI.h += RJ.h;
|
|
|
|
RJ.w = 0;
|
|
|
|
found++;
|
|
|
|
}
|
|
|
|
else if ((RI.y + RI.h) == RJ.y) // below
|
|
|
|
{
|
|
|
|
RI.h += RJ.h;
|
|
|
|
RJ.w = 0;
|
|
|
|
found++;
|
|
|
|
}
|
2012-02-20 23:01:39 -08:00
|
|
|
}
|
2016-12-30 01:55:55 -08:00
|
|
|
// check if its same height, immediately left or right
|
|
|
|
else if ((RJ.h == RI.h) && (RJ.y == RI.y))
|
2012-02-20 23:01:39 -08:00
|
|
|
{
|
2016-12-30 01:55:55 -08:00
|
|
|
if ((RJ.x + RJ.w) == RI.x) // left
|
|
|
|
{
|
|
|
|
RI.x = RJ.x;
|
|
|
|
RI.w += RJ.w;
|
|
|
|
RJ.w = 0;
|
|
|
|
found++;
|
|
|
|
}
|
|
|
|
else if ((RI.x + RI.w) == RJ.x) // right
|
|
|
|
{
|
|
|
|
RI.w += RJ.w;
|
|
|
|
RJ.w = 0;
|
|
|
|
found++;
|
|
|
|
}
|
2012-02-20 23:01:39 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-07-04 02:39:23 -07:00
|
|
|
|
2016-12-30 01:55:55 -08:00
|
|
|
// Repack the cutout
|
2012-07-04 02:39:23 -07:00
|
|
|
j = 0;
|
2012-02-20 23:01:39 -08:00
|
|
|
for (i = 0; i < res->active; i++)
|
|
|
|
{
|
|
|
|
if (RI.w == 0) continue;
|
2016-12-30 01:55:55 -08:00
|
|
|
if (i != j) RJ = RI;
|
2012-07-04 02:39:23 -07:00
|
|
|
j++;
|
2012-02-20 23:01:39 -08:00
|
|
|
}
|
2012-07-04 02:39:23 -07:00
|
|
|
res->active = j;
|
2012-02-20 23:01:39 -08:00
|
|
|
}
|
2007-04-04 02:55:40 -07:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2015-09-23 22:06:40 -07:00
|
|
|
evas_common_draw_context_apply_clear_cutouts(Cutout_Rects *rects)
|
2007-04-04 02:55:40 -07:00
|
|
|
{
|
|
|
|
evas_common_draw_context_apply_clean_cutouts(rects);
|
|
|
|
free(rects);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2015-09-23 22:06:40 -07:00
|
|
|
evas_common_draw_context_apply_clean_cutouts(Cutout_Rects *rects)
|
2007-04-04 02:55:40 -07:00
|
|
|
{
|
|
|
|
free(rects->rects);
|
|
|
|
rects->rects = NULL;
|
|
|
|
rects->active = 0;
|
|
|
|
rects->max = 0;
|
2015-09-23 22:06:40 -07:00
|
|
|
rects->last_add.w = 0;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_common_draw_context_set_anti_alias(RGBA_Draw_Context *dc , unsigned char aa)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-12-03 01:27:53 -08:00
|
|
|
dc->anti_alias = !!aa;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2005-12-03 01:27:53 -08:00
|
|
|
evas_common_draw_context_set_color_interpolation(RGBA_Draw_Context *dc, int color_space)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-12-03 01:27:53 -08:00
|
|
|
dc->interpolation.color_space = color_space;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2006-09-06 00:33:40 -07:00
|
|
|
EAPI void
|
2006-05-02 00:28:49 -07:00
|
|
|
evas_common_draw_context_set_render_op(RGBA_Draw_Context *dc , int op)
|
2005-12-10 20:55:20 -08:00
|
|
|
{
|
2006-05-02 00:28:49 -07:00
|
|
|
dc->render_op = op;
|
2005-12-10 20:55:20 -08:00
|
|
|
}
|