00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef DEBUG
00024
00025 #define FDP_PRIVATE
00026
00027 #include <dbg.h>
00028 #include <neatoprocs.h>
00029 #include <fdp.h>
00030 #include <math.h>
00031
00032 static int indent = -1;
00033
00034 void incInd()
00035 {
00036 indent++;
00037 }
00038
00039 void decInd()
00040 {
00041 if (indent >= 0)
00042 indent--;
00043 }
00044
00045 void prIndent(void)
00046 {
00047 int i;
00048 for (i = 0; i < indent; i++)
00049 fputs(" ", stderr);
00050 }
00051
00052 static void dumpBB(graph_t * g)
00053 {
00054 boxf bb;
00055 box b;
00056
00057 bb = BB(g);
00058 b = GD_bb(g);
00059 prIndent();
00060 fprintf(stderr, " LL (%f,%f) UR (%f,%f)\n", bb.LL.x, bb.LL.y,
00061 bb.UR.x, bb.UR.y);
00062 prIndent();
00063 fprintf(stderr, " LL (%d,%d) UR (%d,%d)\n", b.LL.x, b.LL.y,
00064 b.UR.x, b.UR.y);
00065 }
00066
00067 static void dumpSG(graph_t * g)
00068 {
00069 graph_t *subg;
00070 int i;
00071
00072 if (GD_n_cluster(g) == 0)
00073 return;
00074 prIndent();
00075 fprintf(stderr, " {\n");
00076 for (i = 1; i <= GD_n_cluster(g); i++) {
00077 subg = (GD_clust(g))[i];
00078 prIndent();
00079 fprintf(stderr, " subgraph %s : %d nodes\n", subg->name,
00080 agnnodes(subg));
00081 dumpBB(subg);
00082 incInd ();
00083 dumpSG(subg);
00084 decInd ();
00085 }
00086 prIndent();
00087 fprintf(stderr, " }\n");
00088 }
00089
00090
00091
00092 void dumpE(graph_t * g, int derived)
00093 {
00094 Agnode_t *n;
00095 Agedge_t *e;
00096 Agedge_t **ep;
00097 Agedge_t *el;
00098 int i;
00099 int deg;
00100
00101 prIndent();
00102 fprintf(stderr, "Graph %s : %d nodes %d edges\n", g->name, agnnodes(g),
00103 agnedges(g));
00104 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00105 deg = 0;
00106 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00107 deg++;
00108 prIndent();
00109 fprintf(stderr, " %s -- %s\n", e->tail->name, e->head->name);
00110 if (derived) {
00111 for (i = 0, ep = (Agedge_t **) ED_to_virt(e);
00112 i < ED_count(e); i++, ep++) {
00113 el = *ep;
00114 prIndent();
00115 fprintf(stderr, " %s -- %s\n", el->tail->name,
00116 el->head->name);
00117 }
00118 }
00119 }
00120 if (deg == 0) {
00121 if (!agfstin(g, n))
00122 fprintf(stderr, " %s\n", n->name);
00123 }
00124 }
00125 if (!derived) {
00126 bport_t *pp;
00127 if ((pp = PORTS(g))) {
00128 int sz = NPORTS(g);
00129 fprintf(stderr, " %d ports\n", sz);
00130 while (pp->e) {
00131 fprintf(stderr, " %s : %s -- %s\n", pp->n->name,
00132 pp->e->tail->name, pp->e->head->name);
00133 pp++;
00134 }
00135 }
00136 }
00137 }
00138
00139
00140
00141 void dump(graph_t * g, int level, int doBB)
00142 {
00143 node_t *n;
00144 boxf bb;
00145 double w, h;
00146 pointf pos;
00147
00148 if (Verbose < level)
00149 return;
00150 prIndent();
00151 fprintf(stderr, "Graph %s : %d nodes\n", g->name, agnnodes(g));
00152 dumpBB(g);
00153 if (Verbose > level) {
00154 incInd();
00155 dumpSG(g);
00156 decInd();
00157 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00158 pos.x = ND_pos(n)[0];
00159 pos.y = ND_pos(n)[1];
00160 prIndent();
00161 w = ND_width(n);
00162 h = ND_height(n);
00163 if (doBB) {
00164 bb.LL.x = pos.x - w / 2.0;
00165 bb.LL.y = pos.y - h / 2.0;
00166 bb.UR.x = bb.LL.x + w;
00167 bb.UR.y = bb.LL.y + h;
00168 fprintf(stderr, "%s: (%f,%f) ((%f,%f) , (%f,%f))\n",
00169 n->name, pos.x, pos.y, bb.LL.x, bb.LL.y, bb.UR.x,
00170 bb.UR.y);
00171 } else {
00172 fprintf(stderr, "%s: (%f,%f) (%f,%f) \n",
00173 n->name, pos.x, pos.y, w, h);
00174 }
00175 }
00176 }
00177 }
00178
00179 void dumpG(graph_t * g, char *fname, int expMode)
00180 {
00181 FILE *fp;
00182
00183 fp = fopen(fname, "w");
00184 if (!fp) {
00185 fprintf(stderr, "Couldn not open %s \n", fname);
00186 exit(1);
00187 }
00188 outputGraph(g, fp, expMode);
00189 fclose(fp);
00190 }
00191
00192
00193
00194
00195
00196
00197 double Scale = 0.0;
00198 double ArrowScale = 1.0;
00199
00200 #define ARROW_LENGTH 10
00201 #define ARROW_WIDTH 5
00202
00203
00204 static char *plog = "%%!PS-Adobe-2.0\n\n\
00205 /Times-Roman findfont 14 scalefont setfont\n\
00206 /lLabel {\n\
00207 \tmoveto\n\
00208 \tgsave\n\
00209 \tshow\n\
00210 \tgrestore\n\
00211 } def\n\
00212 /inch {\n\
00213 \t72 mul\n\
00214 } def\n\
00215 /doBox {\n\
00216 \tnewpath\n\
00217 \tmoveto\n\
00218 \t/ht exch def\n\
00219 \t/wd exch def\n\
00220 \t0 ht rlineto\n\
00221 \twd 0 rlineto\n\
00222 \t0 0 ht sub rlineto\n\
00223 \tclosepath\n\
00224 \tgsave\n\
00225 \t\t.9 setgray\n\
00226 \t\tfill\n\
00227 \tgrestore\n\
00228 \tstroke\n\
00229 } def\n\
00230 /drawCircle {\n\
00231 \t/r exch def\n\
00232 \t/y exch def\n\
00233 \t/x exch def\n\
00234 \tnewpath\n\
00235 \tx y r 0 360 arc\n\
00236 \tstroke\n\
00237 } def\n\
00238 /fillCircle {\n\
00239 \t/r exch def\n\
00240 \t/y exch def\n\
00241 \t/x exch def\n\
00242 \tnewpath\n\
00243 \tx y r 0 360 arc\n\
00244 \tfill\n\
00245 } def\n";
00246
00247 static char *elog = "showpage\n";
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 static double PSWidth = 550.0;
00268 static double PSHeight = 756.0;
00269
00270 static void pswrite(Agraph_t * g, FILE * fp, int expMode)
00271 {
00272 Agnode_t *n;
00273 Agnode_t *h;
00274 Agedge_t *e;
00275 Agnodeinfo_t *data;
00276 Agnodeinfo_t *hdata;
00277 double minx, miny, maxx, maxy;
00278 double scale, width, height;
00279 int do_arrow;
00280 int angle;
00281 char *p;
00282 double theta;
00283 double arrow_w, arrow_l;
00284 int portColor;
00285
00286 fprintf(fp, plog);
00287
00288
00289
00290
00291
00292
00293
00294
00295 do_arrow = 0;
00296
00297 n = agfstnode(g);
00298 data = &(n->u);
00299 minx = data->pos[0];
00300 miny = data->pos[1];
00301 maxx = data->pos[0];
00302 maxy = data->pos[1];
00303 n = agnxtnode(g, n);
00304 for (; n; n = agnxtnode(g, n)) {
00305 data = &(n->u);
00306 if (data->pos[0] < minx)
00307 minx = data->pos[0];
00308 if (data->pos[1] < miny)
00309 miny = data->pos[1];
00310 if (data->pos[0] > maxx)
00311 maxx = data->pos[0];
00312 if (data->pos[1] > maxy)
00313 maxy = data->pos[1];
00314 }
00315
00316
00317
00318 minx *= POINTS_PER_INCH;
00319 miny *= POINTS_PER_INCH;
00320 maxx *= POINTS_PER_INCH;
00321 maxy *= POINTS_PER_INCH;
00322
00323
00324
00325 if ((p = agget(g, "rotate")) && (*p != '\0')
00326 && ((angle = atoi(p)) != 0)) {
00327 fprintf(fp, "306 396 translate\n");
00328 fprintf(fp, "%d rotate\n", angle);
00329 fprintf(fp, "-306 -396 translate\n");
00330 }
00331
00332
00333
00334
00335 if (Scale > 0.0)
00336 scale = Scale;
00337 else {
00338 width = maxx - minx + 20;
00339 height = maxy - miny + 20;
00340 if (width > PSWidth) {
00341 if (height > PSHeight) {
00342 scale =
00343 (PSWidth / width <
00344 PSHeight / height ? PSWidth / width : PSHeight /
00345 height);
00346 } else
00347 scale = PSWidth / width;
00348 } else if (height > PSHeight) {
00349 scale = PSHeight / height;
00350 } else
00351 scale = 1.0;
00352 }
00353
00354 fprintf(fp, "%f %f translate\n",
00355 (PSWidth - scale * (minx + maxx)) / 2.0,
00356 (PSHeight - scale * (miny + maxy)) / 2.0);
00357 fprintf(fp, "%f %f scale\n", scale, scale);
00358
00359
00360
00361
00362
00363
00364
00365 if (do_arrow) {
00366 arrow_w = ArrowScale * ARROW_WIDTH / scale;
00367 arrow_l = ArrowScale * ARROW_LENGTH / scale;
00368 }
00369
00370 fprintf(fp, "0.0 setlinewidth\n");
00371 #ifdef SHOW_GRID
00372 if (UseGrid) {
00373 int i;
00374 fprintf(fp, "%f %f 5 fillCircle\n", 0.0, 0.0);
00375 for (i = 0; i < maxx; i += CellW) {
00376 fprintf(fp, "%f 0.0 moveto %f %f lineto stroke\n",
00377 (float) i, (float) i, maxy);
00378 }
00379 for (i = 0; i < maxy; i += CellH) {
00380 fprintf(fp, "0.0 %f moveto %f %f lineto stroke\n",
00381 (float) i, maxx, (float) i);
00382 }
00383 }
00384 #endif
00385 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00386 if (IS_PORT(n)) {
00387 double r;
00388 data = &(n->u);
00389 r = sqrt(data->pos[0] * data->pos[0] +
00390 data->pos[1] * data->pos[1]);
00391 fprintf(fp, "0 0 %f inch drawCircle\n", r);
00392 break;
00393 }
00394 }
00395
00396 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00397 data = &(n->u);
00398 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00399 h = e->head;
00400 hdata = &(h->u);
00401 fprintf(fp, "%f inch %f inch moveto %f inch %f inch lineto\n",
00402 data->pos[0], data->pos[1], hdata->pos[0],
00403 hdata->pos[1]);
00404 fprintf(fp, "stroke\n");
00405 if (do_arrow) {
00406 theta =
00407 atan2(data->pos[1] - hdata->pos[1],
00408 data->pos[0] - hdata->pos[0]);
00409 fprintf(fp, "%f %f %.2f %.2f %.2f doArrow\n",
00410 hdata->pos[0], hdata->pos[1], DEGREES(theta),
00411 arrow_l, arrow_w);
00412 }
00413
00414 }
00415 }
00416
00417 #ifdef BOX
00418 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00419 float wd, ht;
00420
00421 data = getData(n);
00422 wd = data->wd;
00423 ht = data->ht;
00424 fprintf(fp, "%f %f %f %f doBox\n", wd, ht,
00425 data->pos.x - (wd / 2), data->pos.y - (ht / 2));
00426 }
00427 #else
00428 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00429 data = &(n->u);
00430 fprintf(fp, "%% %s\n", n->name);
00431 if (expMode) {
00432 double wd, ht;
00433 double r;
00434 wd = data->width;
00435 ht = data->height;
00436 r = sqrt((wd * wd / 4) + ht * ht / 4);
00437 fprintf(fp, "%f inch %f inch %f inch %f inch doBox\n", wd, ht,
00438 data->pos[0] - (wd / 2), data->pos[1] - (ht / 2));
00439 fprintf(fp, "%f inch %f inch %f inch drawCircle\n",
00440 data->pos[0], data->pos[1], r);
00441 } else {
00442 if (IS_PORT(n)) {
00443 if (!portColor) {
00444 fprintf(fp, "0.667 1.000 1.000 sethsbcolor\n");
00445 portColor = 1;
00446 }
00447 } else {
00448 if (portColor) {
00449 fprintf(fp, "0.0 0.000 0.000 sethsbcolor\n");
00450 portColor = 0;
00451 }
00452 }
00453 }
00454 fprintf(fp, "%f inch %f inch %f fillCircle\n", data->pos[0],
00455 data->pos[1], 3 / scale);
00456 }
00457 #endif
00458
00459 fprintf(fp, "0.667 1.000 1.000 sethsbcolor\n");
00460 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00461 data = &(n->u);
00462 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00463 h = e->head;
00464 hdata = &(h->u);
00465 fprintf(fp, "%f inch %f inch moveto %f inch %f inch lineto\n",
00466 data->pos[0], data->pos[1], hdata->pos[0],
00467 hdata->pos[1]);
00468 fprintf(fp, "stroke\n");
00469 if (do_arrow) {
00470 theta =
00471 atan2(data->pos[1] - hdata->pos[1],
00472 data->pos[0] - hdata->pos[0]);
00473 fprintf(fp, "%f %f %.2f %.2f %.2f doArrow\n",
00474 hdata->pos[0], hdata->pos[1], DEGREES(theta),
00475 arrow_l, arrow_w);
00476 }
00477
00478 }
00479 }
00480
00481 fprintf(fp, elog);
00482 }
00483
00484 void outputGraph(Agraph_t * g, FILE * fp, int expMode)
00485 {
00486 pswrite(g, fp, expMode);
00487 }
00488
00489 #endif