From: ellson Date: Tue, 12 Jul 2005 23:26:14 +0000 (+0000) Subject: Factor out common Agraphinfo_t init code from layoutengines into X-Git-Tag: LAST_LIBGRAPH~32^2~7467 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0e7f6b4127a959228144b2f4179e0f9b71a2e73f;p=graphviz Factor out common Agraphinfo_t init code from layoutengines into common wrapper for layout plugins. All this so that I can add a GVC_t* to Agraphinfo_t instead of passing it down as a parameter through multiple levels of code. Need access to GVC_t* for usershape plugin and dictionary state. --- diff --git a/cmd/tools/gvpack.c b/cmd/tools/gvpack.c index 34e984757..eca462738 100644 --- a/cmd/tools/gvpack.c +++ b/cmd/tools/gvpack.c @@ -245,7 +245,7 @@ static void init_graph(Agraph_t * g, boolean fill) { int d; - graph_init(g); + graph_init(g, FALSE); d = late_int(g, agfindattr(g, "dim"), 2, 2); if (d != 2) { fprintf(stderr, "Error: graph %s has dim = %d (!= 2)\n", g->name, @@ -670,7 +670,6 @@ static Agraph_t **readGraphs(int *cp) /* set various state values */ PSinputscale = POINTS_PER_INCH; - UseRankdir = FALSE; Nop = 2; State = GVSPLINES; diff --git a/lib/circogen/circularinit.c b/lib/circogen/circularinit.c index d4acedb80..8d6781e0f 100644 --- a/lib/circogen/circularinit.c +++ b/lib/circogen/circularinit.c @@ -82,9 +82,6 @@ static void circular_init_node_edge(graph_t * g) void circo_init_graph(graph_t * g) { - UseRankdir = FALSE; - graph_init(g); - GD_drawing(g)->engine = CIRCULAR; /* GD_ndim(g) = late_int(g,agfindattr(g,"dim"),2,2); */ Ndim = GD_ndim(g) = 2; /* The algorithm only makes sense in 2D */ circular_init_node_edge(g); @@ -335,14 +332,6 @@ static void circular_cleanup_edge(edge_t * e) memset(&(e->u), 0, sizeof(Agedgeinfo_t)); } -static void circular_cleanup_graph(graph_t * g) -{ - free(GD_neato_nlist(g)); - free_ugraph(g); - free_label(GD_label(g)); - memset(&(g->u), 0, sizeof(Agraphinfo_t)); -} - void circo_cleanup(graph_t * g) { node_t *n; @@ -360,5 +349,5 @@ void circo_cleanup(graph_t * g) } circular_cleanup_node(n); } - circular_cleanup_graph(g); + free(GD_neato_nlist(g)); } diff --git a/lib/common/globals.h b/lib/common/globals.h index 8d0aedc5b..4bdd38643 100644 --- a/lib/common/globals.h +++ b/lib/common/globals.h @@ -64,7 +64,7 @@ extern "C" { EXTERN int Obj; #endif - EXTERN boolean Verbose, Reduce, UseRankdir, MemTest; + EXTERN boolean Verbose, Reduce, MemTest; EXTERN char *HTTPServerEnVar; EXTERN char *Output_file_name; EXTERN int graphviz_errors; diff --git a/lib/common/input.c b/lib/common/input.c index 356009996..dcfcea418 100644 --- a/lib/common/input.c +++ b/lib/common/input.c @@ -458,7 +458,7 @@ static void setRatio(graph_t * g) } } -static void init_ugraph(graph_t * g) +void graph_init(graph_t * g, boolean use_rankdir) { char *p; double xf; @@ -493,7 +493,7 @@ static void init_ugraph(graph_t * g) * The result is confused output, so we turn it off unless requested. */ GD_rankdir(g) = RANKDIR_TB; - if (UseRankdir && (p = agget(g, "rankdir"))) { + if (use_rankdir && (p = agget(g, "rankdir"))) { if (streq(p, "LR")) GD_rankdir(g) = RANKDIR_LR; else if (streq(p, "BT")) @@ -556,19 +556,6 @@ static void init_ugraph(graph_t * g) Nodesep = 1.0; Nodefactor = 1.0; Initial_dist = MYHUGE; -} - -void free_ugraph(graph_t * g) -{ - free(GD_drawing(g)); - GD_drawing(g) = NULL; -} - - -void graph_init(graph_t * g) -{ - /* initialize the graph */ - init_ugraph(g); /* initialize nodes */ N_height = agfindattr(g->proto->n, "height"); @@ -628,6 +615,14 @@ void graph_init(graph_t * g) E_headclip = agfindattr(g->proto->e, "headclip"); } +void graph_cleanup(graph_t *g) +{ + free(GD_drawing(g)); + GD_drawing(g) = NULL; + free_label(GD_label(g)); + memset(&(g->u), 0, sizeof(Agraphinfo_t)); +} + /* charsetToStr: * Given an internal charset value, return a canonical string * representation. diff --git a/lib/common/renderprocs.h b/lib/common/renderprocs.h index b3b488b5a..0191241f1 100644 --- a/lib/common/renderprocs.h +++ b/lib/common/renderprocs.h @@ -67,7 +67,8 @@ extern "C" { extern Agnode_t *dequeue(nodequeue *); extern void do_graph_label(graph_t * sg); extern point dotneato_closest(splines * spl, point p); - extern void graph_init(graph_t * g); + extern void graph_init(graph_t * g, boolean use_rankdir); + extern void graph_cleanup(graph_t * g); extern void dotneato_initialize(GVC_t * gvc, int, char **); extern void dotneato_usage(int); extern void dotneato_postprocess(Agraph_t *, nodesizefn_t); @@ -101,7 +102,6 @@ extern "C" { extern void free_line(textline_t *); extern void free_label(textlabel_t *); extern void free_queue(nodequeue *); - extern void free_ugraph(graph_t *); extern char *gd_alternate_fontlist(char *font); extern char *gd_textsize(textline_t * textline, char *fontname, double fontsz, char **fontpath); diff --git a/lib/common/types.h b/lib/common/types.h index c8c733b70..72c2e58c6 100644 --- a/lib/common/types.h +++ b/lib/common/types.h @@ -278,7 +278,6 @@ extern "C" { adjmatrix_t *flat; } rank_t; - typedef enum engine_e { DOT, NEATO, TWOPI, FDP, CIRCULAR } engine_t; typedef enum { R_NONE = 0, R_VALUE, R_FILL, R_COMPRESS, R_AUTO, R_EXPAND } ratio_t; @@ -289,7 +288,6 @@ extern "C" { point margin, page, size; boolean filled, landscape, centered; ratio_t ratio_kind; - engine_t engine; } layout_t; /* for "record" shapes */ @@ -354,6 +352,7 @@ extern "C" { int ht1, ht2; /* below and above extremal ranks */ unsigned short flags; void *alg; + GVC_t *gvc; /* context for "globals" over multiple graphs */ #ifndef DOT_ONLY /* to place nodes */ diff --git a/lib/dotgen/dotinit.c b/lib/dotgen/dotinit.c index 7c95a7b31..3b37e403a 100644 --- a/lib/dotgen/dotinit.c +++ b/lib/dotgen/dotinit.c @@ -186,9 +186,6 @@ dot_cleanup_graph(graph_t * g) free(GD_rank(g)[i].v); free(GD_rank(g)); } - free_ugraph(g); - free_label(GD_label(g)); - memset(&(g->u), 0, sizeof(Agraphinfo_t)); } /* delete the layout (but retain the underlying graph) */ @@ -207,15 +204,6 @@ void dot_cleanup(graph_t * g) dot_cleanup_graph(g); } -void -dot_init_graph(Agraph_t * g) -{ - UseRankdir = TRUE; - graph_init(g); - GD_drawing(g)->engine = DOT; - dot_init_node_edge(g); -} - #ifdef DEBUG int fastn (graph_t * g) @@ -252,7 +240,7 @@ dumpRanks (graph_t * g) void dot_layout(Agraph_t * g) { - dot_init_graph(g); + dot_init_node_edge(g); dot_rank(g); dot_mincross(g); /* dumpRanks (g); */ diff --git a/lib/dotgen/dotprocs.h b/lib/dotgen/dotprocs.h index 3c9834f57..7ca1bdaf7 100644 --- a/lib/dotgen/dotprocs.h +++ b/lib/dotgen/dotprocs.h @@ -36,8 +36,8 @@ extern "C" { extern void delete_fast_node(Agraph_t *, Agnode_t *); extern void delete_flat_edge(Agedge_t *); extern void dot_cleanup(graph_t * g); - extern void dot_init_graph(Agraph_t * g); extern void dot_layout(Agraph_t * g); + extern void dot_init_node_edge(graph_t * g); extern void expand_cluster(Agraph_t *); extern Agedge_t *fast_edge(Agedge_t *); extern void fast_node(Agraph_t *, Agnode_t *); diff --git a/lib/dotgen/dotsplines.c b/lib/dotgen/dotsplines.c index 38ca06b64..ee8d6c8d5 100644 --- a/lib/dotgen/dotsplines.c +++ b/lib/dotgen/dotsplines.c @@ -21,8 +21,6 @@ #include "dot.h" -extern void dot_init_node_edge(graph_t * g); - #define NSUB 9 /* number of subdivisions, re-aiming splines */ #define CHUNK 128 /* in building list of edges */ @@ -616,9 +614,6 @@ static struct { * graph's settings for certain geometry parameters, and * declares all node and edge attributes used in the original * graph. - * NOTE: We do not call dot_init_graph, to avoid the call to - * graph_init and init_ugraph. Just the necessary pieces of the - * latter are handled here. */ static graph_t* cloneGraph (graph_t* g) @@ -629,7 +624,6 @@ cloneGraph (graph_t* g) agraphattr(auxg, "rank", ""); GD_drawing(auxg) = NEW(layout_t); - GD_drawing(auxg)->engine = DOT; GD_drawing(auxg)->quantum = GD_drawing(g)->quantum; GD_drawing(auxg)->dpi = GD_drawing(g)->dpi; diff --git a/lib/fdpgen/fdpinit.c b/lib/fdpgen/fdpinit.c index 4090ac5af..b14a39a5f 100644 --- a/lib/fdpgen/fdpinit.c +++ b/lib/fdpgen/fdpinit.c @@ -177,9 +177,6 @@ static void fdp_cleanup_graph(graph_t * g) cleanup_subgs(g); free(GD_neato_nlist(g)); free(GD_alg(g)); - free_ugraph(g); - free_label(GD_label(g)); - memset(&(g->u), 0, sizeof(Agraphinfo_t)); } void fdp_cleanup(graph_t * g) diff --git a/lib/fdpgen/layout.c b/lib/fdpgen/layout.c index 03e70ef5f..c055ad5bf 100644 --- a/lib/fdpgen/layout.c +++ b/lib/fdpgen/layout.c @@ -1032,11 +1032,7 @@ mkClusters (graph_t * g, clist_t* pclist, graph_t* parent) void fdp_init_graph(Agraph_t * g) { - UseRankdir = FALSE; - - graph_init(g); GD_alg(g) = (void *) NEW(gdata); /* freed in cleanup_graph */ - /* GD_drawing(g)->engine = FDP; */ g->u.ndim = late_int(g, agfindattr(g, "dim"), 2, 2); Ndim = g->u.ndim = MIN(g->u.ndim, MAXDIM); diff --git a/lib/gvc/gvcint.h b/lib/gvc/gvcint.h index a60f9ed79..9c79fe2bd 100644 --- a/lib/gvc/gvcint.h +++ b/lib/gvc/gvcint.h @@ -72,6 +72,12 @@ extern "C" { int flags; } gvdevice_features_t; +#define LAYOUT_USES_RANKDIR (1<<0) + + typedef struct { + int flags; + } gvlayout_features_t; + /* active plugin headers */ typedef struct gvplugin_active_device_s { gvdevice_engine_t *engine; @@ -82,6 +88,7 @@ extern "C" { typedef struct gvplugin_active_layout_s { gvlayout_engine_t *engine; int id; + gvlayout_features_t *features; char *type; } gvplugin_active_layout_t; diff --git a/lib/gvc/gvlayout.c b/lib/gvc/gvlayout.c index 0636c3f7a..ab4ce5bcc 100644 --- a/lib/gvc/gvlayout.c +++ b/lib/gvc/gvlayout.c @@ -28,10 +28,15 @@ #include "const.h" #include "types.h" #include "macros.h" +#include "graph.h" +#include "cdt.h" #include "gvplugin_layout.h" #include "gvc.h" +extern void graph_init(graph_t *g, boolean use_rankdir); +extern void graph_cleanup(graph_t *g); + int gvlayout_select(GVC_t * gvc, char *layout) { gvplugin_available_t *plugin; @@ -43,7 +48,8 @@ int gvlayout_select(GVC_t * gvc, char *layout) gvc->layout.type = typeptr->type; gvc->layout.engine = (gvlayout_engine_t *) (typeptr->engine); gvc->layout.id = typeptr->id; - return GVRENDER_PLUGIN; + gvc->layout.features = (gvlayout_features_t *) (typeptr->features); + return GVRENDER_PLUGIN; /* FIXME - need better return code */ } return NO_SUPPORT; } @@ -52,6 +58,9 @@ void gvlayout_layout(GVC_t * gvc, graph_t * g) { gvlayout_engine_t *gvle = gvc->layout.engine; + graph_init(g, gvc->layout.features->flags & LAYOUT_USES_RANKDIR); + g->u.gvc = gvc; + if (gvle && gvle->layout) gvle->layout(g); } @@ -62,4 +71,6 @@ void gvlayout_cleanup(GVC_t * gvc, graph_t * g) if (gvle && gvle->cleanup) gvle->cleanup(g); + + graph_cleanup(g); } diff --git a/lib/neatogen/neatoinit.c b/lib/neatogen/neatoinit.c index 0661e0bce..c3ce0df6a 100644 --- a/lib/neatogen/neatoinit.c +++ b/lib/neatogen/neatoinit.c @@ -174,9 +174,6 @@ void neato_cleanup_graph(graph_t * g) { if (Nop || (Pack < 0)) free_scan_graph(g); - free_ugraph(g); - free_label(GD_label(g)); - memset(&(g->u), 0, sizeof(Agraphinfo_t)); } void neato_cleanup(graph_t * g) @@ -587,9 +584,6 @@ int init_nop(Agraph_t * g) void neato_init_graphn(Agraph_t * g, int dfltdim) { - UseRankdir = FALSE; - graph_init(g); - GD_drawing(g)->engine = NEATO; GD_ndim(g) = late_int(g, agfindattr(g, "dim"), dfltdim, 2); Ndim = GD_ndim(g) = MIN(GD_ndim(g), MAXDIM); neato_init_node_edge(g); diff --git a/lib/twopigen/twopiinit.c b/lib/twopigen/twopiinit.c index f6f38f1c6..a037b30c5 100644 --- a/lib/twopigen/twopiinit.c +++ b/lib/twopigen/twopiinit.c @@ -71,9 +71,6 @@ static void twopi_init_node_edge(graph_t * g) void twopi_init_graph(graph_t * g) { - UseRankdir = FALSE; - graph_init(g); - GD_drawing(g)->engine = TWOPI; /* GD_ndim(g) = late_int(g,agfindattr(g,"dim"),2,2); */ Ndim = GD_ndim(g) = 2; /* The algorithm only makes sense in 2D */ twopi_init_node_edge(g); @@ -168,9 +165,6 @@ static void twopi_cleanup_edge(edge_t * e) static void twopi_cleanup_graph(graph_t * g) { free(GD_neato_nlist(g)); - free_ugraph(g); - free_label(GD_label(g)); - memset(&(g->u), 0, sizeof(Agraphinfo_t)); } void twopi_cleanup(graph_t * g)