Simplify dotneato_postprocess interface;
authorerg <devnull@localhost>
Fri, 29 Jul 2005 22:59:35 +0000 (22:59 +0000)
committererg <devnull@localhost>
Fri, 29 Jul 2005 22:59:35 +0000 (22:59 +0000)
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
lib/common/input.c
lib/common/postproc.c
lib/common/renderprocs.h
lib/dotgen/dotinit.c
lib/dotgen/dotsplines.c
lib/fdpgen/layout.c
lib/neatogen/neatoinit.c
lib/neatogen/neatosplines.c

index 8d6781e0fc34e10a319b08ea1142a02eb8988201..b9b91d3e125fb7722645ac2eefddde3d23cfcfbc 100644 (file)
 #include    "adjust.h"
 #include    "pack.h"
 #include    "neatoprocs.h"
-#include       <string.h>
-
-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    <string.h>
 
 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)
index 2eb9bf83ea439e6a04878720cc299dc018e57e6f..abfa4b62f2c1859327412249bf023c514144af26 100644 (file)
@@ -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])
index c247d804d3148c4d600b58e38a43df835027665c..4154081de7cd58e4dd6905e1be0f57afc7f82292 100644 (file)
@@ -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);
 
index 89ac24a1d07efdc76388cfa02eff31af5ff84328..e17c9933ac5889146666f592cd3132b7b1535fea 100644 (file)
@@ -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);
index 3b37e403a52950afae4909c850358055be9003ca..8b6c64d463cccdf273e04c0c293fef4ae70e446f 100644 (file)
 
 #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);
 }
index 259d70062c05253cc9c293a18bb2813c768a3d19..95cb2bd1a76455c7066231bd7f3cfde2f1cc9f97 100644 (file)
@@ -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)) {
index c055ad5bfddb35cc96ff57bd371bb0703de91873..6d95e2fafaef871f6fd98b091fc55e46141cd9a4 100644 (file)
@@ -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);
 }
index f477ef1c4685a19a9bcd9e2b47c73e9545a8e264..5d7813fd18111001f714891989529cdcb2b517e2 100644 (file)
@@ -1222,5 +1222,5 @@ void neato_layout(Agraph_t * g)
            spline_edges(g);
        }
     }
-    dotneato_postprocess(g, neato_nodesize);
+    dotneato_postprocess(g);
 }
index 0984f46387159b009da1fb85529468dfd0c8b223..d63cc3fa06fae00341aaf10cc044fc34dec251b9 100644 (file)
@@ -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]);
+    }
+}
+