diff --git a/src/lib/ector/software/ector_software_rasterizer.c b/src/lib/ector/software/ector_software_rasterizer.c index d9b3351248..b2b5779f69 100644 --- a/src/lib/ector/software/ector_software_rasterizer.c +++ b/src/lib/ector/software/ector_software_rasterizer.c @@ -11,8 +11,23 @@ #include "draw.h" +//FIXME: This enum add temporarily to help understanding of additional code +//related to masking in prepare_mask. +//This needs to be formally declared through the eo class. +typedef enum _EFL_CANVAS_VG_NODE_BLEND_TYPE +{ + EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE = 0, + EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA, + EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE +}EFL_CANVAS_VG_NODE_BLEND_TYPE; +// + static void -_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data) +_blend_argb(int count, const SW_FT_Span *spans, void *user_data) { Span_Data *sd = user_data; uint32_t color, *buffer, *target; @@ -34,7 +49,7 @@ _blend_color_argb(int count, const SW_FT_Span *spans, void *user_data) } static void -_blend_color_argb_with_maskA(int count, const SW_FT_Span *spans, void *user_data) +_blend_alpha(int count, const SW_FT_Span *spans, void *user_data) { Span_Data *sd = user_data; const int pix_stride = sd->raster_buffer->stride / 4; @@ -77,7 +92,7 @@ _blend_color_argb_with_maskA(int count, const SW_FT_Span *spans, void *user_data } static void -_blend_color_argb_with_maskInvA(int count, const SW_FT_Span *spans, void *user_data) +_blend_alpha_inv(int count, const SW_FT_Span *spans, void *user_data) { Span_Data *sd = user_data; const int pix_stride = sd->raster_buffer->stride / 4; @@ -120,6 +135,122 @@ _blend_color_argb_with_maskInvA(int count, const SW_FT_Span *spans, void *user_d } } +static void +_blend_mask_add(int count, const SW_FT_Span *spans, void *user_data) +{ + Span_Data *sd = user_data; + Ector_Software_Buffer_Base_Data *mask = sd->mask; + + uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); + RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); + uint32_t *mbuffer = mask->pixels.u32; + + while (count--) + { + uint32_t *ttarget = alloca(sizeof(uint32_t) * spans->len); + memset(ttarget, 0x00, sizeof(uint32_t) * spans->len); + uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x); + comp_func(ttarget, spans->len, color, spans->coverage); + for (int i = 0; i < spans->len; i++) + { + double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; + double asrc = A_VAL(&ttarget[i]) == 0 ? 0 : (double)(A_VAL(&ttarget[i])) / (double)255; + uint32_t aout = (int)(((adst * (1 - asrc)) + asrc) * 255); + mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); + } + ++spans; + } +} + +static void +_blend_mask_sub(int count, const SW_FT_Span *spans, void *user_data) +{ + Span_Data *sd = user_data; + Ector_Software_Buffer_Base_Data *mask = sd->mask; + + uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); + RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); + uint32_t *mtarget = mask->pixels.u32; + + int tsize = sd->raster_buffer->generic->w * sd->raster_buffer->generic->h; + uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize); + memset(tbuffer, 0x00, sizeof(uint32_t) * tsize); + + while (count--) + { + uint32_t *ttarget = tbuffer + ((mask->generic->w * spans->y) + spans->x); + comp_func(ttarget, spans->len, color, spans->coverage); + ++spans; + } + + for(int i = 0; i < tsize; i++) + { + double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; + double asrc = A_VAL(&tbuffer[i]) == 0 ? 0 : (double)(A_VAL(&tbuffer[i])) / (double)255; + uint32_t aout = (int)((adst * (1 - asrc)) * 255); + mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); + } +} + + +static void +_blend_mask_ins(int count, const SW_FT_Span *spans, void *user_data) +{ + Span_Data *sd = user_data; + Ector_Software_Buffer_Base_Data *mask = sd->mask; + + uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); + RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); + uint32_t *mtarget = mask->pixels.u32; + + int tsize = sd->raster_buffer->generic->w * sd->raster_buffer->generic->h; + uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize); + memset(tbuffer, 0x00, sizeof(uint32_t) * tsize); + + while (count--) + { + uint32_t *ttarget = tbuffer + ((mask->generic->w * spans->y) + spans->x); + comp_func(ttarget, spans->len, color, spans->coverage); + ++spans; + } + + for(int i = 0; i < tsize; i++) + { + double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; + double asrc = A_VAL(&tbuffer[i]) == 0 ? 0 : (double)(A_VAL(&tbuffer[i])) / (double)255; + uint32_t aout = (int)((adst * asrc) * 255); + mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); + } +} + + +static void +_blend_mask_diff(int count, const SW_FT_Span *spans, void *user_data) +{ + Span_Data *sd = user_data; + Ector_Software_Buffer_Base_Data *mask = sd->mask; + + uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); + RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); + uint32_t *mbuffer = mask->pixels.u32; + + while (count--) + { + uint32_t *ttarget = alloca(sizeof(uint32_t) * spans->len); + memset(ttarget, 0x00, sizeof(uint32_t) * spans->len); + uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x); + comp_func(ttarget, spans->len, color, spans->coverage); + for (int i = 0; i < spans->len; i++) + { + double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; + double asrc = A_VAL(&ttarget[i]) == 0 ? 0 : (double)(A_VAL(&ttarget[i])) / (double)255; + uint32_t aout = (int)((((1 - adst) * asrc) + ((1 - asrc) * adst)) * 255); + mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); + } + ++spans; + } +} + #define BLEND_GRADIENT_BUFFER_SIZE 2048 typedef void (*src_fetch) (unsigned int *buffer, Span_Data *data, int y, int x, int length); @@ -362,14 +493,32 @@ _adjust_span_fill_methods(Span_Data *spdata) case Solid: { if (spdata->mask) - { - if (spdata->mask_op == 2) - spdata->unclipped_blend = &_blend_color_argb_with_maskInvA; - else - spdata->unclipped_blend = &_blend_color_argb_with_maskA; - } + { + switch (spdata->mask_op) + { + default: + case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA: + spdata->unclipped_blend = &_blend_alpha; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV: + spdata->unclipped_blend = &_blend_alpha_inv; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD: + spdata->unclipped_blend = &_blend_mask_add; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT: + spdata->unclipped_blend = &_blend_mask_sub; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT: + spdata->unclipped_blend = &_blend_mask_ins; + break; + case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE: + spdata->unclipped_blend = &_blend_mask_diff; + break; + } + } else - spdata->unclipped_blend = &_blend_color_argb; + spdata->unclipped_blend = &_blend_argb; } break; case LinearGradient: @@ -378,6 +527,10 @@ _adjust_span_fill_methods(Span_Data *spdata) break; } + //FIXME: Mask and mask case is not use clipping. + if (spdata->mask_op >= EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD) + spdata->clip.enabled = EINA_FALSE; + // Clipping Function if (spdata->clip.enabled) {