evas/common: Prepare soil to land line drawing code for threaded render
authorLeandro Pereira <leandro@profusion.mobi>
Mon, 17 Dec 2012 21:28:08 +0000 (21:28 +0000)
committerLeandro Pereira <leandro@profusion.mobi>
Mon, 17 Dec 2012 21:28:08 +0000 (21:28 +0000)
SVN revision: 81185

src/lib/evas/common/evas_line.h
src/lib/evas/common/evas_line_main.c
src/lib/evas/common/evas_map_image.c

index 1cdff08..8f6f8a2 100644 (file)
@@ -3,8 +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_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_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 baea395..1985b46 100644 (file)
@@ -1,20 +1,6 @@
 #include "evas_common.h"
 #include "evas_blend_private.h"
 
-
-static void
-_evas_draw_point(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y);
-
-static void
-_evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1);
-
-static void
-_evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1);
-
-static void
-_evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1);
-
-
 #define IN_RANGE(x, y, w, h) \
   ( x > 0 && y > 0 &&((unsigned)(x) < (unsigned)(w)) && ((unsigned)(y) < (unsigned)(h)) )
 
@@ -34,79 +20,11 @@ _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x
      x1 = _tmp;                                 \
   }
 
-
 EAPI void
 evas_common_line_init(void)
 {
 }
 
