cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=2766ce57ce698850e50ebd8b92c4897fa739baf9

commit 2766ce57ce698850e50ebd8b92c4897fa739baf9
Author: Subhransu Mohanty <sub.moha...@samsung.com>
Date:   Mon Aug 17 15:18:26 2015 +0900

    ector: refactored software drawing backend to use composition function.
    
    Signed-off-by: Cedric BAIL <ced...@osg.samsung.com>
---
 src/Makefile_Ector.am                              |   5 +-
 src/lib/ector/software/ector_drawhelper.c          | 155 ++++++++
 src/lib/ector/software/ector_drawhelper_private.h  | 102 ++++++
 src/lib/ector/software/ector_software_rasterizer.c | 403 ++++++++++-----------
 4 files changed, 461 insertions(+), 204 deletions(-)

diff --git a/src/Makefile_Ector.am b/src/Makefile_Ector.am
index 6d99092..c05642f 100644
--- a/src/Makefile_Ector.am
+++ b/src/Makefile_Ector.am
@@ -95,7 +95,8 @@ lib/ector/software/ector_software_rasterizer.c \
 lib/ector/software/ector_software_surface.c \
 lib/ector/software/sw_ft_math.c \
 lib/ector/software/sw_ft_raster.c \
-lib/ector/software/sw_ft_stroker.c
+lib/ector/software/sw_ft_stroker.c \
+lib/ector/software/ector_drawhelper.c
 
 installed_ectorsoftwareheadersdir = $(includedir)/ector-@VMAJ@/software
 nodist_installed_ectorsoftwareheaders_DATA = $(ector_eolian_software_h)
@@ -147,7 +148,7 @@ endif
 EXTRA_DIST += \
 lib/ector/ector_private.h \
 lib/ector/cairo/ector_cairo_private.h \
-lib/ector/software/ector_blend_private.h \
+lib/ector/software/ector_drawhelper_private.h \
 lib/ector/software/ector_software_private.h \
 lib/ector/software/sw_ft_math.h \
 lib/ector/software/sw_ft_raster.h \
