From 3cefadd098bb72a087406ecc09c1c04f1dca0ab5 Mon Sep 17 00:00:00 2001 From: Patrick Hornecker Date: Mon, 21 Dec 2009 16:07:36 +0100 Subject: file locations reorderd, map in gui...build problems on local machine --- friendfinder/render/line.c | 394 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 394 insertions(+) create mode 100644 friendfinder/render/line.c (limited to 'friendfinder/render/line.c') diff --git a/friendfinder/render/line.c b/friendfinder/render/line.c new file mode 100644 index 0000000..5af1ec7 --- /dev/null +++ b/friendfinder/render/line.c @@ -0,0 +1,394 @@ +#include + +#include + +#include +#include "render/line.h" + +static Evas_Smart *get_smart(); + +static void _line_object_add(Evas_Object *o); +static void _line_object_del(Evas_Object *o); +static void _line_object_move(Evas_Object *o, Evas_Coord x, Evas_Coord y); +static void _line_object_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h); +static void _line_object_show(Evas_Object *o); +static void _line_object_hide(Evas_Object *o); +static void _line_object_color_set(Evas_Object *o, int r, int g, int b, int a); +static void _line_object_clip_set(Evas_Object *o, Evas_Object *clip); +static void _line_object_clip_unset(Evas_Object *o); + +#define SMART_LINE_NAME "e_smart_line" + +struct polyline *polyline_empty() +{ + struct polyline *pl; + + pl = (struct polyline *)malloc(sizeof(struct polyline)); + if (pl == NULL) + return NULL; + + pl->w = 0; + pl->a = 255; + pl->r = 0; + pl->g = 0; + pl->b = 0; + + pl->points = NULL; + pl->count = 0; + pl->mode = 0; + + return pl; +} + +void polyline_delete(struct polyline *pl) +{ + free(pl->points); + free(pl); +} + +void polyline_set_color(struct polyline *pl, int r, int g, int b, int a) +{ + pl->a = a; + pl->r = r; + pl->g = g; + pl->b = b; +} + +void polyline_set_width(struct polyline *pl, int w) +{ + pl->w = w; +} + +void polyline_add_point(struct polyline *pl, struct point p) +{ + pl->points = realloc(pl->points, (pl->count + 1) * sizeof(struct point)); + pl->points[pl->count] = p; + pl->count++; +} + +struct smart_line +{ + Evas_Object *obj; + Evas_Coord x, y, w, h; + + Evas_Object *clip; + Evas_Object *poly; + struct point *points; + struct polyline *pl; + int pcount; +}; + +Evas_Object *e_smart_line_add(Evas *e) +{ + Evas_Object *o; + struct smart_line *smart; + + o = evas_object_smart_add(e, get_smart()); + smart = evas_object_smart_data_get(o); + if(smart == NULL) + { + evas_object_del(o); + return NULL; + } + smart->points = NULL; + smart->pcount = 0; + smart->pl = NULL; + return o; +} + +static inline int +line_cut(struct line l0, struct line l1, struct point *p) +{ + Evas_Coord c1, c2, det, a1, a2, b1, b2; + + b1 = l0.p0.x - l0.p1.x; // b1 = x1 - x2 + a1 = l0.p1.y - l0.p0.y; // a1 = y2 - y1 + c1 = l0.p1.x * l0.p0.y - l0.p0.x * l0.p1.y; // c = x2*y1 - x1*y2; + + b2 = l1.p0.x - l1.p1.x; // b2 = x3 - x4 + a2 = l1.p1.y - l1.p0.y; // a2 = y4 - y3 + c2 = l1.p1.x * l1.p0.y - l1.p0.x * l1.p1.y; + + det = a1 * b2 - a2 * b1; + if(det == 0) + return -1; + + p->x = (b1*c2 - b2*c1)/det; + p->y = (a2*c1 - a1*c2)/det; + + return 0; +} + +static inline struct line +new_line(struct point p0, struct point p1) +{ + struct line l; + l.p0 = p0; + l.p1 = p1; + return l; +} + +static inline void +wide_line(Evas_Coord w, struct line l, struct line *l0, struct line *l1) +{ + Evas_Coord dX, dY, dx, dy; + double scale, len, ddx, ddy; + + dX = l.p1.x - l.p0.x; + dY = l.p1.y - l.p0.y; + len = sqrt(dX * dX + dY * dY); + scale = (double)(w) / (2 * len); + + ddx = -scale * (double)dY; + ddy = scale * (double)dX; + ddx += (ddx > 0) ? 0.5 : -0.5; + ddy += (ddy > 0) ? 0.5 : -0.5; + + dx = (Evas_Coord)ddx; + dy = (Evas_Coord)ddy; + + l0->p0.x = l.p0.x + dx; + l0->p0.y = l.p0.y + dy; + + l1->p0.x = l.p0.x - dx; + l1->p0.y = l.p0.y - dy; + + l0->p1.x = l.p1.x + dx; + l0->p1.y = l.p1.y + dy; + + l1->p1.x = l.p1.x - dx; + l1->p1.y = l.p1.y - dy; +} + +static int _is_line_valid(struct line *l, int w) +{ + int dx = abs(l->p1.x - l->p0.x); + int dy = abs(l->p1.y - l->p0.y); + if(dx < w && dy < w) + return 0; + return 1; +} + +static void _line_update(struct smart_line *smart, int dx, int dy) +{ + int i; + + evas_object_polygon_points_clear(smart->poly); + for(i = 0; i < smart->pcount; i++) + { +// printf("p[%i]: %i,%i\n", i, poly[i].x, poly[i].y); + evas_object_polygon_point_add(smart->poly, smart->points[i].x - dx, smart->points[i].y - dy); + } + evas_object_show(smart->poly); +} + +struct polyline *e_smart_line_get(Evas_Object *o) +{ + struct smart_line *smart; + smart = evas_object_smart_data_get(o); + return smart->pl; +} + +void e_smart_line_set(Evas_Object *o, struct polyline *pl) +{ + int i; + struct smart_line *smart; + struct line l0_0 = {{0}}; + struct line l0_1 = {{0}}; + + struct point fwd[pl->count]; + struct point bwd[pl->count]; + + int pcount = 0; + struct point last; + + if(pl->count < 1) + return; + smart = evas_object_smart_data_get(o); + last = pl->points[0]; + + for(i = 1; i < pl->count; i++) + { + struct point tmp; + struct line l = new_line(last, pl->points[i]); + if(!_is_line_valid(&l, pl->w)) + continue; + + if(pcount == 0) + { + wide_line(pl->w, l, &l0_0, &l0_1); + fwd[pcount] = l0_0.p0; + bwd[pcount] = l0_1.p0; + last = pl->points[i]; + pcount++; + continue; + } + if(i >= pl->count - 1) + { + fwd[pcount] = l0_0.p1; + bwd[pcount] = l0_1.p1; + pcount++; + break; + } + + struct line l1_0, l1_1; + + wide_line(pl->w, l, &l1_0, &l1_1); + + if(line_cut(l0_0, l1_0, &tmp) < 0) + continue; + fwd[pcount] = tmp; + + if(line_cut(l0_1, l1_1, &tmp) < 0) + continue; + + bwd[pcount] = tmp; + last = pl->points[i]; + l0_0 = l1_0; + l0_1 = l1_1; + pcount++; + } + + if(smart->points != NULL) + free(smart->points); + smart->points = (struct point *)malloc(sizeof(struct point) * pcount * 2); + smart->pcount = pcount * 2; + + for(i = 0; i < pcount; i++) + { + smart->points[i] = fwd[i]; + smart->points[2 * pcount - i - 1] = bwd[i]; + } + evas_object_color_set(smart->poly, pl->r, pl->g, pl->b, pl->a); + _line_update(smart, smart->x, smart->y); + smart->pl = pl; +} + +static void _line_object_add(Evas_Object *o) +{ + struct smart_line *smart; + + smart = calloc(1, sizeof(struct smart_line)); + if (smart == NULL) + return; + + smart->obj = o; + smart->x = 0; + smart->y = 0; + smart->w = 0; + smart->h = 0; + + smart->clip = evas_object_rectangle_add(evas_object_evas_get(o)); + evas_object_smart_member_add(smart->clip, o); + evas_object_color_set(smart->clip, 255, 255, 255, 255); + evas_object_move(smart->clip, smart->x, smart->y); + evas_object_resize(smart->clip, smart->w, smart->h); + + smart->poly = evas_object_polygon_add(evas_object_evas_get(o)); + evas_object_smart_member_add(smart->poly, o); + evas_object_color_set(smart->poly, 255, 255, 255, 255); + evas_object_move(smart->poly, smart->x, smart->y); + evas_object_resize(smart->poly, smart->w, smart->h); + evas_object_show(smart->poly); + + evas_object_smart_data_set(o, smart); +} + +static void _line_object_del(Evas_Object *o) +{ + struct smart_line *smart; + smart = evas_object_smart_data_get(o); + + evas_object_del(smart->clip); + evas_object_del(smart->poly); + + free(smart); +} + +static void _line_object_move(Evas_Object *o, Evas_Coord x, Evas_Coord y) +{ + struct smart_line *smart; + smart = evas_object_smart_data_get(o); + + smart->x = x; + smart->y = y; + + _line_update(smart, smart->x, smart->y); +} + +static void _line_object_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h) +{ + struct smart_line *smart; + smart = evas_object_smart_data_get(o); + + smart->w = w; + smart->h = h; + evas_object_resize(smart->clip, smart->w, smart->h); + evas_object_resize(smart->poly, smart->w, smart->h); +} + +static void _line_object_show(Evas_Object *o) +{ + struct smart_line *smart; + smart = evas_object_smart_data_get(o); + + evas_object_show(smart->clip); +} + +static void _line_object_hide(Evas_Object *o) +{ + struct smart_line *smart; + smart = evas_object_smart_data_get(o); + + evas_object_hide(smart->clip); +} + +static void _line_object_color_set(Evas_Object *o, int r, int g, int b, int a) +{ + struct smart_line *smart; + smart = evas_object_smart_data_get(o); + + evas_object_color_set(smart->poly, r, g, b, a); +} + +static void _line_object_clip_set(Evas_Object *o, Evas_Object *clip) +{ + struct smart_line *smart; + smart = evas_object_smart_data_get(o); + + evas_object_clip_set(smart->clip, clip); +} + +static void _line_object_clip_unset(Evas_Object *o) +{ + struct smart_line *smart; + smart = evas_object_smart_data_get(o); + + evas_object_clip_unset(smart->clip); +} + +static Evas_Smart *get_smart() +{ + static Evas_Smart *e_smart_line = NULL; + + if(e_smart_line != NULL) + return e_smart_line; + + e_smart_line = evas_smart_new(SMART_LINE_NAME, + _line_object_add, + _line_object_del, + NULL, + NULL, + NULL, + NULL, + NULL, + _line_object_move, + _line_object_resize, + _line_object_show, + _line_object_hide, + _line_object_color_set, + _line_object_clip_set, + _line_object_clip_unset, + NULL); + return e_smart_line; +} -- cgit v1.2.3-55-g7522