]> granicus.if.org Git - graphviz/commitdiff
Convert -Tdot, -Txdot, -Tcanon, -Tplain, -Tplain-ext to a plugin
authorellson <devnull@localhost>
Fri, 4 Aug 2006 02:47:16 +0000 (02:47 +0000)
committerellson <devnull@localhost>
Fri, 4 Aug 2006 02:47:16 +0000 (02:47 +0000)
lib/common/xdgen.c becomes plugin/core/gvrender_core_dot.c

Put common code in core plugins into: plugin/core/gvrender_core.c

27 files changed:
lib/common/Makefile.am
lib/common/Makefile.old
lib/common/arrows.c
lib/common/const.h
lib/common/emit.c
lib/common/htmltable.c
lib/common/htmltable.h
lib/common/labels.c
lib/common/output.c
lib/common/render.h
lib/common/shapes.c
lib/common/xdgen.c [deleted file]
lib/gvc/gvc.c
lib/gvc/gvcint.h
lib/gvc/gvcjob.h
lib/gvc/gvconfig.c
lib/gvc/gvjobs.c
plugin/core/Makefile.am
plugin/core/gvloadimage_core.c
plugin/core/gvplugin_core.c
plugin/core/gvrender_core.c [new file with mode: 0644]
plugin/core/gvrender_core_dot.c [new file with mode: 0644]
plugin/core/gvrender_core_fig.c
plugin/core/gvrender_core_map.c
plugin/core/gvrender_core_ps.c
plugin/core/gvrender_core_svg.c
tclpkg/tcldot/tcldot.c

index c46bbeee513ad4787848f2e3f843c00464255ed3..f0d41eb51c1fc04321027b1f3ffc8534dbd68685 100644 (file)
@@ -17,7 +17,7 @@ noinst_HEADERS = render.h utils.h memory.h \
 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
 
 
index 8b2a99be050610ce4ae9f032d12fa1f23b87150c..7e0439bba62ac431abcad15bb82e7c3fd014b4ec 100644 (file)
@@ -24,8 +24,7 @@ NOINST_HDRS = render.h utils.h memory.h \
 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 \
index 8d3a00a6f673a9d5b9dccd178b3ddada17f0c314..04c89a70a6dded4355fb68ed30f8e86310efaa74 100644 (file)
@@ -512,14 +512,15 @@ boxf arrow_bb(pointf p, pointf u, double scale, int flag)
     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 */
@@ -547,15 +548,15 @@ void arrow_newgen(GVJ_t * job, int state, pointf p, pointf u, double scale, int
 
     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);
 }
index 347c014bc2318fe485d7fab58f4d197ea181f856..c0cb40b10029712b2f068196eda9e91571dd6e5c 100644 (file)
 #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
