00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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;
00024 double YF_off;
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
00032
00033
00034
00035
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));
00053 if (port && *port)
00054 fprintf(fp, ":%s", agcanonical(port));
00055 }
00056
00057
00058
00059 #define TAILX 1
00060 #define HEADX 2
00061
00062
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
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)
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;
00171 int s_arrows;
00172 int i, j, sides;
00173 char buf[BUFSIZ];
00174 unsigned char xbuffer[BUFSIZ];
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);
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;
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