7
/* data access - avoid direct access */
9
ddnode_t *dd_node(Agnode_t *n)
11
return (ddnode_t*)(AGDATA(n));
14
ddedge_t *dd_edge(Agedge_t *e)
16
return (ddedge_t*)(AGDATA(e));
19
ILnode_t *dd_nspec(Agnode_t *n) {
20
return il_node(dd_node(n)->model);
23
ILnode_t *ddm_nspec(Agnode_t *mn)
25
return ((ddmdlnode_t*)(AGDATA(mn)))->base.client;
28
ILedge_t *ddm_espec(Agedge_t *me)
30
return ((ddmdledge_t*)(AGDATA(me)))->base.client;
33
ILedge_t *dd_espec(Agedge_t *e)
35
return il_edge(dd_edge(e)->path->model);
38
ILedge_t *dd_pathspec(ddpath_t *path)
40
return path->base.client;
43
Agnode_t *dd_rep(Agnode_t *mn)
45
return ((ddmdlnode_t*)(AGDATA(mn)))->rep;
48
ddpath_t *dd_pathrep(Agedge_t *me)
50
return (ddpath_t*)(AGDATA(me));
53
int dd_rank(Agnode_t *n)
55
return dd_node(n)->rank;
58
int dd_order(Agnode_t *n)
60
return dd_node(n)->order;
63
int dd_newrank(Agnode_t *n)
65
return dd_node(n)->newrank;
68
int dd_oldrank(Agnode_t *n)
70
return dd_node(n)->oldrank;
73
void dd_set_oldrank(Agnode_t *n)
75
dd_node(n)->oldrank = dd_node(n)->rank;
78
void dd_set_newrank(Agnode_t *n, int r)
80
dd_node(n)->newrank = r;
83
void dd_fix_coord(Agnode_t *n, ilbool val)
85
dd_node(n)->coord_fixed = val;
88
ilbool dd_coord_fixed(Agnode_t *n)
90
return dd_node(n)->coord_fixed;
93
void dd_fix_order(Agnode_t *n, ilbool val)
95
dd_node(n)->order_fixed = val;
98
ilbool dd_order_fixed(Agnode_t *n)
100
return dd_node(n)->order_fixed;
103
void dd_set_old_coord(Agnode_t *n)
108
spec->prev = spec->cur;
111
void dd_set_ycoord(ddview_t *view, Agnode_t *n)
115
y = dd_rankd(view,dd_rank(n))->y_base;
119
double dd_ranksep(ddview_t *view)
121
return il_nodesep(BASE(view)).y;
124
double dd_minlen(Agedge_t *e)
127
return dd_espec(e)->length_hint;
130
double dd_efactor(Agedge_t *e)
132
return dd_espec(e)->cost;
135
unsigned char dd_dfsmark(Agnode_t *n)
137
return dd_node(n)->dfsmark;
140
void dd_set_dfsmark(Agnode_t *n, unsigned char val)
142
dd_node(n)->dfsmark = val;
145
double dd_uv_sep(ddview_t *view, Agnode_t *left, Agnode_t *right)
148
s0 = dd_nodesize(view,left).x;
149
s1 = dd_nodesize(view,right).x;
150
rv = (s0 + s1) / 2.0 + dd_nodesep(view).x;
154
ddpath_t *dd_path(Agedge_t *e) { return (ddpath_t*)AGDATA(dd_edge(e)->path->model); }
155
Agnode_t *dd_pathhead(Agedge_t *e) { return aghead(dd_path(e)->last); }
156
Agnode_t *dd_pathtail(Agedge_t *e) { return agtail(dd_path(e)->first); }
157
Agedge_t *dd_first_elt(Agedge_t *e) { return dd_path(e)->first; }
158
Agedge_t *dd_last_elt(Agedge_t *e) { return dd_path(e)->last; }
160
void dd_set_first(ddpath_t *p, Agedge_t *first) {
163
void dd_set_last(ddpath_t *p, Agedge_t *last) {
166
void dd_set_firstlast(ddpath_t *p, Agedge_t *first, Agedge_t *last) {
167
p->first = first; p->last = last;
171
ilcoord_t dd_pos(Agnode_t *n) { return dd_node(n)->cur.pos; }
173
int dd_is_a_vnode(Agnode_t *n)
175
return (dd_node(n)->model == NILnode);
178
ilcoord_t dd_nodesize(ddview_t *view, Agnode_t *node)
182
if (node == NILnode) rv.x = rv.y = 0;
183
else if (dd_is_a_vnode(node)) { /* is a virtual node */
185
rv.x = 2.0 * il_nodesep(BASE(view)).x;
188
rv = il_nodesize(BASE(view),dd_node(node)->model);
189
if (rv.x <= 0) rv.x = EPSILON;
190
if (rv.y <= 0) rv.y = EPSILON;
195
void dd_set_x(Agnode_t *n, double x)
202
nd->cur.valid = TRUE; /* see below, sort of a cheat */
204
spec = il_node(nd->model);
206
spec->pos_valid = TRUE;
210
void dd_set_y(Agnode_t *n, double y)
217
nd->cur.valid = TRUE; /* see above, still sort of a cheat */
219
spec = il_node(nd->model);
221
spec->pos_valid = TRUE;
225
static char DDrecname[] = "_dag";
227
Agedge_t *dd_open_edge(ddview_t *view, Agnode_t *u, Agnode_t *v, ddpath_t *path)
232
rv = agidedge(u,v,AGID(path->model),TRUE);
233
ed = agbindrec(rv,DDrecname,sizeof(ddedge_t),TRUE);
238
void dd_close_edge(ddview_t *view, Agedge_t *e)
243
if (ed->cn) agdelete(view->con[XCON].g,ed->cn);
244
agdelete(view->layout,e);
247
Agnode_t *dd_open_node(ddview_t *view, Agnode_t *model_n)
252
static unsigned long anon_id = 1;
254
if (model_n) id = (unsigned long)(model_n->base.tag.id);
255
else {id = anon_id; anon_id += 2;}
257
n = agidnode(view->layout,id,TRUE);
258
nd = agbindrec(n,DDrecname,sizeof(ddnode_t),TRUE);
260
nd->model = agsubnode(BASE(view)->model.main,model_n,FALSE);
261
((ddmdlnode_t*)(AGDATA(model_n)))->rep = n;
266
Agnode_t *dd_find_node(ddview_t *view, ILnode_t *spec)
268
return agidnode(view->layout,(unsigned long)spec,FALSE);
271
void dd_close_node(ddview_t *view, Agnode_t *n)
273
/* must already be isolated in graph */
274
assert(agfstedge(n) == NIL(Agedge_t*));
275
if (dd_node_in_config(n))
276
dd_rank_delete(view,n);
277
agdelete(view->layout,n);
280
ddpath_t *dd_open_path(ddview_t *view, ILedge_t *spec)
282
Agedge_t *model_edge;
285
model_edge = il_find_edge(BASE(view),spec);
286
assert(il_find_edge(BASE(view),spec));
287
path = (ddpath_t*)AGDATA(model_edge);
288
path->model = model_edge;
292
ddpath_t *dd_find_path(ddview_t *view, ILedge_t *spec)
296
model_e = il_find_edge(BASE(view), spec);
297
if (model_e) return (ddpath_t*)AGDATA(model_e);
298
else return NIL(ddpath_t*);
301
void dd_close_path(ddview_t *view, ddpath_t *path)
307
if (path->first == path->last) {
308
dd_invalidate_mval(dd_pathtail(path->first),DOWN);
309
dd_invalidate_mval(dd_pathhead(path->last),UP);
310
dd_close_edge(view, path->first);
312
else for (vn = path->first->node; dd_is_a_vnode(vn); vn = nv) {
313
nv = agfstout(vn)->node;
314
for (ve = agfstedge(vn); ve; ve = agnxtedge(ve,vn))
315
dd_close_edge(view, ve);
316
dd_close_node(view, vn);
319
else { } /* no work for flat or self edge */
320
if (path->unclipped_path)
321
il_freecurve(vmregion(path->unclipped_path), path->unclipped_path);
322
path->unclipped_path = NIL(ilcurve_t*);
323
path->first = path->last = NILedge;
324
/* note, do not close model edge until callback is cleared ! */
327
ilcoord_t dd_nodesep(ddview_t *view) {return il_nodesep((engview_t*)view);}
329
ilbool dd_constraint(Agedge_t *e)
331
return dd_espec(e)->constraint;