diff --git a/src/lib/ector/software/ector_drawhelper.c 
b/src/lib/ector/software/ector_drawhelper.c
new file mode 100644
index 0000000..40e7faa
--- /dev/null
+++ b/src/lib/ector/software/ector_drawhelper.c
@@ -0,0 +1,155 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <Ector.h>
+#include "ector_drawhelper_private.h"
+
+/*
+  s = source pixel
+  d = destination pixel
+  ca = const_alpha
+  sia = source inverse alpha
+  cia = const inverse alpha
+
+*/
+
+/*
+  result = s + d * sia  
+  dest = (s + d * sia) * ca + d * cia
+       = s * ca + d * (sia * ca + cia)
+       = s * ca + d * (1 - sa*ca)
+*/
+void
+comp_func_solid_source_over(uint *dest, int length, uint color, uint 
const_alpha)
+{
+   int ialpha, i;
+   if (const_alpha != 255)
+     color = BYTE_MUL(color, const_alpha);
+   ialpha = Alpha(~color);
+   for (i = 0; i < length; ++i)
+     dest[i] = color + BYTE_MUL(dest[i], ialpha);
+}
+
+
+static void
+comp_func_source_over(uint *dest, const uint *src, int length, uint color, 
uint const_alpha)
+{
+   int i;
+   uint s, sc, sia;
+   if (const_alpha != 255)
+     color = BYTE_MUL(color, const_alpha);
+
+   if (color == 0xffffffff) // No color multiplier
+     {
+        for (i = 0; i < length; ++i)
+          {
+             s = src[i];
+             if (s >= 0xff000000)
+               dest[i] = s;
+             else if (s != 0)
+               {
+                  sia = Alpha(~s);
+                  dest[i] = s + BYTE_MUL(dest[i], sia);
+               }
+          }
+     }
+   else
+     {
+        for (i = 0; i < length; ++i)
+          {
+             s = src[i];
+             sc = ECTOR_MUL4_SYM(color, s);
+             sia = Alpha(~sc);
+             dest[i] = sc + BYTE_MUL(dest[i], sia);
+          }
+     }
+}
+
+/*
+  result = s
+  dest = s * ca + d * cia
+*/
+static void
+comp_func_solid_source(uint *dest, int length, uint color, uint const_alpha)
+{
+   int ialpha, i;
+   if (const_alpha == 255) _ector_memfill(dest, length, color);
+   else
+     {
+        ialpha = 255 - const_alpha;
+        color = BYTE_MUL(color, const_alpha);
+        for (i = 0; i < length; ++i)
+          dest[i] = color + BYTE_MUL(dest[i], ialpha);
+     }
+}
+
+static void
+comp_func_source(uint *dest, const uint *src, int length, uint color, uint 
const_alpha)
+{
+   int i, ialpha;
+   uint src_color;
+   if (color == 0xffffffff) // No color multiplier
+     {
+        if (const_alpha == 255)
+          memcpy(dest, src, length * sizeof(uint));
+        else
+         {
+            ialpha = 255 - const_alpha;
+            for (i = 0; i < length; ++i)
+              dest[i] = INTERPOLATE_PIXEL_256(src[i], const_alpha, dest[i], 
ialpha);
+         }
+     }
+   else
+     {
+        if (const_alpha == 255)
+          {
+             for (i = 0; i < length; ++i)
+               dest[i] = ECTOR_MUL4_SYM(src[i], color);
+          }
+        else
+          {
+            ialpha = 255 - const_alpha;
+            for (i = 0; i < length; ++i)
+              {
+                 src_color = ECTOR_MUL4_SYM(src[i], color);
+                 dest[i] = INTERPOLATE_PIXEL_256(src_color, const_alpha, 
dest[i], ialpha);
+            }
+          }
+     }
+}
+
+RGBA_Comp_Func_Solid func_for_mode_solid[ECTOR_ROP_LAST] = {
+        comp_func_solid_source_over,
+        comp_func_solid_source
+};
+
+RGBA_Comp_Func func_for_mode[ECTOR_ROP_LAST] = {
+        comp_func_source_over,
+        comp_func_source
+};
+
+RGBA_Comp_Func_Solid
+ector_comp_func_solid_span_get(Ector_Rop op, uint color)
+{
+   if ((color & 0xff000000) == 0xff000000)
+     {
+        if (op == ECTOR_ROP_BLEND) op = ECTOR_ROP_COPY;
+     }
+
+   return func_for_mode_solid[op];
+}
+
+RGBA_Comp_Func ector_comp_func_span_get(Ector_Rop op, uint color, Eina_Bool 
src_alpha)
+{
+   if (((color & 0xff000000) == 0xff000000) && !src_alpha)
+     {
+        if (op == ECTOR_ROP_BLEND) op = ECTOR_ROP_COPY;
+     }
+   return func_for_mode[op];
+}
+
+void init_draw_helper()
+{
+
+}
diff --git a/src/lib/ector/software/ector_drawhelper_private.h 
b/src/lib/ector/software/ector_drawhelper_private.h
new file mode 100644
index 0000000..ea77760
--- /dev/null
+++ b/src/lib/ector/software/ector_drawhelper_private.h
@@ -0,0 +1,102 @@
+#ifndef ECTOR_DRAWHELPER_PRIVATE_H
+#define ECTOR_DRAWHELPER_PRIVATE_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef MIN
+#define MIN( a, b )  ( (a) < (b) ? (a) : (b) )
+#endif
+
+#ifndef MAX
+#define MAX( a, b )  ( (a) > (b) ? (a) : (b) )
+#endif
+
+#ifndef uint
+typedef unsigned int uint;
+#endif
+
+inline int Alpha(uint c)
+{
+   return c>>24;
+}
+
+
+
+#define ECTOR_ARGB_JOIN(a,r,g,b) \
+        (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
+
+#define ECTOR_MUL4_SYM(x, y) \
+ ( ((((((x) >> 16) & 0xff00) * (((y) >> 16) & 0xff00)) + 0xff0000) & 
0xff000000) + \
+   ((((((x) >> 8) & 0xff00) * (((y) >> 16) & 0xff)) + 0xff00) & 0xff0000) + \
+   ((((((x) & 0xff00) * ((y) & 0xff00)) + 0xff0000) >> 16) & 0xff00) + \
+   (((((x) & 0xff) * ((y) & 0xff)) + 0xff) >> 8) )
+
+#define BYTE_MUL(c, a) \
+ ( (((((c) >> 8) & 0x00ff00ff) * (a)) & 0xff00ff00) + \
+   (((((c) & 0x00ff00ff) * (a)) >> 8) & 0x00ff00ff) )
+
+#define LOOP_ALIGNED_U1_A4(DEST, LENGTH, UOP, A4OP) \
+   { \
+      while((uintptr_t)DEST & 0xF && LENGTH) UOP \
+   \
+      while(LENGTH) { \
+         switch(LENGTH) { \
+            case 3: \
+            case 2: \
+            case 1: \
+               UOP \
+               break; \
+            default: \
+               A4OP \
+               break; \
+         } \
+      } \
+   }
+
+static inline void
+_ector_memfill(uint *dest, int length, uint value)
+{
+   int n;
+   if (!length)
+     return;
+
+   n = (length + 7) / 8;
+   switch (length & 0x07)
+     {
+        case 0: do { *dest++ = value;
+        case 7:      *dest++ = value;
+        case 6:      *dest++ = value;
+        case 5:      *dest++ = value;
+        case 4:      *dest++ = value;
+        case 3:      *dest++ = value;
+        case 2:      *dest++ = value;
+        case 1:      *dest++ = value;
+        } while (--n > 0);
+     }
+}
+
+static inline uint 
+INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b)
+{
+   uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+   t >>= 8;
+   t &= 0xff00ff;
+   x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+   x &= 0xff00ff00;
+   x |= t;
+   return x;
+}
+
+typedef void (*RGBA_Comp_Func)(uint *dest, const uint *src, int length, uint 
mul_col, uint const_alpha);
+typedef void (*RGBA_Comp_Func_Solid)(uint *dest, int length, uint color, uint 
const_alpha);
+extern RGBA_Comp_Func_Solid func_for_mode_solid[ECTOR_ROP_LAST];
+extern RGBA_Comp_Func func_for_mode[ECTOR_ROP_LAST];
+
+void init_draw_helper();
+
+RGBA_Comp_Func_Solid ector_comp_func_solid_span_get(Ector_Rop op, uint color);
+RGBA_Comp_Func ector_comp_func_span_get(Ector_Rop op, uint color, Eina_Bool 
src_alpha);
+
+#endif
\ No newline at end of file
diff --git a/src/lib/ector/software/ector_software_rasterizer.c 
b/src/lib/ector/software/ector_software_rasterizer.c
index 5afb1ca..b436eed 100644
--- a/src/lib/ector/software/ector_software_rasterizer.c
+++ b/src/lib/ector/software/ector_software_rasterizer.c
@@ -8,49 +8,27 @@
 
 #include "ector_private.h"
 #include "ector_software_private.h"