index 04c26e14b9dfba6632267d55043f9e4678b3cee3..c02659b5a107596b49177c7d84a1f265880c4d56 100644 (file)
@@ -496,10 +496,6 @@ static void init_job_flags(GVJ_t * job, graph_t * g)
         /* 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;
@@ -622,8 +618,14 @@ static void init_job_pagination(GVJ_t * job, graph_t *g)
     }
 
     /* 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) {
@@ -958,9 +960,7 @@ static void emit_begin_node(GVJ_t * job, node_t * n)
     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);
@@ -1119,7 +1119,6 @@ static void emit_end_node(GVJ_t * job)
 #ifdef WITH_CODEGENS
     Obj = NONE;
 #endif
-    job->gvc->emit_state = job->obj->oldstate;
     pop_obj_state(job);
 }
 
@@ -1484,14 +1483,14 @@ void emit_edge_graphics(GVJ_t * job, edge_t * e)
        }
     }
     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);
@@ -1526,9 +1525,7 @@ static void emit_begin_edge(GVJ_t * job, edge_t * e)
     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);
@@ -1711,7 +1708,6 @@ static void emit_end_edge(GVJ_t * job)
 #ifdef WITH_CODEGENS
     Obj = NONE;
 #endif
-    job->gvc->emit_state = job->obj->oldstate;
     pop_obj_state(job);
 }
 
@@ -1815,13 +1811,9 @@ static void init_job_margin(GVJ_t *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;
@@ -1994,7 +1986,7 @@ void emit_view(GVJ_t * job, graph_t * g, int flags)
 
     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);
@@ -2062,9 +2054,7 @@ static void emit_begin_graph(GVJ_t * job, graph_t * g)
     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)
@@ -2101,7 +2091,6 @@ static void emit_end_graph(GVJ_t * job, graph_t * g)
 #ifdef WITH_CODEGENS
     Obj = NONE;
 #endif
-    job->gvc->emit_state = job->obj->oldstate;
     pop_obj_state(job);
 }
 
@@ -2229,9 +2218,7 @@ static void emit_begin_cluster(GVJ_t * job, Agraph_t * sg)
     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)
@@ -2289,7 +2276,6 @@ static void emit_end_cluster(GVJ_t * job, Agraph_t * g)
 #ifdef WITH_CODEGENS
     Obj = NONE;
 #endif
-    job->gvc->emit_state = job->obj->oldstate;
     pop_obj_state(job);
 }
 
@@ -2382,7 +2368,7 @@ void emit_clusters(GVJ_t * job, Agraph_t * g, int flags)
            }
        }
        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)) {
@@ -2547,27 +2533,8 @@ static void emit_job(GVJ_t * job, graph_t * g)
 
     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)
index aa62a0f5318d4788a052ef4d1c75594d1d5a1a68..3a0db576ac9fe2b40ba34ff4865251392752baec 100644 (file)
@@ -99,48 +99,6 @@ static void popFontInfo(htmlenv_t * env, htmlfont_t * savp)
        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)
@@ -224,7 +182,7 @@ emit_htextparas(GVJ_t* job, int nparas, htextpara_t* paras, pointf p,
 }
 
 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;
@@ -311,7 +269,7 @@ static void doFill(GVJ_t * job, char *color, box B)
     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);
 }
@@ -322,11 +280,10 @@ static void doAnchorEnd(GVJ_t * job)
 }
 
 /* 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;
@@ -344,13 +301,13 @@ emit_html_tbl(GVJ_t * job, htmltbl_t * tbl, htmlenv_t * env, void *obj)
     /* 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++;
     }
 
@@ -366,7 +323,7 @@ emit_html_tbl(GVJ_t * job, htmltbl_t * tbl, htmlenv_t * env, void *obj)
 }
 
 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;
@@ -387,7 +344,7 @@ emit_html_img(GVJ_t * job, htmlimg_t * cp, htmlenv_t * env, void *obj)
 }
 
 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;
@@ -400,17 +357,17 @@ emit_html_cell(GVJ_t * job, htmlcell_t * cp, htmlenv_t * env, void *obj)
     /* 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);
@@ -424,7 +381,7 @@ emit_html_cell(GVJ_t * job, htmlcell_t * cp, htmlenv_t * env, void *obj)
 /* 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;
 
@@ -443,10 +400,10 @@ emit_html_label(GVJ_t * job, htmllabel_t * lp, textlabel_t * tp, void *obj)
            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);
     }
 }
 
@@ -471,25 +428,6 @@ void free_html_data(htmldata_t * dp)
     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;
@@ -694,62 +632,6 @@ int html_path(node_t * n, port* p, int side, box * rv, int *k)
     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)
 {
@@ -1592,22 +1474,6 @@ void printImage(htmlimg_t *ip, int ind)
     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;
index cad000674357b7b2c5b83dd48f96ad2a05d68c41..476599beb17ba2cf54ca9dde58e3537c047a853e 100644 (file)
@@ -171,8 +171,7 @@ extern "C" {
     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 *);
index 25ef8b037be182e303cf50e89afd9b4917dc2686..b522c6cc55e78bef2714202c6c2537c037650557 100644 (file)
@@ -216,17 +216,18 @@ emit_textparas(GVJ_t* job, int nparas, textpara_t paras[], pointf p,
     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;
     }
 
@@ -242,7 +243,8 @@ void emit_label(GVJ_t * job, int state, textlabel_t * lp, void *obj)
 
     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;
 }
 
 
index 5332bae7dd3e56568e5bf35676f343e8fec7d762..c85c492876d54f8ae4ee1bd703e621f60bf3a9e1 100644 (file)
@@ -19,6 +19,8 @@
 
 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)
 {
@@ -58,7 +60,7 @@ static void writenodeandport(FILE * fp, node_t * node, char *port)
 
 /* _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;
@@ -127,39 +129,6 @@ static void _write_plain(GVJ_t * job, graph_t * g, FILE * f, bool extend)
     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;
@@ -329,3 +298,147 @@ void attach_attrs(graph_t * g)
     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]));
+}
index ec6772d8d040b864e1a2acc4a7d7efb71235ae36..104443e2320c6880365220238bc981ee73fd9b02 100644 (file)
@@ -66,7 +66,7 @@ extern "C" {
     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);
@@ -97,7 +97,7 @@ extern "C" {
     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,
@@ -106,7 +106,6 @@ extern "C" {
     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 *);
@@ -152,8 +151,7 @@ extern "C" {
     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__
index 744ed3bfef22f8bd46a2d80abcd0423d68888318..bbcc8c22708148502fe65040d5563404eb65b215 100644 (file)
@@ -1311,7 +1311,7 @@ static void poly_gencode(GVJ_t * job, node_t * n)
        filled = FALSE;
     }
 
-    emit_label(job, EMIT_NLABEL, ND_label(n), (void *) n);
+    emit_label(job, EMIT_NLABEL, ND_label(n));
 }
 
 /*=======================end poly======================================*/
