# HG changeset patch # User Thinker K.F. Li # Date 1231040552 -28800 # Node ID bd8ea44b421ef3e927f5b87d4ae6b04d023e08e7 # Parent 81458bb0bf3483e4387d2af5dea4d0b51cd018cf Fix bug and finish unit test for collision testing in event.c. - mock for cairo, rdman, coord, and shape should be refactoried to a module. diff -r 81458bb0bf34 -r bd8ea44b421e include/mb_tools.h --- a/include/mb_tools.h Wed Dec 31 23:57:12 2008 +0800 +++ b/include/mb_tools.h Sun Jan 04 11:42:32 2009 +0800 @@ -61,6 +61,10 @@ } \ } \ } while(0) +#define STAILQ_FOR_EACH(q, type, field, elm) \ + for((elm) = (q).head; \ + (elm) != NULL; \ + (elm) = (elm)->field) /*! \defgroup darray Dynamic Array * @@ -134,4 +138,7 @@ #define MEM2OBJ(var, type, mem) ((type *)((void *)var - OFFSET(type, mem))) #define OFF2TYPE(obj, off, type) (*(type *)((void *)(obj) + (off))) +#define MAX(a, b) ((a) > (b)? (a): (b)) +#define MIN(a, b) ((a) < (b)? (a): (b)) + #endif /* __TOOLS_H_ */ diff -r 81458bb0bf34 -r bd8ea44b421e include/mb_types.h --- a/include/mb_types.h Wed Dec 31 23:57:12 2008 +0800 +++ b/include/mb_types.h Sun Jan 04 11:42:32 2009 +0800 @@ -108,6 +108,10 @@ extern int areas_are_overlay(area_t *r1, area_t *r2); extern void area_init(area_t *area, int n_pos, co_aix pos[][2]); +#define _in_range(a, s, w) ((a) >= (s) && (a) < ((s) + (w))) +#define area_pos_is_in(area, _x, _y) \ + (_in_range(_x, (area)->x, (area)->w) && \ + _in_range(_y, (area)->y, (area)->h)) extern void geo_init(geo_t *g); extern void geo_from_positions(geo_t *g, int n_pos, co_aix pos[][2]); extern void geo_mark_overlay(geo_t *g, int n_others, geo_t **others, @@ -115,10 +119,7 @@ #define geo_get_shape(g) ((g)->shape) #define geo_get_shape_safe(g) ((g)? (g)->shape: NULL) #define geo_set_shape(g, sh) do {(g)->shape = sh;} while(0) -#define _geo_is_in(a, s, w) ((a) >= (s) && (a) < ((s) + (w))) -#define geo_pos_is_in(g, _x, _y) \ - (_geo_is_in(_x, (g)->cur_area->x, (g)->cur_area->w) && \ - _geo_is_in(_y, (g)->cur_area->y, (g)->cur_area->h)) +#define geo_pos_is_in(g, _x, _y) area_pos_is_in((g)->cur_area, _x, _y) #define geo_get_area(g) ((g)->cur_area) #define geo_get_flags(g, mask) ((g)->flags & (mask)) #define geo_set_flags(g, mask) do {(g)->flags |= mask;} while(0) diff -r 81458bb0bf34 -r bd8ea44b421e src/event.c --- a/src/event.c Wed Dec 31 23:57:12 2008 +0800 +++ b/src/event.c Sun Jan 04 11:42:32 2009 +0800 @@ -21,52 +21,116 @@ #ifdef UNITTEST /* ============================================================ */ +#include +#include "mb_tools.h" + +typedef float co_aix; typedef struct shape shape_t; +typedef struct cairo_surface cairo_surface_t; +typedef struct coord coord_t; typedef struct cairo cairo_t; struct cairo { - shape_t *drawed; + STAILQ(shape_t) drawed; + STAILQ(shape_t) clip_pathes; + cairo_surface_t *tgt; }; -#define cairo_in_fill(cr, x, y) 0 -#define cairo_in_stroke(cr, x, y) 0 -#define cairo_new_path(cr) -#define cairo_get_target(cr) NULL -#define cairo_create(target) NULL -#define cairo_destroy(cr) -#define cairo_clip(cr) -#define cairo_fill(cr) -#define cairo_image_surface_get_data(cr) NULL -#define cairo_image_surface_get_stride(cr) 1 struct cairo_surface { + cairo_t *cr; + int w, h; + unsigned char *data; }; -typedef struct cairo_surface cairo_surface_t; -#define cairo_image_surface_get_width(surface) 0 -#define cairo_image_surface_get_height(surface) 0 -#define cairo_image_surface_create(surface, w, h) NULL -#define cairo_surface_destroy(surface) + +#define cairo_new_path(cr) do { STAILQ_CLEAN((cr)->drawed); } while(0) +#define cairo_get_target(cr) (cr)->tgt +static +cairo_t *cairo_create(cairo_surface_t *target) { + cairo_t *cr; + + cr = (cairo_t *)malloc(sizeof(cairo_t)); + STAILQ_INIT(cr->drawed); + STAILQ_INIT(cr->clip_pathes); + cr->tgt = target; + target->cr = cr; + return cr; +} +#define cairo_destroy(cr) do { free(cr); } while(0) +#define cairo_clip(cr) \ + do { \ + memcpy(&(cr)->clip_pathes, \ + &(cr)->drawed, \ + sizeof((cr)->drawed)); \ + STAILQ_CLEAN((cr)->drawed); \ + } while(0) +#define cairo_fill(cr) -typedef float co_aix; +#define cairo_image_surface_get_width(surface) (surface)->w +#define cairo_image_surface_get_height(surface) (surface)->h +static +cairo_surface_t *cairo_image_surface_create(int format, int w, int h) { + cairo_surface_t *surf; + + surf = (cairo_surface_t *)malloc(sizeof(cairo_surface_t)); + surf->w = w; + surf->h = h; + surf->data = (unsigned char *)malloc(h); + memset(surf->data, 0, h); + + return surf; +} +#define cairo_surface_destroy(surface) \ + do { free((surface)->data); free(surface); } while(0) +#define cairo_image_surface_get_stride(surface) 1 +#define CAIRO_FORMAT_A1 1 + typedef struct _area area_t; struct _area { co_aix x, y; co_aix w, h; }; -#define range_overlay(as, aw, bs, bw) \ - (((bs) - (as)) <= (aw) || ((as) - (bs)) <= (bw)) +#define area_set(area, _x, _y, _w, _h) \ + do { \ + (area)->x = (_x); \ + (area)->y = (_y); \ + (area)->w = (_w); \ + (area)->h = (_h); \ + } while(0) +#define _in_range(a, s, w) ((a) >= (s) && (a) < ((s) + (w))) +#define _range_overlay(as, aw, bs, bw) \ + (_in_range(as, bs, bw) || _in_range(bs, as, aw)) #define areas_are_overlay(a1, a2) \ - (range_overlay((a1)->x, (a1)->w, \ - (a2)->x, (a2)->w) && \ - range_overlay((a1)->y, (a1)->h, \ - (a2)->y, (a2)->h)) + (_range_overlay((a1)->x, (a1)->w, \ + (a2)->x, (a2)->w) && \ + _range_overlay((a1)->y, (a1)->h, \ + (a2)->y, (a2)->h)) +#define area_pos_is_in(area, _x, _y) \ + (_in_range(_x, (area)->x, (area)->w) && \ + _in_range(_y, (area)->y, (area)->h)) +#define _range_extent(a, s, w) \ + do { \ + if((a) < (s)) { \ + (w) += (s) - (a); \ + (s) = (a); \ + } else { \ + (w) = MAX(w, (a) - (s) + 1); \ + } \ + } while(0) + +static +void area_extent(area_t *area, co_aix x, co_aix y) { + _range_extent(x, area->x, area->w); + _range_extent(y, area->y, area->h); +} struct mb_obj { int obj_type; }; typedef struct mb_obj mb_obj_t; +#define MB_OBJ_INIT(obj, type) do { (obj)->obj_type = type; } while(0) #define GEF_OV_DRAW 0x1 #define GEF_HIDDEN 0x2 @@ -74,7 +138,10 @@ struct shape { mb_obj_t obj; + coord_t *coord; area_t area; + shape_t *all_next; + shape_t *drawed_next; void *fill, *stroke; struct shape *sibling; @@ -106,75 +173,165 @@ #define sh_clear_flags(shape, mask) do { (shape)->flags &= ~(mask); } while(0) #define sh_get_area(shape) (&(shape)->area) -typedef struct coord coord_t; struct coord { mb_obj_t obj; area_t area; int flags; coord_t *parent; - coord_t *children; + STAILQ(coord_t) children; coord_t *sibling; - shape_t *shapes; + STAILQ(shape_t) shapes; }; #define COF_SKIP 0x1 #define coord_get_area(coord) (&(coord)->area) #define FOR_COORD_SHAPES(coord, shape) \ - for(shape = (coord)->shapes; \ - shape != NULL; \ - shape = (shape)->sibling) + for((shape) = STAILQ_HEAD((coord)->shapes); \ + (shape) != NULL; \ + (shape) = STAILQ_NEXT(shape_t, sibling, shape)) #define FOR_COORDS_PREORDER(root, last) \ - for(last = root; \ - last != NULL; \ - last = preorder_coord_subtree(root, last)) + for((last) = (root); \ + (last) != NULL; \ + (last) = preorder_coord_subtree(root, last)) +#define FOR_COORD_CHILDREN(parent, child) \ + for((child) = STAILQ_HEAD((parent)->children); \ + (child) != NULL; \ + (child) = STAILQ_NEXT(coord_t, sibling, child)) + +static +void _areas_merge(area_t *area1, area_t *area2) { + co_aix lu_x, lu_y; + co_aix rb_x, rb_y; + + lu_x = area2->x; + lu_y = area2->y; + rb_x = lu_x + area2->w - 1; + rb_y = lu_y + area2->h - 1; + area_extent(area1, lu_x, lu_y); + area_extent(area1, rb_x, rb_y); +} + +static +void coord_update_area(coord_t *coord) { + area_t *area; + shape_t *shape; + coord_t *child; + area_t *cur_area; + + area = coord_get_area(coord); + + shape = STAILQ_HEAD(coord->shapes); + if(shape != NULL) { + cur_area = sh_get_area(shape); + } else { + child = STAILQ_HEAD(coord->children); + if(child == NULL) + return; + cur_area = coord_get_area(child); + } + memcpy(area, cur_area, sizeof(area_t)); + + FOR_COORD_SHAPES(coord, shape) { + cur_area = sh_get_area(shape); + _areas_merge(area, cur_area); + } + + FOR_COORD_CHILDREN(coord, child) { + cur_area = coord_get_area(child); + _areas_merge(area, cur_area); + } +} + +static +void coord_update_area_ancestors(coord_t *coord) { + coord_t *cur; + + for(cur = coord; cur != NULL; cur = cur->parent) { + coord_update_area(cur); + } +} static coord_t *preorder_coord_subtree(coord_t *root, coord_t *last) { - if(last->children) - return last->children; - while(last->sibling == NULL) + if(STAILQ_HEAD(last->children) && !(last->flags & COF_SKIP)) + return STAILQ_HEAD(last->children); + if(last == root) + return NULL; + while(STAILQ_NEXT(coord_t, sibling, last) == NULL) { + if(last == root) + return NULL; last = last->parent; - return last->sibling; + } + return STAILQ_NEXT(coord_t, sibling, last); +} + +static +void preorder_coord_skip_subtree(coord_t *coord) { + coord->flags &= ~COF_SKIP; } static coord_t *postorder_coord_subtree(coord_t *root, coord_t *last) { coord_t *cur; - + if(last != NULL) { - if(last->sibling == NULL) { + if(STAILQ_NEXT(coord_t, sibling, last) == NULL) { + if(cur == root) + return NULL; cur = last->parent; return cur; } - cur = last->sibling; + cur = STAILQ_NEXT(coord_t, sibling, last); } - cur = last; - while(cur->children) { - cur = cur->children; + cur = root; + while(STAILQ_HEAD(cur->children)) { + cur = STAILQ_HEAD(cur->children); } return cur; } -#define sh_path_draw(path, cr) -#define sh_text_draw(path, cr) -#define sh_rect_draw(path, cr) +static +void shape_draw(shape_t *sh, cairo_t *cr) { + STAILQ_INS_TAIL(cr->drawed, shape_t, drawed_next, sh); +} + +#define sh_path_draw(path, cr) shape_draw((shape_t *)path, cr) +#define sh_text_draw(text, cr) shape_draw((shape_t *)text, cr) +#define sh_rect_draw(rect, cr) shape_draw((shape_t *)rect, cr) +static +void sh_update_area(shape_t *sh) { + int i; + co_aix x, y; + area_t *area = &sh->area; + + if(sh->num_points == 0) { + area_set(area, 0, 0, 0, 0); + return; + } + + area_set(area, sh->points[0][0], sh->points[0][1], 1, 1); + for(i = 1; i < sh->num_points; i++) { + x = sh->points[i][0]; + y = sh->points[i][1]; + area_extent(area, x, y); + } +} struct redraw_man { cairo_t *cr; + coord_t *root_coord; int shape_gl_sz; shape_t *shape_gl[32]; + STAILQ(shape_t) all_shapes; }; typedef struct redraw_man redraw_man_t; #define rdman_get_cr(rdman) ((rdman)->cr) -#define rdman_get_gen_geos(rdman) (&(rdman)->gen_geos) #define rdman_force_clean(rdman) OK -#define rdman_geos(rdman, geo) NULL -#define rdman_clear_shape_gl(rdman) \ - do {(rdman)->shape_gl_sz = 0; } while(0) +#define rdman_clear_shape_gl(rdman) do {(rdman)->shape_gl_sz = 0; } while(0) static int rdman_add_shape_gl(redraw_man_t *rdman, shape_t *shape) { (rdman)->shape_gl[(rdman)->shape_gl_sz++] = shape; return OK; @@ -182,9 +339,162 @@ #define rdman_get_shape_gl(rdman, idx) \ (rdman)->shape_gl[idx] #define rdman_shape_gl_len(rdman) (rdman)->shape_gl_sz -static shape_t *rdman_shapes(redraw_man_t *rdman, shape_t *last_shape); +static shape_t *rdman_shapes(redraw_man_t *rdman, shape_t *last_shape) { + if(last_shape == NULL) + return STAILQ_HEAD(rdman->all_shapes); + + return STAILQ_NEXT(shape_t, all_next, last_shape); +} +#define redraw_man_init(rdman, cr, backend) \ + do { \ + memset(rdman, 0, sizeof(redraw_man_t)); \ + (rdman)->cr = cr; \ + (rdman)->root_coord = rdman_coord_new_noparent(rdman); \ + } while(0) +#define redraw_man_destroy(rdman) \ + do { \ + free(rdman); \ + } while(0) +#define rdman_get_root(rdman) ((rdman)->root_coord) + +static coord_t *rdman_coord_new_noparent(redraw_man_t *rdman); + +static +redraw_man_t *redraw_man_new(cairo_t *cr, cairo_t *backend) { + redraw_man_t *rdman; + + rdman = O_ALLOC(redraw_man_t); + redraw_man_init(rdman, cr, backend); + return rdman; +} +#define redraw_man_free(rdman) \ + do { \ + redraw_man_destroy(rdman); \ + free(rdman); \ + } while(0) + +static +int cairo_in_fill(cairo_t *cr, int x, int y) { + shape_t *shape; + int i; + + for(shape = STAILQ_HEAD(cr->drawed); + shape != NULL; + shape = STAILQ_NEXT(shape_t, drawed_next, shape)) { + for(i = 0; i < shape->num_points; i++) + if(shape->points[i][0] == x && + shape->points[i][1] == y) + return 1; + } + return 0; +} + +#define cairo_in_stroke cairo_in_fill + +static +void rdman_coord_init_noparent(redraw_man_t *rdman, coord_t *co) { + memset(co, 0, sizeof(coord_t)); + MB_OBJ_INIT(&co->obj, MBO_COORD); + STAILQ_INIT(co->children); + STAILQ_INIT(co->shapes); +} + +static +void rdman_coord_init(redraw_man_t *rdman, coord_t *co, coord_t *parent) { + rdman_coord_init_noparent(rdman, co); + STAILQ_INS_TAIL(parent->children, coord_t, sibling, co); + co->parent = parent; +} + +static +coord_t *rdman_coord_new(redraw_man_t *rdman, coord_t *parent) { + coord_t *coord; + + coord = O_ALLOC(coord_t); + rdman_coord_init(rdman, coord, parent); + + return coord; +} +coord_t *rdman_coord_new_noparent(redraw_man_t *rdman) { + coord_t *coord; + coord = O_ALLOC(coord_t); + rdman_coord_init_noparent(rdman, coord); + + return coord; +} + +static +void rdman_coord_free(redraw_man_t *rdman, coord_t *coord) { + free(coord); +} + +static +shape_t *rdman_shape_new(redraw_man_t *rdman) { + shape_t *shape; + + shape = O_ALLOC(shape_t); + memset(shape, 0, sizeof(shape_t)); + MB_OBJ_INIT(&shape->obj, MBO_PATH); + STAILQ_INS(rdman->all_shapes, shape_t, all_next, shape); + + return shape; +} + +static +void rdman_shape_free(redraw_man_t *rdman, shape_t *shape) { + STAILQ_REMOVE(rdman->all_shapes, shape_t, all_next, shape); + free(shape); +} + +#define shape_add_point(shape, x, y) \ + do { \ + (shape)->points[(shape)->num_points][0] = x; \ + (shape)->points[(shape)->num_points][1] = y; \ + (shape)->num_points++; \ + sh_update_area(shape); \ + if((shape)->coord) \ + coord_update_area_ancestors((shape)->coord); \ + } while(0) + +static +int rdman_add_shape(redraw_man_t *rdman, shape_t *shape, + coord_t *parent) { + STAILQ_INS_TAIL(parent->shapes, shape_t, sibling, shape); + shape->coord = parent; + + return OK; +} + +static +void *cairo_image_surface_get_data(cairo_surface_t *surf) { + cairo_t *cr; + shape_t *shape1, *shape2; + co_aix x1, y1, x2, y2; + int i, j; + + cr = surf->cr; + + STAILQ_FOR_EACH(cr->drawed, shape_t, sibling, shape1) { + for(i = 0; i < shape1->num_points; i++) { + x1 = shape1->points[i][0]; + y1 = shape1->points[i][1]; + STAILQ_FOR_EACH(cr->clip_pathes, shape_t, sibling, shape2) { + for(j = 0; j < shape2->num_points; j++) { + x2 = shape2->points[j][0]; + y2 = shape2->points[j][1]; + if(x1 == x2 && y1 == y2) { + surf->data[0] = 1; + return surf->data; + } + } + } + } + } + surf->data[0] = 0; + return surf->data; +} /* ============================================================ */ #endif /* UNITTEST */ @@ -303,6 +613,7 @@ co_aix x, co_aix y, int *in_stroke) { coord_t *cur_coord, *root; shape_t *shape; + area_t *area; int r; if(IS_MBO_SHAPES(obj)) { @@ -311,9 +622,12 @@ return r; } root = (coord_t *)obj; - for(cur_coord = postorder_coord_subtree(root, NULL); - cur_coord != NULL; - cur_coord = postorder_coord_subtree(root, cur_coord)) { + FOR_COORDS_PREORDER(root, cur_coord) { + area = coord_get_area(cur_coord); + if(!area_pos_is_in(area, x, y)) { + preorder_coord_skip_subtree(cur_coord); + continue; + } FOR_COORD_SHAPES(cur_coord, shape) { r = _shape_pos_is_in(shape, x, y, in_stroke, rdman_get_cr(rdman)); if(r) @@ -529,39 +843,266 @@ static redraw_man_t *_fake_rdman(void) { redraw_man_t *rdman; - cairo_surface_t *surface; + cairo_t *cr, *backend; + cairo_surface_t *surf; - rdman = (redraw_man_t *)malloc(sizeof(redraw_man_t)); - surface = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); - rdman->cr = cairo_create(surface); - DARRAY_INIT(&rdman->gen_geos); + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + backend = cairo_create(surf); + rdman = redraw_man_new(cr, backend); + return rdman; } static void _free_fake_rdman(redraw_man_t *rdman) { + cairo_surface_destroy(rdman->cr->tgt); cairo_destroy(rdman->cr); - DARRAY_DESTROY(&rdman->gen_geos); free(rdman); } static void test_mb_obj_pos_is_in(void) { redraw_man_t *rdman; - mb_obj_t *obj; + shape_t *shape; + coord_t *root, *child_coord; + int in_stroke = 0; + int r; rdman = _fake_rdman(); CU_ASSERT(rdman != NULL); + root = rdman_get_root(rdman); + + child_coord = rdman_coord_new(rdman, root); + CU_ASSERT(child_coord != NULL); + + shape = rdman_shape_new(rdman); + CU_ASSERT(shape != NULL); + + rdman_add_shape(rdman, shape, child_coord); + + shape_add_point(shape, 3, 12); + + shape->fill = shape; + shape->stroke = shape; + + r = mb_obj_pos_is_in(rdman, (mb_obj_t *)shape, 3, 12, &in_stroke); + CU_ASSERT(r == TRUE); + + r = mb_obj_pos_is_in(rdman, (mb_obj_t *)shape, 3, 13, &in_stroke); + CU_ASSERT(r == FALSE); + + r = mb_obj_pos_is_in(rdman, (mb_obj_t *)root, 3, 12, &in_stroke); + CU_ASSERT(r == TRUE); + + r = mb_obj_pos_is_in(rdman, (mb_obj_t *)root, 4, 12, &in_stroke); + CU_ASSERT(r == FALSE); + + rdman_shape_free(rdman, shape); _free_fake_rdman(rdman); } static void test_is_obj_objs_overlay(void) { + redraw_man_t *rdman; + coord_t *root, *coord1, *coord2; + shape_t *shape1, *shape2, *shape3; + cairo_t *cr; + cairo_surface_t *surf; + int r; + + rdman = _fake_rdman(); + CU_ASSERT(rdman != NULL); + + root = rdman_get_root(rdman); + + coord1 = rdman_coord_new(rdman, root); + shape1 = rdman_shape_new(rdman); + rdman_add_shape(rdman, shape1, coord1); + + coord2 = rdman_coord_new(rdman, root); + shape2 = rdman_shape_new(rdman); + rdman_add_shape(rdman, shape2, coord2); + + shape3 = rdman_shape_new(rdman); + rdman_add_shape(rdman, shape3, coord2); + + shape_add_point(shape1, 3, 2); + shape_add_point(shape2, 5, 5); + shape_add_point(shape3, 4, 3); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)coord1, (mb_obj_t *)coord2, cr); + CU_ASSERT(!r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(coord2, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)shape1, (mb_obj_t *)coord2, cr); + CU_ASSERT(!r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(coord2, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)coord1, (mb_obj_t *)shape2, cr); + CU_ASSERT(!r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(shape2, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)shape1, (mb_obj_t *)shape2, cr); + CU_ASSERT(!r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(shape2, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)shape1, (mb_obj_t *)shape3, cr); + CU_ASSERT(!r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(shape3, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)coord1, (mb_obj_t *)shape3, cr); + CU_ASSERT(!r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(shape3, GEF_OV_DRAW); + + shape_add_point(shape1, 5, 5); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)coord1, (mb_obj_t *)coord2, cr); + CU_ASSERT(r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(coord2, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)shape1, (mb_obj_t *)coord2, cr); + CU_ASSERT(r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(coord2, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)coord1, (mb_obj_t *)shape2, cr); + CU_ASSERT(r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(shape2, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)shape1, (mb_obj_t *)shape2, cr); + CU_ASSERT(r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(shape2, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)shape1, (mb_obj_t *)shape3, cr); + CU_ASSERT(!r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(shape3, GEF_OV_DRAW); + + surf = cairo_image_surface_create(CAIRO_FORMAT_A1, 100, 100); + cr = cairo_create(surf); + r = _is_obj_objs_overlay((mb_obj_t *)coord1, (mb_obj_t *)shape3, cr); + CU_ASSERT(r); + cairo_destroy(cr); + cairo_surface_destroy(surf); + sh_clear_flags(shape3, GEF_OV_DRAW); + + rdman_shape_free(rdman, shape1); + rdman_shape_free(rdman, shape2); + rdman_shape_free(rdman, shape3); + rdman_coord_free(rdman, coord1); + rdman_coord_free(rdman, coord2); + _free_fake_rdman(rdman); } static void test_mb_objs_are_overlay(void) { + redraw_man_t *rdman; + coord_t *root, *coord1, *coord2; + shape_t *shape1, *shape2, *shape3; + int r; + + rdman = _fake_rdman(); + + root = rdman_get_root(rdman); + + coord1 = rdman_coord_new(rdman, root); + shape1 = rdman_shape_new(rdman); + rdman_add_shape(rdman, shape1, coord1); + + coord2 = rdman_coord_new(rdman, root); + shape2 = rdman_shape_new(rdman); + rdman_add_shape(rdman, shape2, coord2); + + shape3 = rdman_shape_new(rdman); + rdman_add_shape(rdman, shape3, coord2); + + shape_add_point(shape1, 3, 2); + shape_add_point(shape2, 5, 5); + shape_add_point(shape3, 4, 3); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)coord1, (mb_obj_t *)coord2); + CU_ASSERT(!r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)shape1, (mb_obj_t *)coord2); + CU_ASSERT(!r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)shape1, (mb_obj_t *)shape2); + CU_ASSERT(!r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)coord1, (mb_obj_t *)shape2); + CU_ASSERT(!r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)shape1, (mb_obj_t *)shape3); + CU_ASSERT(!r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)coord1, (mb_obj_t *)shape3); + CU_ASSERT(!r); + + shape_add_point(shape1, 5, 5); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)coord1, (mb_obj_t *)coord2); + CU_ASSERT(r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)shape1, (mb_obj_t *)coord2); + CU_ASSERT(r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)shape1, (mb_obj_t *)shape2); + CU_ASSERT(r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)coord1, (mb_obj_t *)shape2); + CU_ASSERT(r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)shape1, (mb_obj_t *)shape3); + CU_ASSERT(!r); + + r = mb_objs_are_overlay(rdman, (mb_obj_t *)coord1, (mb_obj_t *)shape3); + CU_ASSERT(!r); + + _free_fake_rdman(rdman); } CU_pSuite get_event_suite(void) {