noinst_LTLIBRARIES = libcommon_C.la
if WITH_CODEGENS
-CODEGENS = $(GD_CODEGENS) diagen.c hpglgen.c mifgen.c mpgen.c picgen.c vtxgen.c xdgen.c
+CODEGENS = $(GD_CODEGENS) diagen.c hpglgen.c mifgen.c mpgen.c picgen.c vtxgen.c
endif
NOINST_GENERATED_HDRS = colortbl.h ps.h htmltable.h htmlparse.h htmllex.h
GD_CODEGENS =
-CODEGENS = $(GD_CODEGENS) diagen.o figgen.o hpglgen.o mifgen.o \
- mpgen.o picgen.o vtxgen.o xdgen.o
+CODEGENS = $(GD_CODEGENS) diagen.o hpglgen.o mifgen.o mpgen.o picgen.o vtxgen.o
OBJS = arrows.o colxlate.o fontmetrics.o \
args.o memory.o globals.o htmllex.o htmlparse.o htmltable.o input.o \
return bb;
}
-void arrow_newgen(GVJ_t * job, int state, pointf p, pointf u, double scale, int flag)
+void arrow_newgen(GVJ_t * job, emit_state_t emit_state, pointf p, pointf u, double scale, int flag)
{
+ obj_state_t *obj = job->obj;
double s;
int f;
- int oldstate;
+ emit_state_t old_emit_state;
- oldstate = job->gvc->emit_state;
- job->gvc->emit_state = state;
+ old_emit_state = obj->emit_state;
+ obj->emit_state = emit_state;
/* Dotted and dashed styles on the arrowhead are ugly (dds) */
/* linewidth needs to be reset */
gvrender_end_context(job);
- job->gvc->emit_state = oldstate;
+ obj->emit_state = old_emit_state;
}
/* FIXME emit.c and output.c require wrapper for int point coords */
-void arrow_gen(GVJ_t * job, int state, point p, point u, double scale, int flag)
+void arrow_gen(GVJ_t * job, emit_state_t emit_state, point p, point u, double scale, int flag)
{
pointf P, U;
P2PF(p, P);
P2PF(u, U);
- arrow_newgen(job, state, P, U, scale, flag);
+ arrow_newgen(job, emit_state, P, U, scale, flag);
}
#define CLST 3
/* output languages */
-#define ATTRIBUTED_DOT 0 /* default */
#define HPGL 2 /* HP Graphics Language */
#define PCL 3 /* Printer Control Language */
#define MIF 4 /* Adobe FrameMaker */
#define PIC_format 5 /* symbol PIC is used by compilers for
Position Independent Code */
-#define PLAIN 6
-#define PLAIN_EXT 7
-
#define TK 15 /* TK canvas */
#define VTX 21 /* visual thought */
#define METAPOST 22
#define DIA 24 /* dia drawing tool */
-#define CANONICAL_DOT 27 /* wanted for tcl/tk version */
-#define EXTENDED_DOT 29 /* dot with drawing info */
#define QPDF 30 /* Quartz paged PDF */
#define QEPDF 31 /* Quartz embedded PDF */
#define RANKDIR_BT 2
#define RANKDIR_RL 3
-/* value specifying emit state */
-#define EMIT_DRAW 0
-#define EMIT_GDRAW EMIT_DRAW
-#define EMIT_CDRAW EMIT_DRAW
-#define EMIT_NDRAW EMIT_DRAW
-#define EMIT_EDRAW EMIT_DRAW
-
-/* values specifying emit state for arrowheads */
-#define EMIT_TDRAW 1
-#define EMIT_HDRAW 2
-
-/* values specifying emit state for labels */
-#define EMIT_LABEL 3
-#define EMIT_GLABEL EMIT_LABEL
-#define EMIT_CLABEL EMIT_LABEL
-#define EMIT_NLABEL EMIT_LABEL
-#define EMIT_ELABEL EMIT_LABEL
-#define EMIT_TLABEL 4
-#define EMIT_HLABEL 5
-
/* allowed charsets */
#define CHAR_UTF8 0
#define CHAR_LATIN1 1
/* output in preorder traversal of the graph */
job->flags = EMIT_PREORDER;
break;
- case EXTENDED_DOT: case ATTRIBUTED_DOT: case CANONICAL_DOT:
- case PLAIN: case PLAIN_EXT:
- job->flags = 0;
- break;
default:
job->flags = chkOrder(g);
break;
}
/* initial window size */
- job->width = (imageSize.x + 2*margin.x) * job->dpi.x / POINTS_PER_INCH;
- job->height = (imageSize.y + 2*margin.y) * job->dpi.x / POINTS_PER_INCH;
+ if (job->rotation) {
+ job->width = (imageSize.y + 2*margin.y) * job->dpi.x / POINTS_PER_INCH;
+ job->height = (imageSize.x + 2*margin.x) * job->dpi.x / POINTS_PER_INCH;
+ }
+ else {
+ job->width = (imageSize.x + 2*margin.x) * job->dpi.x / POINTS_PER_INCH;
+ job->height = (imageSize.y + 2*margin.y) * job->dpi.x / POINTS_PER_INCH;
+ }
/* determine page box including centering */
if (GD_drawing(g)->centered) {
obj = push_obj_state(job);
obj->type = NODE_OBJTYPE;
obj->u.n = n;
-
- obj->oldstate = job->gvc->emit_state;
- job->gvc->emit_state = EMIT_NDRAW;
+ obj->emit_state = EMIT_NDRAW;
if (flags & GVRENDER_DOES_Z) {
obj->z = late_double(n, N_z, 0.0, -MAXFLOAT);
#ifdef WITH_CODEGENS
Obj = NONE;
#endif
- job->gvc->emit_state = job->obj->oldstate;
pop_obj_state(job);
}
}
}
if (ED_label(e)) {
- emit_label(job, EMIT_ELABEL, ED_label(e), (void *) e);
+ emit_label(job, EMIT_ELABEL, ED_label(e));
if (mapbool(late_string(e, E_decorate, "false")) && ED_spl(e))
emit_attachment(job, ED_label(e), ED_spl(e));
}
if (ED_head_label(e))
- emit_label(job, EMIT_HLABEL, ED_head_label(e), (void *) e); /* vladimir */
+ emit_label(job, EMIT_HLABEL, ED_head_label(e)); /* vladimir */
if (ED_tail_label(e))
- emit_label(job, EMIT_TLABEL, ED_tail_label(e), (void *) e); /* vladimir */
+ emit_label(job, EMIT_TLABEL, ED_tail_label(e)); /* vladimir */
if (saved)
gvrender_end_context(job);
obj = push_obj_state(job);
obj->type = EDGE_OBJTYPE;
obj->u.e = e;
-
- obj->oldstate = job->gvc->emit_state;
- job->gvc->emit_state = EMIT_EDRAW;
+ obj->emit_state = EMIT_EDRAW;
if (flags & GVRENDER_DOES_Z) {
obj->tail_z= late_double(e->tail, N_z, 0.0, -1000.0);
#ifdef WITH_CODEGENS
Obj = NONE;
#endif
- job->gvc->emit_state = job->obj->oldstate;
pop_obj_state(job);
}
case GVRENDER_PLUGIN:
job->margin.x = job->margin.y = job->render.features->default_margin;
break;
- case HPGL: case PCL: case MIF: case METAPOST: case VTX: case ATTRIBUTED_DOT:
- case PLAIN: case PLAIN_EXT: case QPDF:
+ case HPGL: case PCL: case MIF: case METAPOST: case VTX: case QPDF:
job->margin.x = job->margin.y = DEFAULT_PRINT_MARGIN;
break;
- case CANONICAL_DOT:
- job->margin.x = job->margin.y = 0;
- break;
default:
job->margin.x = job->margin.y = DEFAULT_EMBED_MARGIN;
break;
gvc->common.viewNum++;
if (GD_label(g))
- emit_label(job, EMIT_GLABEL, GD_label(g), (void *) g);
+ emit_label(job, EMIT_GLABEL, GD_label(g));
/* when drawing, lay clusters down before nodes and edges */
if (!(flags & EMIT_CLUSTERS_LAST))
emit_clusters(job, g, flags);
obj = push_obj_state(job);
obj->type = ROOTGRAPH_OBJTYPE;
obj->u.g = g;
-
- obj->oldstate = job->gvc->emit_state;
- job->gvc->emit_state = EMIT_GDRAW;
+ obj->emit_state = EMIT_GDRAW;
if ((flags & GVRENDER_DOES_LABELS) && ((lab = GD_label(g)))) {
if (lab->html)
#ifdef WITH_CODEGENS
Obj = NONE;
#endif
- job->gvc->emit_state = job->obj->oldstate;
pop_obj_state(job);
}
obj = push_obj_state(job);
obj->type = CLUSTER_OBJTYPE;
obj->u.sg = sg;
-
- obj->oldstate = job->gvc->emit_state;
- job->gvc->emit_state = EMIT_CDRAW;
+ obj->emit_state = EMIT_CDRAW;
if ((flags & GVRENDER_DOES_LABELS) && ((lab = GD_label(sg)))) {
if (lab->html)
#ifdef WITH_CODEGENS
Obj = NONE;
#endif
- job->gvc->emit_state = job->obj->oldstate;
pop_obj_state(job);
}
}
}
if (GD_label(sg))
- emit_label(job, EMIT_GLABEL, GD_label(sg), (void *) sg);
+ emit_label(job, EMIT_GLABEL, GD_label(sg));
if (flags & EMIT_PREORDER) {
for (n = agfstnode(sg); n; n = agnxtnode(sg, n)) {
gvrender_begin_job(job);
- switch (job->output_lang) {
- case EXTENDED_DOT:
- write_extended_dot(job, g, job->output_file);
- break;
- case ATTRIBUTED_DOT:
- write_attributed_dot(g, job->output_file);
- break;
- case CANONICAL_DOT:
- write_canonical_dot(g, job->output_file);
- break;
- case PLAIN:
- write_plain(job, g, job->output_file);
- break;
- case PLAIN_EXT:
- write_plain_ext(job, g, job->output_file);
- break;
- default:
- if (! (job->flags & GVRENDER_X11_EVENTS))
- emit_graph(job, g);
- break;
- }
+ if (! (job->flags & GVRENDER_X11_EVENTS))
+ emit_graph(job, g);
/* Flush is necessary because we may be writing to a pipe. */
if (! job->external_surface && job->output_lang != TK)
env->finfo.size = savp->size;
}
-#ifdef OLD
-static void
-emit_html_txt(GVJ_t * job, htmltxt_t * tp, htmlenv_t * env, void *obj)
-{
- double halfwidth_x;
- pointf p;
- char *fname;
- char *fcolor;
- double fsize;
-
- /* make sure that there is something to do */
- if (tp->nparas < 1)
- return;
-
- /* set font attributes */
- if (tp->font) {
- if (tp->font->size > 0.0)
- fsize = tp->font->size;
- else
- fsize = env->finfo.size;
- if (tp->font->name)
- fname = tp->font->name;
- else
- fname = env->finfo.name;
- if (tp->font->color)
- fcolor = tp->font->color;
- else
- fcolor = env->finfo.color;
- } else {
- fsize = env->finfo.size;
- fname = env->finfo.name;
- fcolor = env->finfo.color;
- }
- halfwidth_x = ((double)(tp->box.UR.x - tp->box.LL.x))/2.0;
- p.x = env->p.x + ((double)(tp->box.UR.x + tp->box.LL.x))/2.0;
- p.y = env->p.y + ((double)(tp->box.UR.y + tp->box.LL.y))/2.0;
-
- emit_textparas(job, tp->nparas, tp->para, p,
- halfwidth_x, fname, fsize, fcolor);
-}
-#endif
-
static void
emit_htextparas(GVJ_t* job, int nparas, htextpara_t* paras, pointf p,
double halfwidth_x, char* fname, double fsize, char* fcolor, box b)
}
static void
-emit_html_txt(GVJ_t* job, htmltxt_t* tp, htmlenv_t* env, void* obj)
+emit_html_txt(GVJ_t* job, htmltxt_t* tp, htmlenv_t* env)
{
double halfwidth_x;
pointf p;
gvrender_box(job, BF, 1);
}
-static void doAnchorStart(GVJ_t * job, htmldata_t * data, void *obj)
+static void doAnchorStart(GVJ_t * job, htmldata_t * data)
{
gvrender_begin_anchor(job, data->href, data->title, data->target);
}
}
/* forward declaration */
-static void emit_html_cell(GVJ_t * job, htmlcell_t * cp,
- htmlenv_t * env, void *obj);
+static void emit_html_cell(GVJ_t * job, htmlcell_t * cp, htmlenv_t * env);
static void
-emit_html_tbl(GVJ_t * job, htmltbl_t * tbl, htmlenv_t * env, void *obj)
+emit_html_tbl(GVJ_t * job, htmltbl_t * tbl, htmlenv_t * env)
{
box pts = tbl->data.box;
point p = env->p;
/* gvrender_begin_context(job); */
if (tbl->data.href)
- doAnchorStart(job, &tbl->data, obj);
+ doAnchorStart(job, &tbl->data);
if (tbl->data.bgcolor)
doFill(job, tbl->data.bgcolor, pts);
while (*cells) {
- emit_html_cell(job, *cells, env, obj);
+ emit_html_cell(job, *cells, env);
cells++;
}
}
static void
-emit_html_img(GVJ_t * job, htmlimg_t * cp, htmlenv_t * env, void *obj)
+emit_html_img(GVJ_t * job, htmlimg_t * cp, htmlenv_t * env)
{
pointf A[4];
box bb = cp->box;
}
static void
-emit_html_cell(GVJ_t * job, htmlcell_t * cp, htmlenv_t * env, void *obj)
+emit_html_cell(GVJ_t * job, htmlcell_t * cp, htmlenv_t * env)
{
box pts = cp->data.box;
point p = env->p;
/* gvrender_begin_context(); */
if (cp->data.href)
- doAnchorStart(job, &cp->data, obj);
+ doAnchorStart(job, &cp->data);
if (cp->data.bgcolor)
doFill(job, cp->data.bgcolor, pts);
if (cp->child.kind == HTML_TBL)
- emit_html_tbl(job, cp->child.u.tbl, env, obj);
+ emit_html_tbl(job, cp->child.u.tbl, env);
else if (cp->child.kind == HTML_IMAGE)
- emit_html_img(job, cp->child.u.img, env, obj);
+ emit_html_img(job, cp->child.u.img, env);
else
- emit_html_txt(job, cp->child.u.txt, env, obj);
+ emit_html_txt(job, cp->child.u.txt, env);
if (cp->data.border)
doBorder(job, cp->data.pencolor, cp->data.border, pts);
/* emit_html_label:
*/
void
-emit_html_label(GVJ_t * job, htmllabel_t * lp, textlabel_t * tp, void *obj)
+emit_html_label(GVJ_t * job, htmllabel_t * lp, textlabel_t * tp)
{
htmlenv_t env;
gvrender_set_pencolor(job, tbl->data.pencolor);
else
gvrender_set_pencolor(job, DEFAULT_COLOR);
- emit_html_tbl(job, tbl, &env, obj);
+ emit_html_tbl(job, tbl, &env);
gvrender_end_context(job);
} else {
- emit_html_txt(job, lp->u.txt, &env, obj);
+ emit_html_txt(job, lp->u.txt, &env);
}
}
free(dp->bgcolor);
}
-#ifdef OLD
-void free_html_text(htmltxt_t * tp)
-{
- textpara_t *lp;
-
- if (!tp)
- return;
- lp = tp->para;
- while (lp->str) {
- free(lp->str);
- lp++;
- }
- free(tp->para);
- if (tp->font)
- free_html_font(tp->font);
- free(tp);
-}
-#endif
-
void free_html_text(htmltxt_t* t)
{
htextpara_t *tl;
return 0;
}
-#ifdef OLD
-static int
-size_html_txt(graph_t *g, htmltxt_t * txt, htmlenv_t * env)
-{
- double xsize = 0.0;
- double fsize;
- char *fname;
- char *news = NULL;
- textpara_t *lp = txt->para;
- pointf size;
-
- if (txt->font) {
- if (txt->font->size > 0.0)
- fsize = txt->font->size;
- else
- fsize = env->finfo.size;
- if (txt->font->name)
- fname = txt->font->name;
- else
- fname = env->finfo.name;
- } else {
- fsize = env->finfo.size;
- fname = env->finfo.name;
- }
-
- while (lp->str) {
- switch (agobjkind(env->obj)) {
- case AGGRAPH:
- news =
- strdup_and_subst_graph(lp->str, (Agraph_t *) (env->obj));
- break;
- case AGNODE:
- news = strdup_and_subst_node(lp->str, (Agnode_t *) (env->obj));
- break;
- case AGEDGE:
- news = strdup_and_subst_edge(lp->str, (Agedge_t *) (env->obj));
- break;
- }
- free(lp->str);
- lp->str = news;
-
- size = textsize(g, lp, fname, fsize);
- /* no margins are added since the containing node or cell will pad */
- if (dimen.x > xsize)
- xsize = size.x;
- lp++;
- }
- txt->box.UR.x = xsize;
- if (txt->nparas == 1)
- txt->box.UR.y = (int) (size.y);
- else
- txt->box.UR.y = txt->nparas * (int) (size.y * LINESPACING);
- return 0;
-}
-#endif
-
static char*
substrGFn (char* s, htmlenv_t* env)
{
fprintf(stderr, "img: %s\n", ip->src);
}
-#ifdef OLD
-void printTxt(htmltxt_t * tp, int ind)
-{
- int i;
- indent(ind);
- fprintf(stderr, "txt ");
- printBox(tp->box);
- fputs("\n", stderr);
- for (i = 0; i < tp->nparas; i++) {
- indent(ind + 1);
- fprintf(stderr, "(%c) \"%s\"\n", tp->para[i].just,
- tp->para[i].str);
- }
-}
-#endif
-
void printTxt(htmltxt_t * txt, int ind)
{
int i, j;
extern htmllabel_t *parseHTML(char *, int *, int);
extern int make_html_label(graph_t *g, textlabel_t * lp, void *obj);
- extern void emit_html_label(GVJ_t * job, htmllabel_t * lp,
- textlabel_t *, void *obj);
+ extern void emit_html_label(GVJ_t * job, htmllabel_t * lp, textlabel_t *);
extern void free_html_label(htmllabel_t *, int);
extern void free_html_data(htmldata_t *);
gvrender_end_context(job);
}
-void emit_label(GVJ_t * job, int state, textlabel_t * lp, void *obj)
+void emit_label(GVJ_t * job, emit_state_t emit_state, textlabel_t * lp)
{
+ obj_state_t *obj = job->obj;
double halfwidth_x;
pointf p;
- int oldstate;
+ emit_state_t old_emit_state;
- oldstate = job->gvc->emit_state;
- job->gvc->emit_state = state;
+ old_emit_state = obj->emit_state;
+ obj->emit_state = emit_state;
if (lp->html) {
- emit_html_label(job, lp->u.html, lp, obj);
+ emit_html_label(job, lp->u.html, lp);
return;
}
emit_textparas(job, lp->u.txt.nparas, lp->u.txt.para, p,
halfwidth_x, lp->fontname, lp->fontsize, lp->fontcolor);
- job->gvc->emit_state = oldstate;
+
+ obj->emit_state = old_emit_state;
}
static int e_arrows; /* graph has edges with end arrows */
static int s_arrows; /* graph has edges with start arrows */
+static attrsym_t *g_draw;
+static attrsym_t *g_l_draw;
static void printptf(FILE * f, point pt)
{
/* _write_plain:
*/
-static void _write_plain(GVJ_t * job, graph_t * g, FILE * f, bool extend)
+void write_plain(GVJ_t * job, graph_t * g, FILE * f, bool extend)
{
int i, j, splinePoints;
char *tport, *hport;
fprintf(f, "stop\n");
}
-void write_plain(GVJ_t * job, graph_t * g, FILE * f)
-{
- _write_plain(job, g, f, FALSE);
-}
-
-void write_plain_ext(GVJ_t * job, graph_t * g, FILE * f)
-{
- _write_plain(job, g, f, TRUE);
-}
-
-
-void write_extended_dot(GVJ_t *job, graph_t *g, FILE *f)
-{
-#ifdef WITH_CODEGENS
- attach_attrs(g);
- extend_attrs(job, g, s_arrows, e_arrows);
- agwrite(g, f);
-#endif
-}
-
-void write_attributed_dot(graph_t *g, FILE *f)
-{
- attach_attrs(g);
- agwrite(g, f);
-}
-
-void write_canonical_dot(graph_t *g, FILE *f)
-{
- if (HAS_CLUST_EDGE(g))
- undoClusterEdges(g);
- agwrite(g, f);
-}
-
static void set_record_rects(node_t * n, field_t * f, agxbuf * xb)
{
int i;
if (HAS_CLUST_EDGE(g))
undoClusterEdges(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).
+ *
+ * N.B. John M. asks:
+ * By the way, I don't know if you ever plan to add other letters for
+ * the xdot spec, but could you reserve "a" and also "A" (for attribute),
+ * "n" and also "N" (for numeric), "w" (for sWitch), "s" (for string)
+ * and "t" (for tooltip) and "x" (for position). We use those letters in
+ * our drawing spec (and also "<" and ">"), so if you start generating
+ * output with them, it could break what we have.
+ */
+
+#define XDOTVERSION "1.1"
+
+void extend_attrs(GVJ_t * job, graph_t *g, agxbuf** xbufs)
+{
+ 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];
+
+ agsafeset (g, "xdotversion", XDOTVERSION, "");
+ if (GD_has_labels(g) & GRAPH_LABEL)
+ g_l_draw = safe_dcl(g, g, "_ldraw_", "", agraphattr);
+ else
+ g_l_draw = NULL;
+ if (GD_n_cluster(g))
+ g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
+ else
+ g_draw = NULL;
+
+ 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(xbufs[0], BUFSIZ, buf0);
+ agxbinit(xbufs[1], BUFSIZ, buf1);
+ agxbinit(xbufs[2], BUFSIZ, buf2);
+ agxbinit(xbufs[3], BUFSIZ, buf3);
+ agxbinit(xbufs[4], BUFSIZ, buf4);
+ agxbinit(xbufs[5], 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(job, n);
+ agxset(n, n_draw->index, agxbuse(xbufs[EMIT_NDRAW]));
+ agxset(n, n_l_draw->index, agxbuse(xbufs[EMIT_NLABEL]));
+ }
+ 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 (job, e);
+ agxset(e, e_draw->index, agxbuse(xbufs[EMIT_EDRAW]));
+ 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_ELABEL]));
+ if (tl_draw) agxset(e, tl_draw->index, agxbuse(xbufs[EMIT_TLABEL]));
+ if (hl_draw) agxset(e, hl_draw->index, agxbuse(xbufs[EMIT_HLABEL]));
+ }
+ }
+
+ emit_background(job, g);
+ if (agxblen(xbufs[EMIT_GDRAW])) {
+ if (!g_draw)
+ g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
+ agxset(g, g_draw->index, agxbuse(xbufs[EMIT_GDRAW]));
+ }
+ if (GD_label(g)) {
+ emit_label(job, EMIT_GLABEL, GD_label(g));
+ agxset(g, g_l_draw->index, agxbuse(xbufs[EMIT_GLABEL]));
+ }
+ emit_clusters(job, g, 0);
+ agxbfree(xbufs[0]);
+ agxbfree(xbufs[1]);
+ agxbfree(xbufs[2]);
+ agxbfree(xbufs[3]);
+ agxbfree(xbufs[4]);
+ agxbfree(xbufs[5]);
+}
+
+void extend_attrs_glabel(graph_t *sg, agxbuf **xbufs)
+{
+ agxset(sg, g_draw->index, agxbuse(xbufs[EMIT_CDRAW]));
+ if (GD_label(sg))
+ agxset(sg, g_l_draw->index, agxbuse(xbufs[EMIT_CLABEL]));
+}
extern void add_box(path *, box);
extern void arrow_flags(Agedge_t * e, int *sflag, int *eflag);
extern boxf arrow_bb(pointf p, pointf u, double scale, int flag);
- extern void arrow_gen(GVJ_t * job, int state, point p, point u,
+ extern void arrow_gen(GVJ_t * job, emit_state_t emit_state, point p, point u,
double scale, int flag);
extern double arrow_length(edge_t * e, int flag);
extern int arrowEndClip(edge_t*, point*, int, int , bezier*, int eflag);
extern void emit_clusters(GVJ_t * job, Agraph_t * g, int flags);
extern void emit_edge_graphics(GVJ_t * job, edge_t * e);
extern void emit_graph(GVJ_t * job, graph_t * g);
- extern void emit_label(GVJ_t * job, int state, textlabel_t *, void *obj);
+ extern void emit_label(GVJ_t * job, emit_state_t emit_state, textlabel_t *);
extern int emit_once(char *message);
extern void emit_jobs_eof(GVC_t * gvc);
extern void emit_textparas(GVJ_t*, int, textpara_t*, pointf,
extern void endpath(path *, Agedge_t *, int, pathend_t *, bool);
extern void epsf_init(node_t * n);
extern void epsf_free(node_t * n);
- extern void extend_attrs(GVJ_t * job, graph_t *g, int s_arrows, int e_arrows);
extern shape_desc *find_user_shape(char *);
extern void free_line(textpara_t *);
extern void free_label(textlabel_t *);
extern void write_attributed_dot(graph_t *g, FILE *f);
extern void write_canonical_dot(graph_t *g, FILE *f);
extern void write_extended_dot(GVJ_t * job, graph_t *g, FILE *f);
- extern void write_plain(GVJ_t * job, graph_t * g, FILE * f);
- extern void write_plain_ext(GVJ_t * job, graph_t * g, FILE * f);
+ extern void write_plain(GVJ_t * job, graph_t * g, FILE * f, bool extend);
#if defined(_BLD_dot) && defined(_DLL)
# define extern __EXPORT__
filled = FALSE;
}
- emit_label(job, EMIT_NLABEL, ND_label(n), (void *) n);
+ emit_label(job, EMIT_NLABEL, ND_label(n));
}
/*=======================end poly======================================*/
cx = (f->b.LL.x + f->b.UR.x) / 2.0 + ND_coord_i(n).x;
cy = (f->b.LL.y + f->b.UR.y) / 2.0 + ND_coord_i(n).y;
f->lp->p = pointof((int) cx, (int) cy);
- emit_label(job, EMIT_NLABEL, f->lp, (void *) n);
+ emit_label(job, EMIT_NLABEL, f->lp);
}
for (i = 0; i < f->n_flds; i++) {
ND_coord_i(n).y + desc->offset.y, desc->macro_id);
ND_label(n)->p = ND_coord_i(n);
gvrender_end_context(job);
- emit_label(job, EMIT_NLABEL, ND_label(n), (void *) n);
+ emit_label(job, EMIT_NLABEL, ND_label(n));
}
+++ /dev/null
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
-#include "render.h"
-#include "agxbuf.h"
-
-#define XDOTVERSION "1.1"
-
-static GVC_t *gvc;
-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 attrsym_t *g_draw;
-static attrsym_t *g_l_draw;
-
-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).
- *
- * N.B. John M. asks:
- * By the way, I don't know if you ever plan to add other letters for
- * the xdot spec, but could you reserve "a" and also "A" (for attribute),
- * "n" and also "N" (for numeric), "w" (for sWitch), "s" (for string)
- * and "t" (for tooltip) and "x" (for position). We use those letters in
- * our drawing spec (and also "<" and ">"), so if you start generating
- * output with them, it could break what we have.
- */
-void extend_attrs(GVJ_t * job, 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];
-
- gvc = job->gvc;
-
- agsafeset (g, "xdotversion", XDOTVERSION, "");
- if (GD_has_labels(g) & GRAPH_LABEL)
- g_l_draw = safe_dcl(g, g, "_ldraw_", "", agraphattr);
- else
- g_l_draw = NULL;
- if (GD_n_cluster(g))
- g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
- else
- g_draw = NULL;
-
- 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(job, n);
- agxset(n, n_draw->index, agxbuse(xbufs[EMIT_NDRAW]));
- agxset(n, n_l_draw->index, agxbuse(xbufs[EMIT_NLABEL]));
- }
- 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 (job, e);
- agxset(e, e_draw->index, agxbuse(xbufs[EMIT_EDRAW]));
- 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_ELABEL]));
- if (tl_draw) agxset(e, tl_draw->index, agxbuse(xbufs[EMIT_TLABEL]));
- if (hl_draw) agxset(e, hl_draw->index, agxbuse(xbufs[EMIT_HLABEL]));
- }
- }
-
- emit_background(job, g);
- if (agxblen(xbufs[EMIT_GDRAW])) {
- if (!g_draw)
- g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
- agxset(g, g_draw->index, agxbuse(xbufs[EMIT_GDRAW]));
- }
- if (GD_label(g)) {
- emit_label(job, EMIT_GLABEL, GD_label(g), (void *) g);
- agxset(g, g_l_draw->index, agxbuse(xbufs[EMIT_GLABEL]));
- }
- emit_clusters(job, 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, (int)strlen(s));
- agxbput(xbufs[gvc->emit_state], buf);
- agxbput(xbufs[gvc->emit_state], s);
- agxbputc(xbufs[gvc->emit_state], ' ');
-}
-
-static void xd_textpara(point p, textpara_t * para)
-{
- char buf[BUFSIZ];
- int j;
-
- switch (para->just) {
- case 'l':
- j = -1;
- break;
- case 'r':
- j = 1;
- break;
- default:
- case 'n':
- j = 0;
- break;
- }
- sprintf(buf, "T %d %d %d %d ", p.x, YDIR(p.y), j, (int) para->width);
- agxbput(xbufs[gvc->emit_state], buf);
- xd_str ("", para->str);
-}
-
-static void xd_ellipse(point p, int rx, int ry, int filled)
-{
- char buf[BUFSIZ];
- int rc;
-
- rc = agxbputc(xbufs[gvc->emit_state], (filled ? 'E' : 'e'));
- sprintf(buf, " %d %d %d %d ", p.x, YDIR(p.y), rx, ry);
- agxbput(xbufs[gvc->emit_state], buf);
-}
-
-static void xd_points(char c, point * A, int n)
-{
- char buf[BUFSIZ];
- int i, rc;
- point p;
-
- rc = agxbputc(xbufs[gvc->emit_state], c);
- sprintf(buf, " %d ", n);
- agxbput(xbufs[gvc->emit_state], buf);
- for (i = 0; i < n; i++) {
- p = A[i];
- sprintf(buf, "%d %d ", p.x, YDIR(p.y));
- agxbput(xbufs[gvc->emit_state], buf);
- }
-}
-
-static void xd_polygon(point * A, int n, int filled)
-{
- xd_points((filled ? 'P' : 'p'), A, n);
-}
-
-static void
-xd_bezier(point * A, int n, int arrow_at_start, int arrow_at_end, int filled)
-{
- if (filled)
- xd_points('b', A, n);
- else
- xd_points('B', A, n);
-}
-
-static void xd_polyline(point * A, int n)
-{
- xd_points('L', A, n);
-}
-
-static void
-xd_set_font (char *fontname, double fontsize)
-{
- char buf[BUFSIZ];
-
- sprintf(buf, "F %f ", fontsize);
- agxbput(xbufs[gvc->emit_state], 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)
-{
- unsigned 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(xbufs[EMIT_CDRAW]));
- if (GD_label(cluster_g))
- agxset(cluster_g, g_l_draw->index, agxbuse(xbufs[EMIT_CLABEL]));
-}
-
-codegen_t XDot_CodeGen = {
- 0, /* xd_reset */
- 0, /* xd_begin_job */ 0, /* xd_end_job */
- 0, /* xd_begin_graph */ 0, /* xd_end_graph */
- 0, /* xd_begin_page */ 0, /* xd_end_page */
- 0, /* xd_begin_layer */ 0, /* xd_end_layer */
- 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_end_node */
- 0, /* xd_begin_edge */ 0, /* xd_end_edge */
- 0, /* xd_begin_context */ 0, /* xd_context */
- 0, /* xd_begin_anchor */ 0, /* xd_anchor */
- xd_set_font, xd_textpara,
- xd_set_pencolor, xd_set_fillcolor, xd_set_style,
- xd_ellipse, xd_polygon,
- xd_bezier, xd_polyline,
- 0, /* xd_has_arrows */
- 0, /* xd_comment */
- 0 /* xd_usershape */
-};
}
job->output_lang = gvrender_select(job, job->output_langname);
- if (!GD_drawing(g) && job->output_lang != CANONICAL_DOT) {
+ if (!GD_drawing(g) && !(job->flags & LAYOUT_NOT_REQUIRED)) {
fprintf(stderr, "Layout was not done\n");
return -1;
}
}
job->output_lang = gvrender_select(job, job->output_langname);
- if (!GD_drawing(g) && job->output_lang != CANONICAL_DOT) {
+ if (!GD_drawing(g) && !(job->flags & LAYOUT_NOT_REQUIRED)) {
fprintf(stderr, "Layout was not done\n");
return -1;
}
GVJ_t *jobs; /* linked list of jobs */
GVJ_t *job; /* current job */
- int emit_state; /* current emit_state */
graph_t *g; /* current graph */
/* gvrender_begin_job() */
#define GVRENDER_DOES_TOOLTIPS (1<<19)
#define GVRENDER_DOES_TARGETS (1<<20)
#define GVRENDER_DOES_Z (1<<21)
+#define LAYOUT_NOT_REQUIRED (1<<22)
typedef struct {
int flags;
typedef enum {MAP_RECTANGLE, MAP_CIRCLE, MAP_POLYGON, } map_shape_t;
typedef enum {ROOTGRAPH_OBJTYPE, CLUSTER_OBJTYPE, NODE_OBJTYPE, EDGE_OBJTYPE} obj_type;
+#if 0
+ typedef enum {EMIT_GDRAW, EMIT_CDRAW, EMIT_NDRAW, EMIT_EDRAW, EMIT_TDRAW, EMIT_HDRAW,
+ EMIT_GLABEL, EMIT_CLABEL, EMIT_NLABEL, EMIT_ELABEL, EMIT_TLABEL, EMIT_HLABEL} emit_state_t;
+#else
+
+/* FIXME - There are places in the core that rely on there being exactly 6 emit_states ! */
+#define emit_state_t int
+
+/* value specifying emit state */
+#define EMIT_DRAW 0
+#define EMIT_GDRAW EMIT_DRAW
+#define EMIT_CDRAW EMIT_DRAW
+#define EMIT_NDRAW EMIT_DRAW
+#define EMIT_EDRAW EMIT_DRAW
+
+/* values specifying emit state for arrowheads */
+#define EMIT_TDRAW 1
+#define EMIT_HDRAW 2
+
+/* values specifying emit state for labels */
+#define EMIT_LABEL 3
+#define EMIT_GLABEL EMIT_LABEL
+#define EMIT_CLABEL EMIT_LABEL
+#define EMIT_NLABEL EMIT_LABEL
+#define EMIT_ELABEL EMIT_LABEL
+#define EMIT_TLABEL 4
+#define EMIT_HLABEL 5
+
+#endif
+
typedef struct obj_state_s obj_state_t;
struct obj_state_s {
edge_t *e;
} u;
- int oldstate; /* FIXME - used by one of those other state stacks */
+ emit_state_t emit_state;
gvcolor_t pencolor, fillcolor;
pen_type pen;
pointf *headendurl_map_p;
};
+typedef enum {COMPRESSION_NONE, COMPRESSION_ZLIB} compression_t;
/* Note on units:
* points - a physical distance (1/72 inch) unaffected by zoom or dpi.
FILE *output_file;
int output_lang;
+ compression_t compression;
+
gvplugin_active_render_t render;
gvplugin_active_device_t device;
gvplugin_active_loadimage_t loadimage;
extern codegen_t QPDF_CodeGen, QEPDF_CodeGen, QBM_CodeGen;
#endif
- extern codegen_t HPGL_CodeGen, MIF_CodeGen, XDot_CodeGen,
- MP_CodeGen, PIC_CodeGen, DIA_CodeGen, VTX_CodeGen;
+ extern codegen_t HPGL_CodeGen, MIF_CodeGen, MP_CodeGen, PIC_CodeGen, DIA_CodeGen, VTX_CodeGen;
#endif
/*
#ifdef HAVE_LIBZ
{&DIA_CodeGen, "dia", DIA},
#endif
-#define DUMMY_CodeGen XDot_CodeGen
- {&DUMMY_CodeGen, "dot", ATTRIBUTED_DOT},
- {&DUMMY_CodeGen, "canon", CANONICAL_DOT},
- {&DUMMY_CodeGen, "plain", PLAIN},
- {&DUMMY_CodeGen, "plain-ext", PLAIN_EXT},
- {&DUMMY_CodeGen, "xdot", EXTENDED_DOT},
{NULL, NULL, 0}
};
void gvjobs_output_filename(GVC_t * gvc, char *name)
{
if (!gvc->jobs) {
- output_filename_job = gvc->job = gvc->jobs =
- zmalloc(sizeof(GVJ_t));
+ output_filename_job = gvc->job = gvc->jobs = zmalloc(sizeof(GVJ_t));
} else {
if (!output_filename_job) {
output_filename_job = gvc->jobs;
} else {
if (!output_filename_job->next) {
- output_filename_job->next =
- zmalloc(sizeof(GVJ_t));
+ output_filename_job->next = zmalloc(sizeof(GVJ_t));
}
output_filename_job = output_filename_job->next;
}
bool gvjobs_output_langname(GVC_t * gvc, char *name)
{
if (!gvc->jobs) {
- output_langname_job = gvc->job = gvc->jobs =
- zmalloc(sizeof(GVJ_t));
+ output_langname_job = gvc->job = gvc->jobs = zmalloc(sizeof(GVJ_t));
} else {
if (!output_langname_job) {
output_langname_job = gvc->jobs;
} else {
if (!output_langname_job->next) {
- output_langname_job->next =
- zmalloc(sizeof(GVJ_t));
+ output_langname_job->next = zmalloc(sizeof(GVJ_t));
}
output_langname_job = output_langname_job->next;
}
libgvplugin_core_C_la_SOURCES = \
gvplugin_core.c \
- gvrender_core_svg.c \
- gvrender_core_fig.c \
+ gvrender_core.c \
+ gvrender_core_dot.c \
gvrender_core_ps.c \
+ gvrender_core_fig.c \
+ gvrender_core_svg.c \
gvrender_core_map.c \
gvloadimage_core.c
/* for n->name */
#include "graph.h"
-extern void svggen_fputs(GVJ_t * job, char *s);
-extern void svggen_printf(GVJ_t * job, const char *format, ...);
-extern void figgen_printf(GVJ_t * job, const char *format, ...);
+extern void core_fputs(GVJ_t * job, char *s);
+extern void core_printf(GVJ_t * job, const char *format, ...);
extern void epsf_emit_body(usershape_t *us, FILE *of);
extern shape_desc *find_user_shape(char *name);
assert(us->name);
assert(us->f);
- svggen_fputs(job, "<image xlink:href=\"");
- svggen_fputs(job, us->name);
+ core_fputs(job, "<image xlink:href=\"");
+ core_fputs(job, us->name);
if (job->rotation) {
- svggen_printf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"",
+ core_printf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"",
b.UR.y - b.LL.y, b.UR.x - b.LL.x, b.LL.x, b.UR.y);
- svggen_printf (job, " transform=\"rotate(%d %g %g)\"",
+ core_printf (job, " transform=\"rotate(%d %g %g)\"",
job->rotation, b.LL.x, b.UR.y);
}
else {
- svggen_printf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"",
+ core_printf (job, "\" width=\"%gpx\" height=\"%gpx\" preserveAspectRatio=\"xMidYMid meet\" x=\"%g\" y=\"%g\"",
b.UR.x - b.LL.x, b.UR.y - b.LL.y, b.LL.x, b.LL.y);
}
- svggen_fputs(job, "/>\n");
+ core_fputs(job, "/>\n");
}
static void core_loadimage_fig(GVJ_t * job, usershape_t *us, boxf bf, bool filled)
BF2B(bf, b);
- figgen_printf(job,
- "%d %d %d %d %d %d %d %d %d %.1f %d %d %d %d %d %d\n %d %s\n",
+ core_printf(job, "%d %d %d %d %d %d %d %d %d %.1f %d %d %d %d %d %d\n %d %s\n",
object_code, sub_type, line_style, thickness, pen_color,
fill_color, depth, pen_style, area_fill, style_val, join_style,
cap_style, radius, forward_arrow, backward_arrow, npoints,
flipped, us->name);
- figgen_printf(job," %d %d %d %d %d %d %d %d %d %d\n",
+ core_printf(job," %d %d %d %d %d %d %d %d %d %d\n",
b.LL.x, b.LL.y,
b.LL.x, b.UR.y,
b.UR.x, b.UR.y,
#include "gvplugin.h"
+extern gvplugin_installed_t gvrender_core_dot_types;
extern gvplugin_installed_t gvrender_core_ps_types;
extern gvplugin_installed_t gvrender_core_fig_types;
extern gvplugin_installed_t gvrender_core_svg_types;
extern gvplugin_installed_t gvloadimage_core_types;
static gvplugin_api_t apis[] = {
+ {API_render, &gvrender_core_dot_types},
{API_render, &gvrender_core_ps_types},
{API_render, &gvrender_core_fig_types},
{API_render, &gvrender_core_svg_types},
--- /dev/null
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+* This software is part of the graphviz package *
+* http://www.graphviz.org/ *
+* *
+* Copyright (c) 1994-2004 AT&T Corp. *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Corp. *
+* *
+* Information and Software Systems Research *
+* AT&T Research, Florham Park NJ *
+**********************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#ifdef WIN32
+#include <io.h>
+#include "compat.h"
+#endif
+
+#include "gvplugin_render.h"
+
+void core_init_compression(GVJ_t *job, compression_t compression)
+{
+#if HAVE_LIBZ
+ int fd;
+#endif
+
+ switch ((job->compression = compression)) {
+ case COMPRESSION_ZLIB:
+#if HAVE_LIBZ
+ /* open dup so can gzclose independent of FILE close */
+ fd = dup(fileno(job->output_file));
+#ifdef HAVE_SETMODE
+#ifdef O_BINARY
+ /*
+ * Windows will do \n -> \r\n translations on
+ * stdout unless told otherwise.
+ */
+ setmode(fd, O_BINARY);
+#endif
+#endif
+
+ job->output_file = (FILE *) (gzdopen(fd, "wb"));
+ if (!job->output_file) {
+ (job->common->errorfn) ("Error initializing compression on output file\n");
+ exit(1);
+ }
+ break;
+#else
+ (job->common->errorfn) ("No libz support.\n");
+ exit(1);
+#endif
+ case COMPRESSION_NONE:
+ break;
+ }
+}
+
+void core_fini_compression(GVJ_t *job)
+{
+ switch (job->compression) {
+ case COMPRESSION_ZLIB:
+#ifdef HAVE_LIBZ
+ gzclose((gzFile *) (job->output_file));
+ break;
+#else
+ (job->common->errorfn) ("No libz support\n");
+ exit(1);
+#endif
+ case COMPRESSION_NONE:
+ break;
+ }
+}
+
+void core_fputs(GVJ_t * job, char *s)
+{
+ int len;
+
+ len = strlen(s);
+ switch (job->compression) {
+ case COMPRESSION_ZLIB:
+#ifdef HAVE_LIBZ
+ gzwrite((gzFile *) (job->output_file), s, (unsigned) len);
+#endif
+ break;
+ case COMPRESSION_NONE:
+ fwrite(s, sizeof(char), (unsigned) len, job->output_file);
+ break;
+ }
+}
+
+/* core_printf:
+ * Note that this function is unsafe due to the fixed buffer size.
+ * It should only be used when the caller is sure the input will not
+ * overflow the buffer. In particular, it should be avoided for
+ * input coming from users. Also, if vsnprintf is available, the
+ * code should check for return values to use it safely.
+ */
+void core_printf(GVJ_t * job, const char *format, ...)
+{
+ char buf[BUFSIZ];
+ va_list argp;
+
+ va_start(argp, format);
+#ifdef HAVE_VSNPRINTF
+ (void) vsnprintf(buf, sizeof(buf), format, argp);
+#else
+ (void) vsprintf(buf, format, argp);
+#endif
+ va_end(argp);
+
+ core_fputs(job, buf);
+}
--- /dev/null
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+* This software is part of the graphviz package *
+* http://www.graphviz.org/ *
+* *
+* Copyright (c) 1994-2004 AT&T Corp. *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Corp. *
+* *
+* Information and Software Systems Research *
+* AT&T Research, Florham Park NJ *
+**********************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <io.h>
+#include "compat.h"
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macros.h"
+#include "const.h"
+
+#include "gvplugin_render.h"
+#include "graph.h"
+#include "agxbuf.h"
+#include "utils.h"
+
+extern void attach_attrs(graph_t * g);
+extern char *xml_string(char *str);
+extern void write_plain(GVJ_t * job, graph_t * g, FILE * f, bool extend);
+extern void extend_attrs(GVJ_t * job, graph_t *g, agxbuf** xbufs);
+extern void extend_attrs_glabel(graph_t *sg, agxbuf **xbufs);
+
+typedef enum { FORMAT_DOT, FORMAT_CANON, FORMAT_PLAIN, FORMAT_PLAIN_EXT, FORMAT_XDOT } format_type;
+
+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 void xdot_str (GVJ_t *job, char* pfx, char* s)
+{
+ emit_state_t emit_state = job->obj->emit_state;
+ char buf[BUFSIZ];
+
+ sprintf (buf, "%s%d -", pfx, (int)strlen(s));
+ agxbput(xbufs[emit_state], buf);
+ agxbput(xbufs[emit_state], s);
+ agxbputc(xbufs[emit_state], ' ');
+}
+
+static void xdot_points(GVJ_t *job, char c, pointf * A, int n)
+{
+ emit_state_t emit_state = job->obj->emit_state;
+ char buf[BUFSIZ];
+ int i, rc;
+
+ rc = agxbputc(xbufs[emit_state], c);
+ sprintf(buf, " %d ", n);
+ agxbput(xbufs[emit_state], buf);
+ for (i = 0; i < n; i++) {
+ sprintf(buf, "%d %d ", ROUND(A[i].x), ROUND(A[i].y));
+ agxbput(xbufs[emit_state], buf);
+ }
+}
+
+static void xdot_set_pencolor (GVJ_t *job, char *name)
+{
+ xdot_str (job, "c ", name);
+}
+
+static void xdot_set_fillcolor (GVJ_t *job, char *name)
+{
+ xdot_str (job, "C ", name);
+}
+
+static void xdot_set_style (GVJ_t *job, char **s)
+{
+ unsigned 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, ')');
+ }
+ xdot_str (job, "S ", agxbuse(&xbuf));
+ }
+ agxbfree(&xbuf);
+}
+
+static void dot_begin_graph(GVJ_t *job)
+{
+ graph_t *g = job->obj->u.g;
+
+ switch (job->render.id) {
+ case FORMAT_DOT:
+ attach_attrs(g);
+ break;
+ case FORMAT_CANON:
+ if (HAS_CLUST_EDGE(g))
+ undoClusterEdges(g);
+ break;
+ case FORMAT_PLAIN:
+ case FORMAT_PLAIN_EXT:
+ break;
+ case FORMAT_XDOT:
+ attach_attrs(g);
+ }
+}
+
+static void dot_end_graph(GVJ_t *job)
+{
+ graph_t *g = job->obj->u.g;
+
+ switch (job->render.id) {
+ case FORMAT_PLAIN:
+ write_plain(job, g, job->output_file, false);
+ break;
+ case FORMAT_PLAIN_EXT:
+ write_plain(job, g, job->output_file, true);
+ break;
+ case FORMAT_DOT:
+ case FORMAT_CANON:
+ agwrite(g, job->output_file);
+ break;
+ case FORMAT_XDOT:
+ extend_attrs(job, g, xbufs);
+ agwrite(g, job->output_file);
+ break;
+ }
+}
+
+static void xdot_end_cluster(GVJ_t *job)
+{
+ extend_attrs_glabel(job->obj->u.sg, xbufs);
+}
+
+static void xdot_textpara(GVJ_t * job, pointf p, textpara_t * para)
+{
+ emit_state_t emit_state = job->obj->emit_state;
+
+ char buf[BUFSIZ];
+ int j;
+
+ switch (para->just) {
+ case 'l':
+ j = -1;
+ break;
+ case 'r':
+ j = 1;
+ break;
+ default:
+ case 'n':
+ j = 0;
+ break;
+ }
+ sprintf(buf, "T %d %d %d %d ", ROUND(p.x), ROUND(p.y), j, (int) para->width);
+ agxbput(xbufs[emit_state], buf);
+ xdot_str (job, "", para->str);
+}
+
+static void xdot_ellipse(GVJ_t * job, pointf * A, int filled)
+{
+ emit_state_t emit_state = job->obj->emit_state;
+
+ char buf[BUFSIZ];
+ int rc;
+
+ rc = agxbputc(xbufs[emit_state], (filled ? 'E' : 'e'));
+ sprintf(buf, " %d %d %d %d ",
+ ROUND(A[0].x), ROUND(A[0].y), ROUND(A[1].x - A[0].x), ROUND(A[1].y - A[0].y));
+ agxbput(xbufs[emit_state], buf);
+}
+
+static void xdot_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start, int arrow_at_end, int filled)
+{
+ xdot_points(job, (filled ? 'B' : 'b'), A, n);
+}
+
+static void xdot_polygon(GVJ_t * job, pointf * A, int n, int filled)
+{
+ xdot_points(job, (filled ? 'P' : 'p'), A, n);
+}
+
+static void xdot_polyline(GVJ_t * job, pointf * A, int n)
+{
+ xdot_points(job, 'L', A, n);
+}
+
+gvrender_engine_t dot_engine = {
+ 0, /* dot_begin_job */
+ 0, /* dot_end_job */
+ dot_begin_graph,
+ dot_end_graph,
+ 0, /* dot_begin_layer */
+ 0, /* dot_end_layer */
+ 0, /* dot_begin_page */
+ 0, /* dot_end_page */
+ 0, /* dot_begin_cluster */
+ 0, /* dot_end_cluster */
+ 0, /* dot_begin_nodes */
+ 0, /* dot_end_nodes */
+ 0, /* dot_begin_edges */
+ 0, /* dot_end_edges */
+ 0, /* dot_begin_node */
+ 0, /* dot_end_node */
+ 0, /* dot_begin_edge */
+ 0, /* dot_end_edge */
+ 0, /* dot_begin_anchor */
+ 0, /* dot_end_anchor */
+ 0, /* dot_textpara */
+ 0, /* dot_resolve_color */
+ 0, /* dot_ellipse */
+ 0, /* dot_polygon */
+ 0, /* dot_bezier */
+ 0, /* dot_polyline */
+ 0, /* dot_comment */
+};
+
+gvrender_engine_t xdot_engine = {
+ 0, /* xdot_begin_job */
+ 0, /* xdot_end_job */
+ dot_begin_graph,
+ dot_end_graph,
+ 0, /* xdot_begin_layer */
+ 0, /* xdot_end_layer */
+ 0, /* xdot_begin_page */
+ 0, /* xdot_end_page */
+ 0, /* xdot_begin_cluster */
+ xdot_end_cluster,
+ 0, /* xdot_begin_nodes */
+ 0, /* xdot_end_nodes */
+ 0, /* xdot_begin_edges */
+ 0, /* xdot_end_edges */
+ 0, /* xdot_begin_node */
+ 0, /* xdot_end_node */
+ 0, /* xdot_begin_edge */
+ 0, /* xdot_end_edge */
+ 0, /* xdot_begin_anchor */
+ 0, /* xdot_end_anchor */
+ xdot_textpara,
+ 0, /* xdot_resolve_color */
+ xdot_ellipse,
+ xdot_polygon,
+ xdot_bezier,
+ xdot_polyline,
+ 0, /* xdot_comment */
+};
+
+gvrender_features_t canon_features = {
+ LAYOUT_NOT_REQUIRED, /* flags */
+ 0., /* default margin - points */
+ {72.,72.}, /* default dpi */
+ NULL, /* knowncolors */
+ 0, /* sizeof knowncolors */
+ COLOR_STRING, /* color_type */
+ NULL, /* device */
+ NULL, /* gvloadimage target for usershapes */
+};
+
+gvrender_features_t dot_features = {
+ 0, /* flags */
+ 0., /* default margin - points */
+ {72.,72.}, /* default dpi */
+ NULL, /* knowncolors */
+ 0, /* sizeof knowncolors */
+ COLOR_STRING, /* color_type */
+ NULL, /* device */
+ NULL, /* gvloadimage target for usershapes */
+};
+
+gvplugin_installed_t gvrender_core_dot_types[] = {
+ {FORMAT_DOT, "dot", 1, &dot_engine, &dot_features},
+ {FORMAT_CANON, "canon", 1, &dot_engine, &canon_features},
+ {FORMAT_PLAIN, "plain", 1, &dot_engine, &dot_features},
+ {FORMAT_PLAIN_EXT, "plain-ext", 1, &dot_engine, &dot_features},
+ {FORMAT_XDOT, "xdot", 1, &xdot_engine, &dot_features},
+ {0, NULL, 0, NULL, NULL}
+};
#ifdef WIN32
#include <io.h>
+#include "compat.h"
#endif
#include "macros.h"
static int Depth;
-void figgen_fputs(GVJ_t * job, char *s)
-{
- int len;
-
- len = strlen(s);
- fwrite(s, sizeof(char), (unsigned) len, job->output_file);
-}
-
-/* figgen_printf:
- * Note that this function is unsafe due to the fixed buffer size.
- * It should only be used when the caller is sure the input will not
- * overflow the buffer. In particular, it should be avoided for
- * input coming from users. Also, if vsnprintf is available, the
- * code should check for return values to use it safely.
- */
-void figgen_printf(GVJ_t * job, const char *format, ...)
-{
- char buf[BUFSIZ];
- va_list argp;
-
- va_start(argp, format);
-#ifdef HAVE_VSNPRINTF
- (void) vsnprintf(buf, sizeof(buf), format, argp);
-#else
- (void) vsprintf(buf, format, argp);
-#endif
- va_end(argp);
-
- figgen_fputs(job, buf);
-}
+extern void core_fputs(GVJ_t * job, char *s);
+extern void core_printf(GVJ_t * job, const char *format, ...);
static void figptarray(GVJ_t *job, pointf * A, int n, int close)
{
for (i = 0; i < n; i++) {
PF2P(A[i],p);
- figgen_printf(job, " %d %d", p.x, p.y);
+ core_printf(job, " %d %d", p.x, p.y);
}
if (close) {
PF2P(A[0],p);
- figgen_printf(job, " %d %d", p.x, p.y);
+ core_printf(job, " %d %d", p.x, p.y);
}
- figgen_fputs(job, "\n");
+ core_fputs(job, "\n");
}
static char *fig_string(char *s)
"black", "blue", "green", "cyan", "red", "magenta", "yellow", "white", (char *) NULL
};
-static void figgen_resolve_color(GVJ_t *job, gvcolor_t * color)
+static void fig_resolve_color(GVJ_t *job, gvcolor_t * color)
{
int object_code = 0; /* always 0 for color */
int i, new;
color->u.rgba[1],
color->u.rgba[2]);
if (new)
- figgen_printf(job, "%d %d #%02x%02x%02x\n",
+ core_printf(job, "%d %d #%02x%02x%02x\n",
object_code, i,
color->u.rgba[0],
color->u.rgba[1],
color->type = COLOR_INDEX;
}
-static void figgen_line_style(obj_state_t *obj, int *line_style, double *style_val)
+static void fig_line_style(obj_state_t *obj, int *line_style, double *style_val)
{
switch (obj->pen) {
case PEN_DASHED:
}
}
-static void figgen_comment(GVJ_t *job, char *str)
+static void fig_comment(GVJ_t *job, char *str)
{
- figgen_printf(job, "# %s\n", str);
+ core_printf(job, "# %s\n", str);
}
-static void figgen_begin_graph(GVJ_t * job)
+static void fig_begin_graph(GVJ_t * job)
{
obj_state_t *obj = job->obj;
- figgen_fputs(job, "#FIG 3.2\n");
- figgen_printf(job, "# Generated by %s version %s (%s)\n",
+ core_fputs(job, "#FIG 3.2\n");
+ core_printf(job, "# Generated by %s version %s (%s)\n",
job->common->info[0], job->common->info[1], job->common->info[2]);
- figgen_printf(job, "# For: %s\n", job->common->user);
- figgen_printf(job, "# Title: %s\n", obj->u.g->name);
- figgen_printf(job, "# Pages: %d\n", job->pagesArraySize.x * job->pagesArraySize.y);
- figgen_fputs(job, "Portrait\n"); /* orientation */
- figgen_fputs(job, "Center\n"); /* justification */
- figgen_fputs(job, "Inches\n"); /* units */
- figgen_fputs(job, "Letter\n"); /* papersize */
- figgen_fputs(job, "100.00\n"); /* magnification % */
- figgen_fputs(job, "Single\n"); /* multiple-page */
- figgen_fputs(job, "-2\n"); /* transparent color (none) */
- figgen_fputs(job, "1200"); /* resolution */
- figgen_fputs(job, " 2\n"); /* coordinate system (upper left) */
+ core_printf(job, "# For: %s\n", job->common->user);
+ core_printf(job, "# Title: %s\n", obj->u.g->name);
+ core_printf(job, "# Pages: %d\n", job->pagesArraySize.x * job->pagesArraySize.y);
+ core_fputs(job, "Portrait\n"); /* orientation */
+ core_fputs(job, "Center\n"); /* justification */
+ core_fputs(job, "Inches\n"); /* units */
+ core_fputs(job, "Letter\n"); /* papersize */
+ core_fputs(job, "100.00\n"); /* magnification % */
+ core_fputs(job, "Single\n"); /* multiple-page */
+ core_fputs(job, "-2\n"); /* transparent color (none) */
+ core_fputs(job, "1200"); /* resolution */
+ core_fputs(job, " 2\n"); /* coordinate system (upper left) */
}
-static void figgen_end_graph(GVJ_t * job)
+static void fig_end_graph(GVJ_t * job)
{
- figgen_fputs(job, "# end of FIG file\n");
+ core_fputs(job, "# end of FIG file\n");
}
-static void figgen_begin_page(GVJ_t * job)
+static void fig_begin_page(GVJ_t * job)
{
Depth = 2;
}
-static void figgen_begin_node(GVJ_t * job)
+static void fig_begin_node(GVJ_t * job)
{
Depth = 1;
}
-static void figgen_end_node(GVJ_t * job)
+static void fig_end_node(GVJ_t * job)
{
Depth = 2;
}
-static void figgen_begin_edge(GVJ_t * job)
+static void fig_begin_edge(GVJ_t * job)
{
Depth = 0;
}
-static void figgen_end_edge(GVJ_t * job)
+static void fig_end_edge(GVJ_t * job)
{
Depth = 2;
}
-static void figgen_textpara(GVJ_t * job, pointf p, textpara_t * para)
+static void fig_textpara(GVJ_t * job, pointf p, textpara_t * para)
{
obj_state_t *obj = job->obj;
break;
}
- figgen_printf(job,
+ core_printf(job,
"%d %d %d %d %d %d %.1f %.4f %d %.1f %.1f %d %d %s\\001\n",
object_code, sub_type, color, depth, pen_style, font,
font_size, angle, font_flags, height, length, ROUND(p.x), ROUND(p.y),
fig_string(para->str));
}
-static void figgen_ellipse(GVJ_t * job, pointf * A, int filled)
+static void fig_ellipse(GVJ_t * job, pointf * A, int filled)
{
obj_state_t *obj = job->obj;
int center_x, center_y, radius_x, radius_y;
int start_x, start_y, end_x, end_y;
- figgen_line_style(obj, &line_style, &style_val);
+ fig_line_style(obj, &line_style, &style_val);
start_x = center_x = ROUND(A[0].x);
start_y = center_y = ROUND(A[0].y);
end_x = ROUND(A[1].x);
end_y = ROUND(A[1].y);
- figgen_printf(job,
+ core_printf(job,
"%d %d %d %d %d %d %d %d %d %.3f %d %.4f %d %d %d %d %d %d %d %d\n",
object_code, sub_type, line_style, thickness, pen_color,
fill_color, depth, pen_style, area_fill, style_val, direction,
start_y, end_x, end_y);
}
-static void figgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
+static void fig_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
int arrow_at_end, int filled)
{
obj_state_t *obj = job->obj;
1) * 20 * sizeof(char));
buf = buffer;
- figgen_line_style(obj, &line_style, &style_val);
+ fig_line_style(obj, &line_style, &style_val);
if (filled) {
sub_type = 5; /* closed X-spline */
}
}
- figgen_printf(job, "%d %d %d %d %d %d %d %d %d %.1f %d %d %d %d\n",
+ core_printf(job, "%d %d %d %d %d %d %d %d %d %.1f %d %d %d %d\n",
object_code,
sub_type,
line_style,
area_fill,
style_val, cap_style, forward_arrow, backward_arrow, count);
- figgen_printf(job, " %s\n", buffer); /* print points */
+ core_printf(job, " %s\n", buffer); /* print points */
free(buffer);
for (i = 0; i < count; i++) {
- figgen_printf(job, " %d", i % (count - 1) ? 1 : 0); /* -1 on all */
+ core_printf(job, " %d", i % (count - 1) ? 1 : 0); /* -1 on all */
}
- figgen_fputs(job, "\n");
+ core_fputs(job, "\n");
}
-static void figgen_polygon(GVJ_t * job, pointf * A, int n, int filled)
+static void fig_polygon(GVJ_t * job, pointf * A, int n, int filled)
{
obj_state_t *obj = job->obj;
int backward_arrow = 0;
int npoints = n + 1;
- figgen_line_style(obj, &line_style, &style_val);
+ fig_line_style(obj, &line_style, &style_val);
- figgen_printf(job,
+ core_printf(job,
"%d %d %d %d %d %d %d %d %d %.1f %d %d %d %d %d %d\n",
object_code, sub_type, line_style, thickness, pen_color,
fill_color, depth, pen_style, area_fill, style_val, join_style,
figptarray(job, A, n, 1); /* closed shape */
}
-static void figgen_polyline(GVJ_t * job, pointf * A, int n)
+static void fig_polyline(GVJ_t * job, pointf * A, int n)
{
obj_state_t *obj = job->obj;
int backward_arrow = 0;
int npoints = n;
- figgen_line_style(obj, &line_style, &style_val);
+ fig_line_style(obj, &line_style, &style_val);
- figgen_printf(job,
+ core_printf(job,
"%d %d %d %d %d %d %d %d %d %.1f %d %d %d %d %d %d\n",
object_code, sub_type, line_style, thickness, pen_color,
fill_color, depth, pen_style, area_fill, style_val, join_style,
figptarray(job, A, n, 0); /* open shape */
}
-gvrender_engine_t figgen_engine = {
- 0, /* figgen_begin_job */
- 0, /* figgen_end_job */
- figgen_begin_graph,
- figgen_end_graph,
- 0, /* figgen_begin_layer */
- 0, /* figgen_end_layer */
- figgen_begin_page,
- 0, /* figgen_end_page */
- 0, /* figgen_begin_cluster */
- 0, /* figgen_end_cluster */
- 0, /* figgen_begin_nodes */
- 0, /* figgen_end_nodes */
- 0, /* figgen_begin_edges */
- 0, /* figgen_end_edges */
- figgen_begin_node,
- figgen_end_node,
- figgen_begin_edge,
- figgen_end_edge,
- 0, /* figgen_begin_anchor */
- 0, /* figgen_end_anchor */
- figgen_textpara,
- figgen_resolve_color,
- figgen_ellipse,
- figgen_polygon,
- figgen_bezier,
- figgen_polyline,
- figgen_comment
+gvrender_engine_t fig_engine = {
+ 0, /* fig_begin_job */
+ 0, /* fig_end_job */
+ fig_begin_graph,
+ fig_end_graph,
+ 0, /* fig_begin_layer */
+ 0, /* fig_end_layer */
+ fig_begin_page,
+ 0, /* fig_end_page */
+ 0, /* fig_begin_cluster */
+ 0, /* fig_end_cluster */
+ 0, /* fig_begin_nodes */
+ 0, /* fig_end_nodes */
+ 0, /* fig_begin_edges */
+ 0, /* fig_end_edges */
+ fig_begin_node,
+ fig_end_node,
+ fig_begin_edge,
+ fig_end_edge,
+ 0, /* fig_begin_anchor */
+ 0, /* fig_end_anchor */
+ fig_textpara,
+ fig_resolve_color,
+ fig_ellipse,
+ fig_polygon,
+ fig_bezier,
+ fig_polyline,
+ fig_comment
};
/* NB. List must be LANG_C sorted */
-static char *figgen_knowncolors[] = {
+static char *fig_knowncolors[] = {
"black", "blue", "cyan", "green", "magenta", "red", "white", "yellow",
};
-gvrender_features_t figgen_features = {
+gvrender_features_t fig_features = {
EMIT_COLORS
| GVRENDER_Y_GOES_DOWN, /* flags */
DEFAULT_EMBED_MARGIN, /* default margin - points */
* It was picked to make .png usershapes the right size on my screen.
* It happens to be 1.2 * 1200, but I can't explain the 1.2.
* (I was expecting 1.3333 which is 96/72, but thats too big.)
- * Also 1200 is hardcoded in figgen_begin_graph() instead of using job->dpi
+ * Also 1200 is hardcoded in fig_begin_graph() instead of using job->dpi
*/
- figgen_knowncolors, /* knowncolors */
- sizeof(figgen_knowncolors) / sizeof(char *), /* sizeof knowncolors */
+ fig_knowncolors, /* knowncolors */
+ sizeof(fig_knowncolors) / sizeof(char *), /* sizeof knowncolors */
RGBA_BYTE, /* color_type */
NULL, /* device */
"fig", /* gvloadimage target for usershapes */
};
gvplugin_installed_t gvrender_core_fig_types[] = {
- {FORMAT_FIG, "fig", 1, &figgen_engine, &figgen_features},
+ {FORMAT_FIG, "fig", 1, &fig_engine, &fig_features},
{0, NULL, 0, NULL, NULL}
};
#include "graph.h"
extern char *xml_string(char *str);
+extern void core_fputs(GVJ_t * job, char *s);
+extern void core_printf(GVJ_t * job, const char *format, ...);
typedef enum { FORMAT_IMAP, FORMAT_ISMAP, FORMAT_CMAP, FORMAT_CMAPX, } format_type;
static void map_output_shape (GVJ_t *job, map_shape_t map_shape, pointf * AF, int nump,
char* url, char *tooltip, char *target)
{
- FILE *out = job->output_file;
int i;
static point *A;
switch (map_shape) {
case MAP_RECTANGLE:
/* Y_GOES_DOWN so need UL to LR */
- fprintf(out, "rect %s %d,%d %d,%d\n", url,
+ core_printf(job, "rect %s %d,%d %d,%d\n", url,
A[0].x, A[1].y, A[1].x, A[0].y);
break;
case MAP_CIRCLE:
- fprintf(out, "circle %s %d,%d,%d\n", url,
+ core_printf(job, "circle %s %d,%d,%d\n", url,
A[0].x, A[0].y, A[1].x-A[0].x);
break;
case MAP_POLYGON:
- fprintf(out, "poly %s", url);
+ core_printf(job, "poly %s", url);
for (i = 0; i < nump; i++)
- fprintf(out, " %d,%d", A[i].x, A[i].y);
- fprintf(out, "\n");
+ core_printf(job, " %d,%d", A[i].x, A[i].y);
+ core_fputs(job, "\n");
break;
default:
assert(0);
switch (map_shape) {
case MAP_RECTANGLE:
/* Y_GOES_DOWN so need UL to LR */
- fprintf(out, "rectangle (%d,%d) (%d,%d) %s %s\n",
+ core_printf(job, "rectangle (%d,%d) (%d,%d) %s %s\n",
A[0].x, A[1].y, A[1].x, A[0].y, url, tooltip);
break;
default:
} else if (job->render.id == FORMAT_CMAP || job->render.id == FORMAT_CMAPX) {
switch (map_shape) {
case MAP_CIRCLE:
- fprintf(out, "<area shape=\"circle\"");
+ core_fputs(job, "<area shape=\"circle\"");
break;
case MAP_RECTANGLE:
- fprintf(out, "<area shape=\"rect\"");
+ core_fputs(job, "<area shape=\"rect\"");
break;
case MAP_POLYGON:
- fprintf(out, "<area shape=\"poly\"");
+ core_fputs(job, "<area shape=\"poly\"");
break;
default:
assert(0);
break;
}
- if (url && url[0])
- fprintf(out, " href=\"%s\"", xml_string(url));
+ if (url && url[0]) {
+ core_fputs(job, " href=\"");
+ core_fputs(job, xml_string(url));
+ core_fputs(job, "\"");
+ }
if (target && target[0])
- fprintf(out, " target=\"%s\"", xml_string(target));
+ core_fputs(job, " target=\"");
+ core_fputs(job, xml_string(target));
+ core_fputs(job, "\"");
if (tooltip && tooltip[0])
- fprintf(out, " title=\"%s\"", xml_string(tooltip));
+ core_fputs(job, " title=\"");
+ core_fputs(job, xml_string(tooltip));
+ core_fputs(job, "\"");
/*
* alt text is intended for the visually impaired, but such
* folk are not likely to be clicking around on a graph anyway.
* that require that there is always an alt string,
* we generate just an empty alt string.
*/
- fprintf(out, " alt=\"\"");
+ core_fputs(job, " alt=\"\"");
- fprintf(out, " coords=\"");
+ core_fputs(job, " coords=\"");
switch (map_shape) {
case MAP_CIRCLE:
- fprintf(out, "%d,%d,%d", A[0].x, A[0].y, A[1].x);
+ core_printf(job, "%d,%d,%d", A[0].x, A[0].y, A[1].x);
break;
case MAP_RECTANGLE:
/* Y_GOES_DOWN so need UL to LR */
- fprintf(out, "%d,%d,%d,%d", A[0].x, A[1].y, A[1].x, A[0].y);
+ core_printf(job, "%d,%d,%d,%d", A[0].x, A[1].y, A[1].x, A[0].y);
break;
case MAP_POLYGON:
- fprintf(out, "%d,%d", A[0].x, A[0].y);
+ core_printf(job, "%d,%d", A[0].x, A[0].y);
for (i = 1; i < nump; i++)
- fprintf(out, " %d,%d", A[i].x, A[i].y);
+ core_printf(job, " %d,%d", A[i].x, A[i].y);
break;
default:
break;
}
if (job->render.id == FORMAT_CMAPX)
- fprintf(out, "\"/>\n");
+ core_fputs(job, "\"/>\n");
else
- fprintf(out, "\">\n");
+ core_fputs(job, "\">\n");
}
}
static void map_begin_page(GVJ_t * job)
{
obj_state_t *obj = job->obj;
- char *name = xml_string(obj->u.g->name);
+ char *s;
switch (job->render.id) {
case FORMAT_IMAP:
- fprintf(job->output_file, "base referer\n");
- if (obj->url && obj->url[0])
- fprintf(job->output_file, "default %s\n", obj->url);
+ core_fputs(job, "base referer\n");
+ if (obj->url && obj->url[0]) {
+ core_fputs(job, "default ");
+ core_fputs(job, xml_string(obj->url));
+ core_fputs(job, "\n");
+ }
break;
case FORMAT_ISMAP:
- if (obj->url && obj->url[0])
- fprintf(job->output_file, "default %s %s\n", obj->url, obj->u.g->name);
+ if (obj->url && obj->url[0]) {
+ core_fputs(job, "default ");
+ core_fputs(job, xml_string(obj->url));
+ core_fputs(job, " ");
+ core_fputs(job, xml_string(obj->u.g->name));
+ core_fputs(job, "\n");
+ }
break;
case FORMAT_CMAPX:
- fprintf(job->output_file, "<map id=\"%s\" name=\"%s\">\n", name, name);
+ s = xml_string(obj->u.g->name);
+ core_fputs(job, "<map id=\"");
+ core_fputs(job, s);
+ core_fputs(job, "\" name=\"");
+ core_fputs(job, s);
+ core_fputs(job, "\">\n");
break;
default:
break;
case FORMAT_CMAPX:
map_output_shape(job, obj->url_map_shape, obj->url_map_p,obj->url_map_n,
obj->url, obj->tooltip, obj->target);
- fprintf(job->output_file, "</map>\n");
+ core_fputs(job, "</map>\n");
break;
default:
break;
{
obj_state_t *obj = job->obj;
- fprintf(job->output_file, "%% %s\n", obj->u.sg->name);
+ core_printf(job, "%% %s\n", obj->u.sg->name);
map_output_shape(job, obj->url_map_shape, obj->url_map_p, obj->url_map_n,
obj->url, obj->tooltip, obj->target);
#ifdef HAVE_LIBZ
#include <zlib.h>
+#endif
+
#ifdef WIN32
#include <io.h>
-#endif
+#include "compat.h"
#endif
#include "gvplugin_render.h"
#include "config.h"
#endif
-#ifdef WIN32
-#include <io.h>
-#include <compat.h>
-#endif
-
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-#ifdef WIN32
-#include <io.h>
-#endif
-
#include "macros.h"
#include "const.h"
typedef enum { FORMAT_SVG, FORMAT_SVGZ, } format_type;
extern char *xml_string(char *str);
+extern void core_init_compression(GVJ_t * job, compression_t compression);
+extern void core_fini_compression(GVJ_t * job);
+extern void core_fputs(GVJ_t * job, char *s);
+extern void core_printf(GVJ_t * job, const char *format, ...);
/* SVG dash array */
static char *sdarray = "5,2";
/* SVG dot array */
static char *sdotarray = "1,5";
-void svggen_fputs(GVJ_t * job, char *s)
-{
- int len;
-
- len = strlen(s);
- switch (job->render.id) {
- case FORMAT_SVGZ:
-#ifdef HAVE_LIBZ
- gzwrite((gzFile *) (job->output_file), s, (unsigned) len);
-#endif
- break;
- case FORMAT_SVG:
- fwrite(s, sizeof(char), (unsigned) len, job->output_file);
- break;
- }
-}
-
-/* svggen_printf:
- * Note that this function is unsafe due to the fixed buffer size.
- * It should only be used when the caller is sure the input will not
- * overflow the buffer. In particular, it should be avoided for
- * input coming from users. Also, if vsnprintf is available, the
- * code should check for return values to use it safely.
- */
-void svggen_printf(GVJ_t * job, const char *format, ...)
-{
- char buf[BUFSIZ];
- va_list argp;
-
- va_start(argp, format);
-#ifdef HAVE_VSNPRINTF
- (void) vsnprintf(buf, sizeof(buf), format, argp);
-#else
- (void) vsprintf(buf, format, argp);
-#endif
- va_end(argp);
-
- svggen_fputs(job, buf);
-}
-
-static void svggen_bzptarray(GVJ_t * job, pointf * A, int n)
+static void svg_bzptarray(GVJ_t * job, pointf * A, int n)
{
int i;
char c;
c = 'M'; /* first point */
for (i = 0; i < n; i++) {
- svggen_printf(job, "%c%g,%g", c, A[i].x, -A[i].y);
+ core_printf(job, "%c%g,%g", c, A[i].x, -A[i].y);
if (i == 0)
c = 'C'; /* second point */
else
}
}
-static void svggen_print_color(GVJ_t * job, gvcolor_t color)
+static void svg_print_color(GVJ_t * job, gvcolor_t color)
{
switch (color.type) {
case COLOR_STRING:
- svggen_fputs(job, color.u.string);
+ core_fputs(job, color.u.string);
break;
case RGBA_BYTE:
if (color.u.rgba[3] == 0) /* transparent */
- svggen_fputs(job, "none");
+ core_fputs(job, "none");
else
- svggen_printf(job, "#%02x%02x%02x",
+ core_printf(job, "#%02x%02x%02x",
color.u.rgba[0], color.u.rgba[1], color.u.rgba[2]);
break;
default:
}
}
-static void svggen_grstyle(GVJ_t * job, int filled)
+static void svg_grstyle(GVJ_t * job, int filled)
{
obj_state_t *obj = job->obj;
- svggen_fputs(job, " style=\"fill:");
+ core_fputs(job, " style=\"fill:");
if (filled)
- svggen_print_color(job, obj->fillcolor);
+ svg_print_color(job, obj->fillcolor);
else
- svggen_fputs(job, "none");
- svggen_fputs(job, ";stroke:");
- svggen_print_color(job, obj->pencolor);
+ core_fputs(job, "none");
+ core_fputs(job, ";stroke:");
+ svg_print_color(job, obj->pencolor);
if (obj->penwidth != PENWIDTH_NORMAL)
- svggen_printf(job, ";stroke-width:%g", obj->penwidth);
+ core_printf(job, ";stroke-width:%g", obj->penwidth);
if (obj->pen == PEN_DASHED) {
- svggen_printf(job, ";stroke-dasharray:%s", sdarray);
+ core_printf(job, ";stroke-dasharray:%s", sdarray);
} else if (obj->pen == PEN_DOTTED) {
- svggen_printf(job, ";stroke-dasharray:%s", sdotarray);
+ core_printf(job, ";stroke-dasharray:%s", sdotarray);
}
- svggen_fputs(job, ";\"");
+ core_fputs(job, ";\"");
}
-static void svggen_comment(GVJ_t * job, char *str)
+static void svg_comment(GVJ_t * job, char *str)
{
- svggen_fputs(job, "<!-- ");
- svggen_fputs(job, xml_string(str));
- svggen_fputs(job, " -->\n");
+ core_fputs(job, "<!-- ");
+ core_fputs(job, xml_string(str));
+ core_fputs(job, " -->\n");
}
-static void svggen_begin_job(GVJ_t * job)
+static void svg_begin_job(GVJ_t * job)
{
-#if HAVE_LIBZ
- int fd;
-#endif
-
switch (job->render.id) {
case FORMAT_SVGZ:
-#if HAVE_LIBZ
- /* open dup so can gzclose independent of FILE close */
- fd = dup(fileno(job->output_file));
-#ifdef HAVE_SETMODE
-#ifdef O_BINARY
- /*
- * Windows will do \n -> \r\n translations on
- * stdout unless told otherwise.
- */
- setmode(fd, O_BINARY);
-#endif
-#endif
-
- job->output_file = (FILE *) (gzdopen(fd, "wb"));
- if (!job->output_file) {
- (job->common->errorfn) ("Error opening compressed output file\n");
- exit(1);
- }
+ core_init_compression(job, COMPRESSION_ZLIB);
break;
-#else
- (job->common->errorfn) ("No libz support.\n");
- exit(1);
-#endif
case FORMAT_SVG:
+ core_init_compression(job, COMPRESSION_NONE);
break;
}
- svggen_fputs(job,
- "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
- svggen_fputs(job,
- "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n");
- svggen_fputs(job,
- " \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"");
+ core_fputs(job, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
+ core_fputs(job, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n");
+ core_fputs(job, " \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"");
/* This is to work around a bug in the SVG 1.0 DTD */
- svggen_fputs(job,
- " [\n <!ATTLIST svg xmlns:xlink CDATA #FIXED \"http://www.w3.org/1999/xlink\">\n]");
-
- svggen_fputs(job, ">\n<!-- Generated by ");
- svggen_fputs(job, xml_string(job->common->info[0]));
- svggen_fputs(job, " version ");
- svggen_fputs(job, xml_string(job->common->info[1]));
- svggen_fputs(job, " (");
- svggen_fputs(job, xml_string(job->common->info[2]));
- svggen_fputs(job, ")\n For user: ");
- svggen_fputs(job, xml_string(job->common->user));
- svggen_fputs(job, " -->\n");
+ core_fputs(job, " [\n <!ATTLIST svg xmlns:xlink CDATA #FIXED \"http://www.w3.org/1999/xlink\">\n]");
+
+ core_fputs(job, ">\n<!-- Generated by ");
+ core_fputs(job, xml_string(job->common->info[0]));
+ core_fputs(job, " version ");
+ core_fputs(job, xml_string(job->common->info[1]));
+ core_fputs(job, " (");
+ core_fputs(job, xml_string(job->common->info[2]));
+ core_fputs(job, ")\n For user: ");
+ core_fputs(job, xml_string(job->common->user));
+ core_fputs(job, " -->\n");
}
-static void svggen_begin_graph(GVJ_t * job)
+static void svg_begin_graph(GVJ_t * job)
{
obj_state_t *obj = job->obj;
- svggen_fputs(job, "<!--");
+ core_fputs(job, "<!--");
if (obj->u.g->name[0]) {
- svggen_fputs(job, " Title: ");
- svggen_fputs(job, xml_string(obj->u.g->name));
+ core_fputs(job, " Title: ");
+ core_fputs(job, xml_string(obj->u.g->name));
}
- svggen_printf(job, " Pages: %d -->\n", job->pagesArraySize.x * job->pagesArraySize.y);
+ core_printf(job, " Pages: %d -->\n", job->pagesArraySize.x * job->pagesArraySize.y);
- svggen_printf(job, "<svg width=\"%dpx\" height=\"%dpx\"\n",
+ core_printf(job, "<svg width=\"%dpx\" height=\"%dpx\"\n",
job->width, job->height);
/* namespace of svg */
- svggen_fputs(job, " xmlns=\"http://www.w3.org/2000/svg\"");
+ core_fputs(job, " xmlns=\"http://www.w3.org/2000/svg\"");
/* namespace of xlink */
- svggen_fputs(job, " xmlns:xlink=\"http://www.w3.org/1999/xlink\"");
- svggen_fputs(job, ">\n");
+ core_fputs(job, " xmlns:xlink=\"http://www.w3.org/1999/xlink\"");
+ core_fputs(job, ">\n");
}
-static void svggen_end_graph(GVJ_t * job)
+static void svg_end_graph(GVJ_t * job)
{
- svggen_fputs(job, "</svg>\n");
- switch (job->render.id) {
- case FORMAT_SVGZ:
-#ifdef HAVE_LIBZ
- gzclose((gzFile *) (job->output_file));
- break;
-#else
- (job->common->errorfn) ("No libz support\n");
- exit(1);
-#endif
- case FORMAT_SVG:
- break;
- }
+ core_fputs(job, "</svg>\n");
+ core_fini_compression(job);
}
-static void svggen_begin_layer(GVJ_t * job, char *layername, int layerNum, int numLayers)
+static void svg_begin_layer(GVJ_t * job, char *layername, int layerNum, int numLayers)
{
- svggen_fputs(job, "<g id=\"");
- svggen_fputs(job, xml_string(layername));
- svggen_fputs(job, "\" class=\"layer\">\n");
+ core_fputs(job, "<g id=\"");
+ core_fputs(job, xml_string(layername));
+ core_fputs(job, "\" class=\"layer\">\n");
}
-static void svggen_end_layer(GVJ_t * job)
+static void svg_end_layer(GVJ_t * job)
{
- svggen_fputs(job, "</g>\n");
+ core_fputs(job, "</g>\n");
}
-static void svggen_begin_page(GVJ_t * job)
+static void svg_begin_page(GVJ_t * job)
{
obj_state_t *obj = job->obj;
/* its really just a page of the graph, but its still a graph,
* and it is the entire graph if we're not currently paging */
- svggen_printf(job, "<g id=\"graph%d\" class=\"graph\"", job->common->viewNum);
- svggen_printf(job, " transform=\"scale(%g %g) rotate(%d) translate(%g %g)\">\n",
+ core_printf(job, "<g id=\"graph%d\" class=\"graph\"", job->common->viewNum);
+ core_printf(job, " transform=\"scale(%g %g) rotate(%d) translate(%g %g)\">\n",
job->scale.x, job->scale.y, -job->rotation,
job->translation.x, -job->translation.y);
/* default style */
if (obj->u.g->name[0]) {
- svggen_fputs(job, "<title>");
- svggen_fputs(job, xml_string(obj->u.g->name));
- svggen_fputs(job, "</title>\n");
+ core_fputs(job, "<title>");
+ core_fputs(job, xml_string(obj->u.g->name));
+ core_fputs(job, "</title>\n");
}
}
-static void svggen_end_page(GVJ_t * job)
+static void svg_end_page(GVJ_t * job)
{
- svggen_fputs(job, "</g>\n");
+ core_fputs(job, "</g>\n");
}
-static void svggen_begin_cluster(GVJ_t * job)
+static void svg_begin_cluster(GVJ_t * job)
{
obj_state_t *obj = job->obj;
- svggen_printf(job, "<g id=\"cluster%ld\" class=\"cluster\">",
+ core_printf(job, "<g id=\"cluster%ld\" class=\"cluster\">",
obj->u.sg->meta_node->id);
- svggen_fputs(job, "<title>");
- svggen_fputs(job, xml_string(obj->u.sg->name));
- svggen_fputs(job, "</title>\n");
+ core_fputs(job, "<title>");
+ core_fputs(job, xml_string(obj->u.sg->name));
+ core_fputs(job, "</title>\n");
}
-static void svggen_end_cluster(GVJ_t * job)
+static void svg_end_cluster(GVJ_t * job)
{
- svggen_fputs(job, "</g>\n");
+ core_fputs(job, "</g>\n");
}
-static void svggen_begin_node(GVJ_t * job)
+static void svg_begin_node(GVJ_t * job)
{
obj_state_t *obj = job->obj;
- svggen_printf(job, "<g id=\"node%ld\" class=\"node\">", obj->u.n->id);
- svggen_fputs(job, "<title>");
- svggen_fputs(job, xml_string(obj->u.n->name));
- svggen_fputs(job, "</title>\n");
+ core_printf(job, "<g id=\"node%ld\" class=\"node\">", obj->u.n->id);
+ core_fputs(job, "<title>");
+ core_fputs(job, xml_string(obj->u.n->name));
+ core_fputs(job, "</title>\n");
}
-static void svggen_end_node(GVJ_t * job)
+static void svg_end_node(GVJ_t * job)
{
- svggen_fputs(job, "</g>\n");
+ core_fputs(job, "</g>\n");
}
static void
-svggen_begin_edge(GVJ_t * job)
+svg_begin_edge(GVJ_t * job)
{
obj_state_t *obj = job->obj;
char *edgeop;
- svggen_printf(job, "<g id=\"edge%ld\" class=\"edge\">", obj->u.e->id);
+ core_printf(job, "<g id=\"edge%ld\" class=\"edge\">", obj->u.e->id);
if (obj->u.e->tail->graph->root->kind & AGFLAG_DIRECTED)
edgeop = "->";
else
edgeop = "--";
- svggen_fputs(job, "<title>");
- svggen_fputs(job, xml_string(obj->u.e->tail->name));
- svggen_fputs(job, edgeop);
- /* can't do this in single svggen_printf because
+ core_fputs(job, "<title>");
+ core_fputs(job, xml_string(obj->u.e->tail->name));
+ core_fputs(job, edgeop);
+ /* can't do this in single core_printf because
* xml_string's buffer gets reused. */
- svggen_fputs(job, xml_string(obj->u.e->head->name));
- svggen_fputs(job, "</title>\n");
+ core_fputs(job, xml_string(obj->u.e->head->name));
+ core_fputs(job, "</title>\n");
}
-static void svggen_end_edge(GVJ_t * job)
+static void svg_end_edge(GVJ_t * job)
{
- svggen_fputs(job, "</g>\n");
+ core_fputs(job, "</g>\n");
}
static void
-svggen_begin_anchor(GVJ_t * job, char *href, char *tooltip, char *target)
+svg_begin_anchor(GVJ_t * job, char *href, char *tooltip, char *target)
{
- svggen_fputs(job, "<a");
+ core_fputs(job, "<a");
if (href && href[0])
- svggen_printf(job, " xlink:href=\"%s\"", xml_string(href));
+ core_printf(job, " xlink:href=\"%s\"", xml_string(href));
if (tooltip && tooltip[0])
- svggen_printf(job, " xlink:title=\"%s\"", xml_string(tooltip));
+ core_printf(job, " xlink:title=\"%s\"", xml_string(tooltip));
if (target && target[0])
- svggen_printf(job, " target=\"%s\"", xml_string(target));
- svggen_fputs(job, ">\n");
+ core_printf(job, " target=\"%s\"", xml_string(target));
+ core_fputs(job, ">\n");
}
-static void svggen_end_anchor(GVJ_t * job)
+static void svg_end_anchor(GVJ_t * job)
{
- svggen_fputs(job, "</a>\n");
+ core_fputs(job, "</a>\n");
}
-static void svggen_textpara(GVJ_t * job, pointf p, textpara_t * para)
+static void svg_textpara(GVJ_t * job, pointf p, textpara_t * para)
{
obj_state_t *obj = job->obj;
- svggen_fputs(job, "<text");
+ core_fputs(job, "<text");
switch (para->just) {
case 'l':
- svggen_fputs(job, " text-anchor=\"start\"");
+ core_fputs(job, " text-anchor=\"start\"");
break;
case 'r':
- svggen_fputs(job, " text-anchor=\"end\"");
+ core_fputs(job, " text-anchor=\"end\"");
break;
default:
case 'n':
- svggen_fputs(job, " text-anchor=\"middle\"");
+ core_fputs(job, " text-anchor=\"middle\"");
break;
}
- svggen_printf(job, " x=\"%g\" y=\"%g\"", p.x, -p.y);
- svggen_fputs(job, " style=\"");
+ core_printf(job, " x=\"%g\" y=\"%g\"", p.x, -p.y);
+ core_fputs(job, " style=\"");
if (para->postscript_alias) {
- svggen_printf(job, "font-family:%s;", para->postscript_alias->family);
+ core_printf(job, "font-family:%s;", para->postscript_alias->family);
if (para->postscript_alias->weight)
- svggen_printf(job, "font-weight:%s;", para->postscript_alias->weight);
+ core_printf(job, "font-weight:%s;", para->postscript_alias->weight);
if (para->postscript_alias->stretch)
- svggen_printf(job, "font-stretch:%s;", para->postscript_alias->stretch);
+ core_printf(job, "font-stretch:%s;", para->postscript_alias->stretch);
if (para->postscript_alias->style)
- svggen_printf(job, "font-style:%s;", para->postscript_alias->style);
+ core_printf(job, "font-style:%s;", para->postscript_alias->style);
}
else {
- svggen_printf(job, "font:%s;", para->fontname);
+ core_printf(job, "font:%s;", para->fontname);
}
- svggen_printf(job, "font-size:%.2fpx;", para->fontsize);
+ core_printf(job, "font-size:%.2fpx;", para->fontsize);
switch (obj->pencolor.type) {
case COLOR_STRING:
if (strcasecmp(obj->pencolor.u.string, "black"))
- svggen_printf(job, "fill:%s;", obj->pencolor.u.string);
+ core_printf(job, "fill:%s;", obj->pencolor.u.string);
break;
case RGBA_BYTE:
- svggen_printf(job, "fill:#%02x%02x%02x;",
+ core_printf(job, "fill:#%02x%02x%02x;",
obj->pencolor.u.rgba[0], obj->pencolor.u.rgba[1], obj->pencolor.u.rgba[2]);
break;
default:
assert(0); /* internal error */
}
- svggen_fputs(job, "\">");
- svggen_fputs(job, xml_string(para->str));
- svggen_fputs(job, "</text>\n");
+ core_fputs(job, "\">");
+ core_fputs(job, xml_string(para->str));
+ core_fputs(job, "</text>\n");
}
-static void svggen_ellipse(GVJ_t * job, pointf * A, int filled)
+static void svg_ellipse(GVJ_t * job, pointf * A, int filled)
{
/* A[] contains 2 points: the center and corner. */
- svggen_fputs(job, "<ellipse");
- svggen_grstyle(job, filled);
- svggen_printf(job, " cx=\"%g\" cy=\"%g\"", A[0].x, -A[0].y);
- svggen_printf(job, " rx=\"%g\" ry=\"%g\"",
+ core_fputs(job, "<ellipse");
+ svg_grstyle(job, filled);
+ core_printf(job, " cx=\"%g\" cy=\"%g\"", A[0].x, -A[0].y);
+ core_printf(job, " rx=\"%g\" ry=\"%g\"",
A[1].x - A[0].x, A[1].y - A[0].y);
- svggen_fputs(job, "/>\n");
+ core_fputs(job, "/>\n");
}
static void
-svggen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
+svg_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
int arrow_at_end, int filled)
{
- svggen_fputs(job, "<path");
- svggen_grstyle(job, filled);
- svggen_fputs(job, " d=\"");
- svggen_bzptarray(job, A, n);
- svggen_fputs(job, "\"/>\n");
+ core_fputs(job, "<path");
+ svg_grstyle(job, filled);
+ core_fputs(job, " d=\"");
+ svg_bzptarray(job, A, n);
+ core_fputs(job, "\"/>\n");
}
-static void svggen_polygon(GVJ_t * job, pointf * A, int n, int filled)
+static void svg_polygon(GVJ_t * job, pointf * A, int n, int filled)
{
int i;
- svggen_fputs(job, "<polygon");
- svggen_grstyle(job, filled);
- svggen_fputs(job, " points=\"");
+ core_fputs(job, "<polygon");
+ svg_grstyle(job, filled);
+ core_fputs(job, " points=\"");
for (i = 0; i < n; i++)
- svggen_printf(job, "%g,%g ", A[i].x, -A[i].y);
- svggen_printf(job, "%g,%g", A[0].x, -A[0].y); /* because Adobe SVG is broken */
- svggen_fputs(job, "\"/>\n");
+ core_printf(job, "%g,%g ", A[i].x, -A[i].y);
+ core_printf(job, "%g,%g", A[0].x, -A[0].y); /* because Adobe SVG is broken */
+ core_fputs(job, "\"/>\n");
}
-static void svggen_polyline(GVJ_t * job, pointf * A, int n)
+static void svg_polyline(GVJ_t * job, pointf * A, int n)
{
int i;
- svggen_fputs(job, "<polyline");
- svggen_grstyle(job, 0);
- svggen_fputs(job, " points=\"");
+ core_fputs(job, "<polyline");
+ svg_grstyle(job, 0);
+ core_fputs(job, " points=\"");
for (i = 0; i < n; i++)
- svggen_printf(job, "%g,%g ", A[i].x, -A[i].y);
- svggen_fputs(job, "\"/>\n");
+ core_printf(job, "%g,%g ", A[i].x, -A[i].y);
+ core_fputs(job, "\"/>\n");
}
/* color names from http://www.w3.org/TR/SVG/types.html */
/* NB. List must be LANG_C sorted */
-static char *svggen_knowncolors[] = {
+static char *svg_knowncolors[] = {
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure",
"beige", "bisque", "black", "blanchedalmond", "blue",
"blueviolet", "brown", "burlywood",
"yellow", "yellowgreen"
};
-gvrender_engine_t svggen_engine = {
- svggen_begin_job,
- 0, /* svggen_end_job */
- svggen_begin_graph,
- svggen_end_graph,
- svggen_begin_layer,
- svggen_end_layer,
- svggen_begin_page,
- svggen_end_page,
- svggen_begin_cluster,
- svggen_end_cluster,
- 0, /* svggen_begin_nodes */
- 0, /* svggen_end_nodes */
- 0, /* svggen_begin_edges */
- 0, /* svggen_end_edges */
- svggen_begin_node,
- svggen_end_node,
- svggen_begin_edge,
- svggen_end_edge,
- svggen_begin_anchor,
- svggen_end_anchor,
- svggen_textpara,
- 0, /* svggen_resolve_color */
- svggen_ellipse,
- svggen_polygon,
- svggen_bezier,
- svggen_polyline,
- svggen_comment,
+gvrender_engine_t svg_engine = {
+ svg_begin_job,
+ 0, /* svg_end_job */
+ svg_begin_graph,
+ svg_end_graph,
+ svg_begin_layer,
+ svg_end_layer,
+ svg_begin_page,
+ svg_end_page,
+ svg_begin_cluster,
+ svg_end_cluster,
+ 0, /* svg_begin_nodes */
+ 0, /* svg_end_nodes */
+ 0, /* svg_begin_edges */
+ 0, /* svg_end_edges */
+ svg_begin_node,
+ svg_end_node,
+ svg_begin_edge,
+ svg_end_edge,
+ svg_begin_anchor,
+ svg_end_anchor,
+ svg_textpara,
+ 0, /* svg_resolve_color */
+ svg_ellipse,
+ svg_polygon,
+ svg_bezier,
+ svg_polyline,
+ svg_comment,
};
-gvrender_features_t svggen_features = {
+gvrender_features_t svg_features = {
GVRENDER_DOES_TRUECOLOR
| GVRENDER_Y_GOES_DOWN
| GVRENDER_DOES_TRANSFORM
| GVRENDER_DOES_TOOLTIPS, /* flags */
DEFAULT_EMBED_MARGIN, /* default margin - points */
{96.,96.}, /* default dpi */
- svggen_knowncolors, /* knowncolors */
- sizeof(svggen_knowncolors) / sizeof(char *), /* sizeof knowncolors */
+ svg_knowncolors, /* knowncolors */
+ sizeof(svg_knowncolors) / sizeof(char *), /* sizeof knowncolors */
RGBA_BYTE, /* color_type */
NULL, /* device */
"svg", /* gvloadimage target for usershapes */
};
gvplugin_installed_t gvrender_core_svg_types[] = {
- {FORMAT_SVG, "svg", 1, &svggen_engine, &svggen_features},
+ {FORMAT_SVG, "svg", 1, &svg_engine, &svg_features},
#if HAVE_LIBZ
- {FORMAT_SVGZ, "svgz", 1, &svggen_engine, &svggen_features},
+ {FORMAT_SVGZ, "svgz", 1, &svg_engine, &svg_features},
#endif
{0, NULL, 0, NULL, NULL}
};
static int graphcmd(ClientData clientData, Tcl_Interp * interp,
#ifndef TCLOBJ
int argc, char *argv[]
-#else /* TCLOBJ */
+#else
int argc, Tcl_Obj * CONST objv[]
-#endif /* TCLOBJ */
+#endif
)
{
unsigned long id;
ClientData outfp;
GVC_t *gvc = (GVC_t *) clientData;
+ GVJ_t *job = gvc->job;
if (argc < 2) {
Tcl_AppendResult(interp, "wrong # args: should be \"",
(char *) 0);
return TCL_ERROR;
}
- gvc->active_jobs = gvc->job;
+ gvc->active_jobs = job;
- gvc->job->surface = (void *)(&tkgendata);
- gvc->job->external_surface = TRUE;
+ job->surface = (void *)(&tkgendata);
+ job->external_surface = TRUE;
/* make sure that layout is done */
g = g->root;
(char *) 0);
return TCL_ERROR;
}
- gvc->active_jobs = gvc->job;
+ gvc->active_jobs = job;
if (! (hdl = tclhandleXlate(GDHandleTable, argv[2]))) {
Tcl_AppendResult(interp, "GD Image not found.", (char *) NULL);
return TCL_ERROR;
}
- gvc->job->surface = *hdl;
- gvc->job->external_surface = TRUE;
+ job->surface = *hdl;
+ job->external_surface = TRUE;
/* make sure that layout is done */
g = g->root;
"\". Use one of:", s, (char *)NULL);
return TCL_ERROR;
}
- gvc->active_jobs = gvc->job;
+ gvc->active_jobs = job;
/* populate new job struct with output language and output file data */
- gvc->job->output_lang =
- gvrender_select(gvc->job, gvc->job->output_langname);
+ job->output_lang = gvrender_select(job, job->output_langname);
if (Tcl_GetOpenFile (interp, argv[2], 1, 1, &outfp) != TCL_OK)
return TCL_ERROR;
- gvc->job->output_file = (FILE *)outfp;
- gvc->job->output_filename = NULL;
+ job->output_file = (FILE *)outfp;
+ job->output_filename = NULL;
/* make sure that layout is done - unless canonical output */
- if ((!GD_drawing(g) || argc > 4)
- && gvc->job->output_lang != CANONICAL_DOT) {
+ if ((!GD_drawing(g) || argc > 4) && !(job->flags & LAYOUT_NOT_REQUIRED)) {
tcldot_layout(gvc, g, (argc > 4) ? argv[4] : (char *) NULL);
}