]> granicus.if.org Git - graphviz/commitdiff
Integrate xlabels with neato -n.
authorEmden Gansner <erg@research.att.com>
Wed, 3 Aug 2011 19:25:35 +0000 (15:25 -0400)
committerEmden Gansner <erg@research.att.com>
Wed, 3 Aug 2011 19:25:35 +0000 (15:25 -0400)
lib/common/postproc.c
lib/neatogen/neatoinit.c

index 1c744ff48c0be4b38ea63b4ae2a24335a5bc0026..372d8b503463f872438915dd8b7aa00cbc9fa0ad 100644 (file)
@@ -230,21 +230,65 @@ printData (object_t* objs, int n_objs, xlabel_t* lbls, int n_lbls,
   return 0;
 }
 
+/* addXLabel:
+ * Set up xlabel_t object and connect with related object.
+ * If initObj is set, initialize the object.
+ */
+static void
+addXLabel (textlabel_t* lp, object_t* objp, xlabel_t* xlp, int initObj, pointf pos)
+{
+    if (initObj) {
+       objp->sz.x = 0;
+       objp->sz.y = 0;
+       objp->pos = pos;
+    }
+
+    xlp->sz = lp->dimen;
+    xlp->lbl = lp;
+    xlp->set = 0;
+    objp->lbl = xlp;
+}
+
+/* addLabelObj:
+ * Set up obstacle object based on set external label.
+ * Use label information to determine size and position of object.
+ * Then adjust given bounding box bb to include label and return new bb.
+ */
+static boxf
+addLabelObj (textlabel_t* lp, object_t* objp, boxf bb)
+{
+    pointf ur;
+
+    objp->sz.x = lp->dimen.x; 
+    objp->sz.y = lp->dimen.y;
+    objp->pos = lp->pos;
+    objp->pos.x -= (objp->sz.x) / 2.0;
+    objp->pos.y -= (objp->sz.y) / 2.0;
+
+    /* Adjust bounding box */
+    bb.LL.x = MIN(bb.LL.x, objp->pos.x);
+    bb.LL.y = MIN(bb.LL.y, objp->pos.y);
+    ur.x = objp->pos.x + objp->sz.x;
+    ur.y = objp->pos.y + objp->sz.y;
+    bb.UR.x = MAX(bb.UR.x, ur.x);
+    bb.UR.y = MAX(bb.UR.y, ur.y);
+    return bb;
+}
+
 /* addXLabels:
  * Position xlabels and any unpositioned edge labels using
  * a map placement algorithm to avoid overlap.
  *
  * TODO: interaction with spline=ortho
- *       interaction with rankdir=LR
  */
 static void addXLabels(Agraph_t * gp)
 {
     Agnode_t *np;
     Agedge_t *ep;
     int cnt, i, n_objs, n_lbls;
-    int n_nlbls = 0;           /* # of node xlabels */
-    int n_elbls = 0;           /* # of edge xlabels */
-    int n_set_elbls = 0;       /* # of edge labels set */
+    int n_nlbls = 0;           /* # of unset node xlabels */
+    int n_elbls = 0;           /* # of unset edge labels or xlabels */
+    int n_set_lbls = 0;                /* # of set xlabels and edge labels */
     boxf bb;
     pointf ur;
     textlabel_t* lp;
@@ -261,26 +305,36 @@ static void addXLabels(Agraph_t * gp)
        return;
 
     for (np = agfstnode(gp); np; np = agnxtnode(gp, np)) {
-       if (ND_xlabel(np))
-           n_nlbls++;
+       if (ND_xlabel(np)) {
+           if (ND_xlabel(np)->set)
+               n_set_lbls++;
+           else
+               n_nlbls++;
+       }
        for (ep = agfstout(gp, np); ep; ep = agnxtout(gp, ep)) {
-           if (ED_xlabel(ep))
-               n_elbls++;
+           if (ED_xlabel(ep)) {
+               if (ED_xlabel(ep)->set)
+                   n_set_lbls++;
+               else
+                   n_elbls++;
+           }
            if (ED_label(ep)) {
                if (ED_label(ep)->set)
-                   n_set_elbls++;
+                   n_set_lbls++;
                else
                    n_elbls++;
            }
        }
     }
 
-    /* An object for each node, each positioned edge label, and all unset edge
+    /* A label for each unpositioned external label */
+    n_lbls = n_nlbls + n_elbls;
+    if (n_lbls == 0) return;
+
+    /* An object for each node, each positioned external label, and all unset edge
      * labels and xlabels.
      */
-    n_objs = agnnodes(gp) + n_set_elbls + n_elbls;
-    /* A label for each unpositioned label */
-    n_lbls = n_nlbls + n_elbls;
+    n_objs = agnnodes(gp) + n_set_lbls + n_elbls;
     objp = objs = N_NEW(n_objs, object_t);
     xlp = lbls = N_NEW(n_lbls, xlabel_t);
     bb.LL = pointfof(INT_MAX, INT_MAX);
@@ -302,54 +356,36 @@ static void addXLabels(Agraph_t * gp)
        bb.UR.x = MAX(bb.UR.x, ur.x);
        bb.UR.y = MAX(bb.UR.y, ur.y);
 
-       if (ND_xlabel(np)) {
-           xlp->sz = ND_xlabel(np)->dimen;
-           xlp->lbl = ND_xlabel(np);
-           xlp->set = 0;
-           objp->lbl = xlp;
-           xlp++;
+       if ((lp = ND_xlabel(np))) {
+           if (lp->set) {
+               bb = addLabelObj (lp, objp, bb);
+               objp++;
+           }
+           else {
+               addXLabel (lp, objp, xlp, 0, ur); 
+               xlp++;
+           }
        }
        objp++;
        for (ep = agfstout(gp, np); ep; ep = agnxtout(gp, ep)) {
            if ((lp = ED_label(ep))) {
                if (lp->set) {
-                   objp->sz.x = lp->dimen.x; 
-                   objp->sz.y = lp->dimen.y;
-                   objp->pos = lp->pos;
-                   objp->pos.x -= (objp->sz.x) / 2.0;
-                   objp->pos.y -= (objp->sz.y) / 2.0;
-
-                       /* Adjust bounding box */
-                   bb.LL.x = MIN(bb.LL.x, objp->pos.x);
-                   bb.LL.y = MIN(bb.LL.y, objp->pos.y);
-                   ur.x = objp->pos.x + objp->sz.x;
-                   ur.y = objp->pos.y + objp->sz.y;
-                   bb.UR.x = MAX(bb.UR.x, ur.x);
-                   bb.UR.y = MAX(bb.UR.y, ur.y);
+                   bb = addLabelObj (lp, objp, bb);
                }
                else {
-                   objp->sz.x = 0;
-                   objp->sz.y = 0;
-                   objp->pos = edgeMidpoint(gp, ep);
-
-                   xlp->sz = ED_label(ep)->dimen;
-                   xlp->lbl = ED_label(ep);
-                   xlp->set = 0;
-                   objp->lbl = xlp;
+                   addXLabel (lp, objp, xlp, 1, edgeMidpoint(gp, ep)); 
                    xlp++;
                }
                objp++;
            }
-           if (ED_xlabel(ep)) {
-               objp->sz.x = 0;
-               objp->sz.y = 0;
-               objp->pos = edgeMidpoint(gp, ep);
-
-               xlp->sz = ED_xlabel(ep)->dimen;
-               xlp->lbl = ED_xlabel(ep);
-               xlp->set = 0;
-               objp->lbl = xlp;
-               xlp++;
+           if ((lp = ED_xlabel(ep))) {
+               if (lp->set) {
+                   bb = addLabelObj (lp, objp, bb);
+               }
+               else {
+                   addXLabel (lp, objp, xlp, 1, edgeMidpoint(gp, ep)); 
+                   xlp++;
+               }
                objp++;
            }
        }
index 4b8a9ccb7a38f548ef07c9036ccf9bad9abd171f..886e168733ae9f314e1933fda81b0a105253591e 100644 (file)
@@ -197,11 +197,11 @@ static int numFields(unsigned char *pos)
     return cnt;
 }
 
-static void set_elabel(edge_t * e, textlabel_t * l, char *name)
+static void set_label(void* obj, textlabel_t * l, char *name)
 {
     double x, y;
     char *lp;
-    lp = agget(e, name);
+    lp = agget(obj, name);
     if (lp && (sscanf(lp, "%lf,%lf", &x, &y) == 2)) {
        l->pos = pointfof(x, y);
        l->set = TRUE;
@@ -404,11 +404,13 @@ static int user_spline(attrsym_t * E_pos, edge_t * e)
     } while (more);
 
     if (ED_label(e))
-       set_elabel(e, ED_label(e), "lp");
+       set_label(e, ED_label(e), "lp");
+    if (ED_xlabel(e))
+       set_label(e, ED_xlabel(e), "xlp");
     if (ED_head_label(e))
-       set_elabel(e, ED_head_label(e), "head_lp");
+       set_label(e, ED_head_label(e), "head_lp");
     if (ED_tail_label(e))
-       set_elabel(e, ED_tail_label(e), "tail_lp");
+       set_label(e, ED_tail_label(e), "tail_lp");
 
     return 1;
 }
@@ -705,6 +707,8 @@ int init_nop(Agraph_t * g, int adjust)
                  agnameof(np), agnameof(g));
            return -1;
        }
+       if (ND_xlabel(np))
+           set_label(np, ND_xlabel(np), "xlp");
     }
     nop_init_graphs(g, G_lp, G_bb);
     posEdges = nop_init_edges(g);