]> granicus.if.org Git - graphviz/commitdiff
Make loops independent of node size and dependent on available space.
authorerg <devnull@localhost>
Thu, 5 May 2005 21:20:03 +0000 (21:20 +0000)
committererg <devnull@localhost>
Thu, 5 May 2005 21:20:03 +0000 (21:20 +0000)
lib/common/renderprocs.h
lib/common/splines.c
lib/dotgen/dotsplines.c
lib/neatogen/neatosplines.c

index 2166e97fcf11e357811612ad1d53617bb0f13708..c7795678591c93e1b5e55bb27cf51f1fed56c8d0 100644 (file)
@@ -134,7 +134,7 @@ extern "C" {
     extern char *strdup_and_subst_node(char *str, Agnode_t * n);
     extern char *strdup_and_subst_edge(char *str, Agedge_t * e);
     extern char *xml_string(char *s);
-    extern void makeSelfEdge(path *, edge_t **, int, int, int,
+    extern void makeSelfEdge(path *, edge_t **, int, int, int, int,
                             splineInfo *);
     extern textlabel_t *make_label(int, char *, double, char *, char *,
                                   graph_t *);
index 362c8231b53021187887bde94b41e478446c1a82..1d0db95e41bf87ef3a3eeca956e047d8d72b9fd0 100644 (file)
@@ -853,7 +853,7 @@ completeselfpath(path * P, pathend_t * tendp, pathend_t * hendp,
 #endif
 
 static void
-selfBottom (edge_t* edges[], int ind, int cnt, int stepy, splineInfo* sinfo) 
+selfBottom (edge_t* edges[], int ind, int cnt, int sizex, int stepy, splineInfo* sinfo) 
 {
     int sgn, hy, ty;
     point tp, hp;
@@ -868,8 +868,10 @@ selfBottom (edge_t* edges[], int ind, int cnt, int stepy, splineInfo* sinfo)
     e = edges[ind];
     n = e->tail;
 
-    /* stepx = (ND_rw_i(n)) / cnt; */
-    stepx = stepy;
+    stepy /= 2;
+    stepy = MAX(stepy, 2);
+    stepx = sizex / cnt;
+    stepx = MAX(stepx, 2);
     pointn = 0;
     np = ND_coord_i(n);
     tp = ED_tail_port(e).p;
@@ -917,7 +919,8 @@ selfBottom (edge_t* edges[], int ind, int cnt, int stepy, splineInfo* sinfo)
 }
 
 static void
-selfTop (edge_t* edges[], int ind, int cnt, int stepy, splineInfo* sinfo) 
+selfTop (edge_t* edges[], int ind, int cnt, int sizex, int stepy, 
+         splineInfo* sinfo) 
 {
     int sgn, hy, ty;
     point tp, hp;
@@ -932,8 +935,10 @@ selfTop (edge_t* edges[], int ind, int cnt, int stepy, splineInfo* sinfo)
     e = edges[ind];
     n = e->tail;
 
-    /* stepx = (ND_rw_i(n)) / cnt; */
-    stepx = stepy;
+    stepy /= 2;
+    stepy = MAX(stepy, 2);
+    stepx = sizex / cnt;
+    stepx = MAX(stepx, 2);
     pointn = 0;
     np = ND_coord_i(n);
     tp = ED_tail_port(e).p;
@@ -981,7 +986,8 @@ selfTop (edge_t* edges[], int ind, int cnt, int stepy, splineInfo* sinfo)
 }
 
 static void
-selfRight (edge_t* edges[], int ind, int cnt, int stepx, splineInfo* sinfo) 
+selfRight (edge_t* edges[], int ind, int cnt, int stepx, int sizey,
+           splineInfo* sinfo) 
 {
     int hx, tx, sgn;
     point tp, hp;
@@ -996,7 +1002,8 @@ selfRight (edge_t* edges[], int ind, int cnt, int stepx, splineInfo* sinfo)
     e = edges[ind];
     n = e->tail;
 
-    stepy = (ND_ht_i(n) / 2) / cnt;
+    stepy = (sizey / 2) / cnt;
+    stepy = MAX(stepy, 2);
     pointn = 0;
     np = ND_coord_i(n);
     tp  = ED_tail_port(e).p;
@@ -1045,7 +1052,8 @@ selfRight (edge_t* edges[], int ind, int cnt, int stepx, splineInfo* sinfo)
 }
 
 static void
-selfLeft (edge_t* edges[], int ind, int cnt, int stepx, splineInfo* sinfo) 
+selfLeft (edge_t* edges[], int ind, int cnt, int stepx, int sizey,
+          splineInfo* sinfo) 
 {
     int hx, tx, sgn;
     point tp, hp;
@@ -1060,7 +1068,8 @@ selfLeft (edge_t* edges[], int ind, int cnt, int stepx, splineInfo* sinfo)
     e = edges[ind];
     n = e->tail;
 
-    stepy = (ND_ht_i(n) / 2) / cnt;
+    stepy = (sizey / 2) / cnt;
+    stepy = MAX(stepy,2);
     pointn = 0;
     np = ND_coord_i(n);
     tp = ED_tail_port(e).p;
@@ -1111,6 +1120,9 @@ selfLeft (edge_t* edges[], int ind, int cnt, int stepx, splineInfo* sinfo)
  * Assume e is self-edge.
  * Return extra space necessary on the right for this edge.
  * If the edge does not go on the right, return 0.
+ * NOTE: the actual space is determined dynamically by GD_nodesep,
+ * so using the constant SELF_EDGE_SIZE is going to be wrong.
+ * Fortunately, the default nodesep is the same as SELF_EDGE_SIZE.
  */
 int
 selfRightSpace (edge_t* e)
@@ -1141,8 +1153,8 @@ selfRightSpace (edge_t* e)
  * Perhaps for self-edges, the label should be centered.
  */
 void
-makeSelfEdge(path * P, edge_t * edges[], int ind, int cnt, int stepx,
-            splineInfo * sinfo)
+makeSelfEdge(path * P, edge_t * edges[], int ind, int cnt, int sizex,
+            int sizey, splineInfo * sinfo)
 {
     edge_t *e;
 #ifdef OLD
@@ -1166,7 +1178,7 @@ makeSelfEdge(path * P, edge_t * edges[], int ind, int cnt, int stepx,
          !(ED_head_port(e).side & LEFT) &&
           ((ED_tail_port(e).side != ED_head_port(e).side) || 
           (!(ED_tail_port(e).side & (TOP|BOTTOM)))))) {
-       selfRight(edges, ind, cnt, stepx, sinfo);
+       selfRight(edges, ind, cnt, sizex, sizey, sinfo);
     }
 
     /* self edge with port on left side */
@@ -1174,19 +1186,19 @@ makeSelfEdge(path * P, edge_t * edges[], int ind, int cnt, int stepx,
 
        /* handle L-R specially */
        if ((ED_tail_port(e).side & RIGHT) || (ED_head_port(e).side & RIGHT)) {
-           selfTop(edges, ind, cnt, stepx, sinfo);
+           selfTop(edges, ind, cnt, sizex, sizey, sinfo);
        }
        else {
-           selfLeft(edges, ind, cnt, stepx, sinfo);
+           selfLeft(edges, ind, cnt, sizex, sizey, sinfo);
        }
     }
 
     /* self edge with both ports on top side */
     else if (ED_tail_port(e).side & TOP) {
-       selfTop(edges, ind, cnt, stepx, sinfo);
+       selfTop(edges, ind, cnt, sizex, sizey, sinfo);
     }
     else if (ED_tail_port(e).side & BOTTOM) {
-       selfBottom(edges, ind, cnt, stepx, sinfo);
+       selfBottom(edges, ind, cnt, sizex, sizey, sinfo);
     }
 
     else assert(0);
index 24491e0e304e556d89f87b5d9bcd14f0f784d55e..184b599c0d372ce5b187b37b0651c7e554e3e1a6 100644 (file)
@@ -331,8 +331,23 @@ void dot_splines(graph_t * g)
            if (ED_tree_index(edges[i]) & MAINGRAPH)    /* Aha! -C is on */
                break;
        }
-       if (e0->tail == e0->head)
-           makeSelfEdge(P, edges, ind, cnt, Multisep, &sinfo);
+       if (e0->tail == e0->head) {
+           int sizey, r;
+           n = e0->tail;
+           r = ND_rank(n);
+           if (r == GD_maxrank(g)) {
+               sizey = ND_coord_i(GD_rank(g)[r-1].v[0]).y - ND_coord_i(n).y;
+           }
+           else if (r == GD_minrank(g)) {
+               sizey = ND_coord_i(n).y - ND_coord_i(GD_rank(g)[r+1].v[0]).y;
+           }
+           else {
+               int upy = ND_coord_i(GD_rank(g)[r-1].v[0]).y - ND_coord_i(n).y;
+               int dwny = ND_coord_i(n).y - ND_coord_i(GD_rank(g)[r+1].v[0]).y;
+               sizey = MIN(upy, dwny);
+           }
+           makeSelfEdge(P, edges, ind, cnt, Multisep, sizey, &sinfo);
+       }
        else if (ND_rank(e0->tail) == ND_rank(e0->head)) {
            make_flat_edge(P, edges, ind, cnt);
        }
index d378fafb42e3e387891520309079d2c8f11e0c92..0984f46387159b009da1fb85529468dfd0c8b223 100644 (file)
@@ -320,7 +320,7 @@ void makeSelfArcs(path * P, edge_t * e, int stepx)
     if (cnt == 1) {
        edge_t *edges1[1];
        edges1[0] = e;
-       makeSelfEdge(P, edges1, 0, 1, stepx, &sinfo);
+       makeSelfEdge(P, edges1, 0, 1, stepx, stepx, &sinfo);
        if (ED_label(e))
            updateBB(e->tail->graph, ED_label(e));
        makePortLabels(e);
@@ -331,7 +331,7 @@ void makeSelfArcs(path * P, edge_t * e, int stepx)
            edges[i] = e;
            e = ED_to_virt(e);
        }
-       makeSelfEdge(P, edges, 0, cnt, stepx, &sinfo);
+       makeSelfEdge(P, edges, 0, cnt, stepx, stepx, &sinfo);
        for (i = 0; i < cnt; i++) {
            e = edges[i];
            if (ED_label(e))