#undef BETWEEN
#endif
#define BETWEEN(a,b,c) (((a) <= (b)) && ((b) <= (c)))
-#define INSIDE(p,b) (BETWEEN(b.LL.x,p.x,b.UR.x) && BETWEEN(b.LL.y,p.y,b.UR.y))
+#define INSIDE(p,b) (BETWEEN((b).LL.x,(p).x,(b).UR.x) && BETWEEN((b).LL.y,(p).y,(b).UR.y))
+#define OVERLAP(b0,b1) (((b0).UR.x >= (b1).LL.x) && ((b1).UR.x >= (b0).LL.x) && ((b0).UR.y >= (b1).LL.y) && ((b1).UR.y >= (b0).LL.y))
+#define CONTAINS(b0,b1) (((b0).UR.x >= (b1).UR.x) && ((b0).UR.y >= (b1).UR.y) && ((b0).LL.x <= (b1).LL.x) && ((b0).LL.y <= (b1).LL.y))
#define ROUND(f) ((f>=0)?(int)(f + .5):(int)(f - .5))
#define RADIANS(deg) ((deg)/180.0 * PI)
boolean box_overlap(box b0, box b1)
{
- if ((b0.UR.x < b1.LL.x) || (b1.UR.x < b0.LL.x)
- || (b0.UR.y < b1.LL.y) || (b1.UR.y < b0.LL.y))
- return FALSE;
- return TRUE;
+ return OVERLAP(b0, b1);
}
boolean boxf_overlap(boxf b0, boxf b1)
{
- if ((b0.UR.x < b1.LL.x) || (b1.UR.x < b0.LL.x)
- || (b0.UR.y < b1.LL.y) || (b1.UR.y < b0.LL.y))
- return FALSE;
- return TRUE;
+ return OVERLAP(b0, b1);
}
-boolean boxf_contains_p(boxf b0, boxf b1)
+boolean box_contains(box b0, box b1)
{
- if ((b0.UR.x >= b1.UR.x) && (b0.UR.y >= b1.UR.y)
- && (b0.LL.x <= b1.LL.x) && (b0.LL.y <= b1.LL.y))
- return TRUE;
- return FALSE;
+ return CONTAINS(b0, b1);
+}
+boolean boxf_contains(boxf b0, boxf b1)
+{
+ return CONTAINS(b0, b1);
}
int maptoken(char *p, char **name, int *val)
emit_graph(job, job->g);
}
-static boolean inside_node(node_t *n, pointf p)
+static boolean inside_node(node_t *n, boxf b)
{
+ boxf bb;
// inside_t ictxt;
- if (! INSIDE(p, ND_bb(n)))
+ bb = ND_bb(n);
+ if (! OVERLAP(b, bb))
return FALSE;
// ictxt.s.n = n;
return TRUE;
}
-static boolean inside_label(edge_t *e, pointf p)
+static boolean inside_label(edge_t *e, boxf b)
{
textlabel_t *lp;
double sx, sy;
bb.UR.x = lp->p.x + sx;
bb.LL.y = lp->p.y - sy;
bb.UR.y = lp->p.y + sy;
- return INSIDE(p, bb);
+ return OVERLAP(b, bb);
}
-static boolean inside_spline(edge_t *e, pointf p)
+static boolean inside_spline(edge_t *e, boxf b)
{
int i, j, k;
bezier bz;
spl = ED_spl(e);
if (spl == NULL)
return FALSE;
-
- if (! INSIDE(p, spl->bb))
+
+ bbf = spl->bb;
+ if (! OVERLAP(b, bbf))
return FALSE;
for (i = 0; i < spl->size; i++) {
bb.UR.x = MAX(bb.UR.x,bz.list[k].x);
bb.UR.y = MAX(bb.UR.y,bz.list[k].y);
}
- B2BF(bb,bbf);
- if (INSIDE(p,bbf)) {
+ B2BF(bb, bbf);
+ if (OVERLAP(b, bbf)) {
/* FIXME - check if really close enough to actual curve */
return TRUE;
}
return FALSE;
}
-static boolean inside_edge(edge_t *e, pointf p)
+static boolean inside_edge(edge_t *e, boxf b)
{
- if (inside_spline(e, p))
+ if (inside_spline(e, b))
return TRUE;
// FIXME
// if (inside_arrow(e))
// return TRUE;
- return inside_label(e, p);
+ return inside_label(e, b);
}
/* recursively find innermost cluster containing the point */
-static graph_t *gvevent_find_cluster(graph_t *g, pointf p)
+static graph_t *gvevent_find_cluster(graph_t *g, boxf b)
{
int i;
graph_t *sg;
boxf bb;
for (i = 1; i <= GD_n_cluster(g); i++) {
- sg = gvevent_find_cluster(GD_clust(g)[i], p);
+ sg = gvevent_find_cluster(GD_clust(g)[i], b);
if (sg)
return(sg);
}
B2BF(GD_bb(g), bb);
- if (INSIDE(p, bb))
+ if (OVERLAP(b, bb))
return g;
return NULL;
}
-static void * gvevent_find_obj(graph_t *g, pointf p)
+static void * gvevent_find_obj(graph_t *g, boxf b)
{
graph_t *sg;
node_t *n;
/* edges might overlap nodes, so search them first */
for (n = agfstnode(g); n; n = agnxtnode(g, n))
for (e = agfstout(g, n); e; e = agnxtout(g, e))
- if (inside_edge(e, p))
+ if (inside_edge(e, b))
return (void *)e;
/* search graph backwards to get topmost node, in case of overlap */
for (n = aglstnode(g); n; n = agprvnode(g, n))
- if (inside_node(n, p))
+ if (inside_node(n, b))
return (void *)n;
/* search for innermost cluster */
- sg = gvevent_find_cluster(g, p);
+ sg = gvevent_find_cluster(g, b);
if (sg)
return (void *)sg;
return (void *)g;
}
+/* CLOSEENOUGH is in window units - probably should be a feature... */
+#define CLOSEENOUGH 1
+
static void gvevent_find_current_obj(GVJ_t * job, double x, double y)
{
void *obj;
pointf p;
+ boxf b;
+ double closeenough;
/* convert window point to graph coordinates */
if (job->rotation) {
p.x = job->focus.x + (x - job->width / 2.) / job->compscale.x;
p.y = job->focus.y + (y - job->height / 2.) / job->compscale.y;
}
+ closeenough = CLOSEENOUGH / job->compscale.x;
+
+ b.UR.x = p.x + closeenough;
+ b.UR.y = p.y + closeenough;
+ b.LL.x = p.x - closeenough;
+ b.LL.y = p.y - closeenough;
- obj = gvevent_find_obj(job->g, p);
+ obj = gvevent_find_obj(job->g, b);
if (obj != job->current_obj) {
job->current_obj = obj;
fprintf(stderr,"obj=%x kind=%d\n",obj,agobjkind(obj));