From 5ddb8e3865114d305db45823cf404adc9a202e9c Mon Sep 17 00:00:00 2001 From: erg Date: Fri, 29 Jul 2005 22:59:35 +0000 Subject: [PATCH] Simplify dotneato_postprocess interface; remove unnecessary nodesize functions for circo and twopi; initialize layout state in graph_init so that it will be initialized anew for each layout; move aspect ratio and copying of coords from ND_pos to ND_coord out of neato spline code; adopt convention that if the splines attribute is set to "", no splines are generated. --- lib/circogen/circularinit.c | 16 ++--------- lib/common/input.c | 1 + lib/common/postproc.c | 38 +++++++++++++++++++++---- lib/common/renderprocs.h | 2 +- lib/dotgen/dotinit.c | 22 +-------------- lib/dotgen/dotsplines.c | 9 +++++- lib/fdpgen/layout.c | 25 +++++++++++------ lib/neatogen/neatoinit.c | 2 +- lib/neatogen/neatosplines.c | 55 +++++++++++++++++++++++++------------ 9 files changed, 101 insertions(+), 69 deletions(-) diff --git a/lib/circogen/circularinit.c b/lib/circogen/circularinit.c index 8d6781e0f..b9b91d3e1 100644 --- a/lib/circogen/circularinit.c +++ b/lib/circogen/circularinit.c @@ -32,23 +32,13 @@ #include "adjust.h" #include "pack.h" #include "neatoprocs.h" -#include - -void circo_nodesize(node_t * n, boolean flip) -{ - int w; - - w = ND_xsize(n) = POINTS(ND_width(n)); - ND_lw_i(n) = ND_rw_i(n) = w / 2; - ND_ht_i(n) = ND_ysize(n) = POINTS(ND_height(n)); -} - +#include static void circular_init_node(node_t * n) { common_init_node(n); - circo_nodesize(n, GD_flip(n->graph)); + neato_nodesize(n, GD_flip(n->graph)); ND_pos(n) = N_NEW(GD_ndim(n->graph), double); ND_alg(n) = NEW(ndata); } @@ -300,7 +290,7 @@ void circo_layout(Agraph_t * g) circo_init_graph(g); circoLayout(g); spline_edges(g); - dotneato_postprocess(g, circo_nodesize); + dotneato_postprocess(g); } static void circular_cleanup_node(node_t * n) diff --git a/lib/common/input.c b/lib/common/input.c index 2eb9bf83e..abfa4b62f 100644 --- a/lib/common/input.c +++ b/lib/common/input.c @@ -558,6 +558,7 @@ void graph_init(graph_t * g, boolean use_rankdir) CL_type = maptoken(p, rankname, rankcode); p = agget(g, "concentrate"); Concentrate = mapbool(p); + State = GVBEGIN; GD_drawing(g)->dpi = 0.0; if (((p = agget(g, "dpi")) && p[0]) diff --git a/lib/common/postproc.c b/lib/common/postproc.c index c247d804d..4154081de 100644 --- a/lib/common/postproc.c +++ b/lib/common/postproc.c @@ -139,18 +139,44 @@ void translate_bb(graph_t * g, int rankdir) translate_bb(GD_clust(g)[c], rankdir); } -static void translate_drawing(graph_t * g, nodesizefn_t ns) +void dot_nodesize(node_t * n, boolean flip) +{ + double x, y; + int ps; + + if (flip == FALSE) { + x = ND_width(n); + y = ND_height(n); + } else { + y = ND_width(n); + x = ND_height(n); + } + ps = POINTS(x) / 2; + if (ps < 1) + ps = 1; + ND_lw_i(n) = ND_rw_i(n) = ps; + ND_ht_i(n) = POINTS(y); +} + +/* translate_drawing: + * Translate and/or rotate nodes, spline points, and bbox info if + * Offset is non-trivial. + * Also, if Rankdir, reset ND_lw, ND_rw, and ND_ht to correct value. + */ +static void translate_drawing(graph_t * g) { node_t *v; edge_t *e; int shift = (Offset.x || Offset.y); + if (!shift && !Rankdir) return; for (v = agfstnode(g); v; v = agnxtnode(g, v)) { - ns(v, FALSE); + if (Rankdir) dot_nodesize(v, FALSE); if (shift) { ND_coord_i(v) = map_point(ND_coord_i(v)); - for (e = agfstout(g, v); e; e = agnxtout(g, e)) - map_edge(e); + if (State == GVSPLINES) + for (e = agfstout(g, v); e; e = agnxtout(g, e)) + map_edge(e); } } if (shift) @@ -192,7 +218,7 @@ static void place_root_label(graph_t * g, point d) * Assumes the boxes of all clusters have been computed. * When done, the bounding box of g has LL at origin. */ -void dotneato_postprocess(Agraph_t * g, nodesizefn_t ns) +void dotneato_postprocess(Agraph_t * g) { int diff; pointf dimen; @@ -251,7 +277,7 @@ void dotneato_postprocess(Agraph_t * g, nodesizefn_t ns) Offset = pointof(GD_bb(g).LL.y, GD_bb(g).LL.x); break; } - translate_drawing(g, ns); + translate_drawing(g); if (GD_label(g) && !GD_label(g)->set) place_root_label(g, d); diff --git a/lib/common/renderprocs.h b/lib/common/renderprocs.h index 89ac24a1d..e17c9933a 100644 --- a/lib/common/renderprocs.h +++ b/lib/common/renderprocs.h @@ -50,7 +50,7 @@ extern "C" { extern void graph_cleanup(graph_t * g); extern void dotneato_args_initialize(GVC_t * gvc, int, char **); extern void dotneato_usage(int); - extern void dotneato_postprocess(Agraph_t *, nodesizefn_t); + extern void dotneato_postprocess(Agraph_t *); extern void dotneato_set_margins(GVC_t * gvc, Agraph_t *); extern void dotneato_write(GVC_t * gvc, graph_t *g); extern void dotneato_write_one(GVC_t * gvc, graph_t *g); diff --git a/lib/dotgen/dotinit.c b/lib/dotgen/dotinit.c index 3b37e403a..8b6c64d46 100644 --- a/lib/dotgen/dotinit.c +++ b/lib/dotgen/dotinit.c @@ -17,26 +17,6 @@ #include "dot.h" - -void dot_nodesize(node_t * n, boolean flip) -{ - double x, y; - int ps; - - if (flip == FALSE) { - x = ND_width(n); - y = ND_height(n); - } else { - y = ND_width(n); - x = ND_height(n); - } - ps = POINTS(x) / 2; - if (ps < 1) - ps = 1; - ND_lw_i(n) = ND_rw_i(n) = ps; - ND_ht_i(n) = POINTS(y); -} - static void dot_init_node(node_t * n) { @@ -250,5 +230,5 @@ void dot_layout(Agraph_t * g) dot_splines(g); if (mapbool(agget(g, "compound"))) dot_compoundEdges(g); - dotneato_postprocess(g, dot_nodesize); + dotneato_postprocess(g); } diff --git a/lib/dotgen/dotsplines.c b/lib/dotgen/dotsplines.c index 259d70062..95cb2bd1a 100644 --- a/lib/dotgen/dotsplines.c +++ b/lib/dotgen/dotsplines.c @@ -214,6 +214,7 @@ static void edge_normalize(graph_t * g) } /* dot_splines: + * If the splines attribute is defined but equal to "", skip edge routing. */ void dot_splines(graph_t * g) { @@ -223,6 +224,9 @@ void dot_splines(graph_t * g) edge_t *e, *e0, *e1, *ea, *eb, *le0, *le1, **edges; path *P; spline_info_t sd; + char* s = agget(g, "splines"); + + if (s && (*s == '\0')) return; mark_lowclusters(g); routesplinesinit(); @@ -614,6 +618,7 @@ static struct { attrsym_t* E_weight; attrsym_t* E_minlen; attrsym_t* N_group; + int State; } attr_state; /* cloneGraph: @@ -659,6 +664,7 @@ cloneGraph (graph_t* g) attr_state.E_weight = E_weight; attr_state.E_minlen = E_minlen; attr_state.N_group = N_group; + attr_state.State = State; E_constr = NULL; E_samehead = agfindattr(auxg->proto->e, "samehead"); E_sametail = agfindattr(auxg->proto->e, "sametail"); @@ -683,6 +689,7 @@ cleanupCloneGraph (graph_t* g) E_weight = attr_state.E_weight; E_minlen = attr_state.E_minlen; N_group = attr_state.N_group; + State = attr_state.State; dot_cleanup(g); agclose(g); @@ -838,7 +845,7 @@ make_flat_adj_edges(path* P, edge_t** edges, int ind, int cnt, edge_t* e0) } dot_sameports(auxg); dot_splines(auxg); - dotneato_postprocess(auxg, dot_nodesize); + dotneato_postprocess(auxg); /* copy splines */ if (GD_flip(g)) { diff --git a/lib/fdpgen/layout.c b/lib/fdpgen/layout.c index c055ad5bf..6d95e2faf 100644 --- a/lib/fdpgen/layout.c +++ b/lib/fdpgen/layout.c @@ -1059,20 +1059,16 @@ void fdpLayout(graph_t * g) setBB(g); } -void fdp_layout(graph_t * g) +static void +fdpSplines (graph_t * g, char* str) { char *str; int trySplines = 0; - State = 0; /* initialize state */ - fdp_init_graph(g); - fdpLayout(g); - - str = agget(g, "splines"); if (str) { if (streq(str, "compound")) { trySplines = splineEdges(g, compoundEdges, 1); - /* When doing the edges again, accept edges done by compoundeEdges */ + /* When doing the edges again, accept edges done by compoundEdges */ if (trySplines) Nop = 2; } @@ -1087,5 +1083,18 @@ void fdp_layout(graph_t * g) } if (State < GVSPLINES) spline_edges1(g, 0); - dotneato_postprocess(g, neato_nodesize); +} + +void fdp_layout(graph_t * g) +{ + char *str; + + fdp_init_graph(g); + fdpLayout(g); + neato_set_aspect(g); + + str = agget(g, "splines"); + if (!str || *str) fdpSplines (g, str); + + dotneato_postprocess(g); } diff --git a/lib/neatogen/neatoinit.c b/lib/neatogen/neatoinit.c index f477ef1c4..5d7813fd1 100644 --- a/lib/neatogen/neatoinit.c +++ b/lib/neatogen/neatoinit.c @@ -1222,5 +1222,5 @@ void neato_layout(Agraph_t * g) spline_edges(g); } } - dotneato_postprocess(g, neato_nodesize); + dotneato_postprocess(g); } diff --git a/lib/neatogen/neatosplines.c b/lib/neatogen/neatosplines.c index 0984f4638..d63cc3fa0 100644 --- a/lib/neatogen/neatosplines.c +++ b/lib/neatogen/neatosplines.c @@ -672,22 +672,12 @@ static int _spline_edges(graph_t * g, double SEP, int splines) /* splineEdges: * Main wrapper code for generating edges. - * Gets desired separation, sets the graph's aspect ratio, - * and coalesces equivalent edges (edges - * with the same endpoints). This also copies the internal - * layout coordinates (ND_pos) to the external ones (ND_coord_i). + * Sets desired separation. + * Coalesces equivalent edges (edges * with the same endpoints). * It then calls the edge generating function, and marks the * spline phase complete. * Returns 0 on success. * - * Assumes u.bb for has been computed for g and all clusters - * (not just top-level clusters), and that GD_bb(g).LL is at the origin. - * - * This last criterion is, I believe, mainly to simplify the code - * in neato_set_aspect. It would be good to remove this constraint, - * as this would allow nodes pinned on input to have the same coordinates - * when output in dot or plain format. - * * The edge function is given the graph, the separation to be added * around obstacles, and the type of edge. (At present, this is a boolean, * with 1 meaning splines and 0 meaning line segments.) It must guarantee @@ -709,13 +699,10 @@ splineEdges(graph_t * g, int (*edgefn) (graph_t *, double, int), * still overlap. */ SEP = 1.01; - neato_set_aspect(g); /* find equivalent edges */ map = dtopen(&edgeItemDisc, Dtoset); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { - ND_coord_i(n).x = POINTS(ND_pos(n)[0]); - ND_coord_i(n).y = POINTS(ND_pos(n)[1]); for (e = agfstout(g, n); e; e = agnxtout(g, e)) { edge_t *leader = equivEdge(map, e); if (leader != e) { @@ -744,11 +731,26 @@ int spline_edges1(graph_t * g, int splines) } /* spline_edges0: + * Sets the graph's aspect ratio. * Check splines attribute and construct edges using default algorithm. + * If the splines attribute is defined but equal to "", skip edge routing. + * + * Assumes u.bb for has been computed for g and all clusters + * (not just top-level clusters), and that GD_bb(g).LL is at the origin. + * + * This last criterion is, I believe, mainly to simplify the code + * in neato_set_aspect. It would be good to remove this constraint, + * as this would allow nodes pinned on input to have the same coordinates + * when output in dot or plain format. + * */ void spline_edges0(graph_t * g) { - spline_edges1(g, mapbool(agget(g, "splines"))); + char* s = agget(g, "splines"); + + neato_set_aspect(g); + if (s && (*s == '\0')) return; + spline_edges1(g, mapbool(s)); } /* spline_edges: @@ -839,11 +841,11 @@ static void scaleBB(graph_t * g, double xf, double yf) scaleBB(GD_clust(g)[i], xf, yf); } -/* neato_set_aspect; +/* _neato_set_aspect; * Assume all bounding boxes are correct and * that GD_bb(g).LL is at origin. */ -void neato_set_aspect(graph_t * g) +static void _neato_set_aspect(graph_t * g) { /* int i; */ double xf, yf, actual, desired; @@ -922,3 +924,20 @@ void neato_set_aspect(graph_t * g) } } } + +/* neato_set_aspect: + * Sets aspect ration if necessary; real work done in _neato_set_aspect; + * This also copies the internal layout coordinates (ND_pos) to the + * external ones (ND_coord_i). + */ +void neato_set_aspect(graph_t * g) +{ + node_t *n; + + _neato_set_aspect(g); + for (n = agfstnode(g); n; n = agnxtnode(g, n)) { + ND_coord_i(n).x = POINTS(ND_pos(n)[0]); + ND_coord_i(n).y = POINTS(ND_pos(n)[1]); + } +} + -- 2.40.0