-EAPI void
-evas_common_line_draw_cb(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1, Evas_Common_Line_Draw_Cb cb)
-{
-   int  x, y, w, h;
-   int  clx, cly, clw, clh;
-   int  cuse, cx, cy, cw, ch;
-
-   /* No cutout ? FIXME ? */
-
-   if ((x0 == x1) && (y0 == y1))
-     {
-       _evas_draw_point(dst, dc, x0, y0);
-       return;
-     }
-
-   clx = cly = 0;
-   clw = dst->cache_entry.w;
-   clh = dst->cache_entry.h;
-
-   /* save out clip info */
-   cuse = dc->clip.use;
-   cx = dc->clip.x;
-   cy = dc->clip.y;
-   cw = dc->clip.w;
-   ch = dc->clip.h;
-
-   if (cuse)
-     {
-       RECTS_CLIP_TO_RECT(clx, cly, clw, clh, cx, cy, cw, ch);
-       if ((clw < 1) || (clh < 1))
-          return;
-     }
-
-   x = MIN(x0, x1);
-   y = MIN(y0, y1);
-   w = MAX(x0, x1) - x + 1;
-   h = MAX(y0, y1) - y + 1;
-
-   RECTS_CLIP_TO_RECT(clx, cly, clw, clh, x, y, w, h);
-   if ((clw < 1) || (clh < 1))
-       return;
-
-   dc->clip.use = 1;
-   dc->clip.x = clx;
-   dc->clip.y = cly;
-   dc->clip.w = clw;
-   dc->clip.h = clh;
-
-   cb(dst, dc, x0, y0, x1, y1);
-
-   /* restore clip info */
-   dc->clip.use = cuse;
-   dc->clip.x = cx;
-   dc->clip.y = cy;
-   dc->clip.w = cw;
-   dc->clip.h = ch;
-}
-
-EAPI void
-evas_common_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
-{
-   Evas_Common_Line_Draw_Cb cb;
-
-   cb = dc->anti_alias ? _evas_draw_line_aa : _evas_draw_line;
-   evas_common_line_draw_cb(dst, dc, x0, y0, x1, y1, cb);
-}
-
 static void
 _evas_draw_point(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y)
 {
@@ -136,6 +54,25 @@ _evas_draw_point(RGBA_Image *dst, RGBA_Draw_Context *dc, 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)
+{
+   Eina_Bool no_cuse;
+   RGBA_Gfx_Pt_Func pfunc;
+
+   no_cuse = ((clip_x == 0) && (clip_y == 0) &&
+              ((clip_w == (int)dst->cache_entry.w) &&
+               (clip_h == (int)dst->cache_entry.h)));
+
+   if (!IN_RANGE(x, y, dst->cache_entry.w, dst->cache_entry.h)) return;
+   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, render_op);
+   if (pfunc)
+     pfunc(0, 255, color, dst->image.data + (dst->cache_entry.w * y) + x);
+}
+
 /*
    these functions use the dc->clip data as bounding
    data. they assume that such data has already been cut
@@ -503,152 +440,561 @@ _evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, i
   rx = clw - 1;
 
 static void
-_evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, 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)
 {
-   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     dx, dy, len, lx, ty, rx, by;
    int     clx, cly, clw, clh;
    int     dstw;
-   DATA32  *p, *data, color;
+   DATA32  *p;
    RGBA_Gfx_Pt_Func pfunc;
+   RGBA_Gfx_Func    sfunc;
+
+   dstw = dst->cache_entry.w;
+
+   if (y0 > y1)
+      EXCHANGE_POINTS(x0, y0, x1, y1)
+   if (x0 > x1)
+      EXCHANGE_POINTS(x0, y0, x1, y1)
 
    dx = x1 - x0;
    dy = y1 - y0;
 
-#ifdef HAVE_PIXMAN
-# ifdef PIXMAN_LINE   
-   int pix_x;
-   int pix_y;
-   int pix_x_unit;
-   int pix_y_unit;
-   
-   pixman_op_t op = PIXMAN_OP_SRC; // _EVAS_RENDER_COPY
-   if (dc->render_op == _EVAS_RENDER_BLEND)
-     op = PIXMAN_OP_OVER;
-   pix_x = x0;
-   pix_y = y0;
-   
-   if (dx < 0)
-     pix_x_unit = -1;
-   else
-     pix_x_unit = 1;
-   
-   if (dy < 0)
-     pix_y_unit = -1;
-   else
-     pix_y_unit = 1;
-# endif
-#endif
+   clx = clip_x;
+   cly = clip_y;
+   clw = clip_w;
+   clh = clip_h;
 
-   if ( (dx == 0) || (dy == 0) || (dx == dy) || (dx == -dy) )
+   lx = clx;
+   rx = clx + clw - 1;
+   ty = cly;
+   by = cly + clh - 1;
+
+   if (dy == 0)
      {
-       _evas_draw_simple_line(dst, dc, x0, y0, x1, y1);
-       return;
-     }
+        if ((y0 >= ty) && (y0 <= by))
+          {
+             if (dx < 0)
+               {
+                  int  tmp = x1;
 
-   color = dc->col.col;
-   pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst, dc->render_op);
-   if (!pfunc) return;
+                  x1 = x0;
+                  x0 = tmp;
+               }
 
-   clx = dc->clip.x;
-   cly = dc->clip.y;
-   clw = dc->clip.w;
-   clh = dc->clip.h;
+             if (x0 < lx) x0 = lx;
+             if (x1 > rx) x1 = rx;
 
-   data = dst->image.data;
-   dstw = dst->cache_entry.w;
+             len = x1 - x0 + 1;
+             p = dst->image.data + (dstw * y0) + x0;
+             sfunc = evas_common_gfx_func_composite_color_span_get(color, dst, len, render_op);
+             if (sfunc) sfunc(NULL, NULL, color, p, len);
+          }
+        return;
+     }
 
-   data += (dstw * cly) + clx;
-   x0 -= clx;
-   y0 -= cly;
-   x1 -= clx;
-   y1 -= cly;
+   pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst, render_op);
+   if (!pfunc) return;
 
-   /* shallow: x-parametric */
-   if ((dy < dx) || (dy < -dx))
+   if (dx == 0)
      {
-       SETUP_LINE_SHALLOW;
-
-       while (px < rx)
-         {
-           y = (yy >> 16);
-           y += ((yy - (y << 16)) >> 15);
-           if (prev_y != y)
-             {
-               prev_y = y;
-               p += dh;
-               py += dely;
-#ifdef HAVE_PIXMAN
-# ifdef PIXMAN_LINE                 
-                 pix_y += pix_y_unit;
-# endif
-#endif
-             }
-           if (!p1_in)
-             {
-               if ((py < 0) && (dely < 0)) return;
-               if ((py > by) && (dely > 0)) return;
-             }
-            if (!p0_in)
-              {
-                 if (py < 0) goto next_x;
-              }
-            if (IN_RANGE(px, py, clw, clh))
-              {
-#ifdef HAVE_PIXMAN
-# ifdef PIXMAN_LINE                       
-                 if ((dst->pixman.im) && (dc->col.pixman_color_image))
-                   pixman_image_composite(op, dc->col.pixman_color_image,
-                                          NULL, dst->pixman.im,
-                                          pix_x, pix_y, 0, 0,
-                                          pix_x, pix_y, 1, 1);
-                 else
-# endif                         
-#endif
-                   pfunc(0, 255, color, p);
-              }
+        if ((x0 >= lx) && (x0 <= rx))
+          {
+             if (y0 < ty) y0 = ty;
+             if (y1 > by) y1 = by;
 
-next_x:
-            yy += dyy;
-            px++;
-            p++;
-#ifdef HAVE_PIXMAN
-# ifdef PIXMAN_LINE             
-            pix_x += pix_x_unit;
-# endif
-#endif
-         }
-       return;
+             len = y1 - y0 + 1;
+             p = dst->image.data + (dstw * y0) + x0;
+             while (len--)
+               {
+                  pfunc(0, 255, color, p);
+                  p += dstw;
+               }
+          }
+        return;
      }
 
