#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;
}
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;
}
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;
}
}
+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);
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:
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)
{