Graphviz  2.41.20170921.2350
dotinit.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 
15 #include <time.h>
16 #include "dot.h"
17 #include "pack.h"
18 #include "aspect.h"
19 
20 static void
21 dot_init_subg(graph_t * g, graph_t* droot)
22 {
23  graph_t* subg;
24 
25  if ((g != agroot(g)))
26  agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
27  if (g == droot)
28  GD_dotroot(agroot(g)) = droot;
29 
30  for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
31  dot_init_subg(subg, droot);
32  }
33 }
34 
35 
36 static void
37 dot_init_node(node_t * n)
38 {
39  agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //graph custom data
42  alloc_elist(4, ND_in(n));
43  alloc_elist(4, ND_out(n));
44  alloc_elist(2, ND_flat_in(n));
45  alloc_elist(2, ND_flat_out(n));
46  alloc_elist(2, ND_other(n));
47  ND_UF_size(n) = 1;
48 }
49 
50 static void
51 dot_init_edge(edge_t * e)
52 {
53  char *tailgroup, *headgroup;
54  agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); //graph custom data
56 
57  ED_weight(e) = late_int(e, E_weight, 1, 0);
58  tailgroup = late_string(agtail(e), N_group, "");
59  headgroup = late_string(aghead(e), N_group, "");
60  ED_count(e) = ED_xpenalty(e) = 1;
61  if (tailgroup[0] && (tailgroup == headgroup)) {
62  ED_xpenalty(e) = CL_CROSS;
63  ED_weight(e) *= 100;
64  }
65  if (nonconstraint_edge(e)) {
66  ED_xpenalty(e) = 0;
67  ED_weight(e) = 0;
68  }
69 
70  ED_showboxes(e) = late_int(e, E_showboxes, 0, 0);
71  ED_minlen(e) = late_int(e, E_minlen, 1, 0);
72 }
73 
74 void
76 {
77  node_t *n;
78  edge_t *e;
79 
80  for (n = agfstnode(g); n; n = agnxtnode(g, n))
81  dot_init_node(n);
82  for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
83  for (e = agfstout(g, n); e; e = agnxtout(g, e))
84  dot_init_edge(e);
85  }
86 }
87 
88 #if 0 /* not used */
89 static void free_edge_list(elist L)
90 {
91  edge_t *e;
92  int i;
93 
94  for (i = 0; i < L.size; i++) {
95  e = L.list[i];
96  free(e);
97  }
98 }
99 #endif
100 
101 static void
102 dot_cleanup_node(node_t * n)
103 {
104  free_list(ND_in(n));
105  free_list(ND_out(n));
107  free_list(ND_flat_in(n));
108  free_list(ND_other(n));
109  free_label(ND_label(n));
110  free_label(ND_xlabel(n));
111  if (ND_shape(n))
112  ND_shape(n)->fns->freefn(n);
113  agdelrec(n, "Agnodeinfo_t");
114 }
115 
116 static void free_virtual_edge_list(node_t * n)
117 {
118  edge_t *e;
119  int i;
120 
121  for (i = ND_in(n).size - 1; i >= 0; i--) {
122  e = ND_in(n).list[i];
123  delete_fast_edge(e);
124  free(e->base.data);
125  free(e);
126  }
127  for (i = ND_out(n).size - 1; i >= 0; i--) {
128  e = ND_out(n).list[i];
129  delete_fast_edge(e);
130  free(e->base.data);
131  free(e);
132  }
133 }
134 
135 static void free_virtual_node_list(node_t * vn)
136 {
137  node_t *next_vn;
138 
139  while (vn) {
140  next_vn = ND_next(vn);
141  free_virtual_edge_list(vn);
142  if (ND_node_type(vn) == VIRTUAL) {
143  free_list(ND_out(vn));
144  free_list(ND_in(vn));
145  free(vn->base.data);
146  free(vn);
147  }
148  vn = next_vn;
149  }
150 }
151 
152 static void
153 dot_cleanup_graph(graph_t * g)
154 {
155  int i;
156  graph_t *subg;
157  for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
158  dot_cleanup_graph(subg);
159  }
160  if (! agbindrec(g, "Agraphinfo_t", 0, TRUE)) return;
161  if (GD_clust(g)) free (GD_clust(g));
162  if (GD_rankleader(g)) free (GD_rankleader(g));
163 
164  free_list(GD_comp(g));
165  if (GD_rank(g)) {
166  for (i = GD_minrank(g); i <= GD_maxrank(g); i++)
167  free(GD_rank(g)[i].av);
168  if (GD_minrank(g) == -1)
169  free(GD_rank(g)-1);
170  else
171  free(GD_rank(g));
172  }
173  if (g != agroot(g)) {
174  free_label (GD_label(g));
175  agdelrec(g,"Agraphinfo_t");
176  }
177 }
178 
179 /* delete the layout (but retain the underlying graph) */
181 {
182  node_t *n;
183  edge_t *e;
184 
185  free_virtual_node_list(GD_nlist(g));
186  for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
187  for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
188  gv_cleanup_edge(e);
189  }
190  dot_cleanup_node(n);
191  }
192  dot_cleanup_graph(g);
193 }
194 
195 #ifdef DEBUG
196 int
197 fastn (graph_t * g)
198 {
199  node_t* u;
200  int cnt = 0;
201  for (u = GD_nlist(g); u; u = ND_next(u)) cnt++;
202  return cnt;
203 }
204 
205 #if DEBUG > 1
206 static void
207 dumpRanks (graph_t * g)
208 {
209  int i, j;
210  node_t* u;
211  rank_t *rank = GD_rank(g);
212  int rcnt = 0;
213  for (i = GD_minrank(g); i <= GD_maxrank(g); i++) {
214  fprintf (stderr, "[%d] :", i);
215  for (j = 0; j < rank[i].n; j++) {
216  u = rank[i].v[j];
217  rcnt++;
218  if (streq(agnameof(u),"virtual"))
219  fprintf (stderr, " %x", u);
220  else
221  fprintf (stderr, " %s", agnameof(u));
222 
223  }
224  fprintf (stderr, "\n");
225  }
226  fprintf (stderr, "count %d rank count = %d\n", fastn(g), rcnt);
227 }
228 #endif
229 #endif
230 
231 
232 static void
233 remove_from_rank (Agraph_t * g, Agnode_t* n)
234 {
235  Agnode_t* v = NULL;
236  int j, rk = ND_rank(n);
237 
238  for (j = 0; j < GD_rank(g)[rk].n; j++) {
239  v = GD_rank(g)[rk].v[j];
240  if (v == n) {
241  for (j++; j < GD_rank(g)[rk].n; j++) {
242  GD_rank(g)[rk].v[j-1] = GD_rank(g)[rk].v[j];
243  }
244  GD_rank(g)[rk].n--;
245  break;
246  }
247  }
248  assert (v == n); /* if found */
249 }
250 
251 /* removeFill:
252  * This removes all of the fill nodes added in mincross.
253  * It appears to be sufficient to remove them only from the
254  * rank array and fast node list of the root graph.
255  */
256 static void
257 removeFill (Agraph_t * g)
258 {
259  Agnode_t* n;
260  Agnode_t* nxt;
261  Agraph_t* sg = agsubg (g, "_new_rank", 0);
262 
263  if (!sg) return;
264  for (n = agfstnode(sg); n; n = nxt) {
265  nxt = agnxtnode(sg, n);
266  delete_fast_node (g, n);
267  remove_from_rank (g, n);
268  dot_cleanup_node (n);
269  agdelnode(g, n);
270  }
271  agdelsubg (g, sg);
272 
273 }
274 
275 #define ag_xset(x,a,v) agxset(x,a,v)
276 #define agnodeattr(g,n,v) agattr(g,AGNODE,n,v)
277 
278 static void
279 attach_phase_attrs (Agraph_t * g, int maxphase)
280 {
281  Agsym_t* rk = agnodeattr(g,"rank","");
282  Agsym_t* order = agnodeattr(g,"order","");
283  Agnode_t* n;
284  char buf[BUFSIZ];
285 
286  for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
287  if (maxphase >= 1) {
288  sprintf(buf, "%d", ND_rank(n));
289  ag_xset(n,rk,buf);
290  }
291  if (maxphase >= 2) {
292  sprintf(buf, "%d", ND_order(n));
293  ag_xset(n,order,buf);
294  }
295  }
296 }
297 
298 static void dotLayout(Agraph_t * g)
299 {
300  aspect_t aspect;
301  aspect_t* asp;
302  int maxphase = late_int(g, agfindgraphattr(g,"phase"), -1, 1);
303 
304  setEdgeType (g, ET_SPLINE);
305  asp = setAspect (g, &aspect);
306 
307  dot_init_subg(g,g);
309 
310  do {
311  dot_rank(g, asp);
312  if (maxphase == 1) {
313  attach_phase_attrs (g, 1);
314  return;
315  }
316  if (aspect.badGraph) {
317  agerr(AGWARN, "dot does not support the aspect attribute for disconnected graphs or graphs with clusters\n");
318  asp = NULL;
319  aspect.nextIter = 0;
320  }
321  dot_mincross(g, (asp != NULL));
322  if (maxphase == 2) {
323  attach_phase_attrs (g, 2);
324  return;
325  }
326  dot_position(g, asp);
327  if (maxphase == 3) {
328  attach_phase_attrs (g, 2); /* positions will be attached on output */
329  return;
330  }
331  aspect.nPasses--;
332  } while (aspect.nextIter && aspect.nPasses);
333  if (GD_flags(g) & NEW_RANK)
334  removeFill (g);
335  dot_sameports(g);
336  dot_splines(g);
337  if (mapbool(agget(g, "compound")))
339 }
340 
341 static void
342 initSubg (Agraph_t* sg, Agraph_t* g)
343 {
344  agbindrec(sg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
345  GD_drawing(sg) = NEW(layout_t);
346  GD_drawing(sg)->quantum = GD_drawing(g)->quantum;
347  GD_drawing(sg)->dpi = GD_drawing(g)->dpi;
348  GD_gvc(sg) = GD_gvc (g);
349  GD_charset(sg) = GD_charset (g);
350  GD_rankdir2(sg) = GD_rankdir2 (g);
351  GD_nodesep(sg) = GD_nodesep(g);
352  GD_ranksep(sg) = GD_ranksep(g);
353  GD_fontnames(sg) = GD_fontnames(g);
354 }
355 
356 /* attachPos:
357  * the packing library assumes all units are in inches stored in ND_pos, so we
358  * have to copy the position info there.
359  */
360 static void
361 attachPos (Agraph_t* g)
362 {
363  node_t* np;
364  double* ps = N_NEW(2*agnnodes(g), double);
365 
366  for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
367  ND_pos(np) = ps;
368  ps[0] = PS2INCH(ND_coord(np).x);
369  ps[1] = PS2INCH(ND_coord(np).y);
370  ps += 2;
371  }
372 }
373 
374 /* resetCoord:
375  * Store new position info from pack library call, stored in ND_pos in inches,
376  * back to ND_coord in points.
377  */
378 static void
379 resetCoord (Agraph_t* g)
380 {
381  node_t* np = agfstnode(g);
382  double* sp = ND_pos(np);
383  double* ps = sp;
384 
385  for (np = agfstnode(g); np; np = agnxtnode(g, np)) {
386  ND_pos(np) = 0;
387  ND_coord(np).x = INCH2PS(ps[0]);
388  ND_coord(np).y = INCH2PS(ps[1]);
389  ps += 2;
390  }
391  free (sp);
392 }
393 
394 /* copyCluster:
395  */
396 static void
397 copyCluster (Agraph_t* scl, Agraph_t* cl)
398 {
399  int nclust, j;
400  Agraph_t* cg;
401 
402  agbindrec(cl, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
403  GD_bb(cl) = GD_bb(scl);
404  GD_label_pos(cl) = GD_label_pos(scl);
405  memcpy(GD_border(cl), GD_border(scl), 4*sizeof(pointf));
406  nclust = GD_n_cluster(cl) = GD_n_cluster(scl);
407  GD_clust(cl) = N_NEW(nclust+1,Agraph_t*);
408  for (j = 1; j <= nclust; j++) {
409  cg = mapClust(GD_clust(scl)[j]);
410  GD_clust(cl)[j] = cg;
411  copyCluster (GD_clust(scl)[j], cg);
412  }
413  /* transfer cluster label to original cluster */
414  GD_label(cl) = GD_label(scl);
415  GD_label(scl) = NULL;
416 }
417 
418 /* copyClusterInfo:
419  * Copy cluster tree and info from components to main graph.
420  * Note that the original clusters have no Agraphinfo_t at this time.
421  */
422 static void
423 copyClusterInfo (int ncc, Agraph_t** ccs, Agraph_t* root)
424 {
425  int j, i, nclust = 0;
426  Agraph_t* sg;
427  Agraph_t* cg;
428 
429  for (i = 0; i < ncc; i++)
430  nclust += GD_n_cluster(ccs[i]);
431 
432  GD_n_cluster(root) = nclust;
433  GD_clust(root) = N_NEW(nclust+1,Agraph_t*);
434  nclust = 1;
435  for (i = 0; i < ncc; i++) {
436  sg = ccs[i];
437  for (j = 1; j <= GD_n_cluster(sg); j++) {
438  cg = mapClust(GD_clust(sg)[j]);
439  GD_clust(root)[nclust++] = cg;
440  copyCluster (GD_clust(sg)[j], cg);
441  }
442  }
443 }
444 
445 /* doDot:
446  * Assume g has nodes.
447  */
448 static void doDot (Agraph_t* g)
449 {
450  Agraph_t **ccs;
451  Agraph_t *sg;
452  int ncc;
453  int i;
454  pack_info pinfo;
455  int Pack = getPack(g, -1, CL_OFFSET);
456  pack_mode mode = getPackModeInfo (g, l_undef, &pinfo);
457  getPackInfo(g, l_node, CL_OFFSET, &pinfo);
458 
459  if ((mode == l_undef) && (Pack < 0)) {
460  /* No pack information; use old dot with components
461  * handled during layout
462  */
463  dotLayout(g);
464  } else {
465  /* fill in default values */
466  if (mode == l_undef)
467  pinfo.mode = l_graph;
468  else if (Pack < 0)
469  Pack = CL_OFFSET;
470  pinfo.margin = Pack;
471  pinfo.fixed = 0;
472 
473  /* components using clusters */
474  ccs = cccomps(g, &ncc, 0);
475  if (ncc == 1) {
476  dotLayout(g);
477  } else if (GD_drawing(g)->ratio_kind == R_NONE) {
478  pinfo.doSplines = 1;
479 
480  for (i = 0; i < ncc; i++) {
481  sg = ccs[i];
482  initSubg (sg, g);
483  dotLayout (sg);
484  }
485  attachPos (g);
486  packSubgraphs(ncc, ccs, g, &pinfo);
487  resetCoord (g);
488  copyClusterInfo (ncc, ccs, g);
489  } else {
490  /* Not sure what semantics should be for non-trivial ratio
491  * attribute with multiple components.
492  * One possibility is to layout nodes, pack, then apply the ratio
493  * adjustment. We would then have to re-adjust all positions.
494  */
495  dotLayout(g);
496  }
497 
498  for (i = 0; i < ncc; i++) {
499  free (GD_drawing(ccs[i]));
500  dot_cleanup_graph(ccs[i]);
501  agdelete(g, ccs[i]);
502  }
503  free(ccs);
504  }
505 }
506 
508 {
509  if (agnnodes(g)) doDot (g);
511 }
512 
513 Agraph_t * dot_root (void* p)
514 {
515  return GD_dotroot(agroot(p));
516 }
517 
void dotneato_postprocess(Agraph_t *g)
Definition: postproc.c:693
#define GD_label(g)
Definition: types.h:381
void free_label(textlabel_t *p)
Definition: labels.c:209
#define ND_rank(n)
Definition: types.h:529
#define GD_nlist(g)
Definition: types.h:401
#define ET_SPLINE
Definition: const.h:275
#define N_NEW(n, t)
Definition: memory.h:36
void delete_fast_node(Agraph_t *, Agnode_t *)
Definition: fastgr.c:229
int nextIter
Definition: aspect.h:22
#define CL_CROSS
Definition: const.h:157
pack_mode
Definition: pack.h:37
#define GD_rankleader(g)
Definition: types.h:405
#define agnodeattr(g, n, v)
Definition: dotinit.c:276
Definition: pack.h:49
#define ND_xlabel(n)
Definition: types.h:510
Definition: pack.h:37
CGRAPH_API int agdelnode(Agraph_t *g, Agnode_t *arg_n)
Definition: node.c:192
int nPasses
Definition: aspect.h:23
#define GD_n_cluster(g)
Definition: types.h:396
#define GD_border(g)
Definition: types.h:362
#define GD_rankdir2(g)
Definition: types.h:383
#define ND_node_type(n)
Definition: types.h:518
#define ND_flat_in(n)
Definition: types.h:498
#define assert(x)
Definition: cghdr.h:47
void dot_sameports(Agraph_t *)
Definition: sameport.c:34
Definition: geom.h:28
CGRAPH_API long agdelsubg(Agraph_t *g, Agraph_t *sub)
Definition: subg.c:93
#define ND_UF_size(n)
Definition: types.h:493
#define ED_weight(e)
Definition: types.h:606
#define GD_flags(g)
Definition: types.h:369
void dot_splines(Agraph_t *)
Definition: dotsplines.c:519
void common_init_node(node_t *n)
Definition: utils.c:629
CGRAPH_API int agdelete(Agraph_t *g, void *obj)
Definition: obj.c:16
Agobj_t base
Definition: cgraph.h:134
#define ND_pos(n)
Definition: types.h:526
#define alloc_elist(n, L)
Definition: types.h:273
int agerr(agerrlevel_t level, const char *fmt,...)
Definition: agerror.c:141
void delete_fast_edge(Agedge_t *)
Definition: fastgr.c:115
void gv_cleanup_edge(Agedge_t *e)
Definition: utils.c:1947
Agraph_t ** cccomps(Agraph_t *g, int *ncc, char *pfx)
Definition: ccomps.c:608
CGRAPH_API Agraph_t * agfstsubg(Agraph_t *g)
Definition: subg.c:72
pack_mode getPackInfo(Agraph_t *g, pack_mode dflt, int dfltMargin, pack_info *pinfo)
Definition: pack.c:1398
CGRAPH_API Agraph_t * agroot(void *obj)
Definition: obj.c:169
#define GD_dotroot(g)
Definition: types.h:365
CGRAPH_API Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition: edge.c:25
pack_mode mode
Definition: pack.h:54
#define ND_label(n)
Definition: types.h:509
#define GD_ranksep(g)
Definition: types.h:406
#define GD_gvc(g)
Definition: types.h:358
Definition: cgraph.h:388
#define PS2INCH(a_points)
Definition: geom.h:69
char * agget(void *obj, char *name)
Definition: attr.c:428
CGRAPH_API Agraph_t * agraphof(void *obj)
Definition: obj.c:185
CGRAPH_API Agraph_t * agnxtsubg(Agraph_t *subg)
Definition: subg.c:77
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
Definition: edge.c:525
#define NEW_RANK
Definition: const.h:279
boolean * fixed
Definition: pack.h:55
#define ED_showboxes(e)
Definition: types.h:597
CGRAPH_API Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition: subg.c:52
int rank(graph_t *g, int balance, int maxiter)
Definition: ns.c:866
CGRAPH_API Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition: node.c:45
Definition: types.h:261
int doSplines
Definition: pack.h:53
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
Definition: edge.c:533
unsigned int margin
Definition: pack.h:52
#define ND_shape(n)
Definition: types.h:534
#define ND_order(n)
Definition: types.h:520
EXTERN Agsym_t * E_showboxes
Definition: globals.h:107
#define GD_fontnames(g)
Definition: types.h:411
pack_mode getPackModeInfo(Agraph_t *g, pack_mode dflt, pack_info *pinfo)
Definition: pack.c:1364
CGRAPH_API char * agnameof(void *)
Definition: id.c:143
#define VIRTUAL
Definition: const.h:28
#define GD_maxrank(g)
Definition: types.h:389
#define INCH2PS(a_inches)
Definition: geom.h:68
int n
Definition: types.h:211
Definition: types.h:225
void dot_rank(Agraph_t *, aspect_t *)
Definition: rank.c:573
#define ED_count(e)
Definition: types.h:583
int badGraph
Definition: aspect.h:24
EXTERN Agsym_t * N_group
Definition: globals.h:95
edge_t ** list
Definition: types.h:262
CGRAPH_API Agnode_t * agfstnode(Agraph_t *g)
Definition: node.c:38
int late_int(void *obj, attrsym_t *attr, int def, int low)
Definition: utils.c:71
#define GD_clust(g)
Definition: types.h:364
EXTERN Agsym_t * E_minlen
Definition: globals.h:107
#define GD_flip(g)
Definition: types.h:385
Agobj_t base
Definition: cgraph.h:140
Agraph_t * dot_root(void *p)
Definition: dotinit.c:513
#define CL_OFFSET
Definition: const.h:155
int packSubgraphs(int ng, Agraph_t **gs, Agraph_t *root, pack_info *info)
Definition: pack.c:1163
#define NULL
Definition: logic.h:39
node_t ** v
Definition: types.h:212
real cg(Operator Ax, Operator precond, int n, int dim, real *x0, real *rhs, real tol, int maxit, int *flag)
Definition: sparse_solve.c:227
void dot_cleanup(graph_t *g)
Definition: dotinit.c:180
CGRAPH_API int agdelrec(void *obj, char *name)
Definition: rec.c:145
#define agfindgraphattr(g, a)
Definition: types.h:612
#define GD_charset(g)
Definition: types.h:371
EXTERN Agsym_t * E_weight
Definition: globals.h:107
#define ND_in(n)
Definition: types.h:507
#define GD_label_pos(g)
Definition: types.h:409
#define ND_coord(n)
Definition: types.h:496
void dot_init_node_edge(graph_t *g)
Definition: dotinit.c:75
#define streq(s, t)
Definition: cghdr.h:52
int getPack(Agraph_t *g, int not_def, int dflt)
Definition: pack.c:1381
#define ND_next(n)
Definition: types.h:517
#define GD_comp(g)
Definition: types.h:366
void dot_layout(Agraph_t *g)
Definition: dotinit.c:507
CGRAPH_API int agnnodes(Agraph_t *g)
Definition: graph.c:162
boolean mapbool(char *p)
Definition: utils.c:472
Agrec_t * data
Definition: cgraph.h:109
Definition: pack.h:37
void dot_compoundEdges(graph_t *g)
Definition: compound.c:494
#define ND_out(n)
Definition: types.h:522
int size
Definition: types.h:263
#define ED_xpenalty(e)
Definition: types.h:604
CGRAPH_API void * agbindrec(void *obj, char *name, unsigned int size, int move_to_front)
Definition: rec.c:86
#define ND_other(n)
Definition: types.h:521
int common_init_edge(edge_t *e)
Definition: utils.c:714
Definition: pack.h:37
void setEdgeType(graph_t *g, int dflt)
Definition: utils.c:1802
void gv_nodesize(node_t *n, boolean flip)
Definition: utils.c:1970
char * late_string(void *obj, attrsym_t *attr, char *def)
Definition: utils.c:122
#define GD_bb(g)
Definition: types.h:357
#define GD_nodesep(g)
Definition: types.h:402
#define GD_minrank(g)
Definition: types.h:391
#define ND_flat_out(n)
Definition: types.h:499
#define GD_rank(g)
Definition: types.h:404
Definition: types.h:210
CGRAPH_API Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition: edge.c:40
#define GD_drawing(g)
Definition: types.h:356
void dot_position(Agraph_t *, aspect_t *)
Definition: position.c:120
aspect_t * setAspect(Agraph_t *g, aspect_t *adata)
Definition: aspect.c:1978
#define free_list(L)
Definition: types.h:274
Agraph_t * mapClust(Agraph_t *cl)
Definition: ccomps.c:526
void dot_mincross(Agraph_t *, int)
Definition: mincross.c:332
#define ED_minlen(e)
Definition: types.h:595
int nonconstraint_edge(edge_t *e)
Definition: class1.c:23
#define NEW(t)
Definition: memory.h:35
#define ag_xset(x, a, v)
Definition: dotinit.c:275
#define TRUE
Definition: cgraph.h:38