2
This software may only be used by you under license from AT&T Corp.
3
("AT&T"). A copy of AT&T's Source Code Agreement is available at
4
AT&T's Internet website having the URL:
5
<http://www.research.att.com/sw/tools/graphviz/license/source.html>
6
If you received this software without first entering into a license
7
with AT&T, you have an infringing copy of this software and cannot use
8
it without violating AT&T's intellectual property rights.
22
void dotneato_write(graph_t* g)
29
if ((p = agget(g,"margin"))) {
30
i = sscanf(p,"%lf,%lf",&xf,&yf);
31
if (i > 0) g->u.drawing->margin.x = g->u.drawing->margin.y = POINTS(xf);
32
if (i > 1) g->u.drawing->margin.y = POINTS(yf);
35
/* set default margins depending on format */
36
switch (Output_lang) {
47
g->u.drawing->margin.x = DEFAULT_EMBED_MARGIN_X;
48
g->u.drawing->margin.y = DEFAULT_EMBED_MARGIN_Y;
60
g->u.drawing->margin.x = g->u.drawing->margin.y = DEFAULT_MARGIN;
67
switch (Output_lang) {
84
/* output in breadth first graph walk order */
85
emit_graph(g,0); break;
87
/* output color definition objects first */
88
emit_graph(g,EMIT_COLORS); break;
90
/* output sorted, i.e. all nodes then all edges */
91
emit_graph(g,EMIT_SORTED); break;
94
agwrite(g,Output_file); break;
96
agwrite(g,Output_file); break;
98
attach_attrs(g); write_plain(g,Output_file); break;
100
attach_attrs(g); write_plain_ext(g,Output_file); break;
105
/* Extensible buffer:
106
* Contents in buf; always null-terminated.
109
char* buf; /* start of buffer */
110
char* ptr; /* next place to write */
111
char* eptr; /* end of buffer */
112
int dyna; /* true if buffer is malloc'ed */
116
* Assume if init is non-null, hint = sizeof(init[])
119
initXBuf (xbuf* xb, unsigned int hint, char* init)
126
if (hint == 0) hint = BUFSIZ;
128
xb->buf = (char*)malloc (hint);
130
xb->eptr = xb->buf + hint;
143
* Append string s into xb
146
putXBuf (xbuf* xb, char* s)
148
int ssz = strlen (s);
149
int cnt; /* current no. of characters in buffer */
150
int size; /* current buffer size */
151
int nsize; /* new buffer size */
152
char* nbuf; /* new buffer */
154
if (xb->ptr + ssz >= xb->eptr) {
155
size = xb->eptr - xb->buf;
157
if (size+ssz > nsize) nsize = size+ssz;
158
cnt = xb->ptr - xb->buf;
160
nbuf = (char*)realloc(xb->buf,nsize);
161
if (!nbuf) {fprintf(stderr,"out of memory\n"); abort();}
165
nbuf = (char*)malloc(nsize);
166
if (!nbuf) {fprintf(stderr,"out of memory\n"); abort();}
167
memcpy (nbuf, xb->buf, cnt);
171
xb->ptr = xb->buf + cnt;
172
xb->eptr = xb->buf + nsize;
174
memcpy (xb->ptr, s, ssz+1);
181
if (xb->dyna) free (xb->buf);
187
if (xb->ptr > xb->buf) {
195
set_record_rects (node_t* n, field_t* f, xbuf* xb)
200
if (f->n_flds == 0) {
201
sprintf(buf, "%d,%d,%d,%d ",
202
f->b.LL.x + n->u.coord.x,
203
f->b.LL.y + n->u.coord.y,
204
f->b.UR.x + n->u.coord.x,
205
f->b.UR.y + n->u.coord.y);
208
for (i = 0; i < f->n_flds; i++)
209
set_record_rects (n, f->fld[i], xb);
212
static attrsym_t *safe_dcl(graph_t *g, void *obj, char *name, char *def,
213
attrsym_t*(*fun)(Agraph_t*, char*, char*))
215
attrsym_t *a = agfindattr(obj,name);
216
if (a == NULL) a = fun(g,name,def);
220
void attach_attrs(graph_t* g)
229
initXBuf (&xb, BUFSIZ, buf);
230
safe_dcl(g,g->proto->n,"pos","",agnodeattr);
231
safe_dcl(g,g->proto->n,"rects","",agnodeattr);
232
N_width = safe_dcl(g,g->proto->n,"width","",agnodeattr);
233
N_height = safe_dcl(g,g->proto->n,"height","",agnodeattr);
234
safe_dcl(g,g->proto->e,"pos","",agedgeattr);
235
if (g->u.has_edge_labels) safe_dcl(g,g->proto->e,"lp","",agedgeattr);
237
safe_dcl(g,g,"lp","",agraphattr);
239
sprintf(buf,"%d,%d",pt.x,pt.y);
242
safe_dcl(g,g,"bb","",agraphattr);
243
for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
244
sprintf(buf,"%d,%d",n->u.coord.x,n->u.coord.y);
246
sprintf(buf,"%.2f",PS2INCH(n->u.ht));
247
agxset(n,N_height->index,buf);
248
sprintf(buf,"%.2f",PS2INCH(n->u.lw + n->u.rw));
249
agxset(n,N_width->index,buf);
250
if (strcmp (n->u.shape->name, "record") == 0) {
252
set_record_rects (n, n->u.shape_info, &xb);
253
popXBuf (&xb); /* get rid of last space */
254
agset(n,"rects",xb.buf);
257
extern void poly_init(node_t *);
260
if (N_vertices && (n->u.shape->initfn == poly_init)) {
261
poly = (polygon_t*) n->u.shape_info;
265
char *p = agget(n,"samplepoints");
266
if (p) sides = atoi(p);
268
if (sides < 3) sides = 8;
270
for (i = 0; i < sides; i++) {
271
if (i > 0) {*p++ = ' ';}
272
if (poly->sides >= 3)
273
sprintf(p,"%.3lf %.3lf",
274
poly->vertices[i].x,poly->vertices[i].y);
276
sprintf(p,"%.3lf %.3lf",
277
n->u.width/2.0 * cos(i/(double)sides * PI * 2.0),
278
n->u.height/2.0 * sin(i/(double)sides * PI * 2.0));
281
agxset(n,N_vertices->index,buf);
284
for (e = agfstout(g,n); e; e = agnxtout(g,e)) {
286
if (e->u.spl == NULL)
287
{fprintf(stderr,"lost spline of %s %s\n",e->tail->name,e->head->name); continue;}
288
for (i = 0; i < e->u.spl->size; i++) {
289
if (i > 0) *p++ = ';';
290
if (e->u.spl->list[i].sflag) {
291
sprintf (p, "s,%d,%d ",e->u.spl->list[i].sp.x,e->u.spl->list[i].sp.y);
294
if (e->u.spl->list[i].eflag) {
295
sprintf (p, "e,%d,%d ",e->u.spl->list[i].ep.x,e->u.spl->list[i].ep.y);
298
for (j = 0; j < e->u.spl->list[i].size; j++) {
299
if (j > 0) *p++ = ' ';
300
pt = e->u.spl->list[i].list[j];
301
sprintf(p,"%d,%d",pt.x,pt.y);
309
sprintf(buf,"%d,%d",pt.x,pt.y);
318
void rec_attach_bb(graph_t* g)
323
sprintf(buf,"%d,%d,%d,%d", g->u.bb.LL.x, g->u.bb.LL.y,
324
g->u.bb.UR.x, g->u.bb.UR.y);
326
for (c = 1; c <= g->u.n_cluster; c++) rec_attach_bb(g->u.clust[c]);
329
static char *getoutputbuffer(char *str)
335
req = MAX(2 * strlen(str) + 2, BUFSIZ);
337
if (rv) rv = realloc(rv,req);
338
else rv = malloc(req);
345
static char *canonical(char *str)
347
return agstrcanon(str,getoutputbuffer(str));
350
static void writenodeandport(FILE *fp, char *node, char *port)
352
fprintf(fp,"%s",canonical(node)); /* slimey i know*/
353
if (port && *port) fprintf(fp,"%c%s",port[0],canonical(port+1));
356
void write_plain(graph_t* g, FILE* f)
364
fprintf(f,"graph %.3f",g->u.drawing->scale); printptf(f,g->u.bb.UR); fprintf(f,"\n");
365
for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
366
fprintf(f,"node %s ",canonical(n->name)); printptf(f,n->u.coord);
367
fprintf(f," %.3f %.3f %s %s %s %s %s\n",
368
n->u.width,n->u.height,canonical(n->u.label->text),
369
late_nnstring(n,N_style,"solid"),
371
late_nnstring(n,N_color,DEFAULT_COLOR),
372
late_nnstring(n,N_fillcolor,DEFAULT_FILL));
374
for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
375
for (e = agfstout(g,n); e; e = agnxtout(g,e)) {
376
bz = e->u.spl->list[0];
378
writenodeandport(f,e->tail->name,"");
380
writenodeandport(f,e->head->name,"");
381
fprintf(f," %d",bz.size);
382
for (i = 0; i < bz.size; i++) printptf(f,bz.list[i]);
384
fprintf(f," %s",canonical(e->u.label->text));
385
printptf(f,e->u.label->p);
387
fprintf(f," %s %s\n",late_nnstring(e,E_style,"solid"),
388
late_nnstring(e,E_color,DEFAULT_COLOR));
394
/* FIXME - there must be a proper way to get port info - these are
395
* supposed to be private to libgraph - from libgraph.h */
399
void write_plain_ext(graph_t* g, FILE* f)
408
fprintf(f,"graph %.3f",g->u.drawing->scale); printptf(f,g->u.bb.UR); fprintf(f,"\n");
409
for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
410
fprintf(f,"node %s ",canonical(n->name)); printptf(f,n->u.coord);
411
fprintf(f," %.3f %.3f %s %s %s %s %s\n",
412
n->u.width,n->u.height,canonical(n->u.label->text),
413
late_nnstring(n,N_style,"solid"),
415
late_nnstring(n,N_color,DEFAULT_COLOR),
416
late_nnstring(n,N_fillcolor,DEFAULT_FILL));
418
for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
419
for (e = agfstout(g,n); e; e = agnxtout(g,e)) {
420
bz = e->u.spl->list[0];
421
if (e->attr) {tport = e->attr[TAILX]; hport = e->attr[HEADX];}
422
else tport = hport = "";
424
writenodeandport(f,e->tail->name,tport);
426
writenodeandport(f,e->head->name,hport);
427
fprintf(f," %d",bz.size);
428
for (i = 0; i < bz.size; i++) printptf(f,bz.list[i]);
430
fprintf(f," %s",canonical(e->u.label->text));
431
printptf(f,e->u.label->p);
433
fprintf(f," %s %s\n",late_nnstring(e,E_style,"solid"),
434
late_nnstring(e,E_color,DEFAULT_COLOR));
440
void printptf(FILE* f, point pt)
442
fprintf(f," %.3f %.3f",PS2INCH(pt.x),PS2INCH(pt.y));
445
int codegen_bezier_has_arrows(void)
448
CodeGen->bezier_has_arrows
449
/* (CodeGen->arrowhead == 0)) */;