@@ -1841,7 +1841,7 @@ static void gen_fields(GVJ_t * job, node_t * n, field_t * f)
        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++) {
@@ -1981,5 +1981,5 @@ static void epsf_gencode(GVJ_t * job, node_t * n)
                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));
 }
diff --git a/lib/common/xdgen.c b/lib/common/xdgen.c
deleted file mode 100644 (file)
index 3ccbc07..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-/* $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 */
-};
index d0cac5361713cd46c9a41688f9c5989665f2e8a1..ee758a3d82a65fe0f1e22b70959dc229e37907fa 100644 (file)
@@ -101,7 +101,7 @@ int gvRender(GVC_t *gvc, graph_t *g, char *format, FILE *out)
     }
 
     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;
     }
@@ -131,7 +131,7 @@ int gvRenderFilename(GVC_t *gvc, graph_t *g, char *format, char *filename)
     }
 
     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;
     }
index fcdf99837ebdf9a29169ee32745a611305968592..68ef8bad94ea81418f8d353b0639c994e936ab71 100644 (file)
@@ -98,7 +98,6 @@ extern "C" {
        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() */
index d9cb9c859effd467c3d015c2e49cc8870f912e9f..966b977bebb965369656b1eec24f70b407740fb0 100644 (file)
@@ -62,6 +62,7 @@ extern "C" {
 #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;
@@ -128,6 +129,36 @@ extern "C" {
     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 {
@@ -141,7 +172,7 @@ extern "C" {
            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;
@@ -196,6 +227,7 @@ extern "C" {
        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.
@@ -222,6 +254,8 @@ extern "C" {
        FILE *output_file;
        int output_lang;
 
+       compression_t compression;
+
        gvplugin_active_render_t render;
        gvplugin_active_device_t device;
        gvplugin_active_loadimage_t loadimage;
index 2f05ae75018a329d073012036036ec4175fd678a..2845984ad2e019a369d02a86a0ecdcf223b6a9c7 100644 (file)
@@ -46,8 +46,7 @@ extern const bool Demand_Loading;
 
     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
 
 /*
@@ -374,12 +373,6 @@ static codegen_info_t cg[MAX_CODEGENS] = {
 #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}
 };
 
index e0f872fdcf6f6596d862533231b18b7d273de6c1..5d19bdff2a9671e751aecb5b0d3abca15b8ef8c6 100644 (file)
@@ -50,15 +50,13 @@ static GVJ_t *output_langname_job;
 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;
        }
@@ -71,15 +69,13 @@ void gvjobs_output_filename(GVC_t * gvc, char *name)
 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;
        }
index ad125fb3305d1aa09f6cbea4f03fc44008eb43f1..27ac0b06484422877081210cde26e7e641cb5052 100644 (file)
@@ -16,9 +16,11 @@ pkglib_LTLIBRARIES = libgvplugin_core.la
 
 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
 
index 0b8ced661660aa4cd5254d0f8a16dd86db1d7dd6..f49a8e19524bc0189f7f19d72ec24f4020114529 100644 (file)
@@ -36,9 +36,8 @@
 /* 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);
@@ -57,19 +56,19 @@ static void core_loadimage_svg(GVJ_t * job, usershape_t *us, boxf b, bool filled
     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)
@@ -101,13 +100,12 @@ static void core_loadimage_fig(GVJ_t * job, usershape_t *us, boxf bf, bool fille
 
     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,
index 3a548fa5c9b65353655e120fa85b92d4fceaff19..f5ee99c9932f28b4bf3037c6065f03eec85c0e0a 100644 (file)
@@ -16,6 +16,7 @@
 
 #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;
@@ -23,6 +24,7 @@ extern gvplugin_installed_t gvrender_core_map_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},
diff --git a/plugin/core/gvrender_core.c b/plugin/core/gvrender_core.c
new file mode 100644 (file)
index 0000000..2494ab8
--- /dev/null
@@ -0,0 +1,126 @@
+/* $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);
+}
diff --git a/plugin/core/gvrender_core_dot.c b/plugin/core/gvrender_core_dot.c
new file mode 100644 (file)
index 0000000..82c2cc4
--- /dev/null
@@ -0,0 +1,313 @@
+/* $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}
+};
index e5cd635ba98d07143c4a6e67917684a39a9cba1f..4cd89c8407d562dd2026e57a3a59a637efa856f9 100644 (file)
@@ -25,6 +25,7 @@
 
 #ifdef WIN32
 #include <io.h>
+#include "compat.h"
 #endif
 
 #include "macros.h"
@@ -43,36 +44,8 @@ typedef enum { FORMAT_FIG, } format_type;
 
 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)
 {
@@ -81,13 +54,13 @@ 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)
@@ -166,7 +139,7 @@ static char *figcolor[] = {
     "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;
@@ -186,7 +159,7 @@ static void figgen_resolve_color(GVJ_t *job, gvcolor_t * color)
                        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],
@@ -200,7 +173,7 @@ static void figgen_resolve_color(GVJ_t *job, gvcolor_t * color)
     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: 
@@ -219,63 +192,63 @@ static void figgen_line_style(obj_state_t *obj, int *line_style, double *style_v
     }
 }
 
-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;
 
@@ -307,14 +280,14 @@ static void figgen_textpara(GVJ_t * job, pointf p, textpara_t * para)
         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;
 
@@ -333,7 +306,7 @@ static void figgen_ellipse(GVJ_t * job, pointf * A, int filled)
     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);
@@ -342,7 +315,7 @@ static void figgen_ellipse(GVJ_t * job, pointf * A, int filled)
     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,
@@ -350,7 +323,7 @@ static void figgen_ellipse(GVJ_t * job, pointf * A, int filled)
             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;
@@ -384,7 +357,7 @@ static void figgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
                                 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 */
@@ -419,7 +392,7 @@ static void figgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
         }
     }
 
-    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,
@@ -431,15 +404,15 @@ static void figgen_bezier(GVJ_t * job, pointf * A, int n, int arrow_at_start,
             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;
 
@@ -460,9 +433,9 @@ static void figgen_polygon(GVJ_t * job, pointf * A, int n, int filled)
     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,
@@ -470,7 +443,7 @@ static void figgen_polygon(GVJ_t * job, pointf * A, int n, int filled)
     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;
 
@@ -491,9 +464,9 @@ static void figgen_polyline(GVJ_t * job, pointf * A, int n)
     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,
@@ -501,44 +474,44 @@ static void figgen_polyline(GVJ_t * job, pointf * A, int n)
     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 */
@@ -547,16 +520,16 @@ gvrender_features_t figgen_features = {
          * 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}
 };
index 37942d60eede2e4c45156aca61798c5c694a1ea4..e9d2769b8df0023eeda34344916f8022459a2103 100644 (file)
 #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;
@@ -50,18 +51,18 @@ static void map_output_shape (GVJ_t *job, map_shape_t map_shape, pointf * AF, in
         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);
@@ -72,7 +73,7 @@ static void map_output_shape (GVJ_t *job, map_shape_t map_shape, pointf * AF, in
         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:
@@ -83,24 +84,31 @@ static void map_output_shape (GVJ_t *job, map_shape_t map_shape, pointf * AF, in
     } 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.
@@ -111,49 +119,62 @@ static void map_output_shape (GVJ_t *job, map_shape_t map_shape, pointf * AF, in
         * 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;
@@ -172,7 +193,7 @@ static void map_end_page(GVJ_t * job)
     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;
@@ -183,7 +204,7 @@ static void map_begin_cluster(GVJ_t * job)
 {
     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);
index a64e97db6e5916b0ccb1e5648cb141cb927825ea..9c0dabed32f5bca6c6c3b35b8f4e738c233a71e6 100644 (file)
 
 #ifdef HAVE_LIBZ
 #include <zlib.h>
+#endif
+
 #ifdef WIN32
 #include <io.h>
-#endif
+#include "compat.h"
 #endif
 
 #include "gvplugin_render.h"
index fd746144606eeba05e2db4f0a9050cf384b3e786..f23ee57dd5a13eafe09be05d48e214868b64f3ed 100644 (file)
 #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
@@ -104,17 +56,17 @@ static void svggen_bzptarray(GVJ_t * job, pointf * A, int n)
     }
 }
 
-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:
@@ -122,336 +74,297 @@ static void svggen_print_color(GVJ_t * job, gvcolor_t color)
     }
 }
 
-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 = "&#45;&gt;";
     else
        edgeop = "&#45;&#45;";
-    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",
@@ -494,37 +407,37 @@ static char *svggen_knowncolors[] = {
     "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
@@ -534,17 +447,17 @@ gvrender_features_t svggen_features = {
        | 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}
 };
index 78fadd0417fb01bb2527643813b3199e0c77f688..6c1e77f010b7194081204739e5a12ac9d231e1df 100644 (file)
@@ -606,9 +606,9 @@ static void tcldot_layout(GVC_t *gvc, Agraph_t * g, char *engine)
 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
     )
 {
 
@@ -621,6 +621,7 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
     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 \"",
@@ -1089,10 +1090,10 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
                                      (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;
@@ -1121,14 +1122,14 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
                                      (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;
@@ -1260,20 +1261,18 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp,
                "\". 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);
        }