-   /* steep: y-parametric */
+   if ((dy == dx) || (dy == -dx))
+     {
+        int   p0_in, p1_in;
 
-   SETUP_LINE_STEEP;
+        p0_in = (IN_RECT(x0, y0, clx, cly, clw, clh) ? 1 : 0);
+        p1_in = (IN_RECT(x1, y1, clx, cly, clw, clh) ? 1 : 0);
 
-   while (py < by)
-     {
-       x = (xx >> 16);
-       x += ((xx - (x << 16)) >> 15);
-       if (prev_x != x)
-         {
-             prev_x = x;
-             px += delx;
-             p += delx;
-#ifdef HAVE_PIXMAN
-# ifdef PIXMAN_LINE
-             pix_x += pix_x_unit;
-# endif
-#endif
-         }
-       if (!p1_in)
-         {
-           if ((px < 0) && (delx < 0)) return;
-           if ((px > rx) && (delx > 0)) return;
-         }
-        if (!p0_in)
+        if (dy > 0)
           {
-             if (px < 0) goto next_y;
+             if (!p0_in)
+               {
+                  x0 = x0 + (ty - y0);
+                  y0 = ty;
+                  if (x0 > rx) return;
+                  if (x0 < lx)
+                    {
+                       y0 = y0 + (lx - x0);
+                       x0 = lx;
+                       if ((y0 < ty) || (y0 > by)) return;
+                    }
+               }
+             if (!p1_in)
+               {
+                  x1 = x0 + (by - y0);
+                  y1 = by;
+                  if (x1 < lx) return;
+                  if (x1 > rx)
+                    {
+                       y1 = y0 + (rx - x0);
+                       x1 = rx;
+                       if ((y1 < ty) || (y1 > by)) return;
+                    }
+               }
+          }
+        else
+          {
+             if (!p0_in)
+               {
+                  x0 = x0 - (by - y0);
+                  y0 = by;
+                  if (x0 > rx) return;
+                  if (x0 < lx)
+                    {
+                       y0 = y0 - (lx - x0);
+                       x0 = lx;
+                       if ((y0 < ty) || (y0 > by)) return;
+                    }
+               }
+             if (!p1_in)
+               {
+                  x1 = x0 - (ty - y0);
+                  y1 = ty;
+                  if (x1 < lx) return;
+                  if (x1 > rx)
+                    {
+                       y1 = y0 - (rx - x0);
+                       x1 = rx;
+                       if ((y1 < ty) || (y1 > by)) return;
+                    }
+               }
+          }
+        if (y1 > y0)
+          {
+             p = dst->image.data + (dstw * y0) + x0;
+             len = y1 - y0 + 1;
+             if (dx > 0)  dstw++;
+             else  dstw--;
+          }
+        else
+          {
+             len = y0 - y1 + 1;
+             p = dst->image.data + (dstw * y1) + x1;
+             if (dx > 0)  dstw--;
+             else  dstw++;
+          }
+        while (len--)
+          {
+             pfunc(0, 255, color, p);
+             p += dstw;
+          }
+     }
+}
+
+#define SETUP_LINE_SHALLOW                                             \
+  if (x0 > x1)                                                         \
+    {                                                                  \
+       EXCHANGE_POINTS(x0, y0, x1, y1);                                \
+       dx = -dx;                                                       \
+       dy = -dy;                                                       \
+    }                                                                  \
+                                                                       \
+  px = x0;                                                             \
+  py = y0;                                                             \
+                                                                       \
+  p0_in = (IN_RANGE(x0 , y0 , clw, clh) ? 1 : 0);                      \
+  p1_in = (IN_RANGE(x1 , y1 , clw, clh) ? 1 : 0);                      \
+                                                                       \
+  dely = 1;                                                            \
+  dh = dstw;                                                           \
+  if (dy < 0)                                                          \
+    {                                                                  \
+       dely = -1;                                                      \
+       dh = -dstw;                                                     \
+    }                                                                  \
+                                                                       \
+  dyy = ((dy) << 16) / (dx);                                           \
+                                                                       \
+  if (!p0_in)                                                          \
+    {                                                                  \
+       dxx = ((dx) << 16) / (dy);                                      \
+       if (px < 0)                                                     \
+         {                                                             \
+            x = -px;  px = 0;                                          \
+            yy = x * dyy;                                              \
+            y = yy >> 16;                                              \
+            if (!a_a)                                                  \
+              y += (yy - (y << 16)) >> 15;                             \
+            py += y;                                                   \
+            if ((dely > 0) && (py >= clh))                             \
+              return;                                                  \
+            else if ((dely < 0) && (py < -1))                          \
+              return;                                                  \
+         }                                                             \
+                                                                       \
+       y = 0;                                                          \
+       if ((dely > 0) && (py < 0))                                     \
+         y = (-1 - py);                                                \
+       else if ((dely < 0) && (py >= clh))                             \
+         y = (clh - 1 - py);                                           \
+                                                                       \
+       xx = y * dxx;                                                   \
+       x = xx >> 16;                                                   \
+       if (!a_a)                                                       \
+         x += (xx - (x << 16)) >> 15;                                  \
+       px += x;                                                        \
+       if (px >= clw) return;                                          \
+                                                                       \
+       yy = x * dyy;                                                   \
+       y = yy >> 16;                                                   \
+       if (!a_a)                                                       \
+         y += (yy - (y << 16)) >> 15;                                  \
+       py += y;                                                        \
+       if ((dely > 0) && (py >= clh))                                  \
+         return;                                                       \
+       else if ((dely < 0) && (py < -1))                               \
+         return;                                                       \
+    }                                                                  \
+                                                                       \
+  p = data + (dstw * py) + px;                                         \
+                                                                       \
+  x = px - x0;                                                         \
+  yy = x * dyy;                                                        \
+  prev_y = (yy >> 16);                                                 \
+                                                                       \
+  rx = MIN(x1 + 1, clw);                                               \
+  by = clh - 1;
+
+
+#define SETUP_LINE_STEEP                                               \
+  if (y0 > y1)                                                         \
+    {                                                                  \
+       EXCHANGE_POINTS(x0, y0, x1, y1);                                \
+       dx = -dx;                                                       \
+       dy = -dy;                                                       \
+    }                                                                  \
+                                                                       \
+  px = x0;                                                             \
+  py = y0;                                                             \
+                                                                       \
+  p0_in = (IN_RANGE(x0 , y0 , clw, clh) ? 1 : 0);                      \
+  p1_in = (IN_RANGE(x1 , y1 , clw, clh) ? 1 : 0);                      \
+                                                                       \
+  delx = 1;                                                            \
+  if (dx < 0)                                                          \
+    delx = -1;                                                         \
+                                                                       \
+  dxx = ((dx) << 16) / (dy);                                           \
+                                                                       \
+  if (!p0_in)                                                          \
+    {                                                                  \
+       dyy = ((dy) << 16) / (dx);                                      \
+                                                                       \
+       if (py < 0)                                                     \
+         {                                                             \
+          y = -py;  py = 0;                                            \
+          xx = y * dxx;                                                \
+          x = xx >> 16;                                                \
+          if (!a_a)                                                    \
+             x += (xx - (x << 16)) >> 15;                              \
+          px += x;                                                     \
+          if ((delx > 0) && (px >= clw))                               \
+             return;                                                   \
+          else if ((delx < 0) && (px < -1))                            \
+             return;                                                   \
+         }                                                             \
+                                                                       \
+       x = 0;                                                          \
+       if ((delx > 0) && (px < -1))                                    \
+         x = (-1 - px);                                                \
+       else if ((delx < 0) && (px >= clw))                             \
+         x = (clw - 1 - px);                                           \
+                                                                       \
+       yy = x * dyy;                                                   \
+       y = yy >> 16;                                                   \
+       if (!a_a)                                                       \
+         y += (yy - (y << 16)) >> 15;                                  \
+       py += y;                                                        \
+       if (py >= clh) return;                                          \
+                                                                       \
+       xx = y * dxx;                                                   \
+       x = xx >> 16;                                                   \
+       if (!a_a)                                                       \
+         x += (xx - (x << 16)) >> 15;                                  \
+       px += x;                                                        \
+       if ((delx > 0) && (px >= clw))                                  \
+         return;                                                       \
+       else if ((delx < 0) && (px < -1))                               \
+         return;                                                       \
+    }                                                                  \
+                                                                       \
+  p = data + (dstw * py) + px;                                         \
+                                                                       \
+  y = py - y0;                                                         \
+  xx = y * dxx;                                                        \
+  prev_x = (xx >> 16);                                                 \
+                                                                       \
+  by = MIN(y1 + 1, clh);                                               \
+  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)
+{
+   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;
+   DATA32  *p, *data;
+   RGBA_Gfx_Pt_Func pfunc;
+
+   dx = x1 - x0;
+   dy = y1 - y0;
+
+   if ( (dx == 0) || (dy == 0) || (dx == dy) || (dx == -dy) )
+     {
+       _draw_render_thread_simple_line
+          (dst, clip_x, clip_y, clip_w, clip_h,
+           color, render_op,
+           x0, y0, x1, y1);
+       return;
+     }
+
+   pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst, render_op);
+   if (!pfunc) return;
+
+   clx = clip_x;
+   cly = clip_y;
+   clw = clip_w;
+   clh = clip_h;
+
+   data = dst->image.data;
+   dstw = dst->cache_entry.w;
+
+   data += (dstw * cly) + clx;
+   x0 -= clx;
+   y0 -= cly;
+   x1 -= clx;
+   y1 -= cly;
+
+   /* shallow: x-parametric */
+   if ((dy < dx) || (dy < -dx))
+     {
+       SETUP_LINE_SHALLOW;
+
+       while (px < rx)
+         {
+           y = (yy >> 16);
+           y += ((yy - (y << 16)) >> 15);
+           if (prev_y != y)
+             {
+               prev_y = y;
+               p += dh;
+               py += dely;
+             }
+           if (!p1_in)
+             {
+               if ((py < 0) && (dely < 0)) return;
+               if ((py > by) && (dely > 0)) return;
+             }
+            if (!p0_in)
+              {
+                 if (py < 0) goto next_x;
+              }
+            if (IN_RANGE(px, py, clw, clh)) pfunc(0, 255, color, p);
+
+next_x:
+            yy += dyy;
+            px++;
+            p++;
+         }
+       return;
+     }
+
+   /* steep: y-parametric */
+
+   SETUP_LINE_STEEP;
+
+   while (py < by)
+     {
+       x = (xx >> 16);
+       x += ((xx - (x << 16)) >> 15);
+       if (prev_x != x)
+         {
+             prev_x = x;
+             px += delx;
+             p += delx;
+         }
+       if (!p1_in)
+         {
+           if ((px < 0) && (delx < 0)) return;
+           if ((px > rx) && (delx > 0)) return;
+         }
+        if (!p0_in)
+          {
+             if (px < 0) goto next_y;
+          }
+        if (IN_RANGE(px, py, clw, clh)) pfunc(0, 255, color, p);
+
+next_y:
+       xx += dxx;
+       py++;
+       p += dstw;
+     }
+}
+
+static void
+_evas_draw_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
+{
+   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;
+   DATA32  *p, *data, color;
+   RGBA_Gfx_Pt_Func pfunc;
+
+   dx = x1 - x0;
+   dy = y1 - y0;
+
+#ifdef HAVE_PIXMAN
+# ifdef PIXMAN_LINE
+   int pix_x;
+   int pix_y;
+   int pix_x_unit;
+   int pix_y_unit;
+
+   pixman_op_t op = PIXMAN_OP_SRC; // _EVAS_RENDER_COPY
+   if (dc->render_op == _EVAS_RENDER_BLEND)
+     op = PIXMAN_OP_OVER;
+   pix_x = x0;
+   pix_y = y0;
+
+   if (dx < 0)
+     pix_x_unit = -1;
+   else
+     pix_x_unit = 1;
+
+   if (dy < 0)
+     pix_y_unit = -1;
+   else
+     pix_y_unit = 1;
+# endif
+#endif
+
+   if ( (dx == 0) || (dy == 0) || (dx == dy) || (dx == -dy) )
+     {
+       _evas_draw_simple_line(dst, dc, x0, y0, x1, y1);
+       return;
+     }
+
+   color = dc->col.col;
+   pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst, dc->render_op);
+   if (!pfunc) return;
+
+   clx = dc->clip.x;
+   cly = dc->clip.y;
+   clw = dc->clip.w;
+   clh = dc->clip.h;
+
+   data = dst->image.data;
+   dstw = dst->cache_entry.w;
+
+   data += (dstw * cly) + clx;
+   x0 -= clx;
+   y0 -= cly;
+   x1 -= clx;
+   y1 -= cly;
+
+   /* shallow: x-parametric */
+   if ((dy < dx) || (dy < -dx))
+     {
+       SETUP_LINE_SHALLOW;
+
+       while (px < rx)
+         {
+           y = (yy >> 16);
+           y += ((yy - (y << 16)) >> 15);
+           if (prev_y != y)
+             {
+               prev_y = y;
+               p += dh;
+               py += dely;
+#ifdef HAVE_PIXMAN
+# ifdef PIXMAN_LINE
+                 pix_y += pix_y_unit;
+# endif
+#endif
+             }
+           if (!p1_in)
+             {
+               if ((py < 0) && (dely < 0)) return;
+               if ((py > by) && (dely > 0)) return;
+             }
+            if (!p0_in)
+              {
+                 if (py < 0) goto next_x;
+              }
+            if (IN_RANGE(px, py, clw, clh))
+              {
+#ifdef HAVE_PIXMAN
+# ifdef PIXMAN_LINE
+                 if ((dst->pixman.im) && (dc->col.pixman_color_image))
+                   pixman_image_composite(op, dc->col.pixman_color_image,
+                                          NULL, dst->pixman.im,
+                                          pix_x, pix_y, 0, 0,
+                                          pix_x, pix_y, 1, 1);
+                 else
+# endif
+#endif
+                   pfunc(0, 255, color, p);
+              }
+
+next_x:
+            yy += dyy;
+            px++;
+            p++;
+#ifdef HAVE_PIXMAN
+# ifdef PIXMAN_LINE
+            pix_x += pix_x_unit;
+# endif
+#endif
+         }
+       return;
+     }
+
+   /* steep: y-parametric */
+
+   SETUP_LINE_STEEP;
+
+   while (py < by)
+     {
+       x = (xx >> 16);
+       x += ((xx - (x << 16)) >> 15);
+       if (prev_x != x)
+         {
+             prev_x = x;
+             px += delx;
+             p += delx;
+#ifdef HAVE_PIXMAN
+# ifdef PIXMAN_LINE
+             pix_x += pix_x_unit;
+# endif
+#endif
+         }
+       if (!p1_in)
+         {
+           if ((px < 0) && (delx < 0)) return;
+           if ((px > rx) && (delx > 0)) return;
+         }
+        if (!p0_in)
+          {
+             if (px < 0) goto next_y;
           }
         if (IN_RANGE(px, py, clw, clh))
           {
@@ -676,6 +1022,129 @@ 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)
+{
+   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;
+   DATA32  *p, *data;
+   RGBA_Gfx_Pt_Func pfunc;
+
+   dx = x1 - x0;
+   dy = y1 - y0;
+
+   if (y0 > y1)
+     EXCHANGE_POINTS(x0, y0, x1, y1);
+
+   dx = x1 - x0;
+   dy = y1 - y0;
+
+   if ((dx == 0) || (dy == 0) || (dx == dy) || (dx == -dy))
+     {
+       _draw_render_thread_simple_line
+          (dst, clip_x, clip_y, clip_w, clip_h,
+           color, render_op,
+           x0, y0, x1, y1);
+       return;
+     }
+
+   pfunc = evas_common_gfx_func_composite_mask_color_pt_get(color, dst, render_op);
+   if (!pfunc) return;
+
+   clx = clip_x;
+   cly = clip_y;
+   clw = clip_w;
+   clh = clip_h;
+
+   data = evas_cache_image_pixels(&dst->cache_entry);
+   dstw = dst->cache_entry.w;
+
+   data += (dstw * cly) + clx;
+   x0 -= clx;
+   y0 -= cly;
+   x1 -= clx;
+   y1 -= cly;
+
+   /* shallow: x-parametric */
+   if ((dy < dx) || (dy < -dx))
+     {
+       SETUP_LINE_SHALLOW;
+
+       while (px < rx)
+         {
+           DATA8   aa;
+
+           y = (yy >> 16);
+           if (prev_y != y)
+             {
+                 prev_y = y;
+                 p += dh;
+                 py += dely;
+             }
+           if (!p1_in)
+             {
+               if ((py < 0) && (dely < 0)) return;
+               if ((py > by) && (dely > 0)) return;
+             }
+            if (!p0_in)
+              {
+                 if (py < 0) goto next_x;
+              }
+           if (px < clw)
+             {
+                 aa = ((yy - (y << 16)) >> 8);
+
+                 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++;
+         }
+       return;
+     }
+
+   /* steep: y-parametric */
+   SETUP_LINE_STEEP;
+
+   while (py < by)
+     {
+       DATA8   aa;
+
+       x = (xx >> 16);
+       if (prev_x != x)
+         {
+             prev_x = x;
+             px += delx;
+             p += delx;
+         }
+       if (!p1_in)
+         {
+             if ((px < 0) && (delx < 0)) return;
+             if ((px > rx) && (delx > 0)) return;
+         }
+        if (!p0_in)
+          {
+             if (px < 0) goto next_y;
+          }
+       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);
+          }
+
+     next_y:
+       xx += dxx;
+       py++;
+       p += dstw;
+     }
+}
 
 static void
 _evas_draw_line_aa(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
@@ -935,3 +1404,72 @@ next_x:
 #endif
      }
 }
