00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "circular.h"
00019 #include "blocktree.h"
00020 #include "circpos.h"
00021 #include <string.h>
00022
00023 #define MINDIST 1.0
00024
00025
00026
00027
00028
00029
00030 static void initGraphAttrs(Agraph_t * g, circ_state * state)
00031 {
00032 static Agraph_t *rootg;
00033 static attrsym_t *N_artpos;
00034 static attrsym_t *N_root;
00035 static double min_dist;
00036 static char *rootname;
00037 Agraph_t *rg;
00038 attrsym_t *G_mindist;
00039 node_t *n = agfstnode(g);
00040
00041 rg = ORIGN(n)->graph;
00042 if (rg != rootg) {
00043 state->blockCount = 0;
00044 rootg = rg;
00045 G_mindist = agfindattr(rootg, "mindist");
00046 min_dist = late_double(rootg, G_mindist, MINDIST, 0.0);
00047 N_artpos = agfindattr(rootg->proto->n, "articulation_pos");
00048 N_root = agfindattr(rootg->proto->n, "root");
00049 rootname = agget(rootg, "root");
00050 }
00051 initBlocklist(&state->bl);
00052 state->orderCount = 1;
00053 state->bcstack = mkStack();
00054 state->min_dist = min_dist;
00055 state->N_artpos = N_artpos;
00056 state->N_root = N_root;
00057 state->rootname = rootname;
00058 }
00059
00060
00061
00062
00063
00064
00065 static void cleanup(block_t * root, circ_state * sp)
00066 {
00067 freeBlocktree(root);
00068 freeStack(sp->bcstack);
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 void circularLayout(Agraph_t * g)
00080 {
00081 block_t *root;
00082 static circ_state state;
00083
00084 if (agnnodes(g) == 1) {
00085 Agnode_t *n = agfstnode(g);
00086 ND_pos(n)[0] = 0;
00087 ND_pos(n)[1] = 0;
00088 return;
00089 }
00090
00091 initGraphAttrs(g, &state);
00092
00093 root = createBlocktree(g, &state);
00094 circPos(g, root, &state);
00095
00096 cleanup(root, &state);
00097 }
00098
00099 #ifdef DEBUG
00100 void prGraph(Agraph_t * g)
00101 {
00102 Agnode_t *n;
00103 Agedge_t *e;
00104
00105 fprintf(stderr, "%s\n", g->name);
00106 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00107 fprintf(stderr, "%s (%x)\n", n->name, (unsigned int) n);
00108 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00109 fprintf(stderr, "%s -- %s (%x)\n", n->name, e->head->name,
00110 (unsigned int) e);
00111 }
00112 }
00113 }
00114
00115 cdata *cvt(Agnode_t * n)
00116 {
00117 return DATA(n);
00118 }
00119
00120 void prData(Agnode_t * n, int pass)
00121 {
00122 char *pname;
00123 char *bname;
00124 char *tname;
00125 char *name1;
00126 char *name2;
00127 int dist1, dist2;
00128
00129 if (PARENT(n))
00130 pname = PARENT(n)->name;
00131 else
00132 pname = "<P0>";
00133 if (BLOCK(n))
00134 bname = BLOCK(n)->sub_graph->name;
00135 else
00136 pname = "<B0>";
00137 fprintf(stderr, "%s: %x %s %s ", n->name, FLAGS(n), pname, bname);
00138 switch (pass) {
00139 case 0:
00140 fprintf(stderr, "%d %d\n", VAL(n), LOWVAL(n));
00141 break;
00142 case 1:
00143 if (TPARENT(n))
00144 tname = TPARENT(n)->name;
00145 else
00146 tname = "<ROOT>";
00147 dist1 = DISTONE(n);
00148 if (dist1 > 0)
00149 name1 = LEAFONE(n)->name;
00150 else
00151 name1 = "<null>";
00152 dist2 = DISTTWO(n);
00153 if (dist2 > 0)
00154 name2 = LEAFTWO(n)->name;
00155 else
00156 name2 = "<null>";
00157 fprintf(stderr, "%s %s %d %s %d\n", tname, name1, dist1, name2,
00158 dist2);
00159 break;
00160 default:
00161 fprintf(stderr, "%d\n", POSITION(n));
00162 break;
00163 }
00164 }
00165 #endif