From 6747fadd9a697236c5307f8cb1cb5e9ceec6dabe Mon Sep 17 00:00:00 2001 From: Jaeun Choi Date: Thu, 13 Nov 2014 20:45:14 +0900 Subject: [PATCH] Evas masking: Implement support for line draw (SW) Signed-off-by: Jean-Philippe Andre --- src/lib/evas/common/evas_line.h | 6 +- src/lib/evas/common/evas_line_main.c | 356 +++++++++++++++--- .../engines/software_generic/evas_engine.c | 14 +- 3 files changed, 321 insertions(+), 55 deletions(-) diff --git a/src/lib/evas/common/evas_line.h b/src/lib/evas/common/evas_line.h index 8f6f8a280b..a19dbd8529 100644 --- a/src/lib/evas/common/evas_line.h +++ b/src/lib/evas/common/evas_line.h @@ -3,12 +3,12 @@ typedef void (*Evas_Common_Line_Draw_Cb)(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1); -EAPI void evas_common_line_point_draw (RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x, int y); +EAPI void evas_common_line_point_draw (RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x, int y, RGBA_Image *mask_ie, int mask_x, int mask_y); EAPI void evas_common_line_init (void); -EAPI void evas_common_line_draw_line (RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x1, int y1, int x2, int y2); -EAPI void evas_common_line_draw_line_aa (RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x1, int y1, int x2, int y2); +EAPI void evas_common_line_draw_line (RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x1, int y1, int x2, int y2, RGBA_Image *mask_ie, int mask_x, int mask_y); +EAPI void evas_common_line_draw_line_aa (RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x1, int y1, int x2, int y2, RGBA_Image *mask_ie, int mask_x, int mask_y); EAPI void evas_common_line_draw_cb (RGBA_Image *dst, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2, Evas_Common_Line_Draw_Cb cb); EAPI void evas_common_line_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2); diff --git a/src/lib/evas/common/evas_line_main.c b/src/lib/evas/common/evas_line_main.c index 8301dccee9..109e256ac7 100644 --- a/src/lib/evas/common/evas_line_main.c +++ b/src/lib/evas/common/evas_line_main.c @@ -29,6 +29,7 @@ static void _evas_draw_point(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y) { RGBA_Gfx_Pt_Func pfunc; + DATA8 *mask = NULL; if (!dst->image.data) return; if (!IN_RANGE(x, y, dst->cache_entry.w, dst->cache_entry.h)) @@ -49,17 +50,31 @@ _evas_draw_point(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y) # endif #endif { - pfunc = evas_common_gfx_func_composite_color_pt_get(dc->col.col, dst->cache_entry.flags.alpha, dc->render_op); - if (pfunc) - pfunc(0, 255, dc->col.col, dst->image.data + (dst->cache_entry.w * y) + x); + if (dc->clip.mask) + { + RGBA_Image *im = dc->clip.mask; + mask = im->image.data8 + + (y - dc->clip.mask_y) * im->cache_entry.w + + (x - dc->clip.mask_x); + pfunc = evas_common_gfx_func_composite_mask_color_pt_get(dc->col.col, dst->cache_entry.flags.alpha, dc->render_op); + if (pfunc) + pfunc(0, *mask, dc->col.col, dst->image.data + (dst->cache_entry.w * y) + x); + } + else + { + pfunc = evas_common_gfx_func_composite_color_pt_get(dc->col.col, dst->cache_entry.flags.alpha, dc->render_op); + if (pfunc) + pfunc(0, 255, dc->col.col, dst->image.data + (dst->cache_entry.w * y) + x); + } } } EAPI void -evas_common_line_point_draw(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x, int y) +evas_common_line_point_draw(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x, int y, RGBA_Image *mask_ie, int mask_x, int mask_y) { Eina_Bool no_cuse; RGBA_Gfx_Pt_Func pfunc; + DATA8 *mask = NULL; if (!dst->image.data) return; no_cuse = ((clip_x == 0) && (clip_y == 0) && @@ -70,9 +85,21 @@ evas_common_line_point_draw(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, if ((!no_cuse) && (!IN_RECT(x, y, clip_x, clip_y, clip_w, clip_h))) return; - pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, render_op); - if (pfunc) - pfunc(0, 255, color, dst->image.data + (dst->cache_entry.w * y) + x); + if (mask_ie) + { + mask = mask_ie->image.data8 + + (y - mask_y) * mask_ie->cache_entry.w + + (x - mask_x); + pfunc = evas_common_gfx_func_composite_mask_color_pt_get(color, dst->cache_entry.flags.alpha, render_op); + if (pfunc) + pfunc(0, *mask, color, dst->image.data + (dst->cache_entry.w * y) + x); + } + else + { + pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, render_op); + if (pfunc) + pfunc(0, 255, color, dst->image.data + (dst->cache_entry.w * y) + x); + } } /* @@ -86,8 +113,9 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i { int dx, dy, len, lx, ty, rx, by; int clx, cly, clw, clh; - int dstw; + int dstw, mask_w = 0; DATA32 *p, color; + DATA8 *mask = NULL; RGBA_Gfx_Pt_Func pfunc; RGBA_Gfx_Func sfunc; @@ -147,15 +175,30 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i # endif #endif { - sfunc = evas_common_gfx_func_composite_color_span_get(color, dst->cache_entry.flags.alpha, len, dc->render_op); - if (sfunc) - sfunc(NULL, NULL, color, p, len); + if (dc->clip.mask) + { + RGBA_Image *im = dc->clip.mask; + mask = im->image.data8 + + ((y0 - dc->clip.mask_y) * im->cache_entry.w) + + (x0 - dc->clip.mask_x); + sfunc = evas_common_gfx_func_composite_mask_color_span_get(color, dst->cache_entry.flags.alpha, len, dc->render_op); + if (sfunc) sfunc(NULL, mask, color, p, len); + } + else + { + sfunc = evas_common_gfx_func_composite_color_span_get(color, dst->cache_entry.flags.alpha, len, dc->render_op); + if (sfunc) + sfunc(NULL, NULL, color, p, len); + } } } return; } - pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, dc->render_op); + if (dc->clip.mask) + pfunc = evas_common_gfx_func_composite_mask_color_pt_get(color, dst->cache_entry.flags.alpha, dc->render_op); + else + pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, dc->render_op); if (!pfunc) return; if (dx == 0) @@ -177,10 +220,27 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i # endif #endif { - while (len--) + if (dc->clip.mask) { - pfunc(0, 255, color, p); - p += dstw; + RGBA_Image *im = dc->clip.mask; + mask_w = im->cache_entry.w; + mask = im->image.data8 + + ((y0 - dc->clip.mask_y) * mask_w) + + (x0 - dc->clip.mask_x); + while (len--) + { + pfunc(0, *mask, color, p); + p += dstw; + mask += mask_w; + } + } + else + { + while (len--) + { + pfunc(0, 255, color, p); + p += dstw; + } } } } @@ -254,6 +314,16 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i len = y1 - y0 + 1; if (dx > 0) dstw++; else dstw--; + if (dc->clip.mask) + { + RGBA_Image *im = dc->clip.mask; + mask_w = im->cache_entry.w; + mask = im->image.data8 + + ((y0 - dc->clip.mask_y) * mask_w) + + (x0 - dc->clip.mask_x); + if (dx > 0) mask_w++; + else mask_w--; + } } else { @@ -261,6 +331,16 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i p = dst->image.data + (dstw * y1) + x1; if (dx > 0) dstw--; else dstw++; + if (dc->clip.mask) + { + RGBA_Image *im = dc->clip.mask; + mask_w = im->cache_entry.w; + mask = im->image.data8 + + ((y1 - dc->clip.mask_y) * mask_w) + + (x1 - dc->clip.mask_x); + if (dx > 0) mask_w--; + else mask_w++; + } } #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE @@ -283,7 +363,15 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i else # endif #endif - pfunc(0, 255, color, p); + { + if (mask) + { + pfunc(0, *mask, color, p); + mask += mask_w; + } + else + pfunc(0, 255, color, p); + } #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pixman_x_position += x_unit; @@ -442,12 +530,13 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i rx = clw - 1; static void -_draw_render_thread_simple_line(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x0, int y0, int x1, int y1) +_draw_render_thread_simple_line(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x0, int y0, int x1, int y1, RGBA_Image *mask_ie, int mask_x, int mask_y) { int dx, dy, len, lx, ty, rx, by; int clx, cly, clw, clh; - int dstw; + int dstw, mask_w = 0; DATA32 *p; + DATA8 *mask = NULL; RGBA_Gfx_Pt_Func pfunc; RGBA_Gfx_Func sfunc; @@ -488,13 +577,27 @@ _draw_render_thread_simple_line(RGBA_Image *dst, int clip_x, int clip_y, int cli len = x1 - x0 + 1; p = dst->image.data + (dstw * y0) + x0; - sfunc = evas_common_gfx_func_composite_color_span_get(color, dst->cache_entry.flags.alpha, len, render_op); - if (sfunc) sfunc(NULL, NULL, color, p, len); + if (mask_ie) + { + mask = mask_ie->image.data8 + + ((y0 - mask_y) * mask_ie->cache_entry.w) + + (x0 - mask_x); + sfunc = evas_common_gfx_func_composite_mask_color_span_get(color, dst->cache_entry.flags.alpha, len, render_op); + if (sfunc) sfunc(NULL, mask, color, p, len); + } + else + { + sfunc = evas_common_gfx_func_composite_color_span_get(color, dst->cache_entry.flags.alpha, len, render_op); + if (sfunc) sfunc(NULL, NULL, color, p, len); + } } return; } - pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, render_op); + if (mask_ie) + pfunc = evas_common_gfx_func_composite_mask_color_pt_get(color, dst->cache_entry.flags.alpha, render_op); + else + pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, render_op); if (!pfunc) return; if (dx == 0) @@ -506,10 +609,26 @@ _draw_render_thread_simple_line(RGBA_Image *dst, int clip_x, int clip_y, int cli len = y1 - y0 + 1; p = dst->image.data + (dstw * y0) + x0; - while (len--) + if (mask_ie) { - pfunc(0, 255, color, p); - p += dstw; + mask_w = mask_ie->cache_entry.w; + mask = mask_ie->image.data8 + + ((y0 - mask_y) * mask_w) + + (x0 - mask_x); + while (len--) + { + pfunc(0, *mask, color, p); + p += dstw; + mask += mask_w; + } + } + else + { + while (len--) + { + pfunc(0, 255, color, p); + p += dstw; + } } } return; @@ -582,6 +701,15 @@ _draw_render_thread_simple_line(RGBA_Image *dst, int clip_x, int clip_y, int cli len = y1 - y0 + 1; if (dx > 0) dstw++; else dstw--; + if (mask_ie) + { + mask_w = mask_ie->cache_entry.w; + mask = mask_ie->image.data8 + + ((y0 - mask_y) * mask_w) + + (x0 - mask_x); + if (dx > 0) mask_w++; + else mask_w--; + } } else { @@ -589,11 +717,32 @@ _draw_render_thread_simple_line(RGBA_Image *dst, int clip_x, int clip_y, int cli p = dst->image.data + (dstw * y1) + x1; if (dx > 0) dstw--; else dstw++; + if (mask_ie) + { + mask_w = mask_ie->cache_entry.w; + mask = mask_ie->image.data8 + + ((y1 - mask_y) * mask_w) + + (x1 - mask_x); + if (dx > 0) mask_w--; + else mask_w++; + } } - while (len--) + if (mask) { - pfunc(0, 255, color, p); - p += dstw; + while (len--) + { + pfunc(0, *mask, color, p); + p += dstw; + mask += mask_w; + } + } + else + { + while (len--) + { + pfunc(0, 255, color, p); + p += dstw; + } } } } @@ -745,14 +894,15 @@ _draw_render_thread_simple_line(RGBA_Image *dst, int clip_x, int clip_y, int cli rx = clw - 1; EAPI void -evas_common_line_draw_line(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x0, int y0, int x1, int y1) +evas_common_line_draw_line(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x0, int y0, int x1, int y1, RGBA_Image *mask_ie, int mask_x, int mask_y) { int px, py, x, y, prev_x, prev_y; int dx, dy, rx, by, p0_in, p1_in, dh, a_a = 0; int delx, dely, xx, yy, dxx, dyy; int clx, cly, clw, clh; - int dstw; + int dstw, mask_w = 0; DATA32 *p, *data; + DATA8 *mask = NULL; RGBA_Gfx_Pt_Func pfunc; dx = x1 - x0; @@ -763,11 +913,15 @@ evas_common_line_draw_line(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, _draw_render_thread_simple_line (dst, clip_x, clip_y, clip_w, clip_h, color, render_op, - x0, y0, x1, y1); + x0, y0, x1, y1, + mask_ie, mask_x, mask_y); return; } - pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, render_op); + if (mask_ie) + pfunc = evas_common_gfx_func_composite_mask_color_pt_get(color, dst->cache_entry.flags.alpha, render_op); + else + pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, render_op); if (!pfunc) return; clx = clip_x; @@ -784,11 +938,19 @@ evas_common_line_draw_line(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, x1 -= clx; y1 -= cly; + if (mask_ie) + { + mask_w = mask_ie->cache_entry.w; + mask = mask_ie->image.data8 + + ((cly - mask_y) * mask_w) + (clx - mask_x); + } + /* shallow: x-parametric */ if ((dy < dx) || (dy < -dx)) { SETUP_LINE_SHALLOW; + if (mask) mask += (py * mask_w) + px; while (px < rx) { y = (yy >> 16); @@ -797,6 +959,7 @@ evas_common_line_draw_line(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, { prev_y = y; p += dh; + if (mask) mask += mask_w; py += dely; } if (!p1_in) @@ -808,12 +971,17 @@ evas_common_line_draw_line(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, { if (py < 0) goto next_x; } - if (IN_RANGE(px, py, clw, clh)) pfunc(0, 255, color, p); + if (IN_RANGE(px, py, clw, clh)) + { + if (mask) pfunc(0, *mask, color, p); + else pfunc(0, 255, color, p); + } next_x: yy += dyy; px++; p++; + if (mask) mask++; } return; } @@ -821,6 +989,7 @@ next_x: /* steep: y-parametric */ SETUP_LINE_STEEP; + if (mask) mask += (py * mask_w) + px; while (py < by) { @@ -831,6 +1000,7 @@ next_x: prev_x = x; px += delx; p += delx; + if (mask) mask += delx; } if (!p1_in) { @@ -841,12 +1011,17 @@ next_x: { if (px < 0) goto next_y; } - if (IN_RANGE(px, py, clw, clh)) pfunc(0, 255, color, p); + if (IN_RANGE(px, py, clw, clh)) + { + if (mask) pfunc(0, *mask, color, p); + else pfunc(0, 255, color, p); + } next_y: xx += dxx; py++; p += dstw; + if (mask) mask += mask_w; } } @@ -857,8 +1032,9 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int dx, dy, rx, by, p0_in, p1_in, dh, a_a = 0; int delx, dely, xx, yy, dxx, dyy; int clx, cly, clw, clh; - int dstw; + int dstw, mask_w = 0; DATA32 *p, *data, color; + DATA8 *mask = NULL; RGBA_Gfx_Pt_Func pfunc; dx = x1 - x0; @@ -896,7 +1072,10 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, } color = dc->col.col; - pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, dc->render_op); + if (dc->clip.mask) + pfunc = evas_common_gfx_func_composite_mask_color_pt_get(color, dst->cache_entry.flags.alpha, dc->render_op); + else + pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst->cache_entry.flags.alpha, dc->render_op); if (!pfunc) return; clx = dc->clip.x; @@ -913,11 +1092,20 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, x1 -= clx; y1 -= cly; + if (dc->clip.mask) + { + RGBA_Image *im = dc->clip.mask; + mask_w = im->cache_entry.w; + mask = im->image.data8 + + ((cly - dc->clip.mask_y) * mask_w) + (clx - dc->clip.mask_x); + } + /* shallow: x-parametric */ if ((dy < dx) || (dy < -dx)) { SETUP_LINE_SHALLOW; + if (mask) mask += (py * mask_w) + px; while (px < rx) { y = (yy >> 16); @@ -926,6 +1114,7 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, { prev_y = y; p += dh; + if (mask) mask += mask_w; py += dely; #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE @@ -954,13 +1143,17 @@ _evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, else # endif #endif - pfunc(0, 255, color, p); + { + if (mask) pfunc(0, *mask, color, p); + else pfunc(0, 255, color, p); + } } next_x: yy += dyy; px++; p++; + if (mask) mask++; #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pix_x += pix_x_unit; @@ -973,6 +1166,7 @@ next_x: /* steep: y-parametric */ SETUP_LINE_STEEP; + if (mask) mask += (py * mask_w) + px; while (py < by) { @@ -983,6 +1177,7 @@ next_x: prev_x = x; px += delx; p += delx; + if (mask) mask += delx; #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pix_x += pix_x_unit; @@ -1010,12 +1205,16 @@ next_x: else # endif #endif - pfunc(0, 255, color, p); + { + if (mask) pfunc(0, *mask, color, p); + else pfunc(0, 255, color, p); + } } next_y: xx += dxx; py++; p += dstw; + if (mask) mask += mask_w; #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pix_y += pix_y_unit; @@ -1025,14 +1224,15 @@ next_y: } EAPI void -evas_common_line_draw_line_aa(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x0, int y0, int x1, int y1) +evas_common_line_draw_line_aa(RGBA_Image *dst, int clip_x, int clip_y, int clip_w, int clip_h, DATA32 color, int render_op, int x0, int y0, int x1, int y1, RGBA_Image *mask_ie, int mask_x, int mask_y) { int px, py, x, y, prev_x, prev_y; int dx, dy, rx, by, p0_in, p1_in, dh, a_a = 1; int delx, dely, xx, yy, dxx, dyy; int clx, cly, clw, clh; - int dstw; + int dstw, mask_w = 0; DATA32 *p, *data; + DATA8 *mask = NULL; RGBA_Gfx_Pt_Func pfunc; dx = x1 - x0; @@ -1049,7 +1249,8 @@ evas_common_line_draw_line_aa(RGBA_Image *dst, int clip_x, int clip_y, int clip_ _draw_render_thread_simple_line (dst, clip_x, clip_y, clip_w, clip_h, color, render_op, - x0, y0, x1, y1); + x0, y0, x1, y1, + mask_ie, mask_x, mask_y); return; } @@ -1070,11 +1271,19 @@ evas_common_line_draw_line_aa(RGBA_Image *dst, int clip_x, int clip_y, int clip_ x1 -= clx; y1 -= cly; + if (mask_ie) + { + mask_w = mask_ie->cache_entry.w; + mask = mask_ie->image.data8 + + (cly - mask_y) * mask_w + (clx - mask_x); + } + /* shallow: x-parametric */ if ((dy < dx) || (dy < -dx)) { SETUP_LINE_SHALLOW; + if (mask) mask += (py * mask_w) + px; while (px < rx) { DATA8 aa; @@ -1084,6 +1293,7 @@ evas_common_line_draw_line_aa(RGBA_Image *dst, int clip_x, int clip_y, int clip_ { prev_y = y; p += dh; + if (mask) mask += mask_w; py += dely; } if (!p1_in) @@ -1099,20 +1309,30 @@ evas_common_line_draw_line_aa(RGBA_Image *dst, int clip_x, int clip_y, int clip_ { aa = ((yy - (y << 16)) >> 8); - if ((py) < clh) pfunc(0, 255 - aa, color, p); - if ((py + 1) < clh) pfunc(0, aa, color, p + dstw); + if (mask) + { + if ((py) < clh) pfunc(0, (255 - aa) * (*mask) / 255, color, p); + if ((py + 1) < clh) pfunc(0, aa * (*(mask + mask_w)) / 255, color, p + dstw); + } + else + { + if ((py) < clh) pfunc(0, 255 - aa, color, p); + if ((py + 1) < clh) pfunc(0, aa, color, p + dstw); + } } next_x: yy += dyy; px++; p++; + if (mask) mask++; } return; } /* steep: y-parametric */ SETUP_LINE_STEEP; + if (mask) mask += (py * mask_w) + px; while (py < by) { @@ -1124,6 +1344,7 @@ next_x: prev_x = x; px += delx; p += delx; + if (mask) mask += delx; } if (!p1_in) { @@ -1137,14 +1358,24 @@ next_x: if (py < clh) { aa = ((xx - (x << 16)) >> 8); - if ((px) < clw) pfunc(0, 255 - aa, color, p); - if ((px + 1) < clw) pfunc(0, aa, color, p + 1); + + if (mask) + { + if ((px) < clw) pfunc(0, (255 - aa) * (*mask) / 255, color, p); + if ((px + 1) < clw) pfunc(0, aa * (*(mask + 1)) / 255, color, p + 1); + } + else + { + if ((px) < clw) pfunc(0, 255 - aa, color, p); + if ((px + 1) < clw) pfunc(0, aa, color, p + 1); + } } next_y: xx += dxx; py++; p += dstw; + if (mask) mask += mask_w; } } @@ -1155,8 +1386,9 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x int dx, dy, rx, by, p0_in, p1_in, dh, a_a = 1; int delx, dely, xx, yy, dxx, dyy; int clx, cly, clw, clh; - int dstw; + int dstw, mask_w = 0; DATA32 *p, *data, color; + DATA8 *mask = NULL; RGBA_Gfx_Pt_Func pfunc; dx = x1 - x0; @@ -1219,11 +1451,20 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x x1 -= clx; y1 -= cly; + if (dc->clip.mask) + { + RGBA_Image *im = dc->clip.mask; + mask_w = im->cache_entry.w; + mask = im->image.data8 + + ((cly - dc->clip.mask_y) * mask_w) + (clx - dc->clip.mask_x); + } + /* shallow: x-parametric */ if ((dy < dx) || (dy < -dx)) { SETUP_LINE_SHALLOW; + if (mask) mask += (py * mask_w) + px; while (px < rx) { DATA8 aa; @@ -1233,6 +1474,7 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x { prev_y = y; p += dh; + if (mask) mask += mask_w; py += dely; #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE @@ -1268,7 +1510,10 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x else # endif #endif - pfunc(0, 255 - aa, color, p); + { + if (mask) pfunc(0, (255 - aa) * (*mask) / 255, color, p); + else pfunc(0, 255 - aa, color, p); + } #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pixman_image_unref(aa_mask_image); @@ -1291,7 +1536,10 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x else # endif #endif - pfunc(0, aa, color, p + dstw); + { + if (mask) pfunc(0, aa * (*(mask + mask_w)) / 255, color, p + dstw); + else pfunc(0, aa, color, p + dstw); + } #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pixman_image_unref(aa_mask_image); @@ -1304,6 +1552,7 @@ next_x: yy += dyy; px++; p++; + if (mask) mask++; #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pix_x += pix_x_unit; @@ -1315,6 +1564,7 @@ next_x: /* steep: y-parametric */ SETUP_LINE_STEEP; + if (mask) mask += (py * mask_w) + px; while (py < by) { @@ -1326,6 +1576,7 @@ next_x: prev_x = x; px += delx; p += delx; + if (mask) mask += delx; #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pix_x += pix_x_unit; @@ -1359,7 +1610,10 @@ next_x: else # endif #endif - pfunc(0, 255 - aa, color, p); + { + if (mask) pfunc(0, (255 - aa) * (*mask) / 255, color, p); + else pfunc(0, 255 - aa, color, p); + } #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pixman_image_unref(aa_mask_image); @@ -1383,7 +1637,10 @@ next_x: else # endif #endif - pfunc(0, aa, color, p + 1); + { + if (mask) pfunc(0, aa * (*(mask + 1)) / 255, color, p + 1); + else pfunc(0, aa, color, p + 1); + } #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pixman_image_unref(aa_mask_image); @@ -1395,6 +1652,7 @@ next_x: xx += dxx; py++; p += dstw; + if (mask) mask += mask_w; #ifdef HAVE_PIXMAN # ifdef PIXMAN_LINE pix_y += pix_y_unit; diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 92272cd990..2484532a46 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -309,6 +309,8 @@ struct _Evas_Thread_Command_Line Eina_Bool anti_alias; int x1, y1; int x2, y2; + void *mask; + int mask_x, mask_y; }; struct _Evas_Thread_Command_Polygon @@ -649,7 +651,8 @@ _draw_thread_line_draw(void *data) evas_common_line_point_draw(line->surface, clip_x, clip_y, clip_w, clip_h, line->color, line->render_op, - line->x1, line->y1); + line->x1, line->y1, + line->mask, line->mask_x, line->mask_y); return; } @@ -659,14 +662,16 @@ _draw_thread_line_draw(void *data) clip_x, clip_y, clip_w, clip_h, line->color, line->render_op, line->x1, line->y1, - line->x2, line->y2); + line->x2, line->y2, + line->mask, line->mask_x, line->mask_y); else evas_common_line_draw_line (line->surface, clip_x, clip_y, clip_w, clip_h, line->color, line->render_op, line->x1, line->y1, - line->x2, line->y2); + line->x2, line->y2, + line->mask, line->mask_x, line->mask_y); eina_mempool_free(_mp_command_line, line); } @@ -732,6 +737,9 @@ _line_draw_thread_cmd(RGBA_Image *dst, RGBA_Draw_Context *dc, int x1, int y1, in cl->y1 = y1; cl->x2 = x2; cl->y2 = y2; + cl->mask = dc->clip.mask; + cl->mask_x = dc->clip.mask_x; + cl->mask_y = dc->clip.mask_y; evas_thread_cmd_enqueue(_draw_thread_line_draw, cl); }