summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo C. A. Cavalcanti Jr <paulo.cavalcanti@intel.com>2013-02-16 11:10:47 +0100
committerCedric BAIL <cedric@efl.so>2013-02-16 11:14:40 +0100
commit04e660c5c76fa9168be08de1f979a1684c464154 (patch)
treef20481fe3e52886e9e9dc33f6053425c5ab00328
parentb6c89728a859c9fa2e0ea9c60191ba7d7b64abc5 (diff)
downloadefl-04e660c5c76fa9168be08de1f979a1684c464154.tar.gz
evas: Introduce pixel_alpha_get()
The _pixel_alpha_get() function used in evas_object_image_is_inside won't work with engines other than software - since it relies on engine data being *always* RGBA_Image * - which is wrong for OpenGL backend that uses Evas_GL_Image * for "engine_data" pointer.
-rw-r--r--AUTHORS2
-rw-r--r--ChangeLog4
-rw-r--r--NEWS1
-rw-r--r--src/lib/evas/canvas/evas_object_image.c123
-rw-r--r--src/lib/evas/include/evas_private.h2
-rw-r--r--src/modules/evas/engines/gl_x11/evas_engine.c83
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c88
7 files changed, 219 insertions, 84 deletions
diff --git a/AUTHORS b/AUTHORS
index 32fe9ea536..430e4315f9 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -122,6 +122,8 @@ Eduardo Lima (Etrunko) <eblima@gmail.com>
Leandro Dorileo (dorileo) <dorileo@profusion.mobi>
Patryk Kaczmarek <patryk.k@samsung.com>
Zbigniew Kosinski <z.kosinski@samsung.com>
+Paulo C. A. Cavalcanti Jr <paulo.cavalcanti@intel.com>
+
Ecore
-----
diff --git a/ChangeLog b/ChangeLog
index dfb55b64d3..392ee8fca1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-02-16 Paulo C. A. Cavalcanti Jr
+
+ * Evas: add pixels_alpha_get to evas engine.
+
2013-02-16 Cedric Bail
* Eina: improved Eina_Clist support for 64bits system.
diff --git a/NEWS b/NEWS
index a5c702aece..b70c510a08 100644
--- a/NEWS
+++ b/NEWS
@@ -53,6 +53,7 @@ Additions:
- Add ellipsis support in Evas_Object_Text.
- Add EVAS_GL_LINE_OFFSET_HACK_DISABLE to turn off line shift correction by evas.
- Add EVAS_GL_DIRECT_MEM_OPT to enable on-demand fallback memory allocation policy for EvasGL direct rendering.
+ - Add engine specific alpha_get.
* Add ecore_audio API
* Added eina_xattr_fd_get(), eina_xattr_fd_set(),
eina_xattr_del(), eina_xattr_fd_del(), eina_xattr_copy() and
diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c
index f3492e2627..b3df22b65a 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -4459,83 +4459,13 @@ evas_object_image_was_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob
return obj->prev.opaque;
}
-static inline Eina_Bool
-_pixel_alpha_get(RGBA_Image *im, int x, int y, DATA8 *alpha,
- int src_region_x, int src_region_y, int src_region_w, int src_region_h,
- int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h)
-{
- int px, py, dx, dy, sx, sy, src_w, src_h;
- double scale_w, scale_h;
-
- if ((dst_region_x > x) || (x >= (dst_region_x + dst_region_w)) ||
- (dst_region_y > y) || (y >= (dst_region_y + dst_region_h)))
- {
- *alpha = 0;
- return EINA_FALSE;
- }
-
- src_w = im->cache_entry.w;
- src_h = im->cache_entry.h;
- if ((src_w == 0) || (src_h == 0))
- {
- *alpha = 0;
- return EINA_TRUE;
- }
-
- EINA_SAFETY_ON_TRUE_GOTO(src_region_x < 0, error_oob);
- EINA_SAFETY_ON_TRUE_GOTO(src_region_y < 0, error_oob);
- EINA_SAFETY_ON_TRUE_GOTO(src_region_x + src_region_w > src_w, error_oob);
- EINA_SAFETY_ON_TRUE_GOTO(src_region_y + src_region_h > src_h, error_oob);
-
- scale_w = (double)dst_region_w / (double)src_region_w;
- scale_h = (double)dst_region_h / (double)src_region_h;
-
- /* point at destination */
- dx = x - dst_region_x;
- dy = y - dst_region_y;
-
- /* point at source */
- sx = dx / scale_w;
- sy = dy / scale_h;
-
- /* pixel point (translated) */
- px = src_region_x + sx;
- py = src_region_y + sy;
- EINA_SAFETY_ON_TRUE_GOTO(px >= src_w, error_oob);
- EINA_SAFETY_ON_TRUE_GOTO(py >= src_h, error_oob);
-
- switch (im->cache_entry.space)
- {
- case EVAS_COLORSPACE_ARGB8888:
- {
- DATA32 *pixel = im->image.data;
- pixel += ((py * src_w) + px);
- *alpha = ((*pixel) >> 24) & 0xff;
- }
- break;
-
- default:
- ERR("Colorspace %d not supported.", im->cache_entry.space);
- *alpha = 0;
- }
-
- return EINA_TRUE;
-
- error_oob:
- ERR("Invalid region src=(%d, %d, %d, %d), dst=(%d, %d, %d, %d), image=%dx%d",
- src_region_x, src_region_y, src_region_w, src_region_h,
- dst_region_x, dst_region_y, dst_region_w, dst_region_h,
- src_w, src_h);
- *alpha = 0;
- return EINA_TRUE;
-}
-
static int
evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Coord px, Evas_Coord py)
{
Evas_Object_Image *o = eo_data_get(eo_obj, MY_CLASS);
int imagew, imageh, uvw, uvh;
void *pixels;
+ Evas_Func *eng = obj->layer->evas->engine.func;
int is_inside = 0;
/* the following code is similar to evas_object_image_render(), but doesn't
@@ -4609,7 +4539,7 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
}
else
{
- RGBA_Image *im;
+ void *im;
DATA32 *data = NULL;
int err = 0;
@@ -4617,7 +4547,8 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
(obj->layer->evas->engine.data.output, pixels, 0, &data, &err);
if ((!im) || (!data) || (err))
{
- ERR("Couldn't get image pixels RGBA_Image %p: im=%p, data=%p, err=%d", pixels, im, data, err);
+ ERR("Couldn't get image pixels %p: im=%p, data=%p, err=%d",
+ pixels, im, data, err);
goto end;
}
@@ -4665,7 +4596,13 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
*/
{
DATA8 alpha = 0;
- if (_pixel_alpha_get(pixels, px, py, &alpha, 0, 0, imagew, imageh, obj->cur.geometry.x + ix, obj->cur.geometry.y + iy, iw, ih))
+
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ 0, 0,
+ imagew, imageh,
+ obj->cur.geometry.x + ix,
+ obj->cur.geometry.y + iy,
+ iw, ih))
{
is_inside = alpha > 0;
dobreak_h = 1;
@@ -4726,7 +4663,9 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
inw = bl; inh = bt;
outx = ox; outy = oy;
outw = bsl; outh = bst;
- if (_pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ inx, iny, inw, inh,
+ outx, outy, outw, outh))
{
is_inside = alpha > 0;
dobreak_h = 1;
@@ -4740,7 +4679,9 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
inw = imw - bl - br; inh = bt;
outx = ox + bsl; outy = oy;
outw = iw - bsl - bsr; outh = bst;
- if (_pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ inx, iny, inw, inh,
+ outx, outy, outw, outh))
{
is_inside = alpha > 0;
dobreak_h = 1;
@@ -4753,7 +4694,9 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
inw = br; inh = bt;
outx = ox + iw - bsr; outy = oy;
outw = bsr; outh = bst;
- if (_pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ inx, iny, inw, inh,
+ outx, outy, outw, outh))
{
is_inside = alpha > 0;
dobreak_h = 1;
@@ -4761,12 +4704,14 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
break;
}
// .--
- // #
+ // #
inx = 0; iny = bt;
inw = bl; inh = imh - bt - bb;
outx = ox; outy = oy + bst;
outw = bsl; outh = ih - bst - bsb;
- if (_pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ inx, iny, inw, inh,
+ outx, outy, outw, outh))
{
is_inside = alpha > 0;
dobreak_h = 1;
@@ -4781,7 +4726,9 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
inw = imw - bl - br; inh = imh - bt - bb;
outx = ox + bsl; outy = oy + bst;
outw = iw - bsl - bsr; outh = ih - bst - bsb;
- if (_pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ inx, iny, inw, inh,
+ outx, outy, outw, outh))
{
is_inside = alpha > 0;
dobreak_h = 1;
@@ -4795,7 +4742,9 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
inw = br; inh = imh - bt - bb;
outx = ox + iw - bsr; outy = oy + bst;
outw = bsr; outh = ih - bst - bsb;
- if (_pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ inx, iny, inw, inh,
+ outx, outy, outw, outh))
{
is_inside = alpha > 0;
dobreak_h = 1;
@@ -4808,7 +4757,9 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
inw = bl; inh = bb;
outx = ox; outy = oy + ih - bsb;
outw = bsl; outh = bsb;
- if (_pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ inx, iny, inw, inh,
+ outx, outy, outw, outh))
{
is_inside = alpha > 0;
dobreak_h = 1;
@@ -4821,7 +4772,9 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
inw = imw - bl - br; inh = bb;
outx = ox + bsl; outy = oy + ih - bsb;
outw = iw - bsl - bsr; outh = bsb;
- if (_pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ inx, iny, inw, inh,
+ outx, outy, outw, outh))
{
is_inside = alpha > 0;
dobreak_h = 1;
@@ -4834,7 +4787,9 @@ evas_object_image_is_inside(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
inw = br; inh = bb;
outx = ox + iw - bsr; outy = oy + ih - bsb;
outw = bsr; outh = bsb;
- if (_pixel_alpha_get(pixels, px, py, &alpha, inx, iny, inw, inh, outx, outy, outw, outh))
+ if (eng->pixel_alpha_get(pixels, px, py, &alpha,
+ inx, iny, inw, inh,
+ outx, outy, outw, outh))
{
is_inside = alpha > 0;
dobreak_h = 1;
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 9f377e4317..088107eb5a 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -905,6 +905,8 @@ struct _Evas_Func
/* multiple font draws */
Eina_Bool (*multi_font_draw) (void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w, int h, int ow, int oh, Evas_Font_Array *texts, Eina_Bool do_async);
+
+ Eina_Bool (*pixel_alpha_get) (void *image, int x, int y, DATA8 *alpha, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
};
struct _Evas_Image_Load_Func
diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c
index 9b059fc194..f273959d12 100644
--- a/src/modules/evas/engines/gl_x11/evas_engine.c
+++ b/src/modules/evas/engines/gl_x11/evas_engine.c
@@ -2866,6 +2866,87 @@ eng_image_max_size_get(void *data, int *maxw, int *maxh)
if (maxh) *maxh = re->win->gl_context->shared->info.max_texture_size;
}
+static Eina_Bool
+eng_pixel_alpha_get(void *image, int x, int y, DATA8 *alpha, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h)
+{
+ Evas_GL_Image *im = image;
+ int px, py, dx, dy, sx, sy, src_w, src_h;
+ double scale_w, scale_h;
+
+ if (!im) return EINA_FALSE;
+
+ if ((dst_region_x > x) || (x >= (dst_region_x + dst_region_w)) ||
+ (dst_region_y > y) || (y >= (dst_region_y + dst_region_h)))
+ {
+ *alpha = 0;
+ return EINA_FALSE;
+ }
+
+ src_w = im->im->cache_entry.w;
+ src_h = im->im->cache_entry.h;
+ if ((src_w == 0) || (src_h == 0))
+ {
+ *alpha = 0;
+ return EINA_TRUE;
+ }
+
+ EINA_SAFETY_ON_TRUE_GOTO(src_region_x < 0, error_oob);
+ EINA_SAFETY_ON_TRUE_GOTO(src_region_y < 0, error_oob);
+ EINA_SAFETY_ON_TRUE_GOTO(src_region_x + src_region_w > src_w, error_oob);
+ EINA_SAFETY_ON_TRUE_GOTO(src_region_y + src_region_h > src_h, error_oob);
+
+ scale_w = (double)dst_region_w / (double)src_region_w;
+ scale_h = (double)dst_region_h / (double)src_region_h;
+
+ /* point at destination */
+ dx = x - dst_region_x;
+ dy = y - dst_region_y;
+
+ /* point at source */
+ sx = dx / scale_w;
+ sy = dy / scale_h;
+
+ /* pixel point (translated) */
+ px = src_region_x + sx;
+ py = src_region_y + sy;
+ EINA_SAFETY_ON_TRUE_GOTO(px >= src_w, error_oob);
+ EINA_SAFETY_ON_TRUE_GOTO(py >= src_h, error_oob);
+
+ switch (im->im->cache_entry.space)
+ {
+ case EVAS_COLORSPACE_ARGB8888:
+ {
+ DATA32 *pixel;
+
+ evas_cache_image_load_data(&im->im->cache_entry);
+ if (!im->im->cache_entry.flags.loaded)
+ {
+ ERR("im %p has no pixels loaded yet", im);
+ return EINA_FALSE;
+ }
+
+ pixel = im->im->image.data;
+ pixel += ((py * src_w) + px);
+ *alpha = ((*pixel) >> 24) & 0xff;
+ }
+ break;
+
+ default:
+ ERR("Colorspace %d not supported.", im->im->cache_entry.space);
+ *alpha = 0;
+ }
+
+ return EINA_TRUE;
+
+ error_oob:
+ ERR("Invalid region src=(%d, %d, %d, %d), dst=(%d, %d, %d, %d), image=%dx%d",
+ src_region_x, src_region_y, src_region_w, src_region_h,
+ dst_region_x, dst_region_y, dst_region_w, dst_region_h,
+ src_w, src_h);
+ *alpha = 0;
+ return EINA_TRUE;
+}
+
static int
module_open(Evas_Module *em)
{
@@ -2981,6 +3062,8 @@ module_open(Evas_Module *em)
ORD(image_max_size_get);
+ ORD(pixel_alpha_get);
+
/* now advertise out own api */
em->functions = (void *)(&func);
return 1;
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index b35a9a100c..a2e43ff971 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -1831,6 +1831,93 @@ eng_multi_font_draw(void *data EINA_UNUSED, void *context, void *surface, Evas_F
return EINA_FALSE;
}
+static Eina_Bool
+eng_pixel_alpha_get(void *image, int x, int y, DATA8 *alpha, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h)
+{
+ RGBA_Image *im = image;
+ int px, py, dx, dy, sx, sy, src_w, src_h;
+ double scale_w, scale_h;
+
+ if (!im) return EINA_FALSE;
+
+ if ((dst_region_x > x) || (x >= (dst_region_x + dst_region_w)) ||
+ (dst_region_y > y) || (y >= (dst_region_y + dst_region_h)))
+ {
+ *alpha = 0;
+ return EINA_FALSE;
+ }
+
+ src_w = im->cache_entry.w;
+ src_h = im->cache_entry.h;
+ if ((src_w == 0) || (src_h == 0))
+ {
+ *alpha = 0;
+ return EINA_TRUE;
+ }
+
+ EINA_SAFETY_ON_TRUE_GOTO(src_region_x < 0, error_oob);
+ EINA_SAFETY_ON_TRUE_GOTO(src_region_y < 0, error_oob);
+ EINA_SAFETY_ON_TRUE_GOTO(src_region_x + src_region_w > src_w, error_oob);
+ EINA_SAFETY_ON_TRUE_GOTO(src_region_y + src_region_h > src_h, error_oob);
+
+ scale_w = (double)dst_region_w / (double)src_region_w;
+ scale_h = (double)dst_region_h / (double)src_region_h;
+
+ /* point at destination */
+ dx = x - dst_region_x;
+ dy = y - dst_region_y;
+
+ /* point at source */
+ sx = dx / scale_w;
+ sy = dy / scale_h;
+
+ /* pixel point (translated) */
+ px = src_region_x + sx;
+ py = src_region_y + sy;
+ EINA_SAFETY_ON_TRUE_GOTO(px >= src_w, error_oob);
+ EINA_SAFETY_ON_TRUE_GOTO(py >= src_h, error_oob);
+
+ switch (im->cache_entry.space)
+ {
+ case EVAS_COLORSPACE_ARGB8888:
+ {
+ DATA32 *pixel;
+
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_load_data(&im->cache_entry);
+ else
+#endif
+ evas_cache_image_load_data(&im->cache_entry);
+
+ if (!im->cache_entry.flags.loaded)
+ {
+ ERR("im %p has no pixels loaded yet", im);
+ return EINA_FALSE;
+ }
+
+ pixel = im->image.data;
+ pixel += ((py * src_w) + px);
+ *alpha = ((*pixel) >> 24) & 0xff;
+ }
+ break;
+
+ default:
+ ERR("Colorspace %d not supported.", im->cache_entry.space);
+ *alpha = 0;
+ }
+
+ return EINA_TRUE;
+
+ error_oob:
+ ERR("Invalid region src=(%d, %d, %d, %d), dst=(%d, %d, %d, %d), image=%dx%d",
+ src_region_x, src_region_y, src_region_w, src_region_h,
+ dst_region_x, dst_region_y, dst_region_w, dst_region_h,
+ src_w, src_h);
+ *alpha = 0;
+ return EINA_TRUE;
+}
+
static void
eng_image_cache_flush(void *data EINA_UNUSED)
{
@@ -2565,6 +2652,7 @@ static Evas_Func func =
eng_image_animated_frame_set,
NULL,
eng_multi_font_draw,
+ eng_pixel_alpha_get,
/* FUTURE software generic calls go here */
};