diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index c94e54ea01..f74a737439 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -127,6 +127,7 @@ lib/evas/common/evas_op_add_main_.c \ lib/evas/common/evas_op_sub_main_.c \ lib/evas/common/evas_op_mask_main_.c \ lib/evas/common/evas_op_mul_main_.c \ +lib/evas/common/evas_alpha_main.c \ lib/evas/common/evas_blend_main.c \ lib/evas/common/evas_blit_main.c \ lib/evas/common/evas_convert_color.c \ diff --git a/src/lib/evas/common/evas_alpha_main.c b/src/lib/evas/common/evas_alpha_main.c new file mode 100644 index 0000000000..6bd654cec1 --- /dev/null +++ b/src/lib/evas/common/evas_alpha_main.c @@ -0,0 +1,90 @@ +#include "evas_common_private.h" +#include "evas_blend_private.h" + +/** default op: d = d*(1-sa) + s */ +static void +_alpha_func_blend(DATA8 *src, DATA8 *dst, int len) +{ + int k; + + EINA_SAFETY_ON_NULL_RETURN(src); + EINA_SAFETY_ON_NULL_RETURN(dst); + + for (k = len; k; k--) + { + int val = (*dst * (255 - *src)) / 255 + *src; + *dst++ = val; + src++; + } +} + +/** d = s */ +static void +_alpha_func_copy(DATA8 *src, DATA8 *dst, int len) +{ + EINA_SAFETY_ON_NULL_RETURN(src); + EINA_SAFETY_ON_NULL_RETURN(dst); + + memcpy(dst, src, len); +} + +/** d = d*s */ +static void +_alpha_func_mul(DATA8 *src, DATA8 *dst, int len) +{ + int k; + + EINA_SAFETY_ON_NULL_RETURN(src); + EINA_SAFETY_ON_NULL_RETURN(dst); + + for (k = len; k; k--) + { + int val = (*dst * *src) / 255; + *dst++ = val; + src++; + } +} + + +#if 0 +// Reference ops. In case of alpha, s == sa. +EVAS_RENDER_BLEND = 0, /**< default op: d = d*(1-sa) + s */ +EVAS_RENDER_BLEND_REL = 1, /**< d = d*(1 - sa) + s*da */ +EVAS_RENDER_COPY = 2, /**< d = s */ +EVAS_RENDER_COPY_REL = 3, /**< d = s*da */ +EVAS_RENDER_ADD = 4, /* d = d + s */ +EVAS_RENDER_ADD_REL = 5, /**< d = d + s*da */ +EVAS_RENDER_SUB = 6, /**< d = d - s */ +EVAS_RENDER_SUB_REL = 7, /* d = d - s*da */ +EVAS_RENDER_TINT = 8, /**< d = d*s + d*(1 - sa) + s*(1 - da) */ +EVAS_RENDER_TINT_REL = 9, /**< d = d*(1 - sa + s) */ +EVAS_RENDER_MASK = 10, /**< d = d*sa */ +EVAS_RENDER_MUL = 11, /**< d = d*s */ +#endif + +Alpha_Gfx_Func +evas_common_alpha_func_get(int op) +{ + INF("Requesting alpha function with OP %d", op); + switch (op) + { + case EVAS_RENDER_BLEND: + return _alpha_func_blend; +// case EVAS_RENDER_BLEND_REL: + case EVAS_RENDER_COPY: + return _alpha_func_copy; +// case EVAS_RENDER_COPY_REL: +// case EVAS_RENDER_ADD: +// case EVAS_RENDER_ADD_REL: +// case EVAS_RENDER_SUB: +// case EVAS_RENDER_SUB_REL: +// case EVAS_RENDER_TINT: +// case EVAS_RENDER_TINT_REL: + case EVAS_RENDER_MASK: + case EVAS_RENDER_MUL: + return _alpha_func_mul; + default: + ERR("Not implemented yet."); + return NULL; + } +} diff --git a/src/lib/evas/common/evas_blend_private.h b/src/lib/evas/common/evas_blend_private.h index 1d14951da1..00291981bf 100644 --- a/src/lib/evas/common/evas_blend_private.h +++ b/src/lib/evas/common/evas_blend_private.h @@ -27,5 +27,8 @@ RGBA_Gfx_Pt_Func evas_common_gfx_func_composite_pixel_color_pt_get (Image_ RGBA_Gfx_Pt_Func evas_common_gfx_func_composite_mask_color_pt_get (DATA32 col, RGBA_Image *dst, int op); RGBA_Gfx_Pt_Func evas_common_gfx_func_composite_pixel_mask_pt_get (Image_Entry_Flags src_flags, RGBA_Image *dst, int op); +/* Alpha/mask functions */ +Alpha_Gfx_Func evas_common_alpha_func_get (int op); + #endif /* _EVAS_BLEND_PRIVATE_H */ diff --git a/src/lib/evas/common/evas_image_data.c b/src/lib/evas/common/evas_image_data.c index fe808323e6..8971867c25 100644 --- a/src/lib/evas/common/evas_image_data.c +++ b/src/lib/evas/common/evas_image_data.c @@ -33,6 +33,13 @@ evas_common_rgba_image_from_data(Image_Entry* ie_dst, int w, int h, DATA32 *imag dst->cs.data = image_data; dst->cs.no_free = 1; break; + case EVAS_COLORSPACE_GRY8: + dst->cache_entry.w = w; + dst->cache_entry.h = h; + dst->mask.data = (DATA8 *) image_data; + dst->mask.no_free = 1; + dst->cache_entry.flags.alpha = 1; + break; default: abort(); break; @@ -65,6 +72,11 @@ evas_common_rgba_image_from_copied_data(Image_Entry* ie_dst, int w, int h, DATA3 if (image_data && (dst->cs.data)) memcpy(dst->cs.data, image_data, dst->cache_entry.h * sizeof(unsigned char*) * 2); break; + case EVAS_COLORSPACE_GRY8: + dst->cache_entry.flags.alpha = 1; + if (image_data) + memcpy(dst->mask.data, image_data, w * h * sizeof(DATA8)); + break; default: abort(); break; @@ -104,17 +116,25 @@ int evas_common_rgba_image_colorspace_set(Image_Entry* ie_dst, int cspace) { RGBA_Image *dst = (RGBA_Image *) ie_dst; + Eina_Bool change = (dst->cache_entry.space != cspace); switch (cspace) { case EVAS_COLORSPACE_ARGB8888: + case EVAS_COLORSPACE_GRY8: if (dst->cs.data) { if (!dst->cs.no_free) free(dst->cs.data); dst->cs.data = NULL; dst->cs.no_free = 0; } - break; + if (change && dst->image.data) + { + if (!dst->image.no_free) free(dst->image.data); + dst->image.data = NULL; + dst->image.no_free = 0; + } + break; case EVAS_COLORSPACE_YCBCR422P601_PL: case EVAS_COLORSPACE_YCBCR422P709_PL: case EVAS_COLORSPACE_YCBCR422601_PL: @@ -136,7 +156,7 @@ evas_common_rgba_image_colorspace_set(Image_Entry* ie_dst, int cspace) } dst->cs.data = calloc(1, dst->cache_entry.h * sizeof(unsigned char *) * 2); dst->cs.no_free = 0; - break; + break; default: abort(); break; diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index e75cd93290..83c027208f 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -424,7 +424,7 @@ typedef void (*RGBA_Gfx_Pt_Func) (DATA32 src, DATA8 mask, DATA32 col, DATA32 *ds typedef void (*Gfx_Func_Copy) (DATA32 *src, DATA32 *dst, int len); typedef void (*Gfx_Func_Convert) (DATA32 *src, DATA8 *dst, int src_jump, int dst_jump, int w, int h, int dith_x, int dith_y, DATA8 *pal); - +typedef void (*Alpha_Gfx_Func) (DATA8 *src, DATA8 *dst, int len); typedef void (*Evas_Render_Done_Cb)(void *); @@ -801,11 +801,20 @@ struct _RGBA_Image Eina_Bool dirty : 1; } cs; - /* RGBA stuff */ - struct { - DATA32 *data; - Eina_Bool no_free : 1; - } image; + union + { + /* RGBA stuff */ + struct { + DATA32 *data; + Eina_Bool no_free : 1; + } image; + + /* Alpha Mask stuff */ + struct { + DATA8 *data; + Eina_Bool no_free : 1; + } mask; + }; struct { SLK(lock);