1 #include "evas_common_soft16.h"
2 #include "evas_soft16_scanline_fill.c"
5 * All functions except by soft16_line_draw() expect x0 <= x1.
9 _in_range(int value, int min, int max)
11 return min <= value && value <= max;
15 _is_xy_inside_clip(int x, int y, const struct RGBA_Draw_Context_clip clip)
20 if (!_in_range(x, clip.x, clip.x + clip.w - 1))
23 if (!_in_range(y, clip.y, clip.y + clip.h - 1))
30 _is_x_inside_clip(int x, const struct RGBA_Draw_Context_clip clip)
35 return _in_range(x, clip.x, clip.x + clip.w - 1);
39 _is_y_inside_clip(int y, const struct RGBA_Draw_Context_clip clip)
44 return _in_range(y, clip.y, clip.y + clip.h - 1);
48 _is_xy_inside_rect(int x, int y, int w, int h)
50 return _in_range(x, 0, w - 1) && _in_range(y, 0, h - 1);
54 _is_empty_clip(const struct RGBA_Draw_Context_clip clip)
56 return clip.w < 1 || clip.h < 1;
60 _soft16_line_point(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y)
62 DATA16 rgb565, *dst_itr;
65 if (!_is_xy_inside_rect(x, y, dst->cache_entry.w, dst->cache_entry.h))
68 if (!_is_xy_inside_clip(x, y, dc->clip))
71 dst_itr = dst->pixels + (dst->stride * y) + x;
72 alpha = A_VAL(&dc->col.col) >> 3;
73 rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
78 _soft16_pt_fill_solid_solid(dst_itr, rgb565);
83 rgb565_unpack = RGB_565_UNPACK(rgb565);
85 _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
90 _soft16_line_horiz(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int x1, int y)
92 DATA16 rgb565, *dst_itr;
96 if (!_is_y_inside_clip(y, dc->clip))
102 if (x1 >= dc->clip.x + dc->clip.w)
103 x1 = dc->clip.x + dc->clip.w - 1;
109 dst_itr = dst->pixels + (dst->stride * y) + x0;
110 alpha = A_VAL(&dc->col.col) >> 3;
111 rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
113 B_VAL(&dc->col.col));
116 _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565);
119 DATA32 rgb565_unpack;
121 rgb565_unpack = RGB_565_UNPACK(rgb565);
123 _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha);
128 _soft16_line_vert(Soft16_Image *dst, RGBA_Draw_Context *dc, int x, int y0, int y1)
130 DATA16 rgb565, *dst_itr;
134 if (!_is_x_inside_clip(x, dc->clip))
148 if (y1 >= dc->clip.y + dc->clip.h)
149 y1 = dc->clip.y + dc->clip.h - 1;
155 dst_itr = dst->pixels + (dst->stride * y0) + x;
156 alpha = A_VAL(&dc->col.col) >> 3;
157 rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
159 B_VAL(&dc->col.col));
163 for (; h > 0; h--, dst_itr += dst->stride)
164 _soft16_pt_fill_solid_solid(dst_itr, rgb565);
168 DATA32 rgb565_unpack;
170 rgb565_unpack = RGB_565_UNPACK(rgb565);
173 for (; h > 0; h--, dst_itr += dst->stride)
174 _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
179 _soft16_line_45deg_adjust_boundaries(const struct RGBA_Draw_Context_clip clip, int *p_x0, int *p_y0, int *p_x1, int *p_y1)
181 int diff, dy, x0, y0, x1, y1;
194 y0 += (dy > 0) ? diff : -diff;
197 diff = x1 - (clip.x + clip.w);
200 x1 = clip.x + clip.w;
201 y1 += (dy > 0) ? -diff : diff;
213 diff = y1 - (clip.y + clip.h);
216 y1 = clip.y + clip.h;
229 diff = y0 - (clip.y + clip.h - 1);
232 y0 = clip.y + clip.h - 1;
244 _soft16_line_45deg(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
246 int dy, step_dst_itr, len;
248 DATA16 *dst_itr, rgb565;
250 alpha = A_VAL(&dc->col.col) >> 3;
254 rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
256 B_VAL(&dc->col.col));
259 step_dst_itr = 1 + ((dy > 0) ? dst->stride : -dst->stride);
261 _soft16_line_45deg_adjust_boundaries(dc->clip, &x0, &y0, &x1, &y1);
263 len = (dy > 0) ? (y1 - y0) : (y0 - y1);
267 dst_itr = dst->pixels + dst->stride * y0 + x0;
270 for (; len > 0; len--, dst_itr += step_dst_itr)
271 _soft16_pt_fill_solid_solid(dst_itr, rgb565);
275 DATA32 rgb565_unpack;
277 rgb565_unpack = RGB_565_UNPACK(rgb565);
279 for (; len > 0; len--, dst_itr += step_dst_itr)
280 _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
284 static always_inline void
285 _soft16_line_aliased_pt(DATA16 *dst_itr, DATA16 rgb565, DATA32 rgb565_unpack, DATA8 alpha)
288 _soft16_pt_fill_solid_solid(dst_itr, rgb565);
290 _soft16_pt_fill_transp_solid(dst_itr, rgb565_unpack, alpha);
294 _soft16_line_aliased(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
296 int dx, dy, step_y, step_dst_itr;
297 DATA32 rgb565_unpack;
301 alpha = A_VAL(&dc->col.col) >> 3;
306 rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
308 B_VAL(&dc->col.col));
309 rgb565_unpack = RGB_565_UNPACK(rgb565);
317 step_dst_itr = dst->stride;
323 step_dst_itr = -dst->stride;
333 dst_itr = dst->pixels + dst->stride * y0 + x0;
334 for (x=x0; x <= x1; x++, dst_itr++)
336 if (_is_xy_inside_clip(x, y, dc->clip))
337 _soft16_line_aliased_pt(dst_itr, rgb565, rgb565_unpack, alpha);
342 dst_itr += step_dst_itr;
355 dst_itr = dst->pixels + dst->stride * y0 + x0;
356 for (y=y0; y != y1; y += step_y, dst_itr += step_dst_itr)
358 if (_is_xy_inside_clip(x, y, dc->clip))
359 _soft16_line_aliased_pt(dst_itr, rgb565, rgb565_unpack, alpha);
373 soft16_line_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1)
375 struct RGBA_Draw_Context_clip c_bkp, c_tmp;
382 c_tmp.w = dst->cache_entry.w;
383 c_tmp.h = dst->cache_entry.h;
385 /* save out clip info */
389 RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h,
390 c_bkp.x, c_bkp.y, c_bkp.w, c_bkp.h);
391 if (_is_empty_clip(c_tmp))
397 w = MAX(x0, x1) - x + 1;
398 h = MAX(y0, y1) - y + 1;
400 RECTS_CLIP_TO_RECT(c_tmp.x, c_tmp.y, c_tmp.w, c_tmp.h, x, y, w, h);
401 if (_is_empty_clip(c_tmp))
404 /* Check if the line doesn't cross the clip area */
405 if (x0 < c_tmp.x && x1 < c_tmp.x)
407 if (x0 >= c_tmp.x + c_tmp.w && x1 >= c_tmp.x + c_tmp.w)
409 if (y0 < c_tmp.y && y1 < c_tmp.y)
411 if (y0 >= c_tmp.y + c_tmp.h && y1 >= c_tmp.y + c_tmp.h)
431 if (dx == 0 && dy == 0)
432 _soft16_line_point(dst, dc, x0, y0);
434 _soft16_line_vert(dst, dc, x0, y0, y1);
436 _soft16_line_horiz(dst, dc, x0, x1, y0);
437 else if (dy == dx || dy == -dx)
438 _soft16_line_45deg(dst, dc, x0, y0, x1, y1);
440 _soft16_line_aliased(dst, dc, x0, y0, x1, y1);
442 /* restore clip info */