/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/fdpgen/dbg.c

Go to the documentation of this file.
00001 /* $Id: dbg.c,v 1.4 2008/03/03 23:01:51 ellson Exp $ $Revision: 1.4 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 
00018 /* dbg.c:
00019  * Written by Emden R. Gansner
00020  *
00021  * Simple debugging infrastructure
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 /* dumpE:
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) {         /* no out edges */
00121             if (!agfstin(g, n)) /* no in edges */
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 /* dump:
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 /* #define BOX */
00193 
00194 /* static char* pos_name      = "pos"; */
00195 /* static char* lp_name       = "lp"; */
00196 
00197 double Scale = 0.0;
00198 double ArrowScale = 1.0;
00199 
00200 #define         ARROW_LENGTH    10
00201 #define         ARROW_WIDTH      5
00202 /* #define DEGREES(rad)   ((rad)/M_PI * 180.0) */
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 static char* arrow = "/doArrow {\n\
00251 \t/arrowwidth exch def\n\
00252 \t/arrowlength exch def\n\
00253 \tgsave\n\
00254 \t\t3 1 roll\n\
00255 \t\ttranslate\n\
00256 \t\t\trotate\n\
00257 \t\t\tnewpath\n\
00258 \t\t\tarrowlength arrowwidth 2 div moveto\n\
00259 \t\t\t0 0 lineto\n\
00260 \t\t\tarrowlength arrowwidth -2 div lineto\n\
00261 \t\tclosepath fill\n\
00262 \t\tstroke\n\
00263 \tgrestore\n\
00264 } def\n";
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     if (agisdirected (g) && DoArrow) {
00290       do_arrow = 1;
00291       fprintf(fp,arrow);
00292     }
00293     else 
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     /* Convert to points
00317      */
00318     minx *= POINTS_PER_INCH;
00319     miny *= POINTS_PER_INCH;
00320     maxx *= POINTS_PER_INCH;
00321     maxy *= POINTS_PER_INCH;
00322 
00323     /* Check for rotation
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     /* If user gives scale factor, use it.
00333      * Else if figure too large for standard PS page, scale it to fit.
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     if (Verbose)
00361       fprintf (stderr, "Region (%f,%f) (%f,%f), scale %f\n", 
00362         minx, miny, maxx, maxy, scale);
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                          /* DEBUG */

Generated on Mon Mar 31 19:03:26 2008 for Graphviz by  doxygen 1.5.1