diff options
Diffstat (limited to 'src/lib/ector')
-rw-r--r-- | src/lib/ector/software/ector_software_rasterizer.c | 173 |
1 files changed, 163 insertions, 10 deletions
diff --git a/src/lib/ector/software/ector_software_rasterizer.c b/src/lib/ector/software/ector_software_rasterizer.c index d9b3351..b2b5779 100644 --- a/src/lib/ector/software/ector_software_rasterizer.c +++ b/src/lib/ector/software/ector_software_rasterizer.c | |||
@@ -11,8 +11,23 @@ | |||
11 | 11 | ||
12 | #include "draw.h" | 12 | #include "draw.h" |
13 | 13 | ||
14 | //FIXME: This enum add temporarily to help understanding of additional code | ||
15 | //related to masking in prepare_mask. | ||
16 | //This needs to be formally declared through the eo class. | ||
17 | typedef enum _EFL_CANVAS_VG_NODE_BLEND_TYPE | ||
18 | { | ||
19 | EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE = 0, | ||
20 | EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA, | ||
21 | EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV, | ||
22 | EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD, | ||
23 | EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT, | ||
24 | EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT, | ||
25 | EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE | ||
26 | }EFL_CANVAS_VG_NODE_BLEND_TYPE; | ||
27 | // | ||
28 | |||
14 | static void | 29 | static void |
15 | _blend_color_argb(int count, const SW_FT_Span *spans, void *user_data) | 30 | _blend_argb(int count, const SW_FT_Span *spans, void *user_data) |
16 | { | 31 | { |
17 | Span_Data *sd = user_data; | 32 | Span_Data *sd = user_data; |
18 | uint32_t color, *buffer, *target; | 33 | uint32_t color, *buffer, *target; |
@@ -34,7 +49,7 @@ _blend_color_argb(int count, const SW_FT_Span *spans, void *user_data) | |||
34 | } | 49 | } |
35 | 50 | ||
36 | static void | 51 | static void |
37 | _blend_color_argb_with_maskA(int count, const SW_FT_Span *spans, void *user_data) | 52 | _blend_alpha(int count, const SW_FT_Span *spans, void *user_data) |
38 | { | 53 | { |
39 | Span_Data *sd = user_data; | 54 | Span_Data *sd = user_data; |
40 | const int pix_stride = sd->raster_buffer->stride / 4; | 55 | 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 | |||
77 | } | 92 | } |
78 | 93 | ||
79 | static void | 94 | static void |
80 | _blend_color_argb_with_maskInvA(int count, const SW_FT_Span *spans, void *user_data) | 95 | _blend_alpha_inv(int count, const SW_FT_Span *spans, void *user_data) |
81 | { | 96 | { |
82 | Span_Data *sd = user_data; | 97 | Span_Data *sd = user_data; |
83 | const int pix_stride = sd->raster_buffer->stride / 4; | 98 | 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 | |||
120 | } | 135 | } |
121 | } | 136 | } |
122 | 137 | ||
138 | static void | ||
139 | _blend_mask_add(int count, const SW_FT_Span *spans, void *user_data) | ||
140 | { | ||
141 | Span_Data *sd = user_data; | ||
142 | Ector_Software_Buffer_Base_Data *mask = sd->mask; | ||
143 | |||
144 | uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); | ||
145 | RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); | ||
146 | uint32_t *mbuffer = mask->pixels.u32; | ||
147 | |||
148 | while (count--) | ||
149 | { | ||
150 | uint32_t *ttarget = alloca(sizeof(uint32_t) * spans->len); | ||
151 | memset(ttarget, 0x00, sizeof(uint32_t) * spans->len); | ||
152 | uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x); | ||
153 | comp_func(ttarget, spans->len, color, spans->coverage); | ||
154 | for (int i = 0; i < spans->len; i++) | ||
155 | { | ||
156 | double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; | ||
157 | double asrc = A_VAL(&ttarget[i]) == 0 ? 0 : (double)(A_VAL(&ttarget[i])) / (double)255; | ||
158 | uint32_t aout = (int)(((adst * (1 - asrc)) + asrc) * 255); | ||
159 | mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); | ||
160 | } | ||
161 | ++spans; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | static void | ||
166 | _blend_mask_sub(int count, const SW_FT_Span *spans, void *user_data) | ||
167 | { | ||
168 | Span_Data *sd = user_data; | ||
169 | Ector_Software_Buffer_Base_Data *mask = sd->mask; | ||
170 | |||
171 | uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); | ||
172 | RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); | ||
173 | uint32_t *mtarget = mask->pixels.u32; | ||
174 | |||
175 | int tsize = sd->raster_buffer->generic->w * sd->raster_buffer->generic->h; | ||
176 | uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize); | ||
177 | memset(tbuffer, 0x00, sizeof(uint32_t) * tsize); | ||
178 | |||
179 | while (count--) | ||
180 | { | ||
181 | uint32_t *ttarget = tbuffer + ((mask->generic->w * spans->y) + spans->x); | ||
182 | comp_func(ttarget, spans->len, color, spans->coverage); | ||
183 | ++spans; | ||
184 | } | ||
185 | |||
186 | for(int i = 0; i < tsize; i++) | ||
187 | { | ||
188 | double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; | ||
189 | double asrc = A_VAL(&tbuffer[i]) == 0 ? 0 : (double)(A_VAL(&tbuffer[i])) / (double)255; | ||
190 | uint32_t aout = (int)((adst * (1 - asrc)) * 255); | ||
191 | mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | |||
196 | static void | ||
197 | _blend_mask_ins(int count, const SW_FT_Span *spans, void *user_data) | ||
198 | { | ||
199 | Span_Data *sd = user_data; | ||
200 | Ector_Software_Buffer_Base_Data *mask = sd->mask; | ||
201 | |||
202 | uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); | ||
203 | RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); | ||
204 | uint32_t *mtarget = mask->pixels.u32; | ||
205 | |||
206 | int tsize = sd->raster_buffer->generic->w * sd->raster_buffer->generic->h; | ||
207 | uint32_t *tbuffer = alloca(sizeof(uint32_t) * tsize); | ||
208 | memset(tbuffer, 0x00, sizeof(uint32_t) * tsize); | ||
209 | |||
210 | while (count--) | ||
211 | { | ||
212 | uint32_t *ttarget = tbuffer + ((mask->generic->w * spans->y) + spans->x); | ||
213 | comp_func(ttarget, spans->len, color, spans->coverage); | ||
214 | ++spans; | ||
215 | } | ||
216 | |||
217 | for(int i = 0; i < tsize; i++) | ||
218 | { | ||
219 | double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; | ||
220 | double asrc = A_VAL(&tbuffer[i]) == 0 ? 0 : (double)(A_VAL(&tbuffer[i])) / (double)255; | ||
221 | uint32_t aout = (int)((adst * asrc) * 255); | ||
222 | mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); | ||
223 | } | ||
224 | } | ||
225 | |||
226 | |||
227 | static void | ||
228 | _blend_mask_diff(int count, const SW_FT_Span *spans, void *user_data) | ||
229 | { | ||
230 | Span_Data *sd = user_data; | ||
231 | Ector_Software_Buffer_Base_Data *mask = sd->mask; | ||
232 | |||
233 | uint32_t color = DRAW_MUL4_SYM(sd->color, sd->mul_col); | ||
234 | RGBA_Comp_Func_Solid comp_func = efl_draw_func_solid_span_get(sd->op, color); | ||
235 | uint32_t *mbuffer = mask->pixels.u32; | ||
236 | |||
237 | while (count--) | ||
238 | { | ||
239 | uint32_t *ttarget = alloca(sizeof(uint32_t) * spans->len); | ||
240 | memset(ttarget, 0x00, sizeof(uint32_t) * spans->len); | ||
241 | uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x); | ||
242 | comp_func(ttarget, spans->len, color, spans->coverage); | ||
243 | for (int i = 0; i < spans->len; i++) | ||
244 | { | ||
245 | double adst = A_VAL(&mtarget[i]) == 0 ? 0 : (double)(A_VAL(&mtarget[i])) / (double)255; | ||
246 | double asrc = A_VAL(&ttarget[i]) == 0 ? 0 : (double)(A_VAL(&ttarget[i])) / (double)255; | ||
247 | uint32_t aout = (int)((((1 - adst) * asrc) + ((1 - asrc) * adst)) * 255); | ||
248 | mtarget[i] = (aout<<24) + (0x00FFFFFF & mtarget[i]); | ||
249 | } | ||
250 | ++spans; | ||
251 | } | ||
252 | } | ||
253 | |||
123 | #define BLEND_GRADIENT_BUFFER_SIZE 2048 | 254 | #define BLEND_GRADIENT_BUFFER_SIZE 2048 |
124 | 255 | ||
125 | typedef void (*src_fetch) (unsigned int *buffer, Span_Data *data, int y, int x, int length); | 256 | 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) | |||
362 | case Solid: | 493 | case Solid: |
363 | { | 494 | { |
364 | if (spdata->mask) | 495 | if (spdata->mask) |
365 | { | 496 | { |
366 | if (spdata->mask_op == 2) | 497 | switch (spdata->mask_op) |
367 | spdata->unclipped_blend = &_blend_color_argb_with_maskInvA; | 498 | { |
368 | else | 499 | default: |
369 | spdata->unclipped_blend = &_blend_color_argb_with_maskA; | 500 | case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA: |
370 | } | 501 | spdata->unclipped_blend = &_blend_alpha; |
502 | break; | ||
503 | case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV: | ||
504 | spdata->unclipped_blend = &_blend_alpha_inv; | ||
505 | break; | ||
506 | case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD: | ||
507 | spdata->unclipped_blend = &_blend_mask_add; | ||
508 | break; | ||
509 | case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT: | ||
510 | spdata->unclipped_blend = &_blend_mask_sub; | ||
511 | break; | ||
512 | case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT: | ||
513 | spdata->unclipped_blend = &_blend_mask_ins; | ||
514 | break; | ||
515 | case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE: | ||
516 | spdata->unclipped_blend = &_blend_mask_diff; | ||
517 | break; | ||
518 | } | ||
519 | } | ||
371 | else | 520 | else |
372 | spdata->unclipped_blend = &_blend_color_argb; | 521 | spdata->unclipped_blend = &_blend_argb; |
373 | } | 522 | } |
374 | break; | 523 | break; |
375 | case LinearGradient: | 524 | case LinearGradient: |
@@ -378,6 +527,10 @@ _adjust_span_fill_methods(Span_Data *spdata) | |||
378 | break; | 527 | break; |
379 | } | 528 | } |
380 | 529 | ||
530 | //FIXME: Mask and mask case is not use clipping. | ||
531 | if (spdata->mask_op >= EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD) | ||
532 | spdata->clip.enabled = EINA_FALSE; | ||
533 | |||
381 | // Clipping Function | 534 | // Clipping Function |
382 | if (spdata->clip.enabled) | 535 | if (spdata->clip.enabled) |
383 | { | 536 | { |