-#include "ector_blend_private.h"
+
+#include "ector_drawhelper_private.h"
 
 static void
 _blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
 {
+   RGBA_Comp_Func_Solid comp_func;
    Span_Data *data = (Span_Data *)(user_data);
+   uint color, *buffer, *target;
 
    // multiply the color with mul_col if any
-   uint color = ECTOR_MUL4_SYM(data->color, data->mul_col);
-   Eina_Bool solid_source = ((color >> 24) == 255);
+   color = ECTOR_MUL4_SYM(data->color, data->mul_col);
+   comp_func = ector_comp_func_solid_span_get(data->op, color);
 
    // move to the offset location
-   uint *buffer = data->raster_buffer.buffer + (data->raster_buffer.width * 
data->offy + data->offx);
-
-   if (solid_source)
-     {
-        while (count--)
-          {
-             uint *target = buffer + (data->raster_buffer.width * spans->y + 
spans->x);
-             if (spans->coverage == 255)
-               {
-                  _ector_memfill(target, color, spans->len);
-               }
-             else
-               {
-                  uint c = ECTOR_MUL_256(color, spans->coverage);
-                  int ialpha = 255 - spans->coverage;
-                  for (int i = 0; i < spans->len; ++i)
-                    target[i] = c + ECTOR_MUL_256(target[i], ialpha);
-               }
-             ++spans;
-          }
-        return;
-     }
+   buffer = data->raster_buffer.buffer + ((data->raster_buffer.width * 
data->offy) + data->offx);
 
    while (count--)
      {
-        uint *target = buffer + (data->raster_buffer.width * spans->y + 
spans->x);
-        uint c =  ECTOR_MUL_256(color, spans->coverage);
-        int ialpha = (~c) >> 24;
-
-        for (int i = 0; i < spans->len; ++i)
-            target[i] = c + ECTOR_MUL_256(target[i], ialpha);
+        target = buffer + ((data->raster_buffer.width * spans->y) + spans->x);
+        comp_func(target, spans->len, color, spans->coverage);
         ++spans;
      }
 }
