summaryrefslogtreecommitdiff
path: root/src/lib/ector
diff options
context:
space:
mode:
authorJunsuChoi <jsuya.choi@samsung.com>2019-05-08 16:57:19 +0900
committerHermet Park <hermetpark@gmail.com>2019-05-08 16:57:19 +0900
commit4473062dd482f89eb57f2bca120a742acec3b4f9 (patch)
tree3a4db3b518963e2d17a9417f4d3be8b8b00cc196 /src/lib/ector
parent3a570c38c99a4db729cded66c2e23c62cc3b033a (diff)
ector_software_rasterizer: Support gradient mask blending
Summary: This patch supports mask blending of gradient shapes. Test Plan: N/A Reviewers: Hermet, kimcinoo Reviewed By: Hermet Subscribers: cedric, #reviewers, smohanty, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8855
Diffstat (limited to 'src/lib/ector')
-rw-r--r--src/lib/ector/software/ector_software_rasterizer.c191
1 files changed, 154 insertions, 37 deletions
diff --git a/src/lib/ector/software/ector_software_rasterizer.c b/src/lib/ector/software/ector_software_rasterizer.c
index b2b5779f69..42a5e8ee89 100644
--- a/src/lib/ector/software/ector_software_rasterizer.c
+++ b/src/lib/ector/software/ector_software_rasterizer.c
@@ -293,6 +293,120 @@ _blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
293 } 293 }
294} 294}
295 295
296static void
297_blend_gradient_alpha(int count, const SW_FT_Span *spans, void *user_data)
298{
299 RGBA_Comp_Func comp_func;
300 Span_Data *data = (Span_Data *)(user_data);
301 src_fetch fetchfunc = NULL;
302 uint32_t *buffer;
303 const int pix_stride = data->raster_buffer->stride / 4;
304 uint32_t gradientbuffer[BLEND_GRADIENT_BUFFER_SIZE];
305
306 // FIXME: Get the proper composition function using ,color, ECTOR_OP etc.
307 if (data->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
308 if (data->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
309
310 if (!fetchfunc)
311 return;
312
313 Ector_Software_Buffer_Base_Data *mask = data->mask;
314 uint32_t *mbuffer = mask->pixels.u32;
315
316 //Temp buffer for intermediate processing
317 uint32_t *tbuffer = malloc(sizeof(uint32_t) * data->raster_buffer->generic->w);
318
319 comp_func = efl_draw_func_span_get(data->op, data->mul_col, data->gradient->alpha);
320
321 // move to the offset location
322 buffer = data->raster_buffer->pixels.u32 + ((pix_stride * data->offy) + data->offx);
323
324 while (count--)
325 {
326 uint32_t *target = buffer + ((data->raster_buffer->generic->w * spans->y) + spans->x);
327 uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x);
328 uint32_t *temp = tbuffer;
329 int length = spans->len;
330 memset(temp, 0x00, sizeof(uint32_t) * spans->len);
331 while (length)
332 {
333 int l = MIN(length, BLEND_GRADIENT_BUFFER_SIZE);
334 fetchfunc(gradientbuffer, data, spans->y, spans->x, l);
335 comp_func(temp, gradientbuffer, l, data->mul_col, spans->coverage);
336
337 for (int i = 0; i < l; i++)
338 {
339 *temp = draw_mul_256(((*mtarget)>>24), *temp);
340 int alpha = 255 - ((*temp) >> 24);
341 *target = *temp + draw_mul_256(alpha, *target);
342 ++temp;
343 ++mtarget;
344 ++target;
345 }
346 length -= l;
347 }
348 ++spans;
349 }
350 free(tbuffer);
351}
352
353static void
354_blend_gradient_alpha_inv(int count, const SW_FT_Span *spans, void *user_data)
355{
356 RGBA_Comp_Func comp_func;
357 Span_Data *data = (Span_Data *)(user_data);
358 src_fetch fetchfunc = NULL;
359 uint32_t *buffer;
360 const int pix_stride = data->raster_buffer->stride / 4;
361 uint32_t gradientbuffer[BLEND_GRADIENT_BUFFER_SIZE];
362
363 // FIXME: Get the proper composition function using ,color, ECTOR_OP etc.
364 if (data->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
365 if (data->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
366
367 if (!fetchfunc)
368 return;
369
370 Ector_Software_Buffer_Base_Data *mask = data->mask;
371 uint32_t *mbuffer = mask->pixels.u32;
372
373 //Temp buffer for intermediate processing
374 uint32_t *tbuffer = malloc(sizeof(uint32_t) * data->raster_buffer->generic->w);
375
376 comp_func = efl_draw_func_span_get(data->op, data->mul_col, data->gradient->alpha);
377
378 // move to the offset location
379 buffer = data->raster_buffer->pixels.u32 + ((pix_stride * data->offy) + data->offx);
380
381 while (count--)
382 {
383 uint32_t *target = buffer + ((data->raster_buffer->generic->w * spans->y) + spans->x);
384 uint32_t *mtarget = mbuffer + ((mask->generic->w * spans->y) + spans->x);
385 uint32_t *temp = tbuffer;
386 int length = spans->len;
387 memset(temp, 0x00, sizeof(uint32_t) * spans->len);
388 while (length)
389 {
390 int l = MIN(length, BLEND_GRADIENT_BUFFER_SIZE);
391 fetchfunc(gradientbuffer, data, spans->y, spans->x, l);
392 comp_func(temp, gradientbuffer, l, data->mul_col, spans->coverage);
393
394 for (int i = 0; i < l; i++)
395 {
396 if (*mtarget)
397 *temp = draw_mul_256((255 - ((*mtarget)>>24)), *temp);
398 int alpha = 255 - ((*temp) >> 24);
399 *target = *temp + draw_mul_256(alpha, *target);
400 ++temp;
401 ++mtarget;
402 ++target;
403 }
404 length -= l;
405 }
406 ++spans;
407 }
408 free(tbuffer);
409}
296/*! 410/*!
297 \internal 411 \internal
298 spans must be sorted on y 412 spans must be sorted on y
@@ -485,46 +599,49 @@ static void
485_adjust_span_fill_methods(Span_Data *spdata) 599_adjust_span_fill_methods(Span_Data *spdata)
486{ 600{
487 //Blending Function 601 //Blending Function
488 switch(spdata->type) 602 if (spdata->mask)
489 { 603 {
490 case None: 604 switch (spdata->mask_op)
491 spdata->unclipped_blend = NULL;
492 break;
493 case Solid:
494 { 605 {
495 if (spdata->mask) 606 default:
496 { 607 case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA:
497 switch (spdata->mask_op) 608 if (spdata->type == Solid)
498 { 609 spdata->unclipped_blend = &_blend_alpha;
499 default: 610 else if (spdata->type == LinearGradient || spdata->type == RadialGradient)
500 case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA: 611 spdata->unclipped_blend = &_blend_gradient_alpha;
501 spdata->unclipped_blend = &_blend_alpha; 612 else //None
502 break; 613 spdata->unclipped_blend = NULL;
503 case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV: 614 break;
504 spdata->unclipped_blend = &_blend_alpha_inv; 615 case EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV:
505 break; 616 if (spdata->type == Solid)
506 case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD: 617 spdata->unclipped_blend = &_blend_alpha_inv;
507 spdata->unclipped_blend = &_blend_mask_add; 618 else if (spdata->type == LinearGradient || spdata->type == RadialGradient)
508 break; 619 spdata->unclipped_blend = &_blend_gradient_alpha_inv;
509 case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT: 620 else //None
510 spdata->unclipped_blend = &_blend_mask_sub; 621 spdata->unclipped_blend = NULL;
511 break; 622 break;
512 case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT: 623 case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD:
513 spdata->unclipped_blend = &_blend_mask_ins; 624 spdata->unclipped_blend = &_blend_mask_add;
514 break; 625 break;
515 case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE: 626 case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT:
516 spdata->unclipped_blend = &_blend_mask_diff; 627 spdata->unclipped_blend = &_blend_mask_sub;
517 break; 628 break;
518 } 629 case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT:
519 } 630 spdata->unclipped_blend = &_blend_mask_ins;
520 else 631 break;
521 spdata->unclipped_blend = &_blend_argb; 632 case EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE:
522 } 633 spdata->unclipped_blend = &_blend_mask_diff;
523 break; 634 break;
524 case LinearGradient: 635 }
525 case RadialGradient: 636 }
637 else
638 {
639 if (spdata->type == Solid)
640 spdata->unclipped_blend = &_blend_argb;
641 else if (spdata->type == LinearGradient || spdata->type == RadialGradient)
526 spdata->unclipped_blend = &_blend_gradient; 642 spdata->unclipped_blend = &_blend_gradient;
527 break; 643 else //None
644 spdata->unclipped_blend = NULL;
528 } 645 }
529 646
530 //FIXME: Mask and mask case is not use clipping. 647 //FIXME: Mask and mask case is not use clipping.