00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "dot.h"
00019
00020 static void
00021 dot_init_node(node_t * n)
00022 {
00023 common_init_node(n);
00024 dot_nodesize(n, GD_flip(n->graph));
00025 alloc_elist(4, ND_in(n));
00026 alloc_elist(4, ND_out(n));
00027 alloc_elist(2, ND_flat_in(n));
00028 alloc_elist(2, ND_flat_out(n));
00029 alloc_elist(2, ND_other(n));
00030 ND_UF_size(n) = 1;
00031 }
00032
00033 static void
00034 dot_init_edge(edge_t * e)
00035 {
00036 char *tailgroup, *headgroup;
00037
00038 common_init_edge(e);
00039
00040 ED_weight(e) = late_double(e, E_weight, 1.0, 0.0);
00041 tailgroup = late_string(e->tail, N_group, "");
00042 headgroup = late_string(e->head, N_group, "");
00043 ED_count(e) = ED_xpenalty(e) = 1;
00044 if (tailgroup[0] && (tailgroup == headgroup)) {
00045 ED_xpenalty(e) = CL_CROSS;
00046 ED_weight(e) *= 100;
00047 }
00048 if (nonconstraint_edge(e)) {
00049 ED_xpenalty(e) = 0;
00050 ED_weight(e) = 0;
00051 }
00052
00053 ED_showboxes(e) = late_int(e, E_showboxes, 0, 0);
00054 ED_minlen(e) = late_int(e, E_minlen, 1, 0);
00055 }
00056
00057 void
00058 dot_init_node_edge(graph_t * g)
00059 {
00060 node_t *n;
00061 edge_t *e;
00062
00063 for (n = agfstnode(g); n; n = agnxtnode(g, n))
00064 dot_init_node(n);
00065 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00066 for (e = agfstout(g, n); e; e = agnxtout(g, e))
00067 dot_init_edge(e);
00068 }
00069 }
00070
00071 #if 0
00072 static void free_edge_list(elist L)
00073 {
00074 edge_t *e;
00075 int i;
00076
00077 for (i = 0; i < L.size; i++) {
00078 e = L.list[i];
00079 free(e);
00080 }
00081 }
00082 #endif
00083
00084 static void
00085 dot_cleanup_node(node_t * n)
00086 {
00087 free_list(ND_in(n));
00088 free_list(ND_out(n));
00089 free_list(ND_flat_out(n));
00090 free_list(ND_flat_in(n));
00091 free_list(ND_other(n));
00092 free_label(ND_label(n));
00093 if (ND_shape(n))
00094 ND_shape(n)->fns->freefn(n);
00095 memset(&(n->u), 0, sizeof(Agnodeinfo_t));
00096 }
00097
00098 static void
00099 dot_free_splines(edge_t * e)
00100 {
00101 int i;
00102 if (ED_spl(e)) {
00103 for (i = 0; i < ED_spl(e)->size; i++)
00104 free(ED_spl(e)->list[i].list);
00105 free(ED_spl(e)->list);
00106 free(ED_spl(e));
00107 }
00108 ED_spl(e) = NULL;
00109 }
00110
00111 static void
00112 dot_cleanup_edge(edge_t * e)
00113 {
00114 dot_free_splines(e);
00115 free_label(ED_label(e));
00116 memset(&(e->u), 0, sizeof(Agedgeinfo_t));
00117 }
00118
00119 static void free_virtual_edge_list(node_t * n)
00120 {
00121 edge_t *e;
00122 int i;
00123
00124 for (i = ND_in(n).size - 1; i >= 0; i--) {
00125 e = ND_in(n).list[i];
00126 delete_fast_edge(e);
00127 free(e);
00128 }
00129 for (i = ND_out(n).size - 1; i >= 0; i--) {
00130 e = ND_out(n).list[i];
00131 delete_fast_edge(e);
00132 free(e);
00133 }
00134 }
00135
00136 static void free_virtual_node_list(node_t * vn)
00137 {
00138 node_t *next_vn;
00139
00140 while (vn) {
00141 next_vn = ND_next(vn);
00142 free_virtual_edge_list(vn);
00143 if (ND_node_type(vn) == VIRTUAL) {
00144 free_list(ND_out(vn));
00145 free_list(ND_in(vn));
00146 free(vn);
00147 }
00148 vn = next_vn;
00149 }
00150 }
00151
00152 static void
00153 dot_cleanup_graph(graph_t * g)
00154 {
00155 int i, c;
00156 graph_t *clust;
00157
00158 for (c = 1; c <= GD_n_cluster(g); c++) {
00159 clust = GD_clust(g)[c];
00160 GD_cluster_was_collapsed(clust) = FALSE;
00161 dot_cleanup(clust);
00162 }
00163
00164 free_list(GD_comp(g));
00165 if ((g == g->root) && GD_rank(g)) {
00166 for (i = GD_minrank(g); i <= GD_maxrank(g); i++)
00167 free(GD_rank(g)[i].v);
00168 free(GD_rank(g));
00169 }
00170 if (g != g->root) memset(&(g->u), 0, sizeof(Agraphinfo_t));
00171 }
00172
00173
00174 void dot_cleanup(graph_t * g)
00175 {
00176 node_t *n;
00177 edge_t *e;
00178
00179 free_virtual_node_list(GD_nlist(g));
00180 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00181 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00182 dot_cleanup_edge(e);
00183 }
00184 dot_cleanup_node(n);
00185 }
00186 dot_cleanup_graph(g);
00187 }
00188
00189 #ifdef DEBUG
00190 int
00191 fastn (graph_t * g)
00192 {
00193 node_t* u;
00194 int cnt = 0;
00195 for (u = GD_nlist(g); u; u = ND_next(u)) cnt++;
00196 return cnt;
00197 }
00198
00199 static void
00200 dumpRanks (graph_t * g)
00201 {
00202 int i, j;
00203 node_t* u;
00204 rank_t *rank = GD_rank(g);
00205 int rcnt = 0;
00206 for (i = GD_minrank(g); i <= GD_maxrank(g); i++) {
00207 fprintf (stderr, "[%d] :", i);
00208 for (j = 0; j < rank[i].n; j++) {
00209 u = rank[i].v[j];
00210 rcnt++;
00211 if (streq(u->name,"virtual"))
00212 fprintf (stderr, " %x", u);
00213 else
00214 fprintf (stderr, " %s", u->name);
00215
00216 }
00217 fprintf (stderr, "\n");
00218 }
00219 fprintf (stderr, "count %d rank count = %d\n", fastn(g), rcnt);
00220 }
00221 #endif
00222
00223 void dot_layout(Agraph_t * g)
00224 {
00225 setEdgeType (g, ET_SPLINE);
00226 dot_init_node_edge(g);
00227 dot_rank(g);
00228 dot_mincross(g);
00229
00230 dot_position(g);
00231
00232 dot_sameports(g);
00233 dot_splines(g);
00234 if (mapbool(agget(g, "compound")))
00235 dot_compoundEdges(g);
00236 dotneato_postprocess(g);
00237 }