return p;
}
-
-static void makePortLabels(edge_t * e)
-{
- if (ED_head_label(e) && !ED_head_label(e)->set) {
- 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));
- }
-}
-
-/* endPoints:
- * Extract the actual end points of the spline, where
- * they touch the node.
- */
-static void endPoints(splines * spl, pointf * p, pointf * q)
-{
- bezier bz;
-
- bz = spl->list[0];
- if (bz.sflag) {
- *p = bz.sp;
- }
- else {
- *p = bz.list[0];
- }
- bz = spl->list[spl->size - 1];
- if (bz.eflag) {
- *q = bz.ep;
- }
- else {
- *q = bz.list[bz.size - 1];
- }
-}
-
-/* polylineMidpoint;
- * Find midpoint of polyline.
- * pp and pq are set to the endpoints of the line segment containing it.
- */
-static pointf
-polylineMidpoint (splines* spl, pointf* pp, pointf* pq)
-{
- bezier bz;
- int i, j, k;
- double d, dist = 0;
- pointf pf, qf, mf;
-
- for (i = 0; i < spl->size; i++) {
- bz = spl->list[i];
- for (j = 0, k=3; k < bz.size; j+=3,k+=3) {
- pf = bz.list[j];
- qf = bz.list[k];
- dist += DIST(pf, qf);
- }
- }
- dist /= 2;
- for (i = 0; i < spl->size; i++) {
- bz = spl->list[i];
- for (j = 0, k=3; k < bz.size; j+=3,k+=3) {
- pf = bz.list[j];
- qf = bz.list[k];
- d = DIST(pf,qf);
- if (d >= dist) {
- *pp = pf;
- *pq = qf;
- mf.x = ((qf.x*dist) + (pf.x*(d-dist)))/d;
- mf.y = ((qf.y*dist) + (pf.y*(d-dist)))/d;
- return mf;
- }
- else
- dist -= d;
- }
- }
- assert (FALSE); /* should never get here */
- return mf;
-}
-
-#define LEFTOF(a,b,c) (((a.y - b.y)*(c.x - b.x) - (c.y - b.y)*(a.x - b.x)) > 0)
-#define MAXLABELWD (POINTS_PER_INCH/2.0)
-
-/* addEdgeLabels:
- * rp and rq are the port points of the tail and head node.
- * Adds label, headlabel and taillabel.
- * The use of 2 and 4 in computing ld.x and ld.y are fudge factors, to
- * introduce a bit of spacing.
- * Updates bounding box.
- * We try to use the actual endpoints of the spline, as they may differ
- * significantly from rp and rq, but if the spline is degenerate (e.g.,
- * the nodes overlap), we use rp and rq.
- */
-void addEdgeLabels(graph_t* g, edge_t * e, pointf rp, pointf rq)
-{
- int et = EDGE_TYPE (g);
- pointf p, q;
- pointf d; /* midpoint of segment p-q */
- point ld;
- point del;
- pointf spf;
- double f, ht, wd, dist2;
- int leftOf;
-
- if (ED_label(e) && !ED_label(e)->set) {
- endPoints(ED_spl(e), &p, &q);
- if (APPROXEQPT(p, q, MILLIPOINT)) { /* degenerate spline */
- p = rp;
- q = rq;
- spf = p;
- }
- else if (et == ET_SPLINE) {
- d.x = (q.x + p.x) / 2.;
- d.y = (p.y + q.y) / 2.;
- spf = dotneato_closest(ED_spl(e), d);
- }
- else { /* ET_PLINE or ET_LINE */
- spf = polylineMidpoint (ED_spl(e), &p, &q);
- }
- del.x = q.x - p.x;
- del.y = q.y - p.y;
- dist2 = del.x*del.x + del.y*del.y;
- ht = (ED_label(e)->dimen.y + 2)/2.0;
- if (dist2) {
- wd = (MIN(ED_label(e)->dimen.x + 2, MAXLABELWD))/2.0;
- leftOf = LEFTOF(p, q, spf);
- if ((leftOf && (del.y >= 0)) || (!leftOf && (del.y < 0))) {
- if (del.x*del.y >= 0)
- ht *= -1;
- }
- else {
- wd *= -1;
- if (del.x*del.y < 0)
- ht *= -1;
- }
- f = (del.y*wd - del.x*ht)/dist2;
- ld.x = -f*del.y;
- ld.y = f*del.x;
- }
- else { /* end points the same */
- ld.x = 0;
- ld.y = -ht;
- }
-
- ED_label(e)->pos.x = spf.x + ld.x;
- ED_label(e)->pos.y = spf.y + ld.y;
- ED_label(e)->set = TRUE;
- updateBB(agraphof(agtail(e)), ED_label(e));
- }
- makePortLabels(e);
-}
-
typedef struct {
node_t *n1;
pointf p1;