Evas masking: Implement support for line draw (SW)
authorJaeun Choi <jaeun12.choi@samsung.com>
Thu, 13 Nov 2014 11:45:14 +0000 (20:45 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Wed, 7 Jan 2015 06:06:02 +0000 (15:06 +0900)
Signed-off-by: Jean-Philippe Andre <jp.andre@samsung.com>
src/lib/evas/common/evas_line.h
src/lib/evas/common/evas_line_main.c
src/modules/evas/engines/software_generic/evas_engine.c

index 8f6f8a2..a19dbd8 100644 (file)
@@ -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);
 
index 8301dcc..109e256 100644 (file)
@@ -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;
index 92272cd..2484532 100644 (file)
@@ -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);
 }