+
+EAPI void
+evas_common_line_draw_cb(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1, Evas_Common_Line_Draw_Cb cb)
+{
+   int  x, y, w, h;
+   int  clx, cly, clw, clh;
+   int  cuse, cx, cy, cw, ch;
+
+   /* No cutout ? FIXME ? */
+
+   if ((x0 == x1) && (y0 == y1))
+     {
+       _evas_draw_point(dst, dc, x0, y0);
+       return;
+     }
+
+   clx = cly = 0;
+   clw = dst->cache_entry.w;
+   clh = dst->cache_entry.h;
+
+   /* save out clip info */
+   cuse = dc->clip.use;
+   cx = dc->clip.x;
+   cy = dc->clip.y;
+   cw = dc->clip.w;
+   ch = dc->clip.h;
+
+   if (cuse)
+     {
+       RECTS_CLIP_TO_RECT(clx, cly, clw, clh, cx, cy, cw, ch);
+       if ((clw < 1) || (clh < 1))
+          return;
+     }
+
+   x = MIN(x0, x1);
+   y = MIN(y0, y1);
+   w = MAX(x0, x1) - x + 1;
+   h = MAX(y0, y1) - y + 1;
+
+   RECTS_CLIP_TO_RECT(clx, cly, clw, clh, x, y, w, h);
+   if ((clw < 1) || (clh < 1))
+       return;
+
+   dc->clip.use = 1;
+   dc->clip.x = clx;
+   dc->clip.y = cly;
+   dc->clip.w = clw;
+   dc->clip.h = clh;
+
+   cb(dst, dc, x0, y0, x1, y1);
+
+   /* restore clip info */
+   dc->clip.use = cuse;
+   dc->clip.x = cx;
+   dc->clip.y = cy;
+   dc->clip.w = cw;
+   dc->clip.h = ch;
+}
+
+EAPI void
+evas_common_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
+{
+   Evas_Common_Line_Draw_Cb cb;
+
+   if (dc->anti_alias) cb = _evas_draw_line_aa;
+   else cb = _evas_draw_line;
+
+   evas_common_line_draw_cb(dst, dc, x0, y0, x1, y1, cb);
+}
index 837257d..ca3ccfc 100644 (file)
@@ -631,7 +631,7 @@ evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst,
 #ifdef BUILD_MMX
 # undef FUNC_NAME
 # undef FUNC_NAME_DO
-# define FUNC_NAME evas_common_map_rgba_internal_mmx
+# define FUNC_NAME _evas_common_map_rgba_internal_mmx
 # define FUNC_NAME_DO evas_common_map_rgba_internal_mmx_do
 # undef SCALE_USING_MMX
 # define SCALE_USING_MMX