colors, fonts, etc. can change within node or edge label.
for (j = 1; j < l; j = j + 1)
s = concat (s, tt[j]);
o.s = s;
+ } else if (t[i] == 'C') {
+ i = i + 3;
+ continue;
+ } else if (t[i] == 'c') {
+ i = i + 3;
+ continue;
+ } else if (t[i] == 'F') {
+ i = i + 4;
+ continue;
+ } else if (t[i] == 'S') {
+ i = i + 3;
+ continue;
} else {
dotty.message (0, concat ('draw language parser error: ', t[i]));
return null;
#define RANKDIR_BT 2
#define RANKDIR_RL 3
+/* values specifying emit state */
+#define EMIT_DRAW 0
+#define EMIT_LABEL 1
+#define EMIT_TDRAW 2
+#define EMIT_HDRAW 3
+#define EMIT_TLABEL 4
+#define EMIT_HLABEL 5
+
/* user-specified node position: ND_pinned */
#define P_SET 1 /* position supplied by user */
#define P_FIX 2 /* position fixed during topological layout */
#include "gvc.h"
static char *defaultlinestyle[3] = { "solid\0", "setlinewidth\0001\0", 0 };
+int emitState;
/* parse_layers:
* Split input string into tokens, with separators specified by
return TRUE;
}
-static void emit_background(GVC_t * gvc, graph_t *g)
+void emit_background(GVC_t * gvc, graph_t *g)
{
gvrender_job_t * job = gvc->job;
char *str;
return boxf_overlap(job->pageBox, b);
}
-static void emit_edge(GVC_t * gvc, edge_t * e)
+void emit_edge_graphics(GVC_t * gvc, edge_t * e)
{
int i, j, cnum, numc = 0;
char *color, *style;
boolean saved = FALSE;
double scale, numc2;
char *p;
- char *s, *url = NULL, *label = NULL, *tooltip = NULL, *target = NULL;
- textlabel_t *lab = NULL;
+ extern int xdemitState;
#define SEP 2.0
-#if 0
-fprintf(stderr,"edge_in_layer %s edge_in_pageBox %s\n",
- edge_in_layer(gvc, e->head->graph, e)?"true":"false",
- edge_in_pageBox(gvc, e)?"true":"false");
-#endif
-
- if (! edge_in_pageBox(gvc, e) || ! edge_in_layer(gvc, e->head->graph, e))
- return;
-
- gvrender_begin_edge(gvc, e);
- if (((s = agget(e, "href")) && s[0])
- || ((s = agget(e, "URL")) && s[0])) {
- url = strdup_and_subst_edge(s, e);
- if ((lab = ED_label(e))) {
- label = lab->text;
- }
- if ((s = agget(e, "tooltip")) && s[0])
- tooltip = strdup_and_subst_edge(s, e);
- else if (label)
- tooltip = strdup_and_subst_edge(label, e);
- if ((s = agget(e, "target")) && s[0])
- target = strdup_and_subst_edge(s, e);
- gvrender_begin_anchor(gvc, url, tooltip, target);
- }
style = late_string(e, E_style, "");
/* We shortcircuit drawing an invisible edge because the arrowhead
* code resets the style to solid, and most of the code generators
}
}
}
+ xdemitState = EMIT_DRAW;
if (ED_spl(e)) {
scale = late_double(e, E_arrowsz, 1.0, 0.0);
color = late_string(e, E_color, "");
FALSE, FALSE);
}
}
+ xdemitState = EMIT_TDRAW;
if (bz.sflag)
arrow_gen(gvc, bz.sp, bz.list[0], scale, bz.sflag);
+ xdemitState = EMIT_HDRAW;
if (bz.eflag)
arrow_gen(gvc, bz.ep, bz.list[bz.size - 1], scale,
bz.eflag);
} else {
gvrender_beziercurve(gvc, bzf.list, bz.size, FALSE,
FALSE);
+ xdemitState = EMIT_TDRAW;
if (bz.sflag)
arrow_gen(gvc, bz.sp, bz.list[0], scale, bz.sflag);
+ xdemitState = EMIT_HDRAW;
if (bz.eflag)
arrow_gen(gvc, bz.ep, bz.list[bz.size - 1], scale,
bz.eflag);
}
}
}
+ xdemitState = EMIT_LABEL;
if (ED_label(e)) {
emit_label(gvc, ED_label(e), (void *) e);
if (mapbool(late_string(e, E_decorate, "false")) && ED_spl(e))
emit_attachment(gvc, ED_label(e), ED_spl(e));
}
+ xdemitState = EMIT_HLABEL;
if (ED_head_label(e))
emit_label(gvc, ED_head_label(e), (void *) e); /* vladimir */
+ xdemitState = EMIT_TLABEL;
if (ED_tail_label(e))
emit_label(gvc, ED_tail_label(e), (void *) e); /* vladimir */
if (saved)
gvrender_end_context(gvc);
+}
+
+static void emit_edge(GVC_t * gvc, edge_t * e)
+{
+ char *s, *url = NULL, *label = NULL, *tooltip = NULL, *target = NULL;
+ textlabel_t *lab = NULL;
+
+#if 0
+fprintf(stderr,"edge_in_layer %s edge_in_pageBox %s\n",
+ edge_in_layer(gvc, e->head->graph, e)?"true":"false",
+ edge_in_pageBox(gvc, e)?"true":"false");
+#endif
+
+ if (! edge_in_pageBox(gvc, e) || ! edge_in_layer(gvc, e->head->graph, e))
+ return;
+
+ gvrender_begin_edge(gvc, e);
+ if (((s = agget(e, "href")) && s[0])
+ || ((s = agget(e, "URL")) && s[0])) {
+ url = strdup_and_subst_edge(s, e);
+ if ((lab = ED_label(e))) {
+ label = lab->text;
+ }
+ if ((s = agget(e, "tooltip")) && s[0])
+ tooltip = strdup_and_subst_edge(s, e);
+ else if (label)
+ tooltip = strdup_and_subst_edge(label, e);
+ if ((s = agget(e, "target")) && s[0])
+ target = strdup_and_subst_edge(s, e);
+ gvrender_begin_anchor(gvc, url, tooltip, target);
+ }
+ emit_edge_graphics (gvc, e);
if (url) {
gvrender_end_anchor(gvc);
free(url);
node_t *n;
edge_t *e;
char *s, *url = NULL, *tooltip = NULL, *target = NULL;
+ extern int xdemitState;
for (c = 1; c <= GD_n_cluster(g); c++) {
sg = GD_clust(g)[c];
}
gvrender_begin_context(gvc);
filled = FALSE;
+ xdemitState = EMIT_DRAW;
if (((str = agget(sg, "style")) != 0) && str[0]) {
gvrender_set_style(gvc, (style = parse_style(str)));
for (i = 0; style[i]; i++)
gvrender_set_pencolor(gvc, str);
gvrender_polygon(gvc, A, 4, filled);
}
+ xdemitState = EMIT_DRAW;
if (GD_label(sg))
emit_label(gvc, GD_label(sg), (void *) sg);
static int e_arrows; /* graph has edges with end arrows */
static int s_arrows; /* graph has edges with start arrows */
-agxbuf outbuf;
-agxbuf charbuf;
static void printptf(FILE * f, point pt)
{
_write_plain(gvc, g, f, TRUE);
}
-static attrsym_t *safe_dcl(graph_t * g, void *obj, char *name, char *def,
- attrsym_t * (*fun) (Agraph_t *, char *, char *))
-{
- attrsym_t *a = agfindattr(obj, name);
- if (a == NULL)
- a = fun(g, name, def);
- return a;
-}
-
-static int isInvis(char *style)
-{
- char **styles = 0;
- char **sp;
- char *p;
-
- if (style[0]) {
- styles = parse_style(style);
- sp = styles;
- while ((p = *sp++)) {
- if (streq(p, "invis"))
- return 1;
- }
- }
- return 0;
-}
-
-/*
- * John M. suggests:
- * You might want to add four more:
- *
- * _ohdraw_ (optional head-end arrow for edges)
- * _ohldraw_ (optional head-end label for edges)
- * _otdraw_ (optional tail-end arrow for edges)
- * _otldraw_ (optional tail-end label for edges)
- *
- * that would be generated when an additional option is supplied to
- * dot, etc. and
- * these would be the arrow/label positions to use if a user want to flip the
- * direction of an edge (as sometimes is there want).
- */
-static void extend_attrs(GVC_t * gvc, graph_t *g)
-{
- int i, j;
- bezier bz = { 0, 0, 0, 0 };
- bezierf bzf;
- double scale;
- node_t *n;
- edge_t *e;
- attrsym_t *n_draw = NULL;
- attrsym_t *n_l_draw = NULL;
- attrsym_t *e_draw = NULL;
- attrsym_t *h_draw = NULL;
- attrsym_t *t_draw = NULL;
- attrsym_t *e_l_draw = NULL;
- attrsym_t *hl_draw = NULL;
- attrsym_t *tl_draw = NULL;
- unsigned char buf[BUFSIZ];
- unsigned char cbuf[BUFSIZ];
-
- if (GD_has_labels(g) & GRAPH_LABEL)
- g_l_draw = safe_dcl(g, g, "_ldraw_", "", agraphattr);
- if (GD_n_cluster(g))
- g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
-
- n_draw = safe_dcl(g, g->proto->n, "_draw_", "", agnodeattr);
- n_l_draw = safe_dcl(g, g->proto->n, "_ldraw_", "", agnodeattr);
-
- e_draw = safe_dcl(g, g->proto->e, "_draw_", "", agedgeattr);
- if (e_arrows)
- h_draw = safe_dcl(g, g->proto->e, "_hdraw_", "", agedgeattr);
- if (s_arrows)
- t_draw = safe_dcl(g, g->proto->e, "_tdraw_", "", agedgeattr);
- if (GD_has_labels(g) & EDGE_LABEL)
- e_l_draw = safe_dcl(g, g->proto->e, "_ldraw_", "", agedgeattr);
- if (GD_has_labels(g) & HEAD_LABEL)
- hl_draw = safe_dcl(g, g->proto->e, "_hldraw_", "", agedgeattr);
- if (GD_has_labels(g) & TAIL_LABEL)
- tl_draw = safe_dcl(g, g->proto->e, "_tldraw_", "", agedgeattr);
-
- agxbinit(&outbuf, BUFSIZ, buf);
- agxbinit(&charbuf, BUFSIZ, cbuf);
- for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- if (ND_shape(n) && !isInvis(late_string(n, N_style, ""))) {
- ND_shape(n)->fns->codefn(gvc, n);
- agxset(n, n_draw->index, agxbuse(&outbuf));
- agxset(n, n_l_draw->index, agxbuse(&charbuf));
- }
- if (State < GVSPLINES)
- continue;
- for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
- if (ED_edge_type(e) == IGNORED)
- continue;
- if (isInvis(late_string(e, E_style, "")))
- continue;
- if (ED_spl(e) == NULL)
- continue;
-
- scale = late_double(e, E_arrowsz, 1.0, 0.0);
- for (i = 0; i < ED_spl(e)->size; i++) {
- bz = ED_spl(e)->list[i];
- /* convert points to pointf for gvrender api */
- bzf.size = bz.size;
- bzf.list = malloc(sizeof(pointf) * bzf.size);
- for (j = 0; j < bz.size; j++)
- P2PF(bz.list[j], bzf.list[j]);
- gvrender_beziercurve(gvc, bzf.list, bz.size, FALSE, FALSE);
- free(bzf.list);
- }
- agxset(e, e_draw->index, agxbuse(&outbuf));
- for (i = 0; i < ED_spl(e)->size; i++) {
- if (bz.sflag) {
- arrow_gen(gvc, bz.sp, bz.list[0], scale, bz.sflag);
- agxset(e, t_draw->index, agxbuse(&outbuf));
- }
- if (bz.eflag) {
- arrow_gen(gvc, bz.ep, bz.list[bz.size - 1], scale,
- bz.eflag);
- agxset(e, h_draw->index, agxbuse(&outbuf));
- }
- }
- if (ED_label(e)) {
- emit_label(gvc, ED_label(e), (void *) e);
- if (mapbool(late_string(e, E_decorate, "false"))
- && ED_spl(e)) {
- emit_attachment(gvc, ED_label(e), ED_spl(e));
- agxbput(&charbuf, agxbuse(&outbuf));
- }
- agxset(e, e_l_draw->index, agxbuse(&charbuf));
- }
- if (ED_head_label(e)) {
- emit_label(gvc, ED_head_label(e), (void *) e);
- agxset(e, hl_draw->index, agxbuse(&charbuf));
- }
- if (ED_tail_label(e)) {
- emit_label(gvc, ED_tail_label(e), (void *) e);
- agxset(e, tl_draw->index, agxbuse(&charbuf));
- }
- }
- }
- if (GD_label(g)) {
- emit_label(gvc, GD_label(g), (void *) g);
- agxset(g, g_l_draw->index, agxbuse(&charbuf));
- }
- emit_clusters(gvc, g, 0);
- agxbfree(&outbuf);
- agxbfree(&charbuf);
-}
void write_extended_dot(GVC_t *gvc, graph_t *g, FILE *f)
{
attach_attrs(g);
- extend_attrs(gvc, g);
+ extend_attrs(gvc, g, s_arrows, e_arrows);
agwrite(g, f);
}
extern void enqueue(queue *, Agnode_t *);
extern void enqueue_neighbors(queue *, Agnode_t *, int);
extern void emit_attachment(GVC_t * gvc, textlabel_t *, splines *);
+ extern void emit_background(GVC_t * gvc, graph_t *g);
extern void emit_clusters(GVC_t * gvc, Agraph_t * g, int flags);
+ extern void emit_edge_graphics(GVC_t * gvc, edge_t * e);
extern void emit_graph(GVC_t * gvc, graph_t * g);
extern void emit_label(GVC_t * gvc, textlabel_t *, void *obj);
extern int emit_once(char *message);
extern void epsf_gencode(GVC_t * gvc, node_t * n);
extern point exch_xy(point p);
extern pointf exch_xyf(pointf p);
+ extern void extend_attrs(GVC_t *, graph_t*, int, int);
extern shape_desc *find_user_shape(char *);
extern box flip_rec_box(box b, point p);
extern point flip_pt(point p, int rankdir);
extern point *routesplines(path *, int *);
extern void routesplinesterm(void);
extern char *safefile(char *shapefilename);
+ extern attrsym_t* safe_dcl(graph_t*, void*, char*, char*,
+ attrsym_t * (*fun) (Agraph_t *, char *, char *));
extern int selfRightSpace (edge_t* e);
extern void setup_graph(GVC_t * gvc, graph_t * g);
extern shape_kind shapeOf(node_t *);
static point *A;
static int A_size;
int filled;
+ extern int xdemitState;
+ xdemitState = EMIT_DRAW;
poly = (polygon_t *) ND_shape_info(n);
vertices = poly->vertices;
sides = poly->sides;
filled = 0;
}
+ xdemitState = EMIT_LABEL;
emit_label(gvc, ND_label(n), (void *) n);
}
point A[4];
int i, style;
field_t *f;
+ extern int xdemitState;
+ xdemitState = EMIT_DRAW;
f = (field_t *) ND_shape_info(n);
A[0] = f->b.LL;
A[2] = f->b.UR;
round_corners(gvc, n, A, 4, ROUNDED);
else
gvrender_polygon(gvc, A, 4, style & FILLED);
+ xdemitState = EMIT_LABEL;
gen_fields(gvc, n, f);
}
}
agclose(clg);
}
+
+/* safe_dcl:
+ * Find the attribute belonging to graph g for objects like obj
+ * with given name. If one does not exist, create it with the
+ * supplied function fun with default value def.
+ */
+attrsym_t*
+safe_dcl(graph_t * g, void *obj, char *name, char *def,
+ attrsym_t * (*fun) (Agraph_t *, char *, char *))
+{
+ attrsym_t *a = agfindattr(obj, name);
+ if (a == NULL)
+ a = fun(g, name, def);
+ return a;
+}
+
#include "gvc.h"
#include "agxbuf.h"
-extern agxbuf charbuf;
-extern agxbuf outbuf;
+int xdemitState;
+static agxbuf xbuf0;
+static agxbuf xbuf1;
+static agxbuf xbuf2;
+static agxbuf xbuf3;
+static agxbuf xbuf4;
+static agxbuf xbuf5;
+static agxbuf* xbufs[6] = {
+ &xbuf0, &xbuf1,
+ &xbuf2, &xbuf3,
+ &xbuf4, &xbuf5,
+};
static Agraph_t *cluster_g;
+static int isInvis(char *style)
+{
+ char **styles = 0;
+ char **sp;
+ char *p;
+
+ if (style[0]) {
+ styles = parse_style(style);
+ sp = styles;
+ while ((p = *sp++)) {
+ if (streq(p, "invis"))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * John M. suggests:
+ * You might want to add four more:
+ *
+ * _ohdraw_ (optional head-end arrow for edges)
+ * _ohldraw_ (optional head-end label for edges)
+ * _otdraw_ (optional tail-end arrow for edges)
+ * _otldraw_ (optional tail-end label for edges)
+ *
+ * that would be generated when an additional option is supplied to
+ * dot, etc. and
+ * these would be the arrow/label positions to use if a user want to flip the
+ * direction of an edge (as sometimes is there want).
+ */
+void extend_attrs(GVC_t * gvc, graph_t *g, int s_arrows, int e_arrows)
+{
+ node_t *n;
+ edge_t *e;
+ attrsym_t *n_draw = NULL;
+ attrsym_t *n_l_draw = NULL;
+ attrsym_t *e_draw = NULL;
+ attrsym_t *h_draw = NULL;
+ attrsym_t *t_draw = NULL;
+ attrsym_t *e_l_draw = NULL;
+ attrsym_t *hl_draw = NULL;
+ attrsym_t *tl_draw = NULL;
+ unsigned char buf0[BUFSIZ];
+ unsigned char buf1[BUFSIZ];
+ unsigned char buf2[BUFSIZ];
+ unsigned char buf3[BUFSIZ];
+ unsigned char buf4[BUFSIZ];
+ unsigned char buf5[BUFSIZ];
+
+ if (GD_has_labels(g) & GRAPH_LABEL)
+ g_l_draw = safe_dcl(g, g, "_ldraw_", "", agraphattr);
+ if (GD_n_cluster(g))
+ g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
+
+ n_draw = safe_dcl(g, g->proto->n, "_draw_", "", agnodeattr);
+ n_l_draw = safe_dcl(g, g->proto->n, "_ldraw_", "", agnodeattr);
+
+ e_draw = safe_dcl(g, g->proto->e, "_draw_", "", agedgeattr);
+ if (e_arrows)
+ h_draw = safe_dcl(g, g->proto->e, "_hdraw_", "", agedgeattr);
+ if (s_arrows)
+ t_draw = safe_dcl(g, g->proto->e, "_tdraw_", "", agedgeattr);
+ if (GD_has_labels(g) & EDGE_LABEL)
+ e_l_draw = safe_dcl(g, g->proto->e, "_ldraw_", "", agedgeattr);
+ if (GD_has_labels(g) & HEAD_LABEL)
+ hl_draw = safe_dcl(g, g->proto->e, "_hldraw_", "", agedgeattr);
+ if (GD_has_labels(g) & TAIL_LABEL)
+ tl_draw = safe_dcl(g, g->proto->e, "_tldraw_", "", agedgeattr);
+
+ agxbinit(&xbuf0, BUFSIZ, buf0);
+ agxbinit(&xbuf1, BUFSIZ, buf1);
+ agxbinit(&xbuf2, BUFSIZ, buf2);
+ agxbinit(&xbuf3, BUFSIZ, buf3);
+ agxbinit(&xbuf4, BUFSIZ, buf4);
+ agxbinit(&xbuf5, BUFSIZ, buf5);
+
+ for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
+ if (ND_shape(n) && !isInvis(late_string(n, N_style, ""))) {
+ ND_shape(n)->fns->codefn(gvc, n);
+ agxset(n, n_draw->index, agxbuse(xbufs[EMIT_DRAW]));
+ agxset(n, n_l_draw->index, agxbuse(xbufs[EMIT_LABEL]));
+ }
+ if (State < GVSPLINES)
+ continue;
+ for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
+ if (ED_edge_type(e) == IGNORED)
+ continue;
+ if (isInvis(late_string(e, E_style, "")))
+ continue;
+ if (ED_spl(e) == NULL)
+ continue;
+
+ emit_edge_graphics (gvc, e);
+ agxset(e, e_draw->index, agxbuse(xbufs[EMIT_DRAW]));
+ if (t_draw) agxset(e, t_draw->index, agxbuse(xbufs[EMIT_TDRAW]));
+ if (h_draw) agxset(e, h_draw->index, agxbuse(xbufs[EMIT_HDRAW]));
+ if (e_l_draw) agxset(e, e_l_draw->index,agxbuse(xbufs[EMIT_LABEL]));
+ if (tl_draw) agxset(e, tl_draw->index, agxbuse(xbufs[EMIT_TLABEL]));
+ if (hl_draw) agxset(e, hl_draw->index, agxbuse(xbufs[EMIT_HLABEL]));
+ }
+ }
+
+ xdemitState = EMIT_DRAW;
+ emit_background(gvc, g);
+ if (agxblen(xbufs[EMIT_DRAW])) {
+ if (!g_draw)
+ g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
+ agxset(g, g_draw->index, agxbuse(xbufs[EMIT_DRAW]));
+ }
+ xdemitState = EMIT_LABEL;
+ if (GD_label(g)) {
+ emit_label(gvc, GD_label(g), (void *) g);
+ agxset(g, g_l_draw->index, agxbuse(xbufs[EMIT_LABEL]));
+ }
+ emit_clusters(gvc, g, 0);
+ agxbfree(&xbuf0);
+ agxbfree(&xbuf1);
+ agxbfree(&xbuf2);
+ agxbfree(&xbuf3);
+ agxbfree(&xbuf4);
+ agxbfree(&xbuf5);
+}
+
+static void xd_str (char* pfx, char* s)
+{
+ char buf[BUFSIZ];
+
+ sprintf (buf, "%s%d -", pfx, strlen(s));
+ agxbput(xbufs[xdemitState], buf);
+ agxbput(xbufs[xdemitState], s);
+ agxbputc(xbufs[xdemitState], ' ');
+}
+
static void xd_textline(point p, textline_t * line)
{
char buf[BUFSIZ];
int j;
- agxbputc(&charbuf, 'T');
switch (line->just) {
case 'l':
j = -1;
j = 0;
break;
}
- sprintf(buf, " %d %d %d %d %d -", p.x, YDIR(p.y), j,
- (int) line->width, (int) strlen(line->str));
- agxbput(&charbuf, buf);
- agxbput(&charbuf, line->str);
- agxbputc(&charbuf, ' ');
+ sprintf(buf, "T %d %d %d %d ", p.x, YDIR(p.y), j, (int) line->width);
+ agxbput(xbufs[xdemitState], buf);
+ xd_str ("", line->str);
}
static void xd_ellipse(point p, int rx, int ry, int filled)
{
char buf[BUFSIZ];
- agxbputc(&outbuf, (filled ? 'E' : 'e'));
+ agxbputc(xbufs[xdemitState], (filled ? 'E' : 'e'));
sprintf(buf, " %d %d %d %d ", p.x, YDIR(p.y), rx, ry);
- agxbput(&outbuf, buf);
+ agxbput(xbufs[xdemitState], buf);
}
static void xd_points(char c, point * A, int n)
int i;
point p;
- agxbputc(&outbuf, c);
+ agxbputc(xbufs[xdemitState], c);
sprintf(buf, " %d ", n);
- agxbput(&outbuf, buf);
+ agxbput(xbufs[xdemitState], buf);
for (i = 0; i < n; i++) {
p = A[i];
sprintf(buf, "%d %d ", p.x, YDIR(p.y));
- agxbput(&outbuf, buf);
+ agxbput(xbufs[xdemitState], buf);
}
}
xd_points('L', A, n);
}
+static void
+xd_set_font (char *fontname, double fontsize)
+{
+ char buf[BUFSIZ];
+
+ sprintf(buf, "F %f ", fontsize);
+ agxbput(xbufs[xdemitState], buf);
+ xd_str ("", fontname);
+}
+
+static void
+xd_set_pencolor (char *name)
+{
+ xd_str ("c ", name);
+}
+
+static void
+xd_set_fillcolor (char *name)
+{
+ xd_str ("C ", name);
+}
+
+static void
+xd_set_style (char **s)
+{
+ char buf[BUFSIZ];
+ agxbuf xbuf;
+ char* p;
+ int more;
+
+ agxbinit(&xbuf, BUFSIZ, buf);
+ while ((p = *s++)) {
+ agxbput(&xbuf, p);
+ while (*p)
+ p++;
+ p++;
+ if (*p) { /* arguments */
+ agxbputc(&xbuf, '(');
+ more = 0;
+ while (*p) {
+ if (more)
+ agxbputc(&xbuf, ',');
+ agxbput(&xbuf, p);
+ while (*p) p++;
+ p++;
+ more++;
+ }
+ agxbputc(&xbuf, ')');
+ }
+ xd_str ("S ", agxbuse(&xbuf));
+ }
+ agxbfree(&xbuf);
+}
+
static void xd_begin_cluster(Agraph_t * sg)
{
cluster_g = sg;
static void xd_end_cluster(void)
{
- agxset(cluster_g, g_draw->index, agxbuse(&outbuf));
+ agxset(cluster_g, g_draw->index, agxbuse(xbufs[EMIT_DRAW]));
if (GD_label(cluster_g))
- agxset(cluster_g, g_l_draw->index, agxbuse(&charbuf));
+ agxset(cluster_g, g_l_draw->index, agxbuse(xbufs[EMIT_LABEL]));
}
codegen_t XDot_CodeGen = {
xd_begin_cluster, xd_end_cluster,
0, /* xd_begin_nodes */ 0, /* xd_end_nodes */
0, /* xd_begin_edges */ 0, /* xd_end_edges */
- 0, /* xd_begin_node */ 0, /* xd_node */
- 0, /* xd_begin_edge */ 0, /* xd_edge */
+ 0, /* xd_begin_node */ 0, /* xd_end_node */
+ 0, /* xd_begin_edge */ 0, /* xd_end_edge */
0, /* xd_begin_context */ 0, /* xd_context */
0, /* xd_begin_anchor */ 0, /* xd_anchor */
- 0, /* xd_set_font */ xd_textline,
- 0, /* xd_set_pencolor */ 0, /* xd_set_fillcolor */ 0, /* xd_set_style */
+ xd_set_font, xd_textline,
+ xd_set_pencolor, xd_set_fillcolor, xd_set_style,
xd_ellipse, xd_polygon,
xd_bezier, xd_polyline,
0, /* xd_has_arrows */ 0, /* xd_comment */