|
Graphviz 2.29.20120208.0545
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 00015 #include "circular.h" 00016 #include "blocktree.h" 00017 #include "circpos.h" 00018 #include <string.h> 00019 00020 #define MINDIST 1.0 00021 00022 /* initGraphAttrs: 00023 * Set attributes based on original root graph. 00024 * This is obtained by taking a node of g, finding its node 00025 * in the original graph, and finding that node's graph. 00026 */ 00027 static void initGraphAttrs(Agraph_t * g, circ_state * state) 00028 { 00029 static Agraph_t *rootg; 00030 static attrsym_t *N_artpos; 00031 static attrsym_t *N_root; 00032 static double min_dist; 00033 static char *rootname; 00034 Agraph_t *rg; 00035 attrsym_t *G_mindist; 00036 node_t *n = agfstnode(g); 00037 00038 rg = agraphof(ORIGN(n)); 00039 if (rg != rootg) { /* new root graph */ 00040 state->blockCount = 0; 00041 rootg = rg; 00042 #ifndef WITH_CGRAPH 00043 G_mindist = agfindattr(rootg, "mindist"); 00044 #else /* WITH_CGRAPH */ 00045 G_mindist = agattr(rootg,AGRAPH, "mindist", NULL); 00046 #endif /* WITH_CGRAPH */ 00047 min_dist = late_double(rootg, G_mindist, MINDIST, 0.0); 00048 #ifndef WITH_CGRAPH 00049 N_artpos = agfindattr(rootg->proto->n, "articulation_pos"); 00050 N_root = agfindattr(rootg->proto->n, "root"); 00051 #else /* WITH_CGRAPH */ 00052 N_artpos = agattr(rootg,AGNODE, "articulation_pos", NULL); 00053 N_root = agattr(rootg,AGNODE, "root", NULL); 00054 #endif /* WITH_CGRAPH */ 00055 rootname = agget(rootg, "root"); 00056 } 00057 initBlocklist(&state->bl); 00058 state->orderCount = 1; 00059 state->min_dist = min_dist; 00060 state->N_artpos = N_artpos; 00061 state->N_root = N_root; 00062 state->rootname = rootname; 00063 } 00064 00065 /* cleanup: 00066 * We need to cleanup objects created in initGraphAttrs 00067 * and all blocks. All graph objects are components of the 00068 * initial derived graph and will be freed when it is closed. 00069 */ 00070 static void cleanup(block_t * root, circ_state * sp) 00071 { 00072 freeBlocktree(root); 00073 } 00074 00075 /* circularLayout: 00076 * Do circular layout of g. 00077 * Assume g is strict. 00078 * g is a "connected" component of the derived graph of the 00079 * original graph. 00080 * We make state static so that it keeps a record of block numbers used 00081 * in a graph; it gets reset when a new root graph is used. 00082 */ 00083 void circularLayout(Agraph_t * g) 00084 { 00085 block_t *root; 00086 static circ_state state; 00087 00088 if (agnnodes(g) == 1) { 00089 Agnode_t *n = agfstnode(g); 00090 ND_pos(n)[0] = 0; 00091 ND_pos(n)[1] = 0; 00092 return; 00093 } 00094 00095 initGraphAttrs(g, &state); 00096 00097 root = createBlocktree(g, &state); 00098 circPos(g, root, &state); 00099 00100 cleanup(root, &state); 00101 } 00102 00103 #ifdef DEBUG 00104 void prGraph(Agraph_t * g) 00105 { 00106 Agnode_t *n; 00107 Agedge_t *e; 00108 00109 fprintf(stderr, "%s\n", g->name); 00110 for (n = agfstnode(g); n; n = agnxtnode(g, n)) { 00111 fprintf(stderr, "%s (%x)\n", n->name, (unsigned int) n); 00112 for (e = agfstout(g, n); e; e = agnxtout(g, e)) { 00113 fprintf(stderr, "%s -- %s (%x)\n", n->name, e->head->name, 00114 (unsigned int) e); 00115 } 00116 } 00117 } 00118 00119 cdata *cvt(Agnode_t * n) 00120 { 00121 return DATA(n); 00122 } 00123 00124 void prData(Agnode_t * n, int pass) 00125 { 00126 char *pname; 00127 char *bname; 00128 char *tname; 00129 char *name1; 00130 char *name2; 00131 int dist1, dist2; 00132 00133 if (PARENT(n)) 00134 pname = PARENT(n)->name; 00135 else 00136 pname = "<P0>"; 00137 if (BLOCK(n)) 00138 bname = BLOCK(n)->sub_graph->name; 00139 else 00140 pname = "<B0>"; 00141 fprintf(stderr, "%s: %x %s %s ", n->name, FLAGS(n), pname, bname); 00142 switch (pass) { 00143 case 0: 00144 fprintf(stderr, "%d %d\n", VAL(n), LOWVAL(n)); 00145 break; 00146 case 1: 00147 if (TPARENT(n)) 00148 tname = TPARENT(n)->name; 00149 else 00150 tname = "<ROOT>"; 00151 dist1 = DISTONE(n); 00152 if (dist1 > 0) 00153 name1 = LEAFONE(n)->name; 00154 else 00155 name1 = "<null>"; 00156 dist2 = DISTTWO(n); 00157 if (dist2 > 0) 00158 name2 = LEAFTWO(n)->name; 00159 else 00160 name2 = "<null>"; 00161 fprintf(stderr, "%s %s %d %s %d\n", tname, name1, dist1, name2, 00162 dist2); 00163 break; 00164 default: 00165 fprintf(stderr, "%d\n", POSITION(n)); 00166 break; 00167 } 00168 } 00169 #endif
1.7.4