From 3ac4f9174e6311a5378ec98f3138ba66dbdfedfc Mon Sep 17 00:00:00 2001 From: Emden Gansner Date: Thu, 18 Aug 2011 15:01:21 -0400 Subject: [PATCH] Convert headlabels and taillabels to use external labels; make forcelabels true by default --- lib/common/postproc.c | 68 +++++++++++++++++++++++++++++++++++++++-- lib/common/render.h | 2 +- lib/common/splines.c | 38 ++++++++++++++++++----- lib/dotgen/dotsplines.c | 10 +++--- 4 files changed, 102 insertions(+), 16 deletions(-) diff --git a/lib/common/postproc.c b/lib/common/postproc.c index 372d8b503..a27888ac0 100644 --- a/lib/common/postproc.c +++ b/lib/common/postproc.c @@ -249,6 +249,36 @@ addXLabel (textlabel_t* lp, object_t* objp, xlabel_t* xlp, int initObj, pointf p objp->lbl = xlp; } +static pointf +edgeTailpoint (Agedge_t* e) +{ + splines *spl; + bezier *bez; + + spl = getsplinepoints(e); + bez = &spl->list[0]; + if (bez->sflag) { + return bez->sp; + } else { + return bez->list[0]; + } +} + +static pointf +edgeHeadpoint (Agedge_t* e) +{ + splines *spl; + bezier *bez; + + spl = getsplinepoints(e); + bez = &spl->list[spl->size - 1]; + if (bez->eflag) { + return bez->ep; + } else { + return bez->list[bez->size - 1]; + } +} + /* addLabelObj: * Set up obstacle object based on set external label. * Use label information to determine size and position of object. @@ -301,7 +331,9 @@ static void addXLabels(Agraph_t * gp) if (!(GD_has_labels(gp) & NODE_XLABEL) && !(GD_has_labels(gp) & EDGE_XLABEL) && - ((!GD_has_labels(gp) & EDGE_LABEL) || EdgeLabelsDone)) + !(GD_has_labels(gp) & TAIL_LABEL) && + !(GD_has_labels(gp) & HEAD_LABEL) && + (!(GD_has_labels(gp) & EDGE_LABEL) || EdgeLabelsDone)) return; for (np = agfstnode(gp); np; np = agnxtnode(gp, np)) { @@ -318,6 +350,18 @@ static void addXLabels(Agraph_t * gp) else n_elbls++; } + if (ED_head_label(ep)) { + if (ED_head_label(ep)->set) + n_set_lbls++; + else + n_elbls++; + } + if (ED_tail_label(ep)) { + if (ED_tail_label(ep)->set) + n_set_lbls++; + else + n_elbls++; + } if (ED_label(ep)) { if (ED_label(ep)->set) n_set_lbls++; @@ -378,6 +422,26 @@ static void addXLabels(Agraph_t * gp) } objp++; } + if ((lp = ED_tail_label(ep))) { + if (lp->set) { + bb = addLabelObj (lp, objp, bb); + } + else { + addXLabel (lp, objp, xlp, 1, edgeTailpoint(ep)); + xlp++; + } + objp++; + } + if ((lp = ED_head_label(ep))) { + if (lp->set) { + bb = addLabelObj (lp, objp, bb); + } + else { + addXLabel (lp, objp, xlp, 1, edgeHeadpoint(ep)); + xlp++; + } + objp++; + } if ((lp = ED_xlabel(ep))) { if (lp->set) { bb = addLabelObj (lp, objp, bb); @@ -393,7 +457,7 @@ static void addXLabels(Agraph_t * gp) force = agfindgraphattr(gp, "forcelabels"); - params.force = late_bool(gp, force, FALSE); + params.force = late_bool(gp, force, TRUE); params.bb = bb; placeLabels(objs, n_objs, lbls, n_lbls, ¶ms); if (Verbose) diff --git a/lib/common/render.h b/lib/common/render.h index 8458a84b6..d0d87a05e 100644 --- a/lib/common/render.h +++ b/lib/common/render.h @@ -132,7 +132,7 @@ extern "C" { extern bezier *new_spline(edge_t * e, int sz); extern char **parse_style(char *s); extern void place_graph_label(Agraph_t *); - extern void place_portlabel(edge_t * e, boolean head_p); + extern int place_portlabel(edge_t * e, boolean head_p); extern void makePortLabels(edge_t * e); extern pointf edgeMidpoint(graph_t* g, edge_t * e); extern void addEdgeLabels(graph_t* g, edge_t * e, pointf rp, pointf rq); diff --git a/lib/common/splines.c b/lib/common/splines.c index c0e8fffa8..31ac8591f 100644 --- a/lib/common/splines.c +++ b/lib/common/splines.c @@ -1119,13 +1119,18 @@ makeSelfEdge(path * P, edge_t * edges[], int ind, int cnt, double sizex, */ void makePortLabels(edge_t * e) { + /* Only use this if labelangle or labeldistance is set for the edge; + * otherwise, handle with external labels. + */ + if (!E_labelangle && !E_labeldistance) return; + if (ED_head_label(e) && !ED_head_label(e)->set) { - place_portlabel(e, TRUE); - updateBB(agraphof(agtail(e)), ED_head_label(e)); + if (place_portlabel(e, TRUE)) + updateBB(agraphof(agtail(e)), ED_head_label(e)); } if (ED_tail_label(e) && !ED_tail_label(e)->set) { - place_portlabel(e, FALSE); - updateBB(agraphof(agtail(e)), ED_tail_label(e)); + if (place_portlabel(e, FALSE)) + updateBB(agraphof(agtail(e)), ED_tail_label(e)); } } @@ -1291,12 +1296,20 @@ void addEdgeLabels(graph_t* g, edge_t * e, pointf rp, pointf rq) makePortLabels(e); } +#ifndef WITH_CGRAPH +#define AGXGET(o,a) agxget(o,a->index) +#else /* WITH_CGRAPH */ +#define AGXGET(o,a) agxget(o,a) +#endif /* WITH_CGRAPH */ + /* vladimir */ -void place_portlabel(edge_t * e, boolean head_p) -/* place the {head,tail}label (depending on HEAD_P) of edge E */ -/* N.B. Assume edges are normalized, so tail is at spl->list[0].list[0] +/* place_portlabel: + * place the {head,tail}label (depending on HEAD_P) of edge E + * N.B. Assume edges are normalized, so tail is at spl->list[0].list[0] * and head is at spl->list[spl->size-l].list[bez->size-1] + * Return 1 on success */ +int place_portlabel(edge_t * e, boolean head_p) { textlabel_t *l; splines *spl; @@ -1304,9 +1317,17 @@ void place_portlabel(edge_t * e, boolean head_p) double dist, angle; pointf c[4], pe, pf; int i; + char* la; + char* ld; if (ED_edge_type(e) == IGNORED) - return; + return 0; + /* add label here only if labelangle or labeldistance is defined; else, use external label */ + if ((!E_labelangle || (*(la = AGXGET(e,E_labelangle)) == '\0')) && + (!E_labeldistance || (*(ld = AGXGET(e,E_labeldistance)) == '\0'))) { + return 0; + } + l = head_p ? ED_head_label(e) : ED_tail_label(e); spl = getsplinepoints(e); if (!head_p) { @@ -1338,6 +1359,7 @@ void place_portlabel(edge_t * e, boolean head_p) l->pos.x = pe.x + dist * cos(angle); l->pos.y = pe.y + dist * sin(angle); l->set = TRUE; + return 1; } splines *getsplinepoints(edge_t * e) diff --git a/lib/dotgen/dotsplines.c b/lib/dotgen/dotsplines.c index 5fc6a4a24..73cd4430a 100644 --- a/lib/dotgen/dotsplines.c +++ b/lib/dotgen/dotsplines.c @@ -461,20 +461,20 @@ finish : #endif /* vladimir: place port labels */ /* FIX: head and tail labels are not part of cluster bbox */ - if (E_headlabel || E_taillabel) { + if ((E_headlabel || E_taillabel) && (E_labelangle || E_labeldistance)) { for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (E_headlabel) { for (e = agfstin(g, n); e; e = agnxtin(g, e)) if (ED_head_label(e)) { - place_portlabel(e, TRUE); - updateBB(g, ED_head_label(e)); + if (place_portlabel(e, TRUE)) + updateBB(g, ED_head_label(e)); } } if (E_taillabel) { for (e = agfstout(g, n); e; e = agnxtout(g, e)) { if (ED_tail_label(e)) { - place_portlabel(e, FALSE); - updateBB(g, ED_tail_label(e)); + if (place_portlabel(e, FALSE)) + updateBB(g, ED_tail_label(e)); } } } -- 2.40.0