@@ -62,37 +40,35 @@ typedef void (*src_fetch) (unsigned int *buffer, Span_Data 
*data, int y, int x,
 static void
 _blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
 {
-    Span_Data *data = (Span_Data *)(user_data);
-    src_fetch fetchfunc = NULL;
-
-    if(data->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
-    if(data->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
-
-    unsigned int buffer[BLEND_GRADIENT_BUFFER_SIZE];
-
-    // move to the offset location
-    unsigned int *destbuffer = data->raster_buffer.buffer + 
(data->raster_buffer.width * data->offy + data->offx);
-
-    while (count--)
-      {
-         unsigned int *target = destbuffer + (data->raster_buffer.width * 
spans->y + spans->x);
-         int length = spans->len;
-         while (length)
-           {
-              int l = MIN(length, BLEND_GRADIENT_BUFFER_SIZE);
-              if (fetchfunc)
-                fetchfunc(buffer, data, spans->y, spans->x, l);
-              else
-                memset(buffer, 0, sizeof(buffer));
-              if (data->mul_col == 0xffffffff)
-                _ector_comp_func_source_over(target, buffer, l, 
spans->coverage); // TODO use proper composition func
-              else
-                _ector_comp_func_source_over_mul_c(target, buffer, 
data->mul_col, l, spans->coverage);
-              target += l;
-              length -= l;
-           }
-         ++spans;
-      }
+   RGBA_Comp_Func comp_func;
+   Span_Data *data = (Span_Data *)(user_data);
+   src_fetch fetchfunc = NULL;
+   unsigned int buffer[BLEND_GRADIENT_BUFFER_SIZE], *target, *destbuffer;
+   int length, l;
+
+   //@TODO, Get the proper composition function using ,color, ECTOR_OP etc.
+   if (data->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
+   if (data->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
+
+   comp_func = ector_comp_func_span_get(data->op, data->mul_col, 
data->gradient->alpha);
+
+   // move to the offset location
+   destbuffer = data->raster_buffer.buffer + ((data->raster_buffer.width * 
data->offy) + data->offx);
+
+   while (count--)
+     {
+        target = destbuffer + ((data->raster_buffer.width * spans->y) + 
spans->x);
+        length = spans->len;
+        while (length)
+          {
+             l = MIN(length, BLEND_GRADIENT_BUFFER_SIZE);
+             fetchfunc(buffer, data, spans->y, spans->x, l);
+             comp_func(target, buffer, l, data->mul_col, spans->coverage);
+             target += l;
+             length -= l;
+          }
+        ++spans;
+     }
 }
 
 
@@ -101,14 +77,18 @@ _blend_gradient(int count, const SW_FT_Span *spans, void 
*user_data)
     spans must be sorted on y
 */
 static const
-SW_FT_Span *_intersect_spans_rect(const Eina_Rectangle *clip, const SW_FT_Span 
*spans, const SW_FT_Span *end,
-                                  SW_FT_Span **out_spans, int available)
+SW_FT_Span *_intersect_spans_rect(const Eina_Rectangle *clip,
+                                  const SW_FT_Span *spans,
+                                  const SW_FT_Span *end,
+                                  SW_FT_Span **out_spans,
+                                  int available)
 {
    SW_FT_Span *out = *out_spans;
-   const short minx = clip->x;
-   const short miny = clip->y;
-   const short maxx = minx + clip->w - 1;
-   const short maxy = miny + clip->h - 1;
+   short minx, miny, maxx, maxy;
+   minx = clip->x;
+   miny = clip->y;
+   maxx = minx + clip->w - 1;
+   maxy = miny + clip->h - 1;
 
    while (available && spans < end )
      {
@@ -140,129 +120,144 @@ SW_FT_Span *_intersect_spans_rect(const Eina_Rectangle 
*clip, const SW_FT_Span *
              out->coverage = spans->coverage;
              ++out;
           }
-
         ++spans;
         --available;
-    }
-
-    *out_spans = out;
+     }
 
-    return spans;
+   *out_spans = out;
+   return spans;
 }
 
 static inline int
 _div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
 
 static const
-SW_FT_Span *_intersect_spans_region(const Shape_Rle_Data *clip, int 
*currentClip,
-                                       const SW_FT_Span *spans, const 
SW_FT_Span *end,
-                                       SW_FT_Span **out_spans, int available)
+SW_FT_Span *_intersect_spans_region(const Shape_Rle_Data *clip,
+                                    int *currentClip,
+                                    const SW_FT_Span *spans,
+                                    const SW_FT_Span *end,
+                                    SW_FT_Span **out_spans,
+                                    int available)
 {
-    SW_FT_Span *out = *out_spans;
-
-    const SW_FT_Span *clipSpans = clip->spans + *currentClip;
-    const SW_FT_Span *clipEnd = clip->spans + clip->size;
-
-    while (available && spans < end ) {
-        if (clipSpans >= clipEnd) {
-            spans = end;
-            break;
-        }
-        if (clipSpans->y > spans->y) {
-            ++spans;
-            continue;
-        }
-        if (spans->y != clipSpans->y) {
-            ++clipSpans;
-            continue;
-        }
+   SW_FT_Span *out = *out_spans;
+   int sx1, sx2, cx1, cx2, x, len;
+
+   const SW_FT_Span *clipSpans = clip->spans + *currentClip;
+   const SW_FT_Span *clipEnd = clip->spans + clip->size;
+
+   while (available && spans < end )
+     {
+        if (clipSpans >= clipEnd)
+          {
+             spans = end;
+             break;
+          }
+        if (clipSpans->y > spans->y)
+          {
+             ++spans;
+             continue;
+          }
+        if (spans->y != clipSpans->y)
+          {
+             ++clipSpans;
+             continue;
+          }
         //assert(spans->y == clipSpans->y);
+        sx1 = spans->x;
+        sx2 = sx1 + spans->len;
+        cx1 = clipSpans->x;
+        cx2 = cx1 + clipSpans->len;
 
-        int sx1 = spans->x;
-        int sx2 = sx1 + spans->len;
-        int cx1 = clipSpans->x;
-        int cx2 = cx1 + clipSpans->len;
-
-        if (cx1 < sx1 && cx2 < sx1) {
-            ++clipSpans;
-            continue;
-        } else if (sx1 < cx1 && sx2 < cx1) {
-            ++spans;
-            continue;
-        }
-        int x = MAX(sx1, cx1);
-        int len = MIN(sx2, cx2) - x;
-        if (len) {
-            out->x = MAX(sx1, cx1);
-            out->len = MIN(sx2, cx2) - out->x;
-            out->y = spans->y;
-            out->coverage = _div_255(spans->coverage * clipSpans->coverage);
-            ++out;
-            --available;
-        }
-        if (sx2 < cx2) {
-            ++spans;
-        } else {
-            ++clipSpans;
-        }
-    }
-
-    *out_spans = out;
-    *currentClip = clipSpans - clip->spans;
-    return spans;
+        if (cx1 < sx1 && cx2 < sx1)
+          {
+             ++clipSpans;
+             continue;
+          }
+        else if (sx1 < cx1 && sx2 < cx1)
+          {
+             ++spans;
+             continue;
+          }
+        x = MAX(sx1, cx1);
+        len = MIN(sx2, cx2) - x;
+        if (len)
+          {
+             out->x = MAX(sx1, cx1);
+             out->len = MIN(sx2, cx2) - out->x;
+             out->y = spans->y;
+             out->coverage = _div_255(spans->coverage * clipSpans->coverage);
+             ++out;
+             --available;
+          }
+        if (sx2 < cx2)
+          {
+             ++spans;
+          }
+        else
+          {
+             ++clipSpans;
+          }
+     }
+
+   *out_spans = out;
+   *currentClip = clipSpans - clip->spans;
+   return spans;
 }
 
 static void
 _span_fill_clipRect(int span_count, const SW_FT_Span *spans, void *user_data)
 {
-    const int NSPANS = 256;
-    int clip_count, i;
-    SW_FT_Span cspans[NSPANS];
-    Span_Data *fill_data = (Span_Data *) user_data;
-    Clip_Data clip = fill_data->clip;
-
-    clip_count = eina_array_count(clip.clips);
-    for (i = 0; i < clip_count ; i ++)
-      {
-        Eina_Rectangle *rect = (Eina_Rectangle 
*)eina_array_data_get(clip.clips, i);
-        Eina_Rectangle tmpRect;
+   const int NSPANS = 256;
+   int clip_count, i;
+   SW_FT_Span cspans[NSPANS];
+   Span_Data *fill_data = (Span_Data *) user_data;
+   Clip_Data clip = fill_data->clip;
+   SW_FT_Span *clipped;
+   Eina_Rectangle *rect;
+   Eina_Rectangle tmp_rect;
+
+
+   clip_count = eina_array_count(clip.clips);
+   for (i = 0; i < clip_count; i++)
+     {
+        rect = (Eina_Rectangle *)eina_array_data_get(clip.clips, i);
 
         // invert transform the offset
-        tmpRect.x = rect->x - fill_data->offx;
-        tmpRect.y = rect->y - fill_data->offy;
-        tmpRect.w = rect->w;
-        tmpRect.h = rect->h;
+        tmp_rect.x = rect->x - fill_data->offx;
+        tmp_rect.y = rect->y - fill_data->offy;
+        tmp_rect.w = rect->w;
+        tmp_rect.h = rect->h;
         const SW_FT_Span *end = spans + span_count;
 
         while (spans < end)
           {
-             SW_FT_Span *clipped = cspans;
-             spans = _intersect_spans_rect(&tmpRect,spans, end, &clipped, 
NSPANS);
+             clipped = cspans;
+             spans = _intersect_spans_rect(&tmp_rect, spans, end, &clipped, 
NSPANS);
              if (clipped - cspans)
                fill_data->unclipped_blend(clipped - cspans, cspans, fill_data);
           }
-      }
+     }
 }
 
 static void
 _span_fill_clipPath(int span_count, const SW_FT_Span *spans, void *user_data)
 {
-    const int NSPANS = 256;
-    int current_clip = 0;
-    SW_FT_Span cspans[NSPANS];
-    Span_Data *fill_data = (Span_Data *) user_data;
-    Clip_Data clip = fill_data->clip;
-
-    //TODO take clip path offset into account.
-    
-    const SW_FT_Span *end = spans + span_count;
-    while (spans < end)
-      {
-         SW_FT_Span *clipped = cspans;
-         spans = _intersect_spans_region(clip.path, &current_clip, spans, end, 
&clipped, NSPANS);
-         if (clipped - cspans)
-           fill_data->unclipped_blend(clipped - cspans, cspans, fill_data);
-      }
+   const int NSPANS = 256;
+   int current_clip = 0;
+   SW_FT_Span cspans[NSPANS];
+   Span_Data *fill_data = (Span_Data *) user_data;
+   Clip_Data clip = fill_data->clip;
+   SW_FT_Span *clipped;
+
+   //TODO take clip path offset into account.
+   const SW_FT_Span *end = spans + span_count;
+   while (spans < end)
+     {
+        clipped = cspans;
+        spans = _intersect_spans_region(clip.path, &current_clip, spans, end, 
&clipped, NSPANS);
+        if (clipped - cspans)
+          fill_data->unclipped_blend(clipped - cspans, cspans, fill_data);
+     }
 }
 
 static void
@@ -270,19 +265,19 @@ _adjust_span_fill_methods(Span_Data *spdata)
 {
    switch(spdata->type)
      {
-      case None:
-         spdata->unclipped_blend = 0;
-         break;
-      case Solid:
-         spdata->unclipped_blend = &_blend_color_argb;
-         break;
-      case LinearGradient:
-      case RadialGradient:
-         spdata->unclipped_blend = &_blend_gradient;
-         break;
-      case Image:
-         spdata->unclipped_blend = 0;//&_blend_image;
-         break;
+        case None:
+          spdata->unclipped_blend = 0;
+          break;
+        case Solid:
+          spdata->unclipped_blend = &_blend_color_argb;
+          break;
+        case LinearGradient:
+        case RadialGradient:
+          spdata->unclipped_blend = &_blend_gradient;
+          break;
+        case Image:
+          spdata->unclipped_blend = 0;//&_blend_image;
+          break;
      }
 
    // setup clipping
@@ -317,6 +312,7 @@ void ector_software_rasterizer_init(Software_Rasterizer 
*rasterizer)
    rasterizer->fill_data.clip.enabled = EINA_FALSE;
    rasterizer->fill_data.unclipped_blend = 0;
    rasterizer->fill_data.blend = 0;
+   init_draw_helper();
 }
 
 void ector_software_rasterizer_done(Software_Rasterizer *rasterizer)
@@ -325,40 +321,38 @@ void ector_software_rasterizer_done(Software_Rasterizer 
*rasterizer)
    SW_FT_Stroker_Done(rasterizer->stroker);
 }
 
-
 void ector_software_rasterizer_stroke_set(Software_Rasterizer *rasterizer, 
double width,
                                           Efl_Gfx_Cap cap_style, Efl_Gfx_Join 
join_style)
 {
    SW_FT_Stroker_LineCap cap;
    SW_FT_Stroker_LineJoin join;
+   int stroke_width = (int)(width * 64);
 
    switch (cap_style)
      {
-      case EFL_GFX_CAP_SQUARE:
-         cap = SW_FT_STROKER_LINECAP_SQUARE;
-         break;
-      case EFL_GFX_CAP_ROUND:
-         cap = SW_FT_STROKER_LINECAP_ROUND;
-         break;
-      default:
-         cap = SW_FT_STROKER_LINECAP_BUTT;
-         break;
+        case EFL_GFX_CAP_SQUARE:
+          cap = SW_FT_STROKER_LINECAP_SQUARE;
+          break;
+        case EFL_GFX_CAP_ROUND:
+          cap = SW_FT_STROKER_LINECAP_ROUND;
+          break;
+        default:
+          cap = SW_FT_STROKER_LINECAP_BUTT;
+          break;
      }
 
    switch (join_style)
      {
-      case EFL_GFX_JOIN_BEVEL:
-         join = SW_FT_STROKER_LINEJOIN_BEVEL;
-         break;
-      case EFL_GFX_JOIN_ROUND:
-         join = SW_FT_STROKER_LINEJOIN_ROUND;
-         break;
-      default:
-         join = SW_FT_STROKER_LINEJOIN_MITER;
-         break;
+        case EFL_GFX_JOIN_BEVEL:
+          join = SW_FT_STROKER_LINEJOIN_BEVEL;
+          break;
+        case EFL_GFX_JOIN_ROUND:
+          join = SW_FT_STROKER_LINEJOIN_ROUND;
+          break;
+        default:
+          join = SW_FT_STROKER_LINEJOIN_MITER;
+          break;
      }
-
-   int stroke_width = (int)(width * 64);
    SW_FT_Stroker_Set(rasterizer->stroker, stroke_width, cap, join, 0);
 }
 
@@ -371,7 +365,7 @@ _rle_generation_cb( int count, const SW_FT_Span*  
spans,void *user)
    // allocate enough memory for new spans
    // alloc is required to prevent free and reallocation
    // when the rle needs to be regenerated because of attribute change.
-   if(rle->alloc < newsize)
+   if (rle->alloc < newsize)
      {
         rle->spans = (SW_FT_Span *) realloc(rle->spans, newsize * 
sizeof(SW_FT_Span));
         rle->alloc = newsize;
@@ -425,18 +419,19 @@ Shape_Rle_Data *
 ector_software_rasterizer_generate_stroke_rle_data(Software_Rasterizer 
*rasterizer, SW_FT_Outline *outline, Eina_Bool closePath)
 {
    uint points,contors;
+   Shape_Rle_Data *rle_data;
+   SW_FT_Outline strokeOutline = { 0, 0, NULL, NULL, NULL, 0 };
 
    SW_FT_Stroker_ParseOutline(rasterizer->stroker, outline, !closePath);
    SW_FT_Stroker_GetCounts(rasterizer->stroker,&points, &contors);
 
-   SW_FT_Outline strokeOutline = { 0, 0, NULL, NULL, NULL, 0 };
    strokeOutline.points = (SW_FT_Vector *) calloc(points, 
sizeof(SW_FT_Vector));
    strokeOutline.tags = (char *) calloc(points, sizeof(char));
    strokeOutline.contours = (short *) calloc(contors, sizeof(short));
 
    SW_FT_Stroker_Export(rasterizer->stroker, &strokeOutline);
 
-   Shape_Rle_Data *rle_data = 
ector_software_rasterizer_generate_rle_data(rasterizer, &strokeOutline);
+   rle_data = ector_software_rasterizer_generate_rle_data(rasterizer, 
&strokeOutline);
 
    // cleanup the outline data.
    free(strokeOutline.points);
@@ -503,20 +498,24 @@ void 
ector_software_rasterizer_color_set(Software_Rasterizer *rasterizer, int r,
    rasterizer->fill_data.color = ECTOR_ARGB_JOIN(a, r, g, b);
    rasterizer->fill_data.type = Solid;
 }
-void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer 
*rasterizer, Ector_Renderer_Software_Gradient_Data *linear)
+
+void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer 
*rasterizer,
+                                                   
Ector_Renderer_Software_Gradient_Data *linear)
 {
    rasterizer->fill_data.gradient = linear;
    rasterizer->fill_data.type = LinearGradient;
 }
-void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer 
*rasterizer, Ector_Renderer_Software_Gradient_Data *radial)
+
+void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer 
*rasterizer,
+                                                   
Ector_Renderer_Software_Gradient_Data *radial)
 {
    rasterizer->fill_data.gradient = radial;
    rasterizer->fill_data.type = RadialGradient;
 }
 
-
 void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
-                                             int x, int y, uint mul_col, 
Ector_Rop op, Shape_Rle_Data* rle)
+                                             int x, int y, uint mul_col,
+                                             Ector_Rop op, Shape_Rle_Data* rle)
 {
    // check for NULL rle data
    if (!rle) return;
@@ -529,6 +528,6 @@ void 
ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
    _setup_span_fill_matrix(rasterizer);
    _adjust_span_fill_methods(&rasterizer->fill_data);
 
-   if(rasterizer->fill_data.blend)
+   if (rasterizer->fill_data.blend)
      rasterizer->fill_data.blend(rle->size, rle->spans, 
&rasterizer->fill_data);
 }

-- 


Reply via email to