/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/common/output.c

Go to the documentation of this file.
00001 /* $Id: output.c,v 1.42 2008/03/03 23:01:51 ellson Exp $ $Revision: 1.42 $ */
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 #include "render.h"
00018 #include "agxbuf.h"
00019 
00020 #define YDIR(y) (Y_invert ? (Y_off - (y)) : (y))
00021 #define YFDIR(y) (Y_invert ? (YF_off - (y)) : (y))
00022 
00023 int Y_off;           /* ymin + ymax */
00024 double YF_off;       /* Y_off in inches */
00025 
00026 static void printptf(FILE * f, point pt)
00027 {
00028     fprintf(f, " %.3f %.3f", PS2INCH(pt.x), PS2INCH(YDIR(pt.y)));
00029 }
00030 
00031 /* setYInvert:
00032  * Set parameters used to flip coordinate system (y=0 at top).
00033  * Values do not need to be unset, since if Y_invert is set, it's
00034  * set for * all graphs during current run, so each will 
00035  * reinitialize the values for its bbox.
00036  */
00037 static void setYInvert(graph_t * g)
00038 {
00039     if (Y_invert) {
00040         Y_off = GD_bb(g).UR.y + GD_bb(g).LL.y;
00041         YF_off = PS2INCH(Y_off);
00042     }
00043 }
00044 
00045 static void writenodeandport(FILE * fp, node_t * node, char *port)
00046 {
00047     char *name;
00048     if (IS_CLUST_NODE(node))
00049         name = strchr(node->name, ':') + 1;
00050     else
00051         name = node->name;
00052     fprintf(fp, "%s", agcanonical(name));       /* slimey i know */
00053     if (port && *port)
00054         fprintf(fp, ":%s", agcanonical(port));
00055 }
00056 
00057 /* FIXME - there must be a proper way to get port info - these are 
00058  * supposed to be private to libgraph - from libgraph.h */
00059 #define TAILX 1
00060 #define HEADX 2
00061 
00062 /* _write_plain:
00063  */
00064 void write_plain(GVJ_t * job, graph_t * g, FILE * f, boolean extend)
00065 {
00066     int i, j, splinePoints;
00067     char *tport, *hport;
00068     node_t *n;
00069     edge_t *e;
00070     bezier bz;
00071     point pt;
00072     char *lbl;
00073 
00074 //    setup_graph(job, g);
00075     setYInvert(g);
00076     pt = GD_bb(g).UR;
00077     fprintf(f, "graph %.3f %.3f %.3f\n", job->zoom, PS2INCH(pt.x), PS2INCH(pt.y));
00078     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00079         if (IS_CLUST_NODE(n))
00080             continue;
00081         fprintf(f, "node %s ", agcanonical(n->name));
00082         printptf(f, ND_coord_i(n));
00083         if (ND_label(n)->html)   /* if html, get original text */
00084             lbl = agxget(n, N_label->index);
00085         else
00086             lbl = ND_label(n)->text;
00087         if (lbl)
00088             lbl = agcanonical(lbl);
00089         else
00090             lbl = "\"\"";
00091         fprintf(f, " %.3f %.3f %s %s %s %s %s\n",
00092                 ND_width(n), ND_height(n), lbl,
00093                 late_nnstring(n, N_style, "solid"),
00094                 ND_shape(n)->name,
00095                 late_nnstring(n, N_color, DEFAULT_COLOR),
00096                 late_nnstring(n, N_fillcolor, DEFAULT_FILL));
00097     }
00098     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00099         for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00100             if (extend && e->attr) {
00101                 tport = e->attr[TAILX];
00102                 hport = e->attr[HEADX];
00103             } else
00104                 tport = hport = "";
00105             if (ED_spl(e)) {
00106                 splinePoints = 0;
00107                 for (i = 0; i < ED_spl(e)->size; i++) {
00108                     bz = ED_spl(e)->list[i];
00109                     splinePoints += bz.size;
00110                 }
00111                 fprintf(f, "edge ");
00112                 writenodeandport(f, e->tail, tport);
00113                 fprintf(f, " ");
00114                 writenodeandport(f, e->head, hport);
00115                 fprintf(f, " %d", splinePoints);
00116                 for (i = 0; i < ED_spl(e)->size; i++) {
00117                     bz = ED_spl(e)->list[i];
00118                     for (j = 0; j < bz.size; j++)
00119                         printptf(f, bz.list[j]);
00120                 }
00121             }
00122             if (ED_label(e)) {
00123                 fprintf(f, " %s", agcanonical(ED_label(e)->text));
00124                 printptf(f, ED_label(e)->p);
00125             }
00126             fprintf(f, " %s %s\n", late_nnstring(e, E_style, "solid"),
00127                     late_nnstring(e, E_color, DEFAULT_COLOR));
00128         }
00129     }
00130     fprintf(f, "stop\n");
00131 }
00132 
00133 static void set_record_rects(node_t * n, field_t * f, agxbuf * xb)
00134 {
00135     int i;
00136     char buf[BUFSIZ];
00137 
00138     if (f->n_flds == 0) {
00139         sprintf(buf, "%d,%d,%d,%d ",
00140                 f->b.LL.x + ND_coord_i(n).x,
00141                 YDIR(f->b.LL.y + ND_coord_i(n).y),
00142                 f->b.UR.x + ND_coord_i(n).x,
00143                 YDIR(f->b.UR.y + ND_coord_i(n).y));
00144         agxbput(xb, buf);
00145     }
00146     for (i = 0; i < f->n_flds; i++)
00147         set_record_rects(n, f->fld[i], xb);
00148 }
00149 
00150 static void rec_attach_bb(graph_t * g)
00151 {
00152     int c;
00153     char buf[BUFSIZ];
00154     point pt;
00155 
00156     sprintf(buf, "%d,%d,%d,%d", GD_bb(g).LL.x, YDIR(GD_bb(g).LL.y),
00157             GD_bb(g).UR.x, YDIR(GD_bb(g).UR.y));
00158     agset(g, "bb", buf);
00159     if (GD_label(g) && GD_label(g)->text[0]) {
00160         pt = GD_label(g)->p;
00161         sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
00162         agset(g, "lp", buf);
00163     }
00164     for (c = 1; c <= GD_n_cluster(g); c++)
00165         rec_attach_bb(GD_clust(g)[c]);
00166 }
00167 
00168 void attach_attrs_and_arrows(graph_t* g, int* sp, int* ep)
00169 {
00170     int e_arrows;               /* graph has edges with end arrows */
00171     int s_arrows;               /* graph has edges with start arrows */
00172     int i, j, sides;
00173     char buf[BUFSIZ];           /* Used only for small strings */
00174     unsigned char xbuffer[BUFSIZ];      /* Initial buffer for xb */
00175     agxbuf xb;
00176     node_t *n;
00177     edge_t *e;
00178     point pt;
00179 
00180     e_arrows = s_arrows = 0;
00181     setYInvert(g);
00182     agxbinit(&xb, BUFSIZ, xbuffer);
00183     safe_dcl(g, g->proto->n, "pos", "", agnodeattr);
00184     safe_dcl(g, g->proto->n, "rects", "", agnodeattr);
00185     N_width = safe_dcl(g, g->proto->n, "width", "", agnodeattr);
00186     N_height = safe_dcl(g, g->proto->n, "height", "", agnodeattr);
00187     safe_dcl(g, g->proto->e, "pos", "", agedgeattr);
00188     if (GD_has_labels(g) & EDGE_LABEL)
00189         safe_dcl(g, g->proto->e, "lp", "", agedgeattr);
00190     if (GD_has_labels(g) & HEAD_LABEL)
00191         safe_dcl(g, g->proto->e, "head_lp", "", agedgeattr);
00192     if (GD_has_labels(g) & TAIL_LABEL)
00193         safe_dcl(g, g->proto->e, "tail_lp", "", agedgeattr);
00194     if (GD_label(g)) {
00195         safe_dcl(g, g, "lp", "", agraphattr);
00196         if (GD_label(g)->text[0]) {
00197             pt = GD_label(g)->p;
00198             sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
00199             agset(g, "lp", buf);
00200         }
00201     }
00202     safe_dcl(g, g, "bb", "", agraphattr);
00203     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00204         sprintf(buf, "%d,%d", ND_coord_i(n).x, YDIR(ND_coord_i(n).y));
00205         agset(n, "pos", buf);
00206         sprintf(buf, "%.2f", PS2INCH(ND_ht_i(n)));
00207         agxset(n, N_height->index, buf);
00208         sprintf(buf, "%.2f", PS2INCH(ND_lw_i(n) + ND_rw_i(n)));
00209         agxset(n, N_width->index, buf);
00210         if (strcmp(ND_shape(n)->name, "record") == 0) {
00211             set_record_rects(n, ND_shape_info(n), &xb);
00212             agxbpop(&xb);       /* get rid of last space */
00213             agset(n, "rects", agxbuse(&xb));
00214         } else {
00215             polygon_t *poly;
00216             int i;
00217             if (N_vertices && isPolygon(n)) {
00218                 poly = (polygon_t *) ND_shape_info(n);
00219                 sides = poly->sides;
00220                 if (sides < 3) {
00221                     char *p = agget(n, "samplepoints");
00222                     if (p)
00223                         sides = atoi(p);
00224                     else
00225                         sides = 8;
00226                     if (sides < 3)
00227                         sides = 8;
00228                 }
00229                 for (i = 0; i < sides; i++) {
00230                     if (i > 0)
00231                         agxbputc(&xb, ' ');
00232                     if (poly->sides >= 3)
00233                         sprintf(buf, "%.3f %.3f",
00234                                 PS2INCH(poly->vertices[i].x),
00235                                 YFDIR(PS2INCH(poly->vertices[i].y)));
00236                     else
00237                         sprintf(buf, "%.3f %.3f",
00238                                 ND_width(n) / 2.0 * cos(i /
00239                                                         (double) sides *
00240                                                         M_PI * 2.0),
00241                                 YFDIR(ND_height(n) / 2.0 *
00242                                    sin(i / (double) sides * M_PI * 2.0)));
00243                     agxbput(&xb, buf);
00244                 }
00245                 agxset(n, N_vertices->index, agxbuse(&xb));
00246             }
00247         }
00248         if (State >= GVSPLINES) {
00249             for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00250                 if (ED_edge_type(e) == IGNORED)
00251                     continue;
00252                 if (ED_spl(e) == NULL)
00253                     continue;   /* reported in postproc */
00254                 for (i = 0; i < ED_spl(e)->size; i++) {
00255                     if (i > 0)
00256                         agxbputc(&xb, ';');
00257                     if (ED_spl(e)->list[i].sflag) {
00258                         s_arrows = 1;
00259                         sprintf(buf, "s,%d,%d ",
00260                                 ED_spl(e)->list[i].sp.x,
00261                                 YDIR(ED_spl(e)->list[i].sp.y));
00262                         agxbput(&xb, buf);
00263                     }
00264                     if (ED_spl(e)->list[i].eflag) {
00265                         e_arrows = 1;
00266                         sprintf(buf, "e,%d,%d ",
00267                                 ED_spl(e)->list[i].ep.x,
00268                                 YDIR(ED_spl(e)->list[i].ep.y));
00269                         agxbput(&xb, buf);
00270                     }
00271                     for (j = 0; j < ED_spl(e)->list[i].size; j++) {
00272                         if (j > 0)
00273                             agxbputc(&xb, ' ');
00274                         pt = ED_spl(e)->list[i].list[j];
00275                         sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
00276                         agxbput(&xb, buf);
00277                     }
00278                 }
00279                 agset(e, "pos", agxbuse(&xb));
00280                 if (ED_label(e)) {
00281                     pt = ED_label(e)->p;
00282                     sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
00283                     agset(e, "lp", buf);
00284                 }
00285                 if (ED_head_label(e)) {
00286                     pt = ED_head_label(e)->p;
00287                     sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
00288                     agset(e, "head_lp", buf);
00289                 }
00290                 if (ED_tail_label(e)) {
00291                     pt = ED_tail_label(e)->p;
00292                     sprintf(buf, "%d,%d", pt.x, YDIR(pt.y));
00293                     agset(e, "tail_lp", buf);
00294                 }
00295             }
00296         }
00297     }
00298     rec_attach_bb(g);
00299     agxbfree(&xb);
00300 
00301     if (HAS_CLUST_EDGE(g))
00302         undoClusterEdges(g);
00303     
00304     *sp = s_arrows;
00305     *ep = e_arrows;
00306 }
00307 
00308 void attach_attrs(graph_t * g)
00309 {
00310     int e, s;
00311     attach_attrs_and_arrows (g, &s, &e);
00312 }
00313 
00314 void output_point(agxbuf *xbuf, pointf p)
00315 {
00316     char buf[BUFSIZ];
00317     sprintf(buf, "%d %d ", ROUND(p.x), YDIR(ROUND(p.y)));
00318     agxbput(xbuf, buf);
00319 }
00320 

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