summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubhransu Mohanty <sub.mohanty@samsung.com>2015-08-17 15:18:26 +0900
committerCedric BAIL <cedric@osg.samsung.com>2015-08-19 15:07:36 +0200
commit2766ce57ce698850e50ebd8b92c4897fa739baf9 (patch)
tree47bbbf907e2ba49f22fd9efae0174ee919cacd06
parent48b558a997e5bfe321b401110daa449dc173bbd6 (diff)
ector: refactored software drawing backend to use composition function.
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
-rw-r--r--src/Makefile_Ector.am5
-rw-r--r--src/lib/ector/software/ector_drawhelper.c155
-rw-r--r--src/lib/ector/software/ector_drawhelper_private.h102
-rw-r--r--src/lib/ector/software/ector_software_rasterizer.c403
4 files changed, 461 insertions, 204 deletions
diff --git a/src/Makefile_Ector.am b/src/Makefile_Ector.am
index 6d99092ffc..c05642f696 100644
--- a/src/Makefile_Ector.am
+++ b/src/Makefile_Ector.am
@@ -95,7 +95,8 @@ lib/ector/software/ector_software_rasterizer.c \
95lib/ector/software/ector_software_surface.c \ 95lib/ector/software/ector_software_surface.c \
96lib/ector/software/sw_ft_math.c \ 96lib/ector/software/sw_ft_math.c \
97lib/ector/software/sw_ft_raster.c \ 97lib/ector/software/sw_ft_raster.c \
98lib/ector/software/sw_ft_stroker.c 98lib/ector/software/sw_ft_stroker.c \
99lib/ector/software/ector_drawhelper.c
99 100
100installed_ectorsoftwareheadersdir = $(includedir)/ector-@VMAJ@/software 101installed_ectorsoftwareheadersdir = $(includedir)/ector-@VMAJ@/software
101nodist_installed_ectorsoftwareheaders_DATA = $(ector_eolian_software_h) 102nodist_installed_ectorsoftwareheaders_DATA = $(ector_eolian_software_h)
@@ -147,7 +148,7 @@ endif
147EXTRA_DIST += \ 148EXTRA_DIST += \
148lib/ector/ector_private.h \ 149lib/ector/ector_private.h \
149lib/ector/cairo/ector_cairo_private.h \ 150lib/ector/cairo/ector_cairo_private.h \
150lib/ector/software/ector_blend_private.h \ 151lib/ector/software/ector_drawhelper_private.h \
151lib/ector/software/ector_software_private.h \ 152lib/ector/software/ector_software_private.h \
152lib/ector/software/sw_ft_math.h \ 153lib/ector/software/sw_ft_math.h \
153lib/ector/software/sw_ft_raster.h \ 154lib/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 0000000000..40e7faaaae
--- /dev/null
+++ b/src/lib/ector/software/ector_drawhelper.c
@@ -0,0 +1,155 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <Ector.h>
6#include "ector_drawhelper_private.h"
7
8/*
9 s = source pixel
10 d = destination pixel
11 ca = const_alpha
12 sia = source inverse alpha
13 cia = const inverse alpha
14
15*/
16
17/*
18 result = s + d * sia
19 dest = (s + d * sia) * ca + d * cia
20 = s * ca + d * (sia * ca + cia)
21 = s * ca + d * (1 - sa*ca)
22*/
23void
24comp_func_solid_source_over(uint *dest, int length, uint color, uint const_alpha)
25{
26 int ialpha, i;
27 if (const_alpha != 255)
28 color = BYTE_MUL(color, const_alpha);
29 ialpha = Alpha(~color);
30 for (i = 0; i < length; ++i)
31 dest[i] = color + BYTE_MUL(dest[i], ialpha);
32}
33
34
35static void
36comp_func_source_over(uint *dest, const uint *src, int length, uint color, uint const_alpha)
37{
38 int i;
39 uint s, sc, sia;
40 if (const_alpha != 255)
41 color = BYTE_MUL(color, const_alpha);
42
43 if (color == 0xffffffff) // No color multiplier
44 {
45 for (i = 0; i < length; ++i)
46 {
47 s = src[i];
48 if (s >= 0xff000000)
49 dest[i] = s;
50 else if (s != 0)
51 {
52 sia = Alpha(~s);
53 dest[i] = s + BYTE_MUL(dest[i], sia);
54 }
55 }
56 }
57 else
58 {
59 for (i = 0; i < length; ++i)
60 {
61 s = src[i];
62 sc = ECTOR_MUL4_SYM(color, s);
63 sia = Alpha(~sc);
64 dest[i] = sc + BYTE_MUL(dest[i], sia);
65 }
66 }
67}
68
69/*
70 result = s
71 dest = s * ca + d * cia
72*/
73static void
74comp_func_solid_source(uint *dest, int length, uint color, uint const_alpha)
75{
76 int ialpha, i;
77 if (const_alpha == 255) _ector_memfill(dest, length, color);
78 else
79 {
80 ialpha = 255 - const_alpha;
81 color = BYTE_MUL(color, const_alpha);
82 for (i = 0; i < length; ++i)
83 dest[i] = color + BYTE_MUL(dest[i], ialpha);
84 }
85}
86
87static void
88comp_func_source(uint *dest, const uint *src, int length, uint color, uint const_alpha)
89{
90 int i, ialpha;
91 uint src_color;
92 if (color == 0xffffffff) // No color multiplier
93 {
94 if (const_alpha == 255)
95 memcpy(dest, src, length * sizeof(uint));
96 else
97 {
98 ialpha = 255 - const_alpha;
99 for (i = 0; i < length; ++i)
100 dest[i] = INTERPOLATE_PIXEL_256(src[i], const_alpha, dest[i], ialpha);
101 }
102 }
103 else
104 {
105 if (const_alpha == 255)
106 {
107 for (i = 0; i < length; ++i)
108 dest[i] = ECTOR_MUL4_SYM(src[i], color);
109 }
110 else
111 {
112 ialpha = 255 - const_alpha;
113 for (i = 0; i < length; ++i)
114 {
115 src_color = ECTOR_MUL4_SYM(src[i], color);
116 dest[i] = INTERPOLATE_PIXEL_256(src_color, const_alpha, dest[i], ialpha);
117 }
118 }
119 }
120}
121
122RGBA_Comp_Func_Solid func_for_mode_solid[ECTOR_ROP_LAST] = {
123 comp_func_solid_source_over,
124 comp_func_solid_source
125};
126
127RGBA_Comp_Func func_for_mode[ECTOR_ROP_LAST] = {
128 comp_func_source_over,
129 comp_func_source
130};
131
132RGBA_Comp_Func_Solid
133ector_comp_func_solid_span_get(Ector_Rop op, uint color)
134{
135 if ((color & 0xff000000) == 0xff000000)
136 {
137 if (op == ECTOR_ROP_BLEND) op = ECTOR_ROP_COPY;
138 }
139
140 return func_for_mode_solid[op];
141}
142
143RGBA_Comp_Func ector_comp_func_span_get(Ector_Rop op, uint color, Eina_Bool src_alpha)
144{
145 if (((color & 0xff000000) == 0xff000000) && !src_alpha)
146 {
147 if (op == ECTOR_ROP_BLEND) op = ECTOR_ROP_COPY;
148 }
149 return func_for_mode[op];
150}
151
152void init_draw_helper()
153{
154
155}
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 0000000000..ea7776001a
--- /dev/null
+++ b/src/lib/ector/software/ector_drawhelper_private.h
@@ -0,0 +1,102 @@
1#ifndef ECTOR_DRAWHELPER_PRIVATE_H
2#define ECTOR_DRAWHELPER_PRIVATE_H
3
4#ifdef HAVE_CONFIG_H
5# include <config.h>
6#endif
7
8#ifndef MIN
9#define MIN( a, b ) ( (a) < (b) ? (a) : (b) )
10#endif
11
12#ifndef MAX
13#define MAX( a, b ) ( (a) > (b) ? (a) : (b) )
14#endif
15
16#ifndef uint
17typedef unsigned int uint;
18#endif
19
20inline int Alpha(uint c)
21{
22 return c>>24;
23}
24
25
26
27#define ECTOR_ARGB_JOIN(a,r,g,b) \
28 (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
29
30#define ECTOR_MUL4_SYM(x, y) \
31 ( ((((((x) >> 16) & 0xff00) * (((y) >> 16) & 0xff00)) + 0xff0000) & 0xff000000) + \
32 ((((((x) >> 8) & 0xff00) * (((y) >> 16) & 0xff)) + 0xff00) & 0xff0000) + \
33 ((((((x) & 0xff00) * ((y) & 0xff00)) + 0xff0000) >> 16) & 0xff00) + \
34 (((((x) & 0xff) * ((y) & 0xff)) + 0xff) >> 8) )
35
36#define BYTE_MUL(c, a) \
37 ( (((((c) >> 8) & 0x00ff00ff) * (a)) & 0xff00ff00) + \
38 (((((c) & 0x00ff00ff) * (a)) >> 8) & 0x00ff00ff) )
39
40#define LOOP_ALIGNED_U1_A4(DEST, LENGTH, UOP, A4OP) \
41 { \
42 while((uintptr_t)DEST & 0xF && LENGTH) UOP \
43 \
44 while(LENGTH) { \
45 switch(LENGTH) { \
46 case 3: \
47 case 2: \
48 case 1: \
49 UOP \
50 break; \
51 default: \
52 A4OP \
53 break; \
54 } \
55 } \
56 }
57
58static inline void
59_ector_memfill(uint *dest, int length, uint value)
60{
61 int n;
62 if (!length)
63 return;
64
65 n = (length + 7) / 8;
66 switch (length & 0x07)
67 {
68 case 0: do { *dest++ = value;
69 case 7: *dest++ = value;
70 case 6: *dest++ = value;
71 case 5: *dest++ = value;
72 case 4: *dest++ = value;
73 case 3: *dest++ = value;
74 case 2: *dest++ = value;
75 case 1: *dest++ = value;
76 } while (--n > 0);
77 }
78}
79
80static inline uint
81INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b)
82{
83 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
84 t >>= 8;
85 t &= 0xff00ff;
86 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
87 x &= 0xff00ff00;
88 x |= t;
89 return x;
90}
91
92typedef void (*RGBA_Comp_Func)(uint *dest, const uint *src, int length, uint mul_col, uint const_alpha);
93typedef void (*RGBA_Comp_Func_Solid)(uint *dest, int length, uint color, uint const_alpha);
94extern RGBA_Comp_Func_Solid func_for_mode_solid[ECTOR_ROP_LAST];
95extern RGBA_Comp_Func func_for_mode[ECTOR_ROP_LAST];
96
97void init_draw_helper();
98
99RGBA_Comp_Func_Solid ector_comp_func_solid_span_get(Ector_Rop op, uint color);
100RGBA_Comp_Func ector_comp_func_span_get(Ector_Rop op, uint color, Eina_Bool src_alpha);
101
102#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 5afb1caf27..b436eed9df 100644
--- a/src/lib/ector/software/ector_software_rasterizer.c
+++ b/src/lib/ector/software/ector_software_rasterizer.c
@@ -8,49 +8,27 @@
8 8
9#include "ector_private.h" 9#include "ector_private.h"
10#include "ector_software_private.h" 10#include "ector_software_private.h"
11#include "ector_blend_private.h" 11
12#include "ector_drawhelper_private.h"
12 13
13static void 14static void
14_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data) 15_blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
15{ 16{
17 RGBA_Comp_Func_Solid comp_func;
16 Span_Data *data = (Span_Data *)(user_data); 18 Span_Data *data = (Span_Data *)(user_data);
19 uint color, *buffer, *target;
17 20
18 // multiply the color with mul_col if any 21 // multiply the color with mul_col if any
19 uint color = ECTOR_MUL4_SYM(data->color, data->mul_col); 22 color = ECTOR_MUL4_SYM(data->color, data->mul_col);
20 Eina_Bool solid_source = ((color >> 24) == 255); 23 comp_func = ector_comp_func_solid_span_get(data->op, color);
21 24
22 // move to the offset location 25 // move to the offset location
23 uint *buffer = data->raster_buffer.buffer + (data->raster_buffer.width * data->offy + data->offx); 26 buffer = data->raster_buffer.buffer + ((data->raster_buffer.width * data->offy) + data->offx);
24
25 if (solid_source)
26 {
27 while (count--)
28 {
29 uint *target = buffer + (data->raster_buffer.width * spans->y + spans->x);
30 if (spans->coverage == 255)
31 {
32 _ector_memfill(target, color, spans->len);
33 }
34 else
35 {
36 uint c = ECTOR_MUL_256(color, spans->coverage);
37 int ialpha = 255 - spans->coverage;
38 for (int i = 0; i < spans->len; ++i)
39 target[i] = c + ECTOR_MUL_256(target[i], ialpha);
40 }
41 ++spans;
42 }
43 return;
44 }
45 27
46 while (count--) 28 while (count--)
47 { 29 {
48 uint *target = buffer + (data->raster_buffer.width * spans->y + spans->x); 30 target = buffer + ((data->raster_buffer.width * spans->y) + spans->x);
49 uint c = ECTOR_MUL_256(color, spans->coverage); 31 comp_func(target, spans->len, color, spans->coverage);
50 int ialpha = (~c) >> 24;
51
52 for (int i = 0; i < spans->len; ++i)
53 target[i] = c + ECTOR_MUL_256(target[i], ialpha);
54 ++spans; 32 ++spans;
55 } 33 }
56} 34}
@@ -62,37 +40,35 @@ typedef void (*src_fetch) (unsigned int *buffer, Span_Data *data, int y, int x,
62static void 40static void
63_blend_gradient(int count, const SW_FT_Span *spans, void *user_data) 41_blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
64{ 42{
65 Span_Data *data = (Span_Data *)(user_data); 43 RGBA_Comp_Func comp_func;
66 src_fetch fetchfunc = NULL; 44 Span_Data *data = (Span_Data *)(user_data);
67 45 src_fetch fetchfunc = NULL;
68 if(data->type == LinearGradient) fetchfunc = &fetch_linear_gradient; 46 unsigned int buffer[BLEND_GRADIENT_BUFFER_SIZE], *target, *destbuffer;
69 if(data->type == RadialGradient) fetchfunc = &fetch_radial_gradient; 47 int length, l;
70 48
71 unsigned int buffer[BLEND_GRADIENT_BUFFER_SIZE]; 49 //@TODO, Get the proper composition function using ,color, ECTOR_OP etc.
72 50 if (data->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
73 // move to the offset location 51 if (data->type == RadialGradient) fetchfunc = &fetch_radial_gradient;
74 unsigned int *destbuffer = data->raster_buffer.buffer + (data->raster_buffer.width * data->offy + data->offx); 52
75 53 comp_func = ector_comp_func_span_get(data->op, data->mul_col, data->gradient->alpha);
76 while (count--) 54
77 { 55 // move to the offset location
78 unsigned int *target = destbuffer + (data->raster_buffer.width * spans->y + spans->x); 56 destbuffer = data->raster_buffer.buffer + ((data->raster_buffer.width * data->offy) + data->offx);
79 int length = spans->len; 57
80 while (length) 58 while (count--)
81 { 59 {
82 int l = MIN(length, BLEND_GRADIENT_BUFFER_SIZE); 60 target = destbuffer + ((data->raster_buffer.width * spans->y) + spans->x);
83 if (fetchfunc) 61 length = spans->len;
84 fetchfunc(buffer, data, spans->y, spans->x, l); 62 while (length)
85 else 63 {
86 memset(buffer, 0, sizeof(buffer)); 64 l = MIN(length, BLEND_GRADIENT_BUFFER_SIZE);
87 if (data->mul_col == 0xffffffff) 65 fetchfunc(buffer, data, spans->y, spans->x, l);
88 _ector_comp_func_source_over(target, buffer, l, spans->coverage); // TODO use proper composition func 66 comp_func(target, buffer, l, data->mul_col, spans->coverage);
89 else 67 target += l;
90 _ector_comp_func_source_over_mul_c(target, buffer, data->mul_col, l, spans->coverage); 68 length -= l;
91 target += l; 69 }
92 length -= l; 70 ++spans;
93 } 71 }
94 ++spans;
95 }
96} 72}
97 73
98 74
@@ -101,14 +77,18 @@ _blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
101 spans must be sorted on y 77 spans must be sorted on y
102*/ 78*/
103static const 79static const
104SW_FT_Span *_intersect_spans_rect(const Eina_Rectangle *clip, const SW_FT_Span *spans, const SW_FT_Span *end, 80SW_FT_Span *_intersect_spans_rect(const Eina_Rectangle *clip,
105 SW_FT_Span **out_spans, int available) 81 const SW_FT_Span *spans,
82 const SW_FT_Span *end,
83 SW_FT_Span **out_spans,
84 int available)
106{ 85{
107 SW_FT_Span *out = *out_spans; 86 SW_FT_Span *out = *out_spans;
108 const short minx = clip->x; 87 short minx, miny, maxx, maxy;
109 const short miny = clip->y; 88 minx = clip->x;
110 const short maxx = minx + clip->w - 1; 89 miny = clip->y;
111 const short maxy = miny + clip->h - 1; 90 maxx = minx + clip->w - 1;
91 maxy = miny + clip->h - 1;
112 92
113 while (available && spans < end ) 93 while (available && spans < end )
114 { 94 {
@@ -140,129 +120,144 @@ SW_FT_Span *_intersect_spans_rect(const Eina_Rectangle *clip, const SW_FT_Span *
140 out->coverage = spans->coverage; 120 out->coverage = spans->coverage;
141 ++out; 121 ++out;
142 } 122 }
143
144 ++spans; 123 ++spans;
145 --available; 124 --available;
146 } 125 }
147
148 *out_spans = out;
149 126
150 return spans; 127 *out_spans = out;
128 return spans;
151} 129}
152 130
153static inline int 131static inline int
154_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; } 132_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
155 133
156static const 134static const
157SW_FT_Span *_intersect_spans_region(const Shape_Rle_Data *clip, int *currentClip, 135SW_FT_Span *_intersect_spans_region(const Shape_Rle_Data *clip,
158 const SW_FT_Span *spans, const SW_FT_Span *end, 136 int *currentClip,
159 SW_FT_Span **out_spans, int available) 137 const SW_FT_Span *spans,
138 const SW_FT_Span *end,
139 SW_FT_Span **out_spans,
140 int available)
160{ 141{
161 SW_FT_Span *out = *out_spans; 142 SW_FT_Span *out = *out_spans;
162 143 int sx1, sx2, cx1, cx2, x, len;
163 const SW_FT_Span *clipSpans = clip->spans + *currentClip; 144
164 const SW_FT_Span *clipEnd = clip->spans + clip->size; 145 const SW_FT_Span *clipSpans = clip->spans + *currentClip;
165 146 const SW_FT_Span *clipEnd = clip->spans + clip->size;
166 while (available && spans < end ) { 147
167 if (clipSpans >= clipEnd) { 148 while (available && spans < end )
168 spans = end; 149 {
169 break; 150 if (clipSpans >= clipEnd)
170 } 151 {
171 if (clipSpans->y > spans->y) { 152 spans = end;
172 ++spans; 153 break;
173 continue; 154 }
174 } 155 if (clipSpans->y > spans->y)
175 if (spans->y != clipSpans->y) { 156 {
176 ++clipSpans; 157 ++spans;
177 continue; 158 continue;
178 } 159 }
160 if (spans->y != clipSpans->y)
161 {
162 ++clipSpans;
163 continue;
164 }
179 //assert(spans->y == clipSpans->y); 165 //assert(spans->y == clipSpans->y);
166 sx1 = spans->x;
167 sx2 = sx1 + spans->len;
168 cx1 = clipSpans->x;
169 cx2 = cx1 + clipSpans->len;
180 170
181 int sx1 = spans->x; 171 if (cx1 < sx1 && cx2 < sx1)
182 int sx2 = sx1 + spans->len; 172 {
183 int cx1 = clipSpans->x; 173 ++clipSpans;
184 int cx2 = cx1 + clipSpans->len; 174 continue;
185 175 }
186 if (cx1 < sx1 && cx2 < sx1) { 176 else if (sx1 < cx1 && sx2 < cx1)
187 ++clipSpans; 177 {
188 continue; 178 ++spans;
189 } else if (sx1 < cx1 && sx2 < cx1) { 179 continue;
190 ++spans; 180 }
191 continue; 181 x = MAX(sx1, cx1);
192 } 182 len = MIN(sx2, cx2) - x;
193 int x = MAX(sx1, cx1); 183 if (len)
194 int len = MIN(sx2, cx2) - x; 184 {
195 if (len) { 185 out->x = MAX(sx1, cx1);
196 out->x = MAX(sx1, cx1); 186 out->len = MIN(sx2, cx2) - out->x;
197 out->len = MIN(sx2, cx2) - out->x; 187 out->y = spans->y;
198 out->y = spans->y; 188 out->coverage = _div_255(spans->coverage * clipSpans->coverage);
199 out->coverage = _div_255(spans->coverage * clipSpans->coverage); 189 ++out;
200 ++out; 190 --available;
201 --available; 191 }
202 } 192 if (sx2 < cx2)
203 if (sx2 < cx2) { 193 {
204 ++spans; 194 ++spans;
205 } else { 195 }
206 ++clipSpans; 196 else
207 } 197 {
208 } 198 ++clipSpans;
209 199 }
210 *out_spans = out; 200 }
211 *currentClip = clipSpans - clip->spans; 201
212 return spans; 202 *out_spans = out;
203 *currentClip = clipSpans - clip->spans;
204 return spans;
213} 205}
214 206
215static void 207static void
216_span_fill_clipRect(int span_count, const SW_FT_Span *spans, void *user_data) 208_span_fill_clipRect(int span_count, const SW_FT_Span *spans, void *user_data)
217{ 209{
218 const int NSPANS = 256; 210 const int NSPANS = 256;
219 int clip_count, i; 211 int clip_count, i;
220 SW_FT_Span cspans[NSPANS]; 212 SW_FT_Span cspans[NSPANS];
221 Span_Data *fill_data = (Span_Data *) user_data; 213 Span_Data *fill_data = (Span_Data *) user_data;
222 Clip_Data clip = fill_data->clip; 214 Clip_Data clip = fill_data->clip;
223 215 SW_FT_Span *clipped;
224 clip_count = eina_array_count(clip.clips); 216 Eina_Rectangle *rect;
225 for (i = 0; i < clip_count ; i ++) 217 Eina_Rectangle tmp_rect;
226 { 218
227 Eina_Rectangle *rect = (Eina_Rectangle *)eina_array_data_get(clip.clips, i); 219
228 Eina_Rectangle tmpRect; 220 clip_count = eina_array_count(clip.clips);
221 for (i = 0; i < clip_count; i++)
222 {
223 rect = (Eina_Rectangle *)eina_array_data_get(clip.clips, i);
229 224
230 // invert transform the offset 225 // invert transform the offset
231 tmpRect.x = rect->x - fill_data->offx; 226 tmp_rect.x = rect->x - fill_data->offx;
232 tmpRect.y = rect->y - fill_data->offy; 227 tmp_rect.y = rect->y - fill_data->offy;
233 tmpRect.w = rect->w; 228 tmp_rect.w = rect->w;
234 tmpRect.h = rect->h; 229 tmp_rect.h = rect->h;
235 const SW_FT_Span *end = spans + span_count; 230 const SW_FT_Span *end = spans + span_count;
236 231
237 while (spans < end) 232 while (spans < end)
238 { 233 {
239 SW_FT_Span *clipped = cspans; 234 clipped = cspans;
240 spans = _intersect_spans_rect(&tmpRect,spans, end, &clipped, NSPANS); 235 spans = _intersect_spans_rect(&tmp_rect, spans, end, &clipped, NSPANS);
241 if (clipped - cspans) 236 if (clipped - cspans)
242 fill_data->unclipped_blend(clipped - cspans, cspans, fill_data); 237 fill_data->unclipped_blend(clipped - cspans, cspans, fill_data);
243 } 238 }
244 } 239 }
245} 240}
246 241
247static void 242static void
248_span_fill_clipPath(int span_count, const SW_FT_Span *spans, void *user_data) 243_span_fill_clipPath(int span_count, const SW_FT_Span *spans, void *user_data)
249{ 244{
250 const int NSPANS = 256; 245 const int NSPANS = 256;
251 int current_clip = 0; 246 int current_clip = 0;
252 SW_FT_Span cspans[NSPANS]; 247 SW_FT_Span cspans[NSPANS];
253 Span_Data *fill_data = (Span_Data *) user_data; 248 Span_Data *fill_data = (Span_Data *) user_data;
254 Clip_Data clip = fill_data->clip; 249 Clip_Data clip = fill_data->clip;
255 250 SW_FT_Span *clipped;
256 //TODO take clip path offset into account. 251
257 252 //TODO take clip path offset into account.
258 const SW_FT_Span *end = spans + span_count; 253 const SW_FT_Span *end = spans + span_count;
259 while (spans < end) 254 while (spans < end)
260 { 255 {
261 SW_FT_Span *clipped = cspans; 256 clipped = cspans;
262 spans = _intersect_spans_region(clip.path, &current_clip, spans, end, &clipped, NSPANS); 257 spans = _intersect_spans_region(clip.path, &current_clip, spans, end, &clipped, NSPANS);
263 if (clipped - cspans) 258 if (clipped - cspans)
264 fill_data->unclipped_blend(clipped - cspans, cspans, fill_data); 259 fill_data->unclipped_blend(clipped - cspans, cspans, fill_data);
265 } 260 }
266} 261}
267 262
268static void 263static void
@@ -270,19 +265,19 @@ _adjust_span_fill_methods(Span_Data *spdata)
270{ 265{
271 switch(spdata->type) 266 switch(spdata->type)
272 { 267 {
273 case None: 268 case None:
274 spdata->unclipped_blend = 0; 269 spdata->unclipped_blend = 0;
275 break; 270 break;
276 case Solid: 271 case Solid:
277 spdata->unclipped_blend = &_blend_color_argb; 272 spdata->unclipped_blend = &_blend_color_argb;
278 break; 273 break;
279 case LinearGradient: 274 case LinearGradient:
280 case RadialGradient: 275 case RadialGradient:
281 spdata->unclipped_blend = &_blend_gradient; 276 spdata->unclipped_blend = &_blend_gradient;
282 break; 277 break;
283 case Image: 278 case Image:
284 spdata->unclipped_blend = 0;//&_blend_image; 279 spdata->unclipped_blend = 0;//&_blend_image;
285 break; 280 break;
286 } 281 }
287 282
288 // setup clipping 283 // setup clipping
@@ -317,6 +312,7 @@ void ector_software_rasterizer_init(Software_Rasterizer *rasterizer)
317 rasterizer->fill_data.clip.enabled = EINA_FALSE; 312 rasterizer->fill_data.clip.enabled = EINA_FALSE;
318 rasterizer->fill_data.unclipped_blend = 0; 313 rasterizer->fill_data.unclipped_blend = 0;
319 rasterizer->fill_data.blend = 0; 314 rasterizer->fill_data.blend = 0;
315 init_draw_helper();
320} 316}
321 317
322void ector_software_rasterizer_done(Software_Rasterizer *rasterizer) 318void ector_software_rasterizer_done(Software_Rasterizer *rasterizer)
@@ -325,40 +321,38 @@ void ector_software_rasterizer_done(Software_Rasterizer *rasterizer)
325 SW_FT_Stroker_Done(rasterizer->stroker); 321 SW_FT_Stroker_Done(rasterizer->stroker);
326} 322}
327 323
328
329void ector_software_rasterizer_stroke_set(Software_Rasterizer *rasterizer, double width, 324void ector_software_rasterizer_stroke_set(Software_Rasterizer *rasterizer, double width,
330 Efl_Gfx_Cap cap_style, Efl_Gfx_Join join_style) 325 Efl_Gfx_Cap cap_style, Efl_Gfx_Join join_style)
331{ 326{
332 SW_FT_Stroker_LineCap cap; 327 SW_FT_Stroker_LineCap cap;
333 SW_FT_Stroker_LineJoin join; 328 SW_FT_Stroker_LineJoin join;
329 int stroke_width = (int)(width * 64);
334 330
335 switch (cap_style) 331 switch (cap_style)
336 { 332 {
337 case EFL_GFX_CAP_SQUARE: 333 case EFL_GFX_CAP_SQUARE:
338 cap = SW_FT_STROKER_LINECAP_SQUARE; 334 cap = SW_FT_STROKER_LINECAP_SQUARE;
339 break; 335 break;
340 case EFL_GFX_CAP_ROUND: 336 case EFL_GFX_CAP_ROUND:
341 cap = SW_FT_STROKER_LINECAP_ROUND; 337 cap = SW_FT_STROKER_LINECAP_ROUND;
342 break; 338 break;
343 default: 339 default:
344 cap = SW_FT_STROKER_LINECAP_BUTT; 340 cap = SW_FT_STROKER_LINECAP_BUTT;
345 break; 341 break;
346 } 342 }
347 343
348 switch (join_style) 344 switch (join_style)
349 { 345 {
350 case EFL_GFX_JOIN_BEVEL: 346 case EFL_GFX_JOIN_BEVEL:
351 join = SW_FT_STROKER_LINEJOIN_BEVEL; 347 join = SW_FT_STROKER_LINEJOIN_BEVEL;
352 break; 348 break;
353 case EFL_GFX_JOIN_ROUND: 349 case EFL_GFX_JOIN_ROUND:
354 join = SW_FT_STROKER_LINEJOIN_ROUND; 350 join = SW_FT_STROKER_LINEJOIN_ROUND;
355 break; 351 break;
356 default: 352 default:
357 join = SW_FT_STROKER_LINEJOIN_MITER; 353 join = SW_FT_STROKER_LINEJOIN_MITER;
358 break; 354 break;
359 } 355 }
360
361 int stroke_width = (int)(width * 64);
362 SW_FT_Stroker_Set(rasterizer->stroker, stroke_width, cap, join, 0); 356 SW_FT_Stroker_Set(rasterizer->stroker, stroke_width, cap, join, 0);
363} 357}
364 358
@@ -371,7 +365,7 @@ _rle_generation_cb( int count, const SW_FT_Span* spans,void *user)
371 // allocate enough memory for new spans 365 // allocate enough memory for new spans
372 // alloc is required to prevent free and reallocation 366 // alloc is required to prevent free and reallocation
373 // when the rle needs to be regenerated because of attribute change. 367 // when the rle needs to be regenerated because of attribute change.
374 if(rle->alloc < newsize) 368 if (rle->alloc < newsize)
375 { 369 {
376 rle->spans = (SW_FT_Span *) realloc(rle->spans, newsize * sizeof(SW_FT_Span)); 370 rle->spans = (SW_FT_Span *) realloc(rle->spans, newsize * sizeof(SW_FT_Span));
377 rle->alloc = newsize; 371 rle->alloc = newsize;
@@ -425,18 +419,19 @@ Shape_Rle_Data *
425ector_software_rasterizer_generate_stroke_rle_data(Software_Rasterizer *rasterizer, SW_FT_Outline *outline, Eina_Bool closePath) 419ector_software_rasterizer_generate_stroke_rle_data(Software_Rasterizer *rasterizer, SW_FT_Outline *outline, Eina_Bool closePath)
426{ 420{
427 uint points,contors; 421 uint points,contors;
422 Shape_Rle_Data *rle_data;
423 SW_FT_Outline strokeOutline = { 0, 0, NULL, NULL, NULL, 0 };
428 424
429 SW_FT_Stroker_ParseOutline(rasterizer->stroker, outline, !closePath); 425 SW_FT_Stroker_ParseOutline(rasterizer->stroker, outline, !closePath);
430 SW_FT_Stroker_GetCounts(rasterizer->stroker,&points, &contors); 426 SW_FT_Stroker_GetCounts(rasterizer->stroker,&points, &contors);
431 427
432 SW_FT_Outline strokeOutline = { 0, 0, NULL, NULL, NULL, 0 };
433 strokeOutline.points = (SW_FT_Vector *) calloc(points, sizeof(SW_FT_Vector)); 428 strokeOutline.points = (SW_FT_Vector *) calloc(points, sizeof(SW_FT_Vector));
434 strokeOutline.tags = (char *) calloc(points, sizeof(char)); 429 strokeOutline.tags = (char *) calloc(points, sizeof(char));
435 strokeOutline.contours = (short *) calloc(contors, sizeof(short)); 430 strokeOutline.contours = (short *) calloc(contors, sizeof(short));
436 431
437 SW_FT_Stroker_Export(rasterizer->stroker, &strokeOutline); 432 SW_FT_Stroker_Export(rasterizer->stroker, &strokeOutline);
438 433
439 Shape_Rle_Data *rle_data = ector_software_rasterizer_generate_rle_data(rasterizer, &strokeOutline); 434 rle_data = ector_software_rasterizer_generate_rle_data(rasterizer, &strokeOutline);
440 435
441 // cleanup the outline data. 436 // cleanup the outline data.
442 free(strokeOutline.points); 437 free(strokeOutline.points);
@@ -503,20 +498,24 @@ void ector_software_rasterizer_color_set(Software_Rasterizer *rasterizer, int r,
503 rasterizer->fill_data.color = ECTOR_ARGB_JOIN(a, r, g, b); 498 rasterizer->fill_data.color = ECTOR_ARGB_JOIN(a, r, g, b);
504 rasterizer->fill_data.type = Solid; 499 rasterizer->fill_data.type = Solid;
505} 500}
506void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *linear) 501
502void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer *rasterizer,
503 Ector_Renderer_Software_Gradient_Data *linear)
507{ 504{
508 rasterizer->fill_data.gradient = linear; 505 rasterizer->fill_data.gradient = linear;
509 rasterizer->fill_data.type = LinearGradient; 506 rasterizer->fill_data.type = LinearGradient;
510} 507}
511void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *radial) 508
509void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer,
510 Ector_Renderer_Software_Gradient_Data *radial)
512{ 511{
513 rasterizer->fill_data.gradient = radial; 512 rasterizer->fill_data.gradient = radial;
514 rasterizer->fill_data.type = RadialGradient; 513 rasterizer->fill_data.type = RadialGradient;
515} 514}
516 515
517
518void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer, 516void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
519 int x, int y, uint mul_col, Ector_Rop op, Shape_Rle_Data* rle) 517 int x, int y, uint mul_col,
518 Ector_Rop op, Shape_Rle_Data* rle)
520{ 519{
521 // check for NULL rle data 520 // check for NULL rle data
522 if (!rle) return; 521 if (!rle) return;
@@ -529,6 +528,6 @@ void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
529 _setup_span_fill_matrix(rasterizer); 528 _setup_span_fill_matrix(rasterizer);
530 _adjust_span_fill_methods(&rasterizer->fill_data); 529 _adjust_span_fill_methods(&rasterizer->fill_data);
531 530
532 if(rasterizer->fill_data.blend) 531 if (rasterizer->fill_data.blend)
533 rasterizer->fill_data.blend(rle->size, rle->spans, &rasterizer->fill_data); 532 rasterizer->fill_data.blend(rle->size, rle->spans, &rasterizer->fill_data);
534} 533}