123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- /*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Details at https://graphviz.org
- *************************************************************************/
- /* dbg.c:
- * Written by Emden R. Gansner
- *
- * Simple debugging infrastructure
- */
- #ifdef DEBUG
- #define FDP_PRIVATE
- #include <fdpgen/dbg.h>
- #include <neatogen/neatoprocs.h>
- #include <fdpgen/fdp.h>
- #include <math.h>
- #include <util/exit.h>
- static int indent = -1;
- void incInd()
- {
- indent++;
- }
- void decInd()
- {
- if (indent >= 0)
- indent--;
- }
- void prIndent(void)
- {
- int i;
- for (i = 0; i < indent; i++)
- fputs(" ", stderr);
- }
- void prEdge(edge_t *e,char *s)
- {
- fprintf(stderr,"%s --", agnameof(agtail(e)));
- fprintf(stderr,"%s%s", agnameof(aghead(e)),s);
- }
- static void dumpBB(graph_t * g)
- {
- boxf bb;
- boxf b;
- bb = BB(g);
- b = GD_bb(g);
- prIndent();
- fprintf(stderr, " LL (%f,%f) UR (%f,%f)\n", bb.LL.x, bb.LL.y,
- bb.UR.x, bb.UR.y);
- prIndent();
- fprintf(stderr, " LL (%f,%f) UR (%f,%f)\n", b.LL.x, b.LL.y,
- b.UR.x, b.UR.y);
- }
- static void dumpSG(graph_t * g)
- {
- graph_t *subg;
- int i;
- if (GD_n_cluster(g) == 0)
- return;
- prIndent();
- fprintf(stderr, " {\n");
- for (i = 1; i <= GD_n_cluster(g); i++) {
- subg = (GD_clust(g))[i];
- prIndent();
- fprintf(stderr, " subgraph %s : %d nodes\n", agnameof(subg),
- agnnodes(subg));
- dumpBB(subg);
- incInd ();
- dumpSG(subg);
- decInd ();
- }
- prIndent();
- fprintf(stderr, " }\n");
- }
- /* dump:
- */
- void dump(graph_t *g, int level) {
- node_t *n;
- boxf bb;
- double w, h;
- pointf pos;
- if (Verbose < level)
- return;
- prIndent();
- fprintf(stderr, "Graph %s : %d nodes\n", agnameof(g), agnnodes(g));
- dumpBB(g);
- if (Verbose > level) {
- incInd();
- dumpSG(g);
- decInd();
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- pos.x = ND_pos(n)[0];
- pos.y = ND_pos(n)[1];
- prIndent();
- w = ND_width(n);
- h = ND_height(n);
- fprintf(stderr, "%s: (%f,%f) (%f,%f) \n",
- agnameof(n), pos.x, pos.y, w, h);
- }
- }
- }
- void dumpG(graph_t * g, char *fname, int expMode)
- {
- FILE *fp;
- fp = fopen(fname, "w");
- if (!fp) {
- fprintf(stderr, "Couldn not open %s \n", fname);
- graphviz_exit(1);
- }
- outputGraph(g, fp, expMode);
- fclose(fp);
- }
- static const double ArrowScale = 1.0;
- #define ARROW_LENGTH 10
- #define ARROW_WIDTH 5
- static char *plog = "%!PS-Adobe-2.0\n\n\
- /Times-Roman findfont 14 scalefont setfont\n\
- /lLabel {\n\
- \tmoveto\n\
- \tgsave\n\
- \tshow\n\
- \tgrestore\n\
- } def\n\
- /inch {\n\
- \t72 mul\n\
- } def\n\
- /doBox {\n\
- \tnewpath\n\
- \tmoveto\n\
- \t/ht exch def\n\
- \t/wd exch def\n\
- \t0 ht rlineto\n\
- \twd 0 rlineto\n\
- \t0 0 ht sub rlineto\n\
- \tclosepath\n\
- \tgsave\n\
- \t\t.9 setgray\n\
- \t\tfill\n\
- \tgrestore\n\
- \tstroke\n\
- } def\n\
- /drawCircle {\n\
- \t/r exch def\n\
- \t/y exch def\n\
- \t/x exch def\n\
- \tnewpath\n\
- \tx y r 0 360 arc\n\
- \tstroke\n\
- } def\n\
- /fillCircle {\n\
- \t/r exch def\n\
- \t/y exch def\n\
- \t/x exch def\n\
- \tnewpath\n\
- \tx y r 0 360 arc\n\
- \tfill\n\
- } def\n";
- static char *elog = "showpage\n";
- static double PSWidth = 550.0;
- static double PSHeight = 756.0;
- static void pswrite(Agraph_t * g, FILE * fp, int expMode)
- {
- Agnode_t *n;
- Agnode_t *h;
- Agedge_t *e;
- double minx, miny, maxx, maxy;
- double scale, width, height;
- int do_arrow;
- int angle;
- char *p;
- double theta;
- double arrow_w, arrow_l;
- int portColor;
- fprintf(fp, "%s", plog);
- do_arrow = 0;
- n = agfstnode(g);
- minx = ND_pos(n)[0];
- miny = ND_pos(n)[1];
- maxx = ND_pos(n)[0];
- maxy = ND_pos(n)[1];
- n = agnxtnode(g, n);
- for (; n; n = agnxtnode(g, n)) {
- minx = fmin(minx, ND_pos(n)[0]);
- miny = fmin(miny, ND_pos(n)[1]);
- maxx = fmax(maxx, ND_pos(n)[0]);
- maxy = fmax(maxy, ND_pos(n)[1]);
- }
- /* Convert to points
- */
- minx *= POINTS_PER_INCH;
- miny *= POINTS_PER_INCH;
- maxx *= POINTS_PER_INCH;
- maxy *= POINTS_PER_INCH;
- /* Check for rotation
- */
- if ((p = agget(g, "rotate")) && *p != '\0' && (angle = atoi(p)) != 0) {
- fprintf(fp, "306 396 translate\n");
- fprintf(fp, "%d rotate\n", angle);
- fprintf(fp, "-306 -396 translate\n");
- }
- /* If user gives scale factor, use it.
- * Else if figure too large for standard PS page, scale it to fit.
- */
- width = maxx - minx + 20;
- height = maxy - miny + 20;
- if (width > PSWidth) {
- if (height > PSHeight) {
- scale = fmin(PSWidth / width, PSHeight / height);
- } else
- scale = PSWidth / width;
- } else if (height > PSHeight) {
- scale = PSHeight / height;
- } else
- scale = 1.0;
- fprintf(fp, "%f %f translate\n",
- (PSWidth - scale * (minx + maxx)) / 2.0,
- (PSHeight - scale * (miny + maxy)) / 2.0);
- fprintf(fp, "%f %f scale\n", scale, scale);
- /*
- if (Verbose)
- fprintf (stderr, "Region (%f,%f) (%f,%f), scale %f\n",
- minx, miny, maxx, maxy, scale);
- */
- if (do_arrow) {
- arrow_w = ArrowScale * ARROW_WIDTH / scale;
- arrow_l = ArrowScale * ARROW_LENGTH / scale;
- }
- fprintf(fp, "0.0 setlinewidth\n");
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- if (IS_PORT(n)) {
- double r;
- r = sqrt(ND_pos(n)[0] * ND_pos(n)[0] +
- ND_pos(n)[1] * ND_pos(n)[1]);
- fprintf(fp, "0 0 %f inch drawCircle\n", r);
- break;
- }
- }
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
- h = aghead(e);
- fprintf(fp, "%f inch %f inch moveto %f inch %f inch lineto\n",
- ND_pos(n)[0], ND_pos(n)[1], ND_pos(h)[0],
- ND_pos(h)[1]);
- fprintf(fp, "stroke\n");
- if (do_arrow) {
- theta =
- atan2(ND_pos(n)[1] - ND_pos(h)[1],
- ND_pos(n)[0] - ND_pos(h)[0]);
- fprintf(fp, "%f %f %.2f %.2f %.2f doArrow\n",
- ND_pos(h)[0], ND_pos(h)[1], DEGREES(theta),
- arrow_l, arrow_w);
- }
- }
- }
- #ifdef BOX
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- float wd, ht;
- data = getData(n);
- wd = data->wd;
- ht = data->ht;
- fprintf(fp, "%f %f %f %f doBox\n", wd, ht,
- data->pos.x - wd / 2, data->pos.y - ht / 2);
- }
- #else
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- fprintf(fp, "%% %s\n", agnameof(n));
- if (expMode) {
- double wd, ht;
- double r;
- wd = ND_width(n);
- ht = ND_height(n);
- r = sqrt(wd * wd / 4 + ht * ht / 4);
- fprintf(fp, "%f inch %f inch %f inch %f inch doBox\n", wd, ht,
- ND_pos(n)[0] - wd / 2, ND_pos(n)[1] - ht / 2);
- fprintf(fp, "%f inch %f inch %f inch drawCircle\n",
- ND_pos(n)[0], ND_pos(n)[1], r);
- } else {
- if (IS_PORT(n)) {
- if (!portColor) {
- fprintf(fp, "0.667 1.000 1.000 sethsbcolor\n");
- portColor = 1;
- }
- } else {
- if (portColor) {
- fprintf(fp, "0.0 0.000 0.000 sethsbcolor\n");
- portColor = 0;
- }
- }
- }
- fprintf(fp, "%f inch %f inch %f fillCircle\n", ND_pos(n)[0],
- ND_pos(n)[1], 3 / scale);
- }
- #endif
- fprintf(fp, "0.667 1.000 1.000 sethsbcolor\n");
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
- h = aghead(e);
- fprintf(fp, "%f inch %f inch moveto %f inch %f inch lineto\n",
- ND_pos(n)[0], ND_pos(n)[1], ND_pos(h)[0],
- ND_pos(h)[1]);
- fprintf(fp, "stroke\n");
- if (do_arrow) {
- theta =
- atan2(ND_pos(n)[1] - ND_pos(h)[1],
- ND_pos(n)[0] - ND_pos(h)[0]);
- fprintf(fp, "%f %f %.2f %.2f %.2f doArrow\n",
- ND_pos(h)[0], ND_pos(h)[1], DEGREES(theta),
- arrow_l, arrow_w);
- }
- }
- }
- fprintf(fp, "%s", elog);
- }
- void outputGraph(Agraph_t * g, FILE * fp, int expMode)
- {
- pswrite(g, fp, expMode);
- }
- #endif /* DEBUG */
|