35 #define GNEW(t) (t*)malloc(sizeof(t))
49 #define XDOTVERSION "1.7"
51 #define NUMXBUFS (EMIT_HLABEL+1)
62 static double penwidth [] = {
86 static void xdot_str_xbuf (
agxbuf* xb,
char* pfx,
char*
s)
90 sprintf (buf,
"%s%d -", pfx, (
int)strlen(s));
96 static void xdot_str (
GVJ_t *job,
char* pfx,
char*
s)
99 xdot_str_xbuf (xbufs[emit_state], pfx, s);
106 static void xdot_trim_zeros (
char* buf,
int addSpace)
111 if ((dotp = strchr (buf,
'.'))) {
115 while (*p ==
'0') *p-- =
'\0';
122 p = buf + strlen(buf);
134 static void xdot_fmt_num (
char* buf,
double v)
137 if (v > -0.00000001 && v < 0.00000001)
141 sprintf(buf,
"%.02f", v);
142 xdot_trim_zeros (buf, 1);
148 xdot_fmt_num (buf, p.
x);
150 xdot_fmt_num (buf,
yDir(p.
y));
154 static void xdot_num(
agxbuf *xbuf,
double v)
157 xdot_fmt_num (buf, v);
161 static void xdot_points(
GVJ_t *job,
char c,
pointf * A,
int n)
168 sprintf(buf,
" %d ", n);
169 agxbput(xbufs[emit_state], buf);
170 for (i = 0; i < n; i++)
175 color2str (
unsigned char rgba[4])
177 static char buf [10];
180 sprintf (buf,
"#%02x%02x%02x", rgba[0], rgba[1], rgba[2]);
182 sprintf (buf,
"#%02x%02x%02x%02x", rgba[0], rgba[1], rgba[2], rgba[3]);
186 static void xdot_pencolor (
GVJ_t *job)
191 static void xdot_fillcolor (
GVJ_t *job)
196 static void xdot_style (
GVJ_t *job)
198 unsigned char buf0[BUFSIZ];
209 agxbput (&xbuf,
"setlinewidth(");
211 xdot_trim_zeros (buf, 0);
214 xdot_str (job,
"S ",
agxbuse(&xbuf));
223 if (
streq(p,
"filled") ||
streq(p,
"bold") ||
streq(p,
"setlinewidth"))
continue;
241 xdot_str (job,
"S ",
agxbuse(&xbuf));
248 static void xdot_end_node(
GVJ_t* job)
261 static void xdot_end_edge(
GVJ_t* job)
296 static void xdot_begin_anchor(
GVJ_t * job,
char *href,
char *tooltip,
char *target,
char *
id)
300 unsigned int flags = 0;
302 agxbput(xbufs[emit_state],
"H ");
309 sprintf (buf,
"%d ", flags);
310 agxbput(xbufs[emit_state], buf);
312 xdot_str (job,
"", href);
314 xdot_str (job,
"", tooltip);
316 xdot_str (job,
"", target);
319 static void xdot_end_anchor(
GVJ_t * job)
323 agxbput(xbufs[emit_state],
"H 0 ");
327 static void xdot_end_cluster(
GVJ_t * job)
340 static unsigned short
341 versionStr2Version (
char*
str)
350 if (n < BUFSIZ-1) buf[n++] = c;
352 agerr(
AGWARN,
"xdot version \"%s\" too long", str);
401 else if ((s =
agget(g,
"xdotversion")) && s[0] && ((us = versionStr2Version(s)) > 10)) {
448 static void dot_begin_graph(
GVJ_t *job)
469 xdot_begin_graph(g, s_arrows, e_arrows, job->
render.
id);
474 static void xdot_end_graph(
graph_t* g)
498 static void dot_end_graph(
GVJ_t *job)
535 static unsigned int flag_masks[] = { 0x1F, 0x3F, 0x7F };
544 agxbput(xbufs[emit_state],
"F ");
545 xdot_fmt_num (buf, span->
font->
size);
546 agxbput(xbufs[emit_state], buf);
547 xdot_str (job,
"", span->
font->
name);
550 switch (span->
just) {
567 unsigned int mask = flag_masks[xd->
version-15];
568 unsigned int bits = flags & mask;
569 if (textflags[emit_state] != bits) {
570 sprintf (buf,
"t %u ", bits);
571 agxbput(xbufs[emit_state], buf);
572 textflags[emit_state] = bits;
577 agxbput(xbufs[emit_state],
"T ");
579 sprintf(buf,
"%d ", j);
580 agxbput(xbufs[emit_state], buf);
581 xdot_fmt_num (buf, span->
size.
x);
582 agxbput(xbufs[emit_state], buf);
583 xdot_str (job,
"", span->
str);
590 sprintf (buf,
"%.03f", v);
591 xdot_trim_zeros (buf, 1);
592 xdot_str_xbuf (xb, buf, color2str (clr->
u.
rgba));
595 static void xdot_gradient_fillcolor (
GVJ_t* job,
int filled,
pointf* A,
int n)
597 unsigned char buf0[BUFSIZ];
605 xdot_fillcolor (job);
626 c1.
x = G[0].
x + (r2/4) * cos(angle);
627 c1.
y = G[0].
y + (r2/4) * sin(angle);
634 xdot_num (&xbuf, r1);
636 xdot_num (&xbuf, r2);
653 xdot_str (job,
"C ",
agxbuse(&xbuf));
657 static void xdot_ellipse(
GVJ_t * job,
pointf * A,
int filled)
667 xdot_gradient_fillcolor (job, filled, A, 2);
670 xdot_fillcolor (job);
671 agxbput(xbufs[emit_state],
"E ");
674 agxbput(xbufs[emit_state],
"e ");
676 xdot_fmt_num (buf, A[1].x - A[0].x);
677 agxbput(xbufs[emit_state], buf);
678 xdot_fmt_num (buf, A[1].y - A[0].y);
679 agxbput(xbufs[emit_state], buf);
682 static void xdot_bezier(
GVJ_t * job,
pointf * A,
int n,
int arrow_at_start,
int arrow_at_end,
int filled)
688 xdot_gradient_fillcolor (job, filled, A, n);
691 xdot_fillcolor (job);
692 xdot_points(job,
'b', A, n);
695 xdot_points(job,
'B', A, n);
698 static void xdot_polygon(
GVJ_t * job,
pointf * A,
int n,
int filled)
704 xdot_gradient_fillcolor (job, filled, A, n);
707 xdot_fillcolor (job);
708 xdot_points(job,
'P', A, n);
711 xdot_points(job,
'p', A, n);
718 xdot_points(job,
'L', A, n);
726 agxbput(xbufs[emit_state],
"I ");
728 xdot_fmt_num (buf, b.
UR.
x - b.
LL.
x);
729 agxbput(xbufs[emit_state], buf);
730 xdot_fmt_num (buf, b.
UR.
y - b.
LL.
y);
731 agxbput(xbufs[emit_state], buf);
732 xdot_str (job,
"", (
char*)(us->
name));
gvrender_engine_t xdot_engine
attrsym_t * safe_dcl(graph_t *g, int obj_kind, char *name, char *def)
gvrender_features_t render_features_dot
#define LAYOUT_NOT_REQUIRED
gvrender_engine_t dot_engine
CGRAPH_API Agiodisc_t AgIoDisc
int agxset(void *obj, Agsym_t *sym, char *value)
void undoClusterEdges(graph_t *g)
size_t agxbput(agxbuf *xb, const char *s)
unsigned char buf[NUMXBUFS][BUFSIZ]
CGRAPH_API int agwrite(Agraph_t *g, void *chan)
int agerr(agerrlevel_t level, const char *fmt,...)
#define GVRENDER_DOES_TRANSFORM
int(* flushfn)(void *chan)
char * agget(void *obj, char *name)
int gvputs(GVJ_t *job, const char *s)
void write_plain(GVJ_t *job, graph_t *g, FILE *f, boolean extend)
void attach_attrs_and_arrows(graph_t *g, int *sp, int *ep)
#define GVRENDER_DOES_TARGETS
#define GVRENDER_DOES_TOOLTIPS
gvplugin_active_render_t render
gvplugin_installed_t gvrender_dot_types[]
gvdevice_features_t device_features_canon
int(* afread)(void *chan, char *buf, int bufsize)
double yoffset_centerline
void agxbinit(agxbuf *xb, unsigned int hint, unsigned char *init)
gvdevice_features_t device_features_dot
int agsafeset(void *obj, char *name, char *value, char *def)
int(* putstrfn)(void *chan, const char *str)
#define GVRENDER_DOES_MAPS
gvplugin_installed_t gvdevice_dot_types[]
#define HAS_CLUST_EDGE(g)
int(* putstr)(void *chan, const char *str)
#define OUTPUT_NOT_REQUIRED
gvrender_features_t render_features_xdot
void core_loadimage_xdot(GVJ_t *, usershape_t *, boxf, boolean)
void attach_attrs(graph_t *g)
void agxbfree(agxbuf *xb)
void get_gradient_points(pointf *A, pointf *G, int n, float angle, int flags)