From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje. Note that embryo wont be used, but I'm not sure yet if you can build edje without it. --- .../evas/src/lib/engines/common/evas_line_main.c | 678 +++++++++++++++++++++ 1 file changed, 678 insertions(+) create mode 100644 libraries/evas/src/lib/engines/common/evas_line_main.c (limited to 'libraries/evas/src/lib/engines/common/evas_line_main.c') diff --git a/libraries/evas/src/lib/engines/common/evas_line_main.c b/libraries/evas/src/lib/engines/common/evas_line_main.c new file mode 100644 index 0000000..04401cb --- /dev/null +++ b/libraries/evas/src/lib/engines/common/evas_line_main.c @@ -0,0 +1,678 @@ +#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)) ) + +#define IN_RECT(x, y, rx, ry, rw, rh) \ + ( ((unsigned)((x) - (rx)) < (unsigned)(rw)) && \ + ((unsigned)((y) - (ry)) < (unsigned)(rh)) ) + +#define EXCHANGE_POINTS(x0, y0, x1, y1) \ + { \ + int _tmp = y0; \ + \ + y0 = y1; \ + y1 = _tmp; \ + \ + _tmp = x0; \ + x0 = x1; \ + x1 = _tmp; \ + } + + +EAPI void +evas_common_line_init(void) +{ +} + +EAPI void +evas_common_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1) +{ + int x, y, w, h; + int clx, cly, clw, clh; + int cuse, cx, cy, cw, ch; + + 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; + + if (dc->anti_alias) + _evas_draw_line_aa(dst, dc, x0, y0, x1, y1); + else + _evas_draw_line(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; +} + + +static void +_evas_draw_point(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y) +{ + RGBA_Gfx_Pt_Func pfunc; + + if (!IN_RANGE(x, y, dst->cache_entry.w, dst->cache_entry.h)) + return; + if ((dc->clip.use) && (!IN_RECT(x, y, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h))) + return; + pfunc = evas_common_gfx_func_composite_color_pt_get(dc->col.col, dst, dc->render_op); + if (pfunc) + pfunc(0, 255, dc->col.col, 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 + back to lie in the dst image rect and the object's + (line) bounding rect. +*/ +static void +_evas_draw_simple_line(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1) +{ + int dx, dy, len, lx, ty, rx, by; + int clx, cly, clw, clh; + int dstw; + DATA32 *p, color; + RGBA_Gfx_Pt_Func pfunc; + RGBA_Gfx_Func sfunc; + + dstw = dst->cache_entry.w; + color = dc->col.col; + + if (y0 > y1) + EXCHANGE_POINTS(x0, y0, x1, y1) + if (x0 > x1) + EXCHANGE_POINTS(x0, y0, x1, y1) + + dx = x1 - x0; + dy = y1 - y0; + + clx = dc->clip.x; + cly = dc->clip.y; + clw = dc->clip.w; + clh = dc->clip.h; + + lx = clx; + rx = clx + clw - 1; + ty = cly; + by = cly + clh - 1; + + if (dy == 0) + { +#ifdef EVAS_SLI + if (((y0) % dc->sli.h) == dc->sli.y) +#endif + { + if ((y0 >= ty) && (y0 <= by)) + { + if (dx < 0) + { + int tmp = x1; + + x1 = x0; + x0 = tmp; + } + + if (x0 < lx) x0 = lx; + if (x1 > rx) x1 = rx; + + len = x1 - x0 + 1; + p = dst->image.data + (dstw * y0) + x0; + sfunc = evas_common_gfx_func_composite_color_span_get(color, dst, len, dc->render_op); + if (sfunc) + sfunc(NULL, NULL, color, p, len); + } + } + return; + } + + pfunc = evas_common_gfx_func_composite_color_pt_get(color, dst, dc->render_op); + if (!pfunc) return; + + if (dx == 0) + { + if ((x0 >= lx) && (x0 <= rx)) + { + if (y0 < ty) y0 = ty; + if (y1 > by) y1 = by; + + len = y1 - y0 + 1; + p = dst->image.data + (dstw * y0) + x0; + while (len--) + { +#ifdef EVAS_SLI + if (((y1 + 1 - len) % dc->sli.h) == dc->sli.y) +#endif + { + pfunc(0, 255, color, p); + } + p += dstw; + } + } + return; + } + + if ((dy == dx) || (dy == -dx)) + { + int p0_in, p1_in; + + p0_in = (IN_RECT(x0, y0, clx, cly, clw, clh) ? 1 : 0); + p1_in = (IN_RECT(x1, y1, clx, cly, clw, clh) ? 1 : 0); + + if (dy > 0) + { + 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--) + { +#ifdef EVAS_SLI + if (((y1 + 1 - len) % dc->sli.h) == dc->sli.y) +#endif + { + 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; + +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; + + 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; + } + if (!p1_in) + { + if ((py < 0) && (dely < 0)) return; + if ((py > by) && (dely > 0)) return; + } + if (!p0_in) + { + if (py < 0) goto next_x; + } +#ifdef EVAS_SLI + if (((py) % dc->sli.h) == dc->sli.y) +#endif + { + 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; + } +#ifdef EVAS_SLI + if (((py) % dc->sli.h) == dc->sli.y) +#endif + { + if (IN_RANGE(px, py, clw, clh)) + pfunc(0, 255, color, p); + } + 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) +{ + 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, color; + RGBA_Gfx_Pt_Func pfunc; + + if (y0 > y1) + EXCHANGE_POINTS(x0, y0, x1, y1); + dx = x1 - x0; + dy = y1 - y0; + + 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_mask_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 = 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; + } +} -- cgit v1.1