aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/engines/common_8/evas_soft8_line.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/engines/common_8/evas_soft8_line.c')
-rw-r--r--libraries/evas/src/lib/engines/common_8/evas_soft8_line.c426
1 files changed, 426 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/engines/common_8/evas_soft8_line.c b/libraries/evas/src/lib/engines/common_8/evas_soft8_line.c
new file mode 100644
index 0000000..6ec2d22
--- /dev/null
+++ b/libraries/evas/src/lib/engines/common_8/evas_soft8_line.c
@@ -0,0 +1,426 @@
1#include "evas_common_soft8.h"
2#include "evas_soft8_scanline_fill.c"
3
4/*
5 * All functions except by evas_common_soft8_line_draw() expect x0 <= x1.
6 */
7
8static inline int
9_in_range(int value, int min, int max)
10{
11 return min <= value && value <= max;
12}
13
14static inline int
15_is_xy_inside_clip(int x, int y, const struct RGBA_Draw_Context_clip clip)
16{
17 if (!clip.use)
18 return 1;
19
20 if (!_in_range(x, clip.x, clip.x + clip.w - 1))
21 return 0;
22
23 if (!_in_range(y, clip.y, clip.y + clip.h - 1))
24 return 0;
25
26 return 1;
27}
28
29static inline int
30_is_x_inside_clip(int x, const struct RGBA_Draw_Context_clip clip)
31{
32 if (!clip.use)
33 return 1;
34
35 return _in_range(x, clip.x, clip.x + clip.w - 1);
36}
37
38static inline int
39_is_y_inside_clip(int y, const struct RGBA_Draw_Context_clip clip)
40{
41 if (!clip.use)
42 return 1;
43
44 return _in_range(y, clip.y, clip.y + clip.h - 1);
45}
46
47static inline int
48_is_xy_inside_rect(int x, int y, int w, int h)
49{
50 return _in_range(x, 0, w - 1) && _in_range(y, 0, h - 1);
51}
52
53static inline int
54_is_empty_clip(const struct RGBA_Draw_Context_clip clip)
55{
56 return clip.w < 1 || clip.h < 1;
57}
58
59static void
60_soft8_line_point(Soft8_Image * dst, RGBA_Draw_Context * dc, int x, int y)
61{
62 DATA8 gry8, *dst_itr;
63 DATA8 alpha;
64
65 if (!_is_xy_inside_rect(x, y, dst->cache_entry.w, dst->cache_entry.h))
66 return;
67
68 if (!_is_xy_inside_clip(x, y, dc->clip))
69 return;
70
71 dst_itr = dst->pixels + (dst->stride * y) + x;
72 alpha = A_VAL(&dc->col.col);
73 gry8 = GRY_8_FROM_RGB(&dc->col.col);
74
75 if (alpha == 0xff)
76 _soft8_pt_fill_solid_solid(dst_itr, gry8);
77 else if (alpha > 0)
78 {
79 alpha++;
80 _soft8_pt_fill_transp_solid(dst_itr, gry8, alpha);
81 }
82}
83
84static void
85_soft8_line_horiz(Soft8_Image * dst, RGBA_Draw_Context * dc, int x0, int x1,
86 int y)
87{
88 DATA8 gry8, *dst_itr;
89 DATA8 alpha;
90 int w;
91
92 if (!_is_y_inside_clip(y, dc->clip))
93 return;
94
95 if (x0 < dc->clip.x)
96 x0 = dc->clip.x;
97
98 if (x1 >= dc->clip.x + dc->clip.w)
99 x1 = dc->clip.x + dc->clip.w - 1;
100
101 w = x1 - x0;
102 if (w < 1)
103 return;
104
105 dst_itr = dst->pixels + (dst->stride * y) + x0;
106 alpha = A_VAL(&dc->col.col);
107 gry8 = GRY_8_FROM_RGB(&dc->col.col);
108
109 if (alpha == 0xff)
110 _soft8_scanline_fill_solid_solid(dst_itr, w, gry8);
111 else if (alpha > 0)
112 {
113 alpha++;
114 _soft8_scanline_fill_transp_solid(dst_itr, w, gry8, alpha);
115 }
116}
117
118static void
119_soft8_line_vert(Soft8_Image * dst, RGBA_Draw_Context * dc, int x, int y0,
120 int y1)
121{
122 DATA8 gry8, *dst_itr;
123 DATA8 alpha;
124 int h;
125
126 if (!_is_x_inside_clip(x, dc->clip))
127 return;
128
129 if (y1 < y0)
130 {
131 int t;
132 t = y0;
133 y0 = y1;
134 y1 = t;
135 }
136
137 if (y0 < dc->clip.y)
138 y0 = dc->clip.y;
139
140 if (y1 >= dc->clip.y + dc->clip.h)
141 y1 = dc->clip.y + dc->clip.h - 1;
142
143 h = y1 - y0;
144 if (h < 1)
145 return;
146
147 dst_itr = dst->pixels + (dst->stride * y0) + x;
148 alpha = A_VAL(&dc->col.col);
149 gry8 = GRY_8_FROM_RGB(&dc->col.col);
150
151 if (alpha == 0xff)
152 {
153 for (; h > 0; h--, dst_itr += dst->stride)
154 _soft8_pt_fill_solid_solid(dst_itr, gry8);
155 }
156 else if (alpha > 0)
157 {
158 alpha++;
159
160 for (; h > 0; h--, dst_itr += dst->stride)
161 _soft8_pt_fill_transp_solid(dst_itr, gry8, alpha);
162 }
163}
164
165static inline void
166_soft8_line_45deg_adjust_boundaries(const struct RGBA_Draw_Context_clip clip,
167 int *p_x0, int *p_y0, int *p_x1, int *p_y1)
168{
169 int diff, dy, x0, y0, x1, y1;
170
171 x0 = *p_x0;
172 y0 = *p_y0;
173 x1 = *p_x1;
174 y1 = *p_y1;
175
176 dy = y1 - y0;
177
178 diff = clip.x - x0;
179 if (diff > 0)
180 {
181 x0 = clip.x;
182 y0 += (dy > 0) ? diff : -diff;
183 }
184
185 diff = x1 - (clip.x + clip.w);
186 if (diff > 0)
187 {
188 x1 = clip.x + clip.w;
189 y1 += (dy > 0) ? -diff : diff;
190 }
191
192 if (dy > 0)
193 {
194 diff = clip.y - y0;
195 if (diff > 0)
196 {
197 y0 = clip.y;
198 x0 += diff;
199 }
200
201 diff = y1 - (clip.y + clip.h);
202 if (diff > 0)
203 {
204 y1 = clip.y + clip.h;
205 x1 -= diff;
206 }
207 }
208 else
209 {
210 diff = clip.y - y1;
211 if (diff > 0)
212 {
213 y1 = clip.y;
214 x1 -= diff;
215 }
216
217 diff = y0 - (clip.y + clip.h - 1);
218 if (diff > 0)
219 {
220 y0 = clip.y + clip.h - 1;
221 x0 += diff;
222 }
223 }
224
225 *p_x0 = x0;
226 *p_y0 = y0;
227 *p_x1 = x1;
228 *p_y1 = y1;
229}
230
231static void
232_soft8_line_45deg(Soft8_Image * dst, RGBA_Draw_Context * dc, int x0, int y0,
233 int x1, int y1)
234{
235 int dy, step_dst_itr, len;
236 DATA8 alpha;
237 DATA8 *dst_itr, gry8;
238
239 alpha = A_VAL(&dc->col.col);
240 if (alpha < 1)
241 return;
242
243 gry8 = GRY_8_FROM_RGB(&dc->col.col);
244
245 dy = y1 - y0;
246 step_dst_itr = 1 + ((dy > 0) ? dst->stride : -dst->stride);
247
248 _soft8_line_45deg_adjust_boundaries(dc->clip, &x0, &y0, &x1, &y1);
249
250 len = (dy > 0) ? (y1 - y0) : (y0 - y1);
251 if (len < 1)
252 return;
253
254 dst_itr = dst->pixels + dst->stride * y0 + x0;
255 if (alpha == 0xff)
256 {
257 for (; len > 0; len--, dst_itr += step_dst_itr)
258 _soft8_pt_fill_solid_solid(dst_itr, gry8);
259 }
260 else
261 {
262 alpha++;
263 for (; len > 0; len--, dst_itr += step_dst_itr)
264 _soft8_pt_fill_transp_solid(dst_itr, gry8, alpha);
265 }
266}
267
268EFL_ALWAYS_INLINE void
269_soft8_line_aliased_pt(DATA8 * dst_itr, DATA8 gry8, DATA8 alpha)
270{
271 if (alpha == 32)
272 _soft8_pt_fill_solid_solid(dst_itr, gry8);
273 else
274 _soft8_pt_fill_transp_solid(dst_itr, gry8, alpha);
275}
276
277static void
278_soft8_line_aliased(Soft8_Image * dst, RGBA_Draw_Context * dc, int x0, int y0,
279 int x1, int y1)
280{
281 int dx, dy, step_y, step_dst_itr;
282 DATA8 gry8;
283 DATA8 alpha;
284
285 alpha = A_VAL(&dc->col.col);
286 if (alpha == 0)
287 return;
288 alpha++;
289
290 gry8 = GRY_8_FROM_RGB(&dc->col.col);
291
292 dx = x1 - x0;
293 dy = y1 - y0;
294
295 if (dy >= 0)
296 {
297 step_y = 1;
298 step_dst_itr = dst->stride;
299 }
300 else
301 {
302 dy = -dy;
303 step_y = -1;
304 step_dst_itr = -dst->stride;
305 }
306
307 if (dx > dy)
308 {
309 DATA8 *dst_itr;
310 int e, x, y;
311
312 e = -(dx / 2);
313 y = y0;
314 dst_itr = dst->pixels + dst->stride * y0 + x0;
315 for (x = x0; x <= x1; x++, dst_itr++)
316 {
317 if (_is_xy_inside_clip(x, y, dc->clip))
318 _soft8_line_aliased_pt(dst_itr, gry8, alpha);
319
320 e += dy;
321 if (e >= 0)
322 {
323 dst_itr += step_dst_itr;
324 y += step_y;
325 e -= dx;
326 }
327 }
328 }
329 else
330 {
331 DATA8 *dst_itr;
332 int e, x, y;
333
334 e = -(dy / 2);
335 x = x0;
336 dst_itr = dst->pixels + dst->stride * y0 + x0;
337 for (y = y0; y != y1; y += step_y, dst_itr += step_dst_itr)
338 {
339 if (_is_xy_inside_clip(x, y, dc->clip))
340 _soft8_line_aliased_pt(dst_itr, gry8, alpha);
341
342 e += dx;
343 if (e >= 0)
344 {
345 dst_itr++;
346 x++;
347 e -= dy;
348 }
349 }
350 }
351}
352
353void
354evas_common_soft8_line_draw(Soft8_Image * dst, RGBA_Draw_Context * dc, int x0, int y0,
355 int x1, int y1)
356{
357 struct RGBA_Draw_Context_clip c_bkp, c_tmp;
358 int dx, dy;
359 int x, y, w, h;
360
361 c_tmp.use = 1;
362 c_tmp.x = 0;
363 c_tmp.y = 0;
364 c_tmp.w = dst->cache_entry.w;
365 c_tmp.h = dst->cache_entry.h;
366
367 /* save out clip info */
368 c_bkp = dc->clip;
369 if (c_bkp.use)
370 {
371 RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h,
372 c_bkp.x, c_bkp.y, c_bkp.w, c_bkp.h);
373 if (_is_empty_clip(c_tmp))
374 return;
375 }
376
377 x = MIN(x0, x1);
378 y = MIN(y0, y1);
379 w = MAX(x0, x1) - x + 1;
380 h = MAX(y0, y1) - y + 1;
381
382 RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h, x, y, w, h);
383 if (_is_empty_clip(c_tmp))
384 return;
385
386 /* Check if the line doesn't cross the clip area */
387 if (x0 < c_tmp.x && x1 < c_tmp.x)
388 return;
389 if (x0 >= c_tmp.x + c_tmp.w && x1 >= c_tmp.x + c_tmp.w)
390 return;
391 if (y0 < c_tmp.y && y1 < c_tmp.y)
392 return;
393 if (y0 >= c_tmp.y + c_tmp.h && y1 >= c_tmp.y + c_tmp.h)
394 return;
395
396 dc->clip = c_tmp;
397 dx = x1 - x0;
398 dy = y1 - y0;
399
400 if (dx < 0)
401 {
402 int t;
403
404 t = x0;
405 x0 = x1;
406 x1 = t;
407
408 t = y0;
409 y0 = y1;
410 y1 = t;
411 }
412
413 if (dx == 0 && dy == 0)
414 _soft8_line_point(dst, dc, x0, y0);
415 else if (dx == 0)
416 _soft8_line_vert(dst, dc, x0, y0, y1);
417 else if (dy == 0)
418 _soft8_line_horiz(dst, dc, x0, x1, y0);
419 else if (dy == dx || dy == -dx)
420 _soft8_line_45deg(dst, dc, x0, y0, x1, y1);
421 else
422 _soft8_line_aliased(dst, dc, x0, y0, x1, y1);
423
424 /* restore clip info */
425 dc->clip = c_bkp;
426}