~ubuntu-branches/ubuntu/precise/graphviz/precise-security

« back to all changes in this revision

Viewing changes to lib/dotgen/dotsplines.c

  • Committer: Bazaar Package Importer
  • Author(s): David Claughton
  • Date: 2010-03-24 22:45:18 UTC
  • mfrom: (1.2.7 upstream) (6.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100324224518-do441tthbqjaqjzd
Tags: 2.26.3-4
Add patch to fix segfault in circo. Backported from upstream snapshot
release.  Thanks to Francis Russell for his work on this.
(Closes: #575255)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: dotsplines.c,v 1.43 2008/04/08 18:58:13 ellson Exp $ $Revision: 1.43 $ */
 
1
/* $Id: dotsplines.c,v 1.65 2009/08/11 21:21:20 erg Exp $ $Revision: 1.65 $ */
2
2
/* vim:set shiftwidth=4 ts=8: */
3
3
 
4
4
/**********************************************************
21
21
 
22
22
#include "dot.h"
23
23
 
 
24
#ifdef ORTHO
 
25
#include <ortho.h>
 
26
#endif
 
27
 
24
28
#define NSUB    9               /* number of subdivisions, re-aiming splines */
25
29
#define CHUNK   128             /* in building list of edges */
26
30
 
34
38
#define AUXGRAPH  128
35
39
#define GRAPHTYPEMASK   192     /* the OR of the above */
36
40
 
 
41
#ifndef WITH_CGRAPH
37
42
#define MAKEFWDEDGE(new, old) { \
38
43
        edge_t *newp; \
39
44
        newp = new; \
45
50
        ED_edge_type(newp) = VIRTUAL; \
46
51
        ED_to_orig(newp) = old; \
47
52
}
48
 
 
49
 
#define P2PF(p, pf) (pf.x = p.x, pf.y = p.y)
50
 
 
51
 
#ifdef OBSOLETE
52
 
static int flatsidemap[16][6] = {
53
 
    {BOTTOM, BOTTOM, BOTTOM, CCW, CCW, FALSE},
54
 
    {TOP,    TOP,    TOP,    CW,  CW,  FALSE},
55
 
    {RIGHT,  LEFT,   BOTTOM, CW,  CW,  TRUE},
56
 
    {BOTTOM, TOP,    RIGHT,  CCW, CW,  TRUE},
57
 
    {TOP,    BOTTOM, RIGHT,  CW,  CCW, TRUE},
58
 
    {RIGHT,  TOP,    RIGHT,  CCW, CW,  TRUE},
59
 
    {RIGHT,  BOTTOM, RIGHT,  CW,  CCW, TRUE},
60
 
    {TOP,    LEFT,   TOP,    CW,  CCW, TRUE},
61
 
    {BOTTOM, LEFT,   BOTTOM, CCW, CW,  TRUE},
62
 
    {RIGHT,  RIGHT,  BOTTOM, CW,  CCW, TRUE},
63
 
    {LEFT,   LEFT,   BOTTOM, CCW, CW,  TRUE},
64
 
    {LEFT,   BOTTOM, BOTTOM, CCW, CCW, FALSE},
65
 
    {TOP,    RIGHT,  TOP,    CW,  CW,  FALSE},
66
 
    {LEFT,   TOP,    TOP,    CW,  CW,  FALSE},
67
 
    {BOTTOM, RIGHT,  BOTTOM, CCW, CCW, FALSE},
68
 
    {LEFT,   RIGHT,  BOTTOM, CCW, CCW, FALSE},
69
 
};
70
 
#endif
71
 
 
72
 
#define AVG(a, b) ((a + b) / 2)
73
 
 
74
 
static box boxes[1000];
 
53
#else /* WITH_CGRAPH */
 
54
#define MAKEFWDEDGE(new, old) { \
 
55
        edge_t *newp; \
 
56
        newp = new; \
 
57
        *newp = *old; \
 
58
        AGTAIL(newp) = AGHEAD(old); \
 
59
        AGHEAD(newp) = AGTAIL(old); \
 
60
        ED_tail_port(newp) = ED_head_port(old); \
 
61
        ED_head_port(newp) = ED_tail_port(old); \
 
62
        ED_edge_type(newp) = VIRTUAL; \
 
63
        ED_to_orig(newp) = old; \
 
64
}
 
65
#endif /* WITH_CGRAPH */
 
66
 
 
67
static boxf boxes[1000];
75
68
typedef struct {
76
69
    int LeftBound, RightBound, Splinesep, Multisep;
77
 
    box* Rank_box;
 
70
    boxf* Rank_box;
78
71
} spline_info_t;
79
72
 
80
73
static void adjustregularpath(path *, int, int);
81
74
static Agedge_t *bot_bound(Agedge_t *, int);
82
75
static boolean pathscross(Agnode_t *, Agnode_t *, Agedge_t *, Agedge_t *);
83
 
#ifdef OBSOLETE
84
 
static void chooseflatsides(pathend_t *, pathend_t *, int *, int *, int *,
85
 
                            int *, int *, int *);
86
 
static void completeflatpath(path *, pathend_t *, pathend_t *,
87
 
                             box *, box *, int, int);
88
 
static box makeflatend(box, int, int, box);
89
 
static box makeflatcomponent(box, box, int, int, int, int, int);
90
 
#endif
91
76
static Agraph_t *cl_bound(Agnode_t *, Agnode_t *);
92
77
static int cl_vninside(Agraph_t *, Agnode_t *);
93
78
static void completeregularpath(path *, Agedge_t *, Agedge_t *,
94
 
                                pathend_t *, pathend_t *, box *, int, int);
 
79
                                pathend_t *, pathend_t *, boxf *, int, int);
95
80
static int edgecmp(Agedge_t **, Agedge_t **);
96
81
static void make_flat_edge(spline_info_t*, path *, Agedge_t **, int, int, int);
97
82
static void make_regular_edge(spline_info_t*, path *, Agedge_t **, int, int, int);
98
 
static box makeregularend(box, int, int);
99
 
static box maximal_bbox(spline_info_t*, Agnode_t *, Agedge_t *, Agedge_t *);
 
83
static boxf makeregularend(boxf, int, int);
 
84
static boxf maximal_bbox(spline_info_t*, Agnode_t *, Agedge_t *, Agedge_t *);
100
85
static Agnode_t *neighbor(Agnode_t *, Agedge_t *, Agedge_t *, int);
101
86
static void place_vnlabel(Agnode_t *);
102
 
static box rank_box(spline_info_t* sp, Agraph_t *, int);
 
87
static boxf rank_box(spline_info_t* sp, Agraph_t *, int);
103
88
static void recover_slack(Agedge_t *, path *);
104
89
static void resize_vn(Agnode_t *, int, int, int);
105
90
static void setflags(Agedge_t *, int, int, int);
106
91
static int straight_len(Agnode_t *);
107
 
static Agedge_t *straight_path(Agedge_t *, int, point *, int *);
 
92
static Agedge_t *straight_path(Agedge_t *, int, pointf *, int *);
108
93
static Agedge_t *top_bound(Agedge_t *, int);
109
94
 
110
95
#define GROWEDGES (edges = ALLOC (n_edges + CHUNK, edges, edge_t*))
130
115
{
131
116
    while (ED_to_orig(e))
132
117
        e = ED_to_orig(e);
133
 
    if (ND_rank(e->head) > ND_rank(e->tail))
 
118
    if (ND_rank(aghead(e)) > ND_rank(agtail(e)))
134
119
        return FALSE;
135
 
    if (ND_rank(e->head) < ND_rank(e->tail))
 
120
    if (ND_rank(aghead(e)) < ND_rank(agtail(e)))
136
121
        return TRUE;
137
 
    if (ND_order(e->head) >= ND_order(e->tail))
 
122
    if (ND_order(aghead(e)) >= ND_order(agtail(e)))
138
123
        return FALSE;
139
124
    return TRUE;
140
125
}
158
143
 */
159
144
static void swap_bezier(bezier * old, bezier * new)
160
145
{
161
 
    point *list;
162
 
    point *lp;
163
 
    point *olp;
 
146
    pointf *list;
 
147
    pointf *lp;
 
148
    pointf *olp;
164
149
    int i, sz;
165
150
 
166
151
    sz = old->size;
167
 
    list = N_GNEW(sz, point);
 
152
    list = N_GNEW(sz, pointf);
168
153
    lp = list;
169
154
    olp = old->list + (sz - 1);
170
155
    for (i = 0; i < sz; i++) {  /* reverse list of points */
238
223
    edge_t *e, *e0, *e1, *ea, *eb, *le0, *le1, **edges;
239
224
    path *P;
240
225
    spline_info_t sd;
241
 
    int et = EDGE_TYPE(g->root);
 
226
#ifndef WITH_CGRAPH
 
227
    int et = EDGE_TYPE(g);
 
228
#else /* WITH_CGRAPH */
 
229
    int et = EDGE_TYPE(g);
 
230
#endif /* WITH_CGRAPH */
242
231
 
243
232
    if (et == ET_NONE) return; 
 
233
#ifdef ORTHO
 
234
    if (et == ET_ORTHO) {
 
235
        orthoEdges (g, 0);
 
236
        goto finish;
 
237
    } 
 
238
#endif
244
239
 
245
240
    mark_lowclusters(g);
246
241
    routesplinesinit();
256
251
    for (i = GD_minrank(g); i <= GD_maxrank(g); i++) {
257
252
        n_nodes += GD_rank(g)[i].n;
258
253
        if ((n = GD_rank(g)[i].v[0]))
259
 
            sd.LeftBound = MIN(sd.LeftBound, (ND_coord_i(n).x - ND_lw_i(n)));
 
254
            sd.LeftBound = MIN(sd.LeftBound, (ND_coord(n).x - ND_lw(n)));
260
255
        if (GD_rank(g)[i].n && (n = GD_rank(g)[i].v[GD_rank(g)[i].n - 1]))
261
 
            sd.RightBound = MAX(sd.RightBound, (ND_coord_i(n).x + ND_rw_i(n)));
 
256
            sd.RightBound = MAX(sd.RightBound, (ND_coord(n).x + ND_rw(n)));
262
257
        sd.LeftBound -= MINW;
263
258
        sd.RightBound += MINW;
264
259
 
270
265
            if (ND_alg(n)) {
271
266
                edge_t* fe = (edge_t*)ND_alg(n);
272
267
                assert (ED_label(fe));
273
 
                ED_label(fe)->p = ND_coord_i(n);
 
268
                ED_label(fe)->pos = ND_coord(n);
274
269
            }
275
270
            if ((ND_node_type(n) != NORMAL) &&
276
271
                (sinfo.splineMerge(n) == FALSE))
298
293
                 * the original value here. 
299
294
                 */
300
295
                if (ND_node_type(n) == NORMAL) {
301
 
                    int tmp = ND_rw_i(n);
302
 
                    ND_rw_i(n) = ND_mval(n);
 
296
                    double tmp = ND_rw(n);
 
297
                    ND_rw(n) = ND_mval(n);
303
298
                    ND_mval(n) = tmp;
304
299
                }
305
300
                for (k = 0; (e = ND_other(n).list[k]); k++) {
322
317
          (qsort_cmpf) edgecmp);
323
318
 
324
319
    /* FIXME: just how many boxes can there be? */
325
 
    P->boxes = N_NEW(n_nodes + 20 * 2 * NSUB, box);
326
 
    sd.Rank_box = N_NEW(i, box);
 
320
    P->boxes = N_NEW(n_nodes + 20 * 2 * NSUB, boxf);
 
321
    sd.Rank_box = N_NEW(i, boxf);
327
322
 
328
323
    if (et == ET_LINE) {
329
324
    /* place regular edge labels */
364
359
                break;
365
360
        }
366
361
 
367
 
        if (e0->tail == e0->head) {
 
362
        if (agtail(e0) == aghead(e0)) {
368
363
            int b, sizey, r;
369
 
            n = e0->tail;
 
364
            n = agtail(e0);
370
365
            r = ND_rank(n);
371
366
            if (r == GD_maxrank(g)) {
372
367
                if (r > 0)
373
 
                    sizey = ND_coord_i(GD_rank(g)[r-1].v[0]).y - ND_coord_i(n).y;
 
368
                    sizey = ND_coord(GD_rank(g)[r-1].v[0]).y - ND_coord(n).y;
374
369
                else
375
 
                    sizey = ND_ht_i(n);
 
370
                    sizey = ND_ht(n);
376
371
            }
377
372
            else if (r == GD_minrank(g)) {
378
 
                sizey = ND_coord_i(n).y - ND_coord_i(GD_rank(g)[r+1].v[0]).y;
 
373
                sizey = ND_coord(n).y - ND_coord(GD_rank(g)[r+1].v[0]).y;
379
374
            }
380
375
            else {
381
 
                int upy = ND_coord_i(GD_rank(g)[r-1].v[0]).y - ND_coord_i(n).y;
382
 
                int dwny = ND_coord_i(n).y - ND_coord_i(GD_rank(g)[r+1].v[0]).y;
 
376
                int upy = ND_coord(GD_rank(g)[r-1].v[0]).y - ND_coord(n).y;
 
377
                int dwny = ND_coord(n).y - ND_coord(GD_rank(g)[r+1].v[0]).y;
383
378
                sizey = MIN(upy, dwny);
384
379
            }
385
380
            makeSelfEdge(P, edges, ind, cnt, sd.Multisep, sizey/2, &sinfo);
389
384
                    updateBB(g, ED_label(e));
390
385
            }
391
386
        }
392
 
        else if (ND_rank(e0->tail) == ND_rank(e0->head)) {
 
387
        else if (ND_rank(agtail(e0)) == ND_rank(aghead(e0))) {
393
388
            make_flat_edge(&sd, P, edges, ind, cnt, et);
394
389
        }
395
390
        else
409
404
    if (normalize)
410
405
        edge_normalize(g);
411
406
 
 
407
#ifdef ORTHO
 
408
finish :
 
409
#endif
412
410
    /* vladimir: place port labels */
413
411
    /* FIX: head and tail labels are not part of cluster bbox */
414
412
    if (E_headlabel || E_taillabel) {
432
430
    }
433
431
    /* end vladimir */
434
432
 
435
 
    free(edges);
436
 
    free(P->boxes);
437
 
    free(P);
438
 
    free(sd.Rank_box);
439
 
    routesplinesterm();
 
433
#ifdef ORTHO
 
434
    if (et != ET_ORTHO) {
 
435
#endif
 
436
        free(edges);
 
437
        free(P->boxes);
 
438
        free(P);
 
439
        free(sd.Rank_box);
 
440
        routesplinesterm();
 
441
#ifdef ORTHO
 
442
    } 
 
443
#endif
440
444
    State = GVSPLINES;
441
445
}
442
446
 
463
467
    for (e = ND_out(n).list[0]; ED_edge_type(e) != NORMAL;
464
468
         e = ED_to_orig(e));
465
469
    dimen = ED_label(e)->dimen;
466
 
    width = GD_flip(n->graph) ? dimen.y : dimen.x;
467
 
    ED_label(e)->p.x = ND_coord_i(n).x + width / 2.0;
468
 
    ED_label(e)->p.y = ND_coord_i(n).y;
 
470
    width = GD_flip(agraphof(n)) ? dimen.y : dimen.x;
 
471
    ED_label(e)->pos.x = ND_coord(n).x + width / 2.0;
 
472
    ED_label(e)->pos.y = ND_coord(n).y;
469
473
}
470
474
 
471
475
static void 
475
479
    if (hint1 != 0)
476
480
        f1 = hint1;
477
481
    else {
478
 
        if (e->tail == e->head)
 
482
        if (agtail(e) == aghead(e))
479
483
            if (ED_tail_port(e).defined || ED_head_port(e).defined)
480
484
                f1 = SELFWPEDGE;
481
485
            else
482
486
                f1 = SELFNPEDGE;
483
 
        else if (ND_rank(e->tail) == ND_rank(e->head))
 
487
        else if (ND_rank(agtail(e)) == ND_rank(aghead(e)))
484
488
            f1 = FLATEDGE;
485
489
        else
486
490
            f1 = REGULAREDGE;
489
493
        f2 = hint2;
490
494
    else {
491
495
        if (f1 == REGULAREDGE)
492
 
            f2 = (ND_rank(e->tail) < ND_rank(e->head)) ? FWDEDGE : BWDEDGE;
 
496
            f2 = (ND_rank(agtail(e)) < ND_rank(aghead(e))) ? FWDEDGE : BWDEDGE;
493
497
        else if (f1 == FLATEDGE)
494
 
            f2 = (ND_order(e->tail) < ND_order(e->head)) ?
495
 
                FWDEDGE : BWDEDGE;
 
498
            f2 = (ND_order(agtail(e)) < ND_order(aghead(e))) ?  FWDEDGE : BWDEDGE;
496
499
        else                    /* f1 == SELF*EDGE */
497
500
            f2 = FWDEDGE;
498
501
    }
514
517
{
515
518
    edge_t fwdedgea, fwdedgeb, *e0, *e1, *ea, *eb, *le0, *le1;
516
519
    int et0, et1, v0, v1, rv;
 
520
    double t0, t1;
517
521
 
518
522
    e0 = (edge_t *) * ptr0;
519
523
    e1 = (edge_t *) * ptr1;
521
525
    et1 = ED_tree_index(e1) & EDGETYPEMASK;
522
526
    if (et0 != et1)
523
527
        return (et1 - et0);
 
528
 
524
529
    le0 = getmainedge(e0);
525
530
    le1 = getmainedge(e1);
526
 
    v0 = ND_rank(le0->tail) - ND_rank(le0->head), v0 = ABS(v0);
527
 
    v1 = ND_rank(le1->tail) - ND_rank(le1->head), v1 = ABS(v1);
528
 
    if (v0 != v1)
529
 
        return (v0 - v1);
530
 
    v0 = ND_coord_i(le0->tail).x - ND_coord_i(le0->head).x, v0 = ABS(v0);
531
 
    v1 = ND_coord_i(le1->tail).x - ND_coord_i(le1->head).x, v1 = ABS(v1);
532
 
    if (v0 != v1)
533
 
        return (v0 - v1);
534
 
    /* This provides a cheap test for edges having the same set of endpoints.
535
 
     */
536
 
    if (le0->id != le1->id)
537
 
        return (le0->id - le1->id);
 
531
 
 
532
    t0 = ND_rank(agtail(le0)) - ND_rank(aghead(le0));
 
533
    t1 = ND_rank(agtail(le1)) - ND_rank(aghead(le1));
 
534
    v0 = ABS((int)t0);   /* ugly, but explicit as to how we avoid equality tests on fp numbers */
 
535
    v1 = ABS((int)t1);
 
536
    if (v0 != v1)
 
537
        return (v0 - v1);
 
538
 
 
539
    t0 = ND_coord(agtail(le0)).x - ND_coord(aghead(le0)).x;
 
540
    t1 = ND_coord(agtail(le1)).x - ND_coord(aghead(le1)).x;
 
541
    v0 = ABS((int)t0);
 
542
    v1 = ABS((int)t1);
 
543
    if (v0 != v1)
 
544
        return (v0 - v1);
 
545
 
 
546
    /* This provides a cheap test for edges having the same set of endpoints.  */
 
547
    if (AGID(le0) != AGID(le1))
 
548
        return (AGID(le0) - AGID(le1));
 
549
 
538
550
    ea = (ED_tail_port(e0).defined || ED_head_port(e0).defined) ? e0 : le0;
539
551
    if (ED_tree_index(ea) & BWDEDGE) {
540
552
        MAKEFWDEDGE(&fwdedgea, ea);
549
561
        return rv;
550
562
    if ((rv = portcmp(ED_head_port(ea), ED_head_port(eb))))
551
563
        return rv;
552
 
    v0 = ED_tree_index(e0) & GRAPHTYPEMASK;
553
 
    v1 = ED_tree_index(e1) & GRAPHTYPEMASK;
554
 
    if (v0 != v1)
555
 
        return (v0 - v1);
 
564
 
 
565
    et0 = ED_tree_index(e0) & GRAPHTYPEMASK;
 
566
    et1 = ED_tree_index(e1) & GRAPHTYPEMASK;
 
567
    if (et0 != et1)
 
568
        return (et0 - et1);
 
569
 
556
570
    if (et0 == FLATEDGE && ED_label(e0) != ED_label(e1))
557
571
        return (int) (ED_label(e0) - ED_label(e1));
558
 
    return (e0->id - e1->id);
559
 
}
560
 
 
561
 
#if 0
562
 
/* fledgecmp:
563
 
 * Sort edges by mid y value of ports.
564
 
 * If this is the same, and all y values are the same,
565
 
 * check if one segment lies within the other.
566
 
 */
567
 
static int 
568
 
fledgecmp(edge_t** ptr0, edge_t** ptr1)
569
 
{
570
 
    edge_t *e0, *e1;
571
 
    point tp0, tp1, hp0, hp1;
572
 
    int y0, y1;
573
 
 
574
 
    e0 = *ptr0;
575
 
    e1 = *ptr1;
576
 
    tp0 = ED_tail_port(e0).p;
577
 
    hp0 = ED_head_port(e0).p;
578
 
    tp1 = ED_tail_port(e1).p;
579
 
    hp1 = ED_head_port(e1).p;
580
 
    y0 = (tp0.y + hp0.y)/2;
581
 
    y1 = (tp1.y + hp1.y)/2;
582
 
    if (y0 != y1) return (y0-y1);
583
 
    if ((tp0.y == hp0.y) && (tp1.y == hp1.y)) {
584
 
        if ((tp0.x <= tp1.x) && (hp0.x >= hp1.x)) {
585
 
            if (tp0.y <= 0) return -1;
586
 
            else return 1;
587
 
        }
588
 
        else if ((tp0.x >= tp1.x) && (hp0.x <= hp1.x)) {
589
 
            if (tp0.y <= 0) return 1;
590
 
            else return -1;
591
 
        }
592
 
    }
593
 
    return (e0->id - e1->id);
594
 
 
595
 
}
596
 
 
597
 
#define LABEL_SPACE 8
598
 
 
599
 
/* setFlatAdjPos:
600
 
 * Create middle boxes for routing using ordered list of edges going from
601
 
 * bottom to top.
602
 
 * Also, set label positions.
603
 
 */
604
 
static void
605
 
setFlatAdjPos (edge_t** edges, int n_edges, int flip, box* boxes, edge_t* e0)
606
 
{
607
 
    int r, i, x, boxw, availht;
608
 
    edge_t* e;
609
 
    double  y, wd, ht, totalht = 0;
610
 
    textlabel_t* lbl;
611
 
    node_t *tn, *hn;
612
 
    graph_t* g;
613
 
 
614
 
assert(0);
615
 
    tn = e0->tail, hn = e0->head;
616
 
    g = tn->graph;
617
 
    x = (ND_coord_i(tn).x + ND_coord_i(hn).x)/2;
618
 
    y = ND_coord_i(tn).y;
619
 
    r = ND_rank(tn);
620
 
    availht = GD_rank(g)[r].ht2 + GD_rank(g)[r].ht1 + GD_ranksep(g);
621
 
    boxw = (ND_coord_i(hn).x - ND_coord_i(tn).x - ND_rw_i(tn) - ND_lw_i(hn))/3;
622
 
    for (i = 0; i < n_edges; i++) {
623
 
        if (!((lbl = ED_label(e)))) continue;
624
 
        if (flip) {
625
 
            ht = lbl->dimen.x;
626
 
            wd = lbl->dimen.y;
627
 
        }
628
 
        else {
629
 
            ht = lbl->dimen.y; 
630
 
            wd = lbl->dimen.x; 
631
 
        }
632
 
        totalht += ht;
633
 
        boxw = MAX(boxw, wd);
634
 
    }
635
 
    for (i = 0; i < n_edges; i++) {
636
 
        e = edges[i];
637
 
        lbl = ED_label(e);
638
 
        if (GD_flip(g)) ht = lbl->dimen.x;
639
 
        else ht = lbl->dimen.y; 
640
 
        lbl->p.x = x;
641
 
        lbl->p.y = ROUND(y - ht/2);
642
 
        y -= ht + LABEL_SPACE;
643
 
    }
644
 
}
645
 
#endif
646
 
 
 
572
 
 
573
    return (AGID(e0) - AGID(e1));
 
574
}
 
575
 
647
576
/* cloneGraph:
648
577
 */
649
578
static struct {
668
597
{
669
598
    Agsym_t* sym;
670
599
    graph_t* auxg;
 
600
#ifndef WITH_CGRAPH
671
601
    Agsym_t **list;
672
 
    
 
602
 
673
603
    auxg = agopen ("auxg", AG_IS_DIRECTED(g)?AGDIGRAPH:AGRAPH);
674
604
    agraphattr(auxg, "rank", "");
 
605
#else /* WITH_CGRAPH */
 
606
//    auxg = agopen ("auxg", AG_IS_DIRECTED(g)?AGDIGRAPH:AGRAPH);
 
607
 
 
608
        if (agisdirected(g))
 
609
                auxg = agopen ("auxg",Agdirected, NIL(Agdisc_t *));
 
610
        else
 
611
                auxg = agopen ("auxg",Agundirected, NIL(Agdisc_t *));
 
612
 
 
613
 
 
614
    agattr(auxg, AGRAPH, "rank", "");
 
615
#endif /* WITH_CGRAPH */
675
616
    GD_drawing(auxg) = NEW(layout_t);
676
617
    GD_drawing(auxg)->quantum = GD_drawing(g)->quantum; 
677
618
    GD_drawing(auxg)->dpi = GD_drawing(g)->dpi;
684
625
    GD_nodesep(auxg) = GD_nodesep(g);
685
626
    GD_ranksep(auxg) = GD_ranksep(g);
686
627
 
 
628
#ifndef WITH_CGRAPH
687
629
    list = g->root->univ->nodeattr->list;
688
630
    while ((sym = *list++)) {
689
631
        agnodeattr (auxg, sym->name, sym->value);
 
632
#else /* WITH_CGRAPH */
 
633
        //copy node attrs to auxg
 
634
//      list = g->root->univ->nodeattr->list;
 
635
        sym=agnxtattr(agroot(g),AGNODE,NULL); //get the first attr.
 
636
        while ((sym = agnxtattr(agroot(g),AGNODE,sym))) {
 
637
                agattr (auxg, AGNODE,sym->name, sym->defval     );
 
638
#endif /* WITH_CGRAPH */
690
639
    }
691
640
 
 
641
#ifndef WITH_CGRAPH
692
642
    list = g->root->univ->edgeattr->list;
693
643
    while ((sym = *list++)) {
694
644
        agedgeattr (auxg, sym->name, sym->value);
 
645
#else /* WITH_CGRAPH */
 
646
        //copy edge attributes
 
647
        sym=agnxtattr(agroot(g),AGEDGE,NULL); //get the first attr.
 
648
        while ((sym = agnxtattr(agroot(g),AGEDGE,sym))) {
 
649
        agattr (auxg, AGEDGE,sym->name, sym->defval);
 
650
#endif /* WITH_CGRAPH */
695
651
    }
696
652
 
 
653
#ifdef WITH_CGRAPH
 
654
 
 
655
#endif /* WITH_CGRAPH */
697
656
    attr_state.E_constr = E_constr;
698
657
    attr_state.E_samehead = E_samehead;
699
658
    attr_state.E_sametail = E_sametail;
702
661
    attr_state.N_group = N_group;
703
662
    attr_state.State = State;
704
663
    E_constr = NULL;
 
664
#ifndef WITH_CGRAPH
705
665
    E_samehead = agfindattr(auxg->proto->e, "samehead");
706
666
    E_sametail = agfindattr(auxg->proto->e, "sametail");
707
667
    E_weight = agfindattr(auxg->proto->e, "weight");
 
668
#else /* WITH_CGRAPH */
 
669
    E_samehead = agattr(auxg,AGEDGE, "samehead", NULL);
 
670
    E_sametail = agattr(auxg,AGEDGE, "sametail", NULL);
 
671
    E_weight = agattr(auxg,AGEDGE, "weight", NULL);
 
672
#endif /* WITH_CGRAPH */
708
673
    if (!E_weight)
 
674
#ifndef WITH_CGRAPH
709
675
        E_weight = agedgeattr (auxg, "weight", "");
 
676
#else /* WITH_CGRAPH */
 
677
        E_weight = agattr (auxg,AGEDGE,"weight", "");
 
678
#endif /* WITH_CGRAPH */
710
679
    E_minlen = NULL;
711
680
    N_group = NULL;
712
681
 
739
708
static node_t*
740
709
cloneNode (graph_t* g, node_t* orign, int flipped)
741
710
{
 
711
#ifndef WITH_CGRAPH
742
712
    node_t* n = agnode(g, orign->name);
 
713
#else /* WITH_CGRAPH */
 
714
    node_t* n = agnode(g, agnameof(orign),1);
 
715
    agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE);   //node custom data
 
716
 
 
717
#endif /* WITH_CGRAPH */
743
718
    agcopyattr (orign, n);
744
719
    if (shapeOf(orign) == SH_RECORD) {
745
720
        int lbllen = strlen(ND_label(orign)->text);
756
731
static edge_t*
757
732
cloneEdge (graph_t* g, node_t* tn, node_t* hn, edge_t* orig)
758
733
{
 
734
#ifndef WITH_CGRAPH
759
735
    edge_t* e = agedge(g, tn, hn);
 
736
#else /* WITH_CGRAPH */
 
737
    edge_t* e = agedge(g, tn, hn,NULL,1);
 
738
#endif /* WITH_CGRAPH */
760
739
    for (; ED_edge_type(orig) != NORMAL; orig = ED_to_orig(orig));
761
740
    agcopyattr (orig, e);
762
741
 
763
742
    return e;
764
743
}
765
744
 
766
 
/* transform:
 
745
/* transformf:
767
746
 * Rotate, if necessary, then translate points.
768
747
 */
769
 
static point
770
 
transform (point p, point del, int flip)
 
748
static pointf
 
749
transformf (pointf p, pointf del, int flip)
771
750
{
772
751
    if (flip) {
773
 
        int i = p.x;
 
752
        double i = p.x;
774
753
        p.x = p.y;
775
754
        p.y = -i;
776
755
    }
777
 
    return add_points(p, del);
 
756
    return add_pointf(p, del);
778
757
}
779
758
 
780
759
/* makeSimpleFlat:
783
762
makeSimpleFlat (node_t* tn, node_t* hn, edge_t** edges, int ind, int cnt, int et)
784
763
{
785
764
    edge_t* e = edges[ind];
786
 
    point points[10];
787
 
    int i, pointn, stepy = (cnt > 1) ? ND_ht_i(tn) / (cnt - 1) : 0;
788
 
    point tp = add_points(ND_coord_i(tn), ED_tail_port(e).p);
789
 
    point hp = add_points(ND_coord_i(hn), ED_head_port(e).p);
790
 
    int dy = tp.y - ((cnt > 1) ? ND_ht_i(tn) / 2 : 0);
 
765
    pointf points[10], tp, hp;
 
766
    int i, pointn;
 
767
    double stepy, dy;
 
768
 
 
769
    tp = add_pointf(ND_coord(tn), ED_tail_port(e).p);
 
770
    hp = add_pointf(ND_coord(hn), ED_head_port(e).p);
 
771
 
 
772
    stepy = (cnt > 1) ? ND_ht(tn) / (double)(cnt - 1) : 0.;
 
773
    dy = tp.y - ((cnt > 1) ? ND_ht(tn) / 2. : 0.);
 
774
 
791
775
    for (i = 0; i < cnt; i++) {
792
776
        e = edges[ind + i];
793
777
        pointn = 0;
794
778
        if ((et == ET_SPLINE) || (et == ET_LINE)) {
795
779
            points[pointn++] = tp;
796
 
            points[pointn++] = pointof((2 * tp.x + hp.x) / 3, dy);
797
 
            points[pointn++] = pointof((2 * hp.x + tp.x) / 3, dy);
 
780
            points[pointn++] = pointfof((2 * tp.x + hp.x) / 3, dy);
 
781
            points[pointn++] = pointfof((2 * hp.x + tp.x) / 3, dy);
798
782
            points[pointn++] = hp;
799
783
        }
800
 
        else {
801
 
            points[pointn++] = tp;
802
 
            points[pointn++] = tp;
803
 
            points[pointn++] = pointof((2 * tp.x + hp.x) / 3, dy);
804
 
            points[pointn++] = pointof((2 * tp.x + hp.x) / 3, dy);
805
 
            points[pointn++] = pointof((2 * tp.x + hp.x) / 3, dy);
806
 
            points[pointn++] = pointof((2 * hp.x + tp.x) / 3, dy);
807
 
            points[pointn++] = pointof((2 * hp.x + tp.x) / 3, dy);
808
 
            points[pointn++] = pointof((2 * hp.x + tp.x) / 3, dy);
 
784
        else {   /* ET_PLINE */
 
785
            points[pointn++] = tp;
 
786
            points[pointn++] = tp;
 
787
            points[pointn++] = pointfof((2 * tp.x + hp.x) / 3, dy);
 
788
            points[pointn++] = pointfof((2 * tp.x + hp.x) / 3, dy);
 
789
            points[pointn++] = pointfof((2 * tp.x + hp.x) / 3, dy);
 
790
            points[pointn++] = pointfof((2 * hp.x + tp.x) / 3, dy);
 
791
            points[pointn++] = pointfof((2 * hp.x + tp.x) / 3, dy);
 
792
            points[pointn++] = pointfof((2 * hp.x + tp.x) / 3, dy);
809
793
            points[pointn++] = hp;
810
794
            points[pointn++] = hp;
811
795
        }
812
796
        dy += stepy;
 
797
#ifndef WITH_CGRAPH
813
798
        clip_and_install(e, e->head, points, pointn, &sinfo);
 
799
#else /* WITH_CGRAPH */
 
800
        clip_and_install(e, aghead(e), points, pointn, &sinfo);
 
801
#endif /* WITH_CGRAPH */
814
802
    }
815
803
}
816
804
 
834
822
    node_t *auxt, *auxh;
835
823
    edge_t* auxe;
836
824
    int     i, j, midx, midy, leftx, rightx;
837
 
    point   del;
 
825
    pointf   del;
838
826
    edge_t* hvye = NULL;
839
827
 
840
 
    g = e0->tail->graph;
841
 
    tn = e0->tail, hn = e0->head;
 
828
    g = agraphof(agtail(e0));
 
829
    tn = agtail(e0), hn = aghead(e0);
842
830
    for (i = 0; i < cnt; i++) {
843
831
        e = edges[ind + i];
844
832
        if (ND_label(e)) labels++;
852
840
    }
853
841
 
854
842
    auxg = cloneGraph (g);
 
843
#ifndef WITH_CGRAPH
855
844
    subg = agsubg (auxg, "xxx");
 
845
#else /* WITH_CGRAPH */
 
846
    subg = agsubg (auxg, "xxx",1);
 
847
        agbindrec(subg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);    //node custom data
 
848
 
 
849
#endif /* WITH_CGRAPH */
856
850
    agset (subg, "rank", "source");
857
 
    rightx = ND_coord_i(hn).x;
858
 
    leftx = ND_coord_i(tn).x;
 
851
    rightx = ND_coord(hn).x;
 
852
    leftx = ND_coord(tn).x;
859
853
    if (GD_flip(g)) {
860
854
        node_t* n;
861
855
        n = tn;
866
860
    auxh = cloneNode(auxg, hn, GD_flip(g)); 
867
861
    for (i = 0; i < cnt; i++) {
868
862
        e = edges[ind + i];
869
 
        if (e->tail == tn)
 
863
        if (agtail(e) == tn)
870
864
            auxe = cloneEdge (auxg, auxt, auxh, e);
871
865
        else
872
866
            auxe = cloneEdge (auxg, auxh, auxt, e);
877
871
        }
878
872
    }
879
873
    if (!hvye) {
 
874
#ifndef WITH_CGRAPH
880
875
        hvye = agedge (auxg, auxt, auxh);
 
876
#else /* WITH_CGRAPH */
 
877
        hvye = agedge (auxg, auxt, auxh,NULL,1);
 
878
#endif /* WITH_CGRAPH */
881
879
    }
 
880
#ifndef WITH_CGRAPH
882
881
    agxset (hvye, E_weight->index, "10000");
 
882
#else /* WITH_CGRAPH */
 
883
    agxset (hvye, E_weight, "10000");
 
884
#endif /* WITH_CGRAPH */
883
885
    GD_gvc(auxg) = GD_gvc(g);
884
886
    setEdgeType (auxg, et);
885
887
    dot_init_node_edge(auxg);
886
888
 
887
 
    dot_rank(auxg);
888
 
    dot_mincross(auxg);
889
 
    dot_position(auxg);
 
889
    dot_rank(auxg, 0);
 
890
    dot_mincross(auxg, 0);
 
891
    dot_position(auxg, 0);
890
892
    
891
893
    /* reposition */
892
 
    midx = (ND_coord_i(tn).x - ND_rw_i(tn) + ND_coord_i(hn).x + ND_lw_i(hn))/2;
893
 
    midy = (ND_coord_i(auxt).x + ND_coord_i(auxh).x)/2;
 
894
    midx = (ND_coord(tn).x - ND_rw(tn) + ND_coord(hn).x + ND_lw(hn))/2;
 
895
    midy = (ND_coord(auxt).x + ND_coord(auxh).x)/2;
894
896
    for (n = GD_nlist(auxg); n; n = ND_next(n)) {
895
897
        if (n == auxt) {
896
 
            ND_coord_i(n).y = rightx;
897
 
            ND_coord_i(n).x = midy;
 
898
            ND_coord(n).y = rightx;
 
899
            ND_coord(n).x = midy;
898
900
        }
899
901
        else if (n == auxh) {
900
 
            ND_coord_i(n).y = leftx;
901
 
            ND_coord_i(n).x = midy;
 
902
            ND_coord(n).y = leftx;
 
903
            ND_coord(n).x = midy;
902
904
        }
903
 
        else ND_coord_i(n).y = midx;
 
905
        else ND_coord(n).y = midx;
904
906
    }
905
907
    dot_sameports(auxg);
906
908
    _dot_splines(auxg, 0);
908
910
 
909
911
       /* copy splines */
910
912
    if (GD_flip(g)) {
911
 
        del.x = ND_coord_i(tn).x - ND_coord_i(auxt).y;
912
 
        del.y = ND_coord_i(tn).y + ND_coord_i(auxt).x;
 
913
        del.x = ND_coord(tn).x - ND_coord(auxt).y;
 
914
        del.y = ND_coord(tn).y + ND_coord(auxt).x;
913
915
    }
914
916
    else {
915
 
        del.x = ND_coord_i(tn).x - ND_coord_i(auxt).x;
916
 
        del.y = ND_coord_i(tn).y - ND_coord_i(auxt).y;
 
917
        del.x = ND_coord(tn).x - ND_coord(auxt).x;
 
918
        del.y = ND_coord(tn).y - ND_coord(auxt).y;
917
919
    }
918
920
    for (i = 0; i < cnt; i++) {
919
921
        bezier* auxbz;
926
928
        bz = new_spline(e, auxbz->size);
927
929
        if (GD_flip(g)) {
928
930
            bz->sflag = auxbz->eflag;
929
 
            bz->sp = transform(auxbz->ep, del, 1);
 
931
            bz->sp = transformf(auxbz->ep, del, 1);
930
932
            bz->eflag = auxbz->sflag;
931
 
            bz->ep = transform(auxbz->sp, del, 1);
 
933
            bz->ep = transformf(auxbz->sp, del, 1);
932
934
        }
933
935
        else {
934
936
            bz->sflag = auxbz->sflag;
935
 
            bz->sp = transform(auxbz->sp, del, 0);
 
937
            bz->sp = transformf(auxbz->sp, del, 0);
936
938
            bz->eflag = auxbz->eflag;
937
 
            bz->ep = transform(auxbz->ep, del, 0);
 
939
            bz->ep = transformf(auxbz->ep, del, 0);
938
940
        }
939
941
        for (j = 0; j <  auxbz->size; ) {
940
 
            point pt, pt1, pt2;
941
 
            pt = bz->list[j] = transform(auxbz->list[j], del, GD_flip(g));
 
942
            pointf cp[4];
 
943
            cp[0] = bz->list[j] = transformf(auxbz->list[j], del, GD_flip(g));
942
944
            j++;
943
 
            update_bb(g, pt);
944
945
            if ( j >= auxbz->size ) 
945
946
                break;
946
 
            /* take the mid-point between the two control points in bb calculation */
947
 
            pt1 = bz->list[j] = transform(auxbz->list[j], del, GD_flip(g));
948
 
            j++;
949
 
            pt2 = bz->list[j] = transform(auxbz->list[j], del, GD_flip(g));
950
 
            j++;
951
 
            pt.x = ( pt1.x + pt2.x ) / 2;
952
 
            pt.y = ( pt1.y + pt2.y ) / 2;
953
 
            update_bb(g, pt);
 
947
            cp[1] = bz->list[j] = transformf(auxbz->list[j], del, GD_flip(g));
 
948
            j++;
 
949
            cp[2] = bz->list[j] = transformf(auxbz->list[j], del, GD_flip(g));
 
950
            j++;
 
951
            cp[3] = transformf(auxbz->list[j], del, GD_flip(g));
 
952
            update_bb_bz(&GD_bb(g), cp);
954
953
        }
955
954
        if (ED_label(e)) {
956
 
            ED_label(e)->p = transform(ED_label(auxe)->p, del, GD_flip(g));
 
955
            ED_label(e)->pos = transformf(ED_label(auxe)->pos, del, GD_flip(g));
957
956
            updateBB(g, ED_label(e));
958
957
        }
959
958
    }
967
966
makeFlatEnd (spline_info_t* sp, path* P, node_t* n, edge_t* e, pathend_t* endp,
968
967
             boolean isBegin)
969
968
{
970
 
    box b;
971
 
    graph_t* g = n->graph;
 
969
    boxf b;
 
970
    graph_t* g = agraphof(n);
972
971
 
973
972
    b = endp->nb = maximal_bbox(sp, n, NULL, e);
974
973
    endp->sidemask = TOP;
976
975
    else endpath(P, e, FLATEDGE, endp, FALSE);
977
976
    b.UR.y = endp->boxes[endp->boxn - 1].UR.y;
978
977
    b.LL.y = endp->boxes[endp->boxn - 1].LL.y;
979
 
    b = makeregularend(b, TOP, ND_coord_i(n).y + GD_rank(g)[ND_rank(n)].ht2);
 
978
    b = makeregularend(b, TOP, ND_coord(n).y + GD_rank(g)[ND_rank(n)].ht2);
980
979
    if (b.LL.x < b.UR.x && b.LL.y < b.UR.y)
981
980
        endp->boxes[endp->boxn++] = b;
982
981
}
986
985
makeBottomFlatEnd (spline_info_t* sp, path* P, node_t* n, edge_t* e, 
987
986
        pathend_t* endp, boolean isBegin)
988
987
{
989
 
    box b;
990
 
    graph_t* g = n->graph;
 
988
    boxf b;
 
989
    graph_t* g = agraphof(n);
991
990
 
992
991
    b = endp->nb = maximal_bbox(sp, n, NULL, e);
993
992
    endp->sidemask = BOTTOM;
995
994
    else endpath(P, e, FLATEDGE, endp, FALSE);
996
995
    b.UR.y = endp->boxes[endp->boxn - 1].UR.y;
997
996
    b.LL.y = endp->boxes[endp->boxn - 1].LL.y;
998
 
    b = makeregularend(b, BOTTOM, ND_coord_i(n).y - GD_rank(g)[ND_rank(n)].ht2);
 
997
    b = makeregularend(b, BOTTOM, ND_coord(n).y - GD_rank(g)[ND_rank(n)].ht2);
999
998
    if (b.LL.x < b.UR.x && b.LL.y < b.UR.y)
1000
999
        endp->boxes[endp->boxn++] = b;
1001
1000
}
1008
1007
{
1009
1008
    graph_t *g;
1010
1009
    node_t *tn, *hn, *ln;
1011
 
    point *ps;
 
1010
    pointf *ps;
1012
1011
    pathend_t tend, hend;
1013
 
    box lb;
 
1012
    boxf lb;
1014
1013
    int boxn, i, pn, ydelta;
1015
1014
    edge_t *f;
1016
 
    point points[7];
 
1015
    pointf points[7];
1017
1016
 
1018
 
    g = e->tail->graph;
1019
 
    tn = e->tail;
1020
 
    hn = e->head;
 
1017
    tn = agtail(e);
 
1018
    hn = aghead(e);
 
1019
    g = agraphof(tn);
1021
1020
 
1022
1021
    for (f = ED_to_virt(e); ED_to_virt(f); f = ED_to_virt(f));
1023
 
    ln = f->tail;
1024
 
    ED_label(e)->p = ND_coord_i(ln);
 
1022
    ln = agtail(f);
 
1023
    ED_label(e)->pos = ND_coord(ln);
1025
1024
 
1026
1025
    if (et == ET_LINE) {
1027
 
        point startp, endp, lp;
1028
 
        startp = add_points(ND_coord_i(tn), ED_tail_port(e).p);
1029
 
        endp = add_points(ND_coord_i(hn), ED_head_port(e).p);
1030
 
        lp = ED_label(e)->p;
 
1026
        pointf startp, endp, lp;
 
1027
 
 
1028
        startp = add_pointf(ND_coord(tn), ED_tail_port(e).p);
 
1029
        endp = add_pointf(ND_coord(hn), ED_head_port(e).p);
 
1030
 
 
1031
        lp = ED_label(e)->pos;
1031
1032
        lp.y -= (ED_label(e)->dimen.y)/2.0;
1032
1033
        points[1] = points[0] = startp;
1033
1034
        points[2] = points[3] = points[4] = lp;
1036
1037
        pn = 7;
1037
1038
    }
1038
1039
    else {
1039
 
        lb.LL.x = ND_coord_i(ln).x - ND_lw_i(ln);
1040
 
        lb.UR.x = ND_coord_i(ln).x + ND_rw_i(ln);
1041
 
        lb.UR.y = ND_coord_i(ln).y + ND_ht_i(ln)/2;
1042
 
        ydelta = ND_coord_i(ln).y - GD_rank(g)[ND_rank(tn)].ht1 -
1043
 
                ND_coord_i(tn).y + GD_rank(g)[ND_rank(tn)].ht2;
1044
 
        ydelta /= 6;
1045
 
        lb.LL.y = lb.UR.y - MAX(5,ydelta); 
 
1040
        lb.LL.x = ND_coord(ln).x - ND_lw(ln);
 
1041
        lb.UR.x = ND_coord(ln).x + ND_rw(ln);
 
1042
        lb.UR.y = ND_coord(ln).y + ND_ht(ln)/2;
 
1043
        ydelta = ND_coord(ln).y - GD_rank(g)[ND_rank(tn)].ht1 -
 
1044
                ND_coord(tn).y + GD_rank(g)[ND_rank(tn)].ht2;
 
1045
        ydelta /= 6.;
 
1046
        lb.LL.y = lb.UR.y - MAX(5.,ydelta); 
1046
1047
 
1047
1048
        boxn = 0;
1048
1049
        makeFlatEnd (sp, P, tn, e, &tend, TRUE);
1072
1073
        else ps = routepolylines(P, &pn);
1073
1074
        if (pn == 0) return;
1074
1075
    }
 
1076
#ifndef WITH_CGRAPH
1075
1077
    clip_and_install(e, e->head, ps, pn, &sinfo);
 
1078
#else /* WITH_CGRAPH */
 
1079
    clip_and_install(e, aghead(e), ps, pn, &sinfo);
 
1080
#endif /* WITH_CGRAPH */
1076
1081
}
1077
1082
 
1078
1083
/* make_flat_bottom_edges:
1085
1090
    int j, i, stepx, stepy, vspace, r;
1086
1091
    rank_t* nextr;
1087
1092
    int pn;
1088
 
    point *ps;
 
1093
    pointf *ps;
1089
1094
    pathend_t tend, hend;
1090
1095
    graph_t* g;
1091
1096
 
1092
 
    tn = e->tail, hn = e->head;
1093
 
    g = tn->graph;
 
1097
    tn = agtail(e);
 
1098
    hn = aghead(e);
 
1099
    g = agraphof(tn);
1094
1100
    r = ND_rank(tn);
1095
1101
    if (r < GD_maxrank(g)) {
1096
1102
        nextr = GD_rank(g) + (r+1);
1097
 
        vspace = ND_coord_i(tn).y - GD_rank(g)[r].pht1 -
1098
 
                (ND_coord_i(nextr->v[0]).y + nextr->pht2);
 
1103
        vspace = ND_coord(tn).y - GD_rank(g)[r].pht1 -
 
1104
                (ND_coord(nextr->v[0]).y + nextr->pht2);
1099
1105
    }
1100
1106
    else {
1101
1107
        vspace = GD_ranksep(g);
1108
1114
 
1109
1115
    for (i = 0; i < cnt; i++) {
1110
1116
        int boxn;
1111
 
        box b;
 
1117
        boxf b;
1112
1118
        e = edges[ind + i];
1113
1119
        boxn = 0;
1114
1120
 
1138
1144
        else ps = routepolylines(P, &pn);
1139
1145
        if (pn == 0)
1140
1146
            return;
1141
 
        clip_and_install(e, e->head, ps, pn, &sinfo);
 
1147
        clip_and_install(e, aghead(e), ps, pn, &sinfo);
1142
1148
        P->nbox = 0;
1143
1149
    }
1144
1150
}
1159
1165
    edge_t fwdedge, *e;
1160
1166
    int j, i, stepx, stepy, vspace, r;
1161
1167
    int tside, hside, pn;
1162
 
    point *ps;
 
1168
    pointf *ps;
1163
1169
    pathend_t tend, hend;
1164
1170
    graph_t* g;
1165
1171
 
1179
1185
    }
1180
1186
 
1181
1187
    if (et == ET_LINE) {
1182
 
        makeSimpleFlat (e->tail, e->head, edges, ind, cnt, et);
 
1188
        makeSimpleFlat (agtail(e), aghead(e), edges, ind, cnt, et);
1183
1189
        return;
1184
1190
    }
1185
1191
 
1191
1197
        return;
1192
1198
    }
1193
1199
 
1194
 
    tn = e->tail, hn = e->head;
1195
 
    g = tn->graph;
 
1200
    tn = agtail(e);
 
1201
    hn = aghead(e);
 
1202
    g = agraphof(tn);
1196
1203
    r = ND_rank(tn);
1197
1204
    if (r > 0) {
1198
1205
        rank_t* prevr;
1200
1207
            prevr = GD_rank(g) + (r-2);
1201
1208
        else
1202
1209
            prevr = GD_rank(g) + (r-1);
1203
 
        vspace = ND_coord_i(prevr->v[0]).y - prevr->ht1 - ND_coord_i(tn).y - GD_rank(g)[r].ht2;
 
1210
        vspace = ND_coord(prevr->v[0]).y - prevr->ht1 - ND_coord(tn).y - GD_rank(g)[r].ht2;
1204
1211
    }
1205
1212
    else {
1206
1213
        vspace = GD_ranksep(g);
1213
1220
 
1214
1221
    for (i = 0; i < cnt; i++) {
1215
1222
        int boxn;
1216
 
        box b;
 
1223
        boxf b;
1217
1224
        e = edges[ind + i];
1218
1225
        boxn = 0;
1219
1226
 
1243
1250
        else ps = routepolylines(P, &pn);
1244
1251
        if (pn == 0)
1245
1252
            return;
1246
 
        clip_and_install(e, e->head, ps, pn, &sinfo);
 
1253
        clip_and_install(e, aghead(e), ps, pn, &sinfo);
1247
1254
        P->nbox = 0;
1248
1255
    }
1249
1256
}
1252
1259
 * Return true if p3 is to left of ray p1->p2
1253
1260
 */
1254
1261
static int
1255
 
leftOf (point p1, point p2, point p3)
 
1262
leftOf (pointf p1, pointf p2, pointf p3)
1256
1263
{
1257
1264
    int d;
1258
1265
 
1277
1284
 * multiple edges better.
1278
1285
 */
1279
1286
static int 
1280
 
makeLineEdge(edge_t* fe, point* points, node_t** hp)
 
1287
makeLineEdge(edge_t* fe, pointf* points, node_t** hp)
1281
1288
{
1282
1289
    int delr, pn;
1283
1290
    node_t* hn;
1284
1291
    node_t* tn;
1285
1292
    edge_t* e = fe;
1286
 
    point startp, endp, lp;
 
1293
    pointf startp, endp, lp;
1287
1294
    pointf dimen;
1288
1295
    double width, height;
1289
1296
 
1290
1297
    while (ED_edge_type(e) != NORMAL)
1291
1298
        e = ED_to_orig(e);
1292
 
    hn = e->head;
1293
 
    tn = e->tail;
 
1299
    hn = aghead(e);
 
1300
    tn = agtail(e);
1294
1301
    delr = ABS(ND_rank(hn)-ND_rank(tn));
1295
 
    if ((delr == 1) || ((delr == 2) && (GD_has_labels(hn->graph) & EDGE_LABEL)))
 
1302
    if ((delr == 1) || ((delr == 2) && (GD_has_labels(agraphof(hn)) & EDGE_LABEL)))
1296
1303
        return 0;
1297
 
    if (fe->tail == e->tail) {
 
1304
    if (agtail(fe) == agtail(e)) {
1298
1305
        *hp = hn;
1299
 
        startp = add_points(ND_coord_i(tn), ED_tail_port(e).p);
1300
 
        endp = add_points(ND_coord_i(hn), ED_head_port(e).p);
 
1306
        startp = add_pointf(ND_coord(tn), ED_tail_port(e).p);
 
1307
        endp = add_pointf(ND_coord(hn), ED_head_port(e).p);
1301
1308
    }
1302
1309
    else {
1303
1310
        *hp = tn; 
1304
 
        startp = add_points(ND_coord_i(hn), ED_head_port(e).p);
1305
 
        endp = add_points(ND_coord_i(tn), ED_tail_port(e).p);
 
1311
        startp = add_pointf(ND_coord(hn), ED_head_port(e).p);
 
1312
        endp = add_pointf(ND_coord(tn), ED_tail_port(e).p);
1306
1313
    }
1307
1314
 
1308
1315
    if (ED_label(e)) {
1309
1316
        dimen = ED_label(e)->dimen;
1310
 
        if (GD_flip(hn->graph)) {
 
1317
        if (GD_flip(agraphof(hn))) {
1311
1318
            width = dimen.y;
1312
1319
            height = dimen.x;
1313
1320
        }
1316
1323
            height = dimen.y;
1317
1324
        }
1318
1325
 
1319
 
        lp = ED_label(e)->p;
 
1326
        lp = ED_label(e)->pos, lp;
1320
1327
        if (leftOf (endp,startp,lp)) {
1321
1328
            lp.x += width/2.0;
1322
1329
            lp.y -= height/2.0;
1348
1355
    graph_t *g;
1349
1356
    node_t *tn, *hn;
1350
1357
    edge_t fwdedgea, fwdedgeb, fwdedge, *e, *fe, *le, *segfirst;
1351
 
    point *ps;
 
1358
    pointf *ps;
1352
1359
    pathend_t tend, hend;
1353
 
    box b;
 
1360
    boxf b;
1354
1361
    int boxn, sl, si, smode, i, j, dx, pn, hackflag, longedge;
1355
 
    point points[1000], points2[1000];
 
1362
    pointf pointfs[1000], pointfs2[1000];
1356
1363
    int pointn;
1357
1364
 
1358
1365
    sl = 0;
1359
1366
    e = edges[ind];
1360
 
    g = e->tail->graph;
 
1367
    g = agraphof(agtail(e));
1361
1368
    hackflag = FALSE;
1362
 
    if (ABS(ND_rank(e->tail) - ND_rank(e->head)) > 1) {
 
1369
    if (ABS(ND_rank(agtail(e)) - ND_rank(aghead(e))) > 1) {
1363
1370
        fwdedgea = *e;
1364
1371
        if (ED_tree_index(e) & BWDEDGE) {
1365
1372
            MAKEFWDEDGE(&fwdedgeb, e);
1366
 
            fwdedgea.tail = e->head;
 
1373
#ifndef WITH_CGRAPH
 
1374
            fwdedgea.tail = aghead(e);
1367
1375
            fwdedgea.u.tail_port = ED_head_port(e);
 
1376
#else /* WITH_CGRAPH */
 
1377
            agtail(&fwdedgea) = aghead(e);
 
1378
            ED_tail_port(&fwdedgea) = ED_head_port(e);
 
1379
#endif /* WITH_CGRAPH */
1368
1380
        } else {
1369
1381
            fwdedgeb = *e;
 
1382
#ifndef WITH_CGRAPH
1370
1383
            fwdedgea.tail = e->tail;
 
1384
#else /* WITH_CGRAPH */
 
1385
            agtail(&fwdedgea) = agtail(e);
 
1386
#endif /* WITH_CGRAPH */
1371
1387
        }
1372
1388
        le = getmainedge(e);
1373
1389
        while (ED_to_virt(le))
1374
1390
            le = ED_to_virt(le);
1375
 
        fwdedgea.head = le->head;
 
1391
#ifndef WITH_CGRAPH
 
1392
        fwdedgea.head = aghead(le);
1376
1393
        fwdedgea.u.head_port.defined = FALSE;
1377
1394
        fwdedgea.u.edge_type = VIRTUAL;
1378
1395
        fwdedgea.u.head_port.p.x = fwdedgea.u.head_port.p.y = 0;
1379
1396
        fwdedgea.u.to_orig = e;
 
1397
#else /* WITH_CGRAPH */
 
1398
        aghead(&fwdedgea) = aghead(le);
 
1399
        ED_head_port(&fwdedgea).defined = FALSE;
 
1400
        ED_edge_type(&fwdedgea) = VIRTUAL;
 
1401
        ED_head_port(&fwdedgea).p.x = ED_head_port(&fwdedgea).p.y = 0;
 
1402
        ED_to_orig(&fwdedgea) = e;
 
1403
#endif /* WITH_CGRAPH */
1380
1404
        e = &fwdedgea;
1381
1405
        hackflag = TRUE;
1382
1406
    } else {
1389
1413
 
1390
1414
    /* compute the spline points for the edge */
1391
1415
 
1392
 
    if ((et == ET_LINE) && (pointn = makeLineEdge (fe, points, &hn))) {
 
1416
    if ((et == ET_LINE) && (pointn = makeLineEdge (fe, pointfs, &hn))) {
1393
1417
    }
1394
1418
    else {
1395
1419
        int splines = et == ET_SPLINE;
1396
1420
        boxn = 0;
1397
1421
        pointn = 0;
1398
1422
        segfirst = e;
1399
 
        tn = e->tail;
1400
 
        hn = e->head;
 
1423
        tn = agtail(e);
 
1424
        hn = aghead(e);
1401
1425
        b = tend.nb = maximal_bbox(sp, tn, NULL, e);
1402
 
        beginpath(P, e, REGULAREDGE, &tend, spline_merge(e->tail));
 
1426
        beginpath(P, e, REGULAREDGE, &tend, spline_merge(tn));
1403
1427
        b.UR.y = tend.boxes[tend.boxn - 1].UR.y;
1404
1428
        b.LL.y = tend.boxes[tend.boxn - 1].LL.y;
1405
1429
        b = makeregularend(b, BOTTOM,
1406
 
                   ND_coord_i(tn).y - GD_rank(tn->graph)[ND_rank(tn)].ht1);
 
1430
                   ND_coord(tn).y - GD_rank(agraphof(tn))[ND_rank(tn)].ht1);
1407
1431
        if (b.LL.x < b.UR.x && b.LL.y < b.UR.y)
1408
1432
            tend.boxes[tend.boxn++] = b;
1409
1433
        longedge = 0;
1421
1445
                si--;
1422
1446
                boxes[boxn++] = maximal_bbox(sp, hn, e, ND_out(hn).list[0]);
1423
1447
                e = ND_out(hn).list[0];
1424
 
                tn = e->tail;
1425
 
                hn = e->head;
 
1448
                tn = agtail(e);
 
1449
                hn = aghead(e);
1426
1450
                continue;
1427
1451
            }
1428
1452
            hend.nb = maximal_bbox(sp, hn, e, ND_out(hn).list[0]);
1429
 
            endpath(P, e, REGULAREDGE, &hend, spline_merge(e->head));
 
1453
            endpath(P, e, REGULAREDGE, &hend, spline_merge(aghead(e)));
1430
1454
            b = makeregularend(hend.boxes[hend.boxn - 1], TOP,
1431
 
                       ND_coord_i(hn).y + GD_rank(hn->graph)[ND_rank(hn)].ht2);
 
1455
                       ND_coord(hn).y + GD_rank(agraphof(hn))[ND_rank(hn)].ht2);
1432
1456
            if (b.LL.x < b.UR.x && b.LL.y < b.UR.y)
1433
1457
                hend.boxes[hend.boxn++] = b;
1434
1458
            P->end.theta = M_PI / 2, P->end.constrained = TRUE;
1444
1468
            }
1445
1469
            if (pn == 0)
1446
1470
                return;
1447
 
            for (i = 0; i < pn; i++)
1448
 
                points[pointn++] = ps[i];
1449
 
            e = straight_path(ND_out(hn).list[0], sl, points, &pointn);
 
1471
            for (i = 0; i < pn; i++) {
 
1472
                pointfs[pointn++] = ps[i];
 
1473
            }
 
1474
            e = straight_path(ND_out(hn).list[0], sl, pointfs, &pointn);
1450
1475
            recover_slack(segfirst, P);
1451
1476
            segfirst = e;
1452
 
            tn = e->tail;
1453
 
            hn = e->head;
 
1477
            tn = agtail(e);
 
1478
            hn = aghead(e);
1454
1479
            boxn = 0;
1455
1480
            tend.nb = maximal_bbox(sp, tn, ND_in(tn).list[0], e);
1456
 
            beginpath(P, e, REGULAREDGE, &tend, spline_merge(e->tail));
 
1481
            beginpath(P, e, REGULAREDGE, &tend, spline_merge(tn));
1457
1482
            b = makeregularend(tend.boxes[tend.boxn - 1], BOTTOM,
1458
 
                       ND_coord_i(tn).y - GD_rank(tn->graph)[ND_rank(tn)].ht1);
 
1483
                       ND_coord(tn).y - GD_rank(agraphof(tn))[ND_rank(tn)].ht1);
1459
1484
            if (b.LL.x < b.UR.x && b.LL.y < b.UR.y)
1460
1485
                tend.boxes[tend.boxn++] = b;
1461
1486
            P->start.theta = -M_PI / 2, P->start.constrained = TRUE;
1464
1489
        boxes[boxn++] = rank_box(sp, g, ND_rank(tn));
1465
1490
        b = hend.nb = maximal_bbox(sp, hn, e, NULL);
1466
1491
        endpath(P, hackflag ? &fwdedgeb : e, REGULAREDGE, &hend,
1467
 
                spline_merge(e->head));
 
1492
                spline_merge(aghead(e)));
1468
1493
        b.UR.y = hend.boxes[hend.boxn - 1].UR.y;
1469
1494
        b.LL.y = hend.boxes[hend.boxn - 1].LL.y;
1470
1495
        b = makeregularend(b, TOP,
1471
 
                   ND_coord_i(hn).y + GD_rank(hn->graph)[ND_rank(hn)].ht2);
 
1496
                   ND_coord(hn).y + GD_rank(agraphof(hn))[ND_rank(hn)].ht2);
1472
1497
        if (b.LL.x < b.UR.x && b.LL.y < b.UR.y)
1473
1498
            hend.boxes[hend.boxn++] = b;
1474
1499
        completeregularpath(P, segfirst, e, &tend, &hend, boxes, boxn,
1486
1511
        }
1487
1512
        if (pn == 0)
1488
1513
            return;
1489
 
        for (i = 0; i < pn; i++)
1490
 
            points[pointn++] = ps[i];
 
1514
        for (i = 0; i < pn; i++) {
 
1515
            pointfs[pointn++] = ps[i];
 
1516
        }
1491
1517
        recover_slack(segfirst, P);
1492
 
        hn = hackflag ? fwdedgeb.head : e->head;
 
1518
        hn = hackflag ? aghead(&fwdedgeb) : aghead(e);
1493
1519
    }
1494
1520
 
1495
1521
    /* make copies of the spline points, one per multi-edge */
1496
1522
 
1497
1523
    if (cnt == 1) {
1498
 
        clip_and_install(fe, hn, points, pointn, &sinfo);
 
1524
        clip_and_install(fe, hn, pointfs, pointn, &sinfo);
1499
1525
        return;
1500
1526
    }
1501
1527
    dx = sp->Multisep * (cnt - 1) / 2;
1502
1528
    for (i = 1; i < pointn - 1; i++)
1503
 
        points[i].x -= dx;
 
1529
        pointfs[i].x -= dx;
1504
1530
    for (i = 0; i < pointn; i++)
1505
 
        points2[i] = points[i];
1506
 
    clip_and_install(fe, hn, points2, pointn, &sinfo);
 
1531
        pointfs2[i] = pointfs[i];
 
1532
    clip_and_install(fe, hn, pointfs2, pointn, &sinfo);
1507
1533
    for (j = 1; j < cnt; j++) {
1508
1534
        e = edges[ind + j];
1509
1535
        if (ED_tree_index(e) & BWDEDGE) {
1511
1537
            e = &fwdedge;
1512
1538
        }
1513
1539
        for (i = 1; i < pointn - 1; i++)
1514
 
            points[i].x += sp->Multisep;
 
1540
            pointfs[i].x += sp->Multisep;
1515
1541
        for (i = 0; i < pointn; i++)
1516
 
            points2[i] = points[i];
1517
 
        clip_and_install(e, e->head, points2, pointn, &sinfo);
1518
 
    }
1519
 
}
1520
 
 
1521
 
/* flat edges */
1522
 
 
1523
 
#ifdef OBSOLETE
1524
 
static void 
1525
 
chooseflatsides(pathend_t* tendp, pathend_t *hendp,
1526
 
                int* tsidep, int* hsidep, int* msidep, int* tdirp, 
1527
 
                int* hdirp, int* crossp)
1528
 
{
1529
 
    int i;
1530
 
 
1531
 
    for (i = 0; i < 16; i++)
1532
 
        if ((flatsidemap[i][0] & tendp->sidemask) &&
1533
 
            (flatsidemap[i][1] & hendp->sidemask))
1534
 
            break;
1535
 
    if (i == 16)
1536
 
        abort();
1537
 
    *tsidep = flatsidemap[i][0], *hsidep = flatsidemap[i][1];
1538
 
    *msidep = flatsidemap[i][2];
1539
 
    *tdirp = flatsidemap[i][3], *hdirp = flatsidemap[i][4];
1540
 
    *crossp = flatsidemap[i][5];
1541
 
}
1542
 
 
1543
 
static void
1544
 
completeflatpath(path * P,
1545
 
                 pathend_t * tendp, pathend_t * hendp,
1546
 
                 int tside, int hside, int mside, int tdir, int hdir,
1547
 
                 box * arg_lb, box * arg_rb, int w, int h)
1548
 
{
1549
 
    int i, side, boxn;
1550
 
    box boxes[8];
1551
 
    box tb, hb;
1552
 
    box lb, rb;
1553
 
    lb = *arg_lb;
1554
 
    rb = *arg_rb;
1555
 
 
1556
 
    tb = makeflatend(tendp->boxes[tendp->boxn - 1], tside, tdir, lb);
1557
 
    hb = makeflatend(hendp->boxes[hendp->boxn - 1], hside, OTHERDIR(hdir),
1558
 
                     rb);
1559
 
 
1560
 
    boxn = 0;
1561
 
    for (side = tside;; side = NEXTSIDE(side, tdir)) {
1562
 
        boxes[boxn++] = makeflatcomponent(lb, rb, side,
1563
 
                                          (side == mside) ? 0 : -1, tdir,
1564
 
                                          w, h);
1565
 
        if (side == mside)
1566
 
            break;
1567
 
    }
1568
 
    if (mside == RIGHT)
1569
 
        mside = LEFT;
1570
 
    if (mside != hside) {
1571
 
        for (side = NEXTSIDE(mside, hdir);; side = NEXTSIDE(side, hdir)) {
1572
 
            boxes[boxn++] = makeflatcomponent(lb, rb, side, 1, hdir, w, h);
1573
 
            if (side == hside)
1574
 
                break;
1575
 
        }
1576
 
    }
1577
 
 
1578
 
    for (i = 0; i < tendp->boxn; i++)
1579
 
        add_box(P, tendp->boxes[i]);
1580
 
    if (tb.LL.x != tb.UR.x && tb.LL.y != tb.UR.y)
1581
 
        add_box(P, tb);
1582
 
    for (i = 0; i < boxn; i++)
1583
 
        add_box(P, boxes[i]);
1584
 
    if (hb.LL.x != hb.UR.x && hb.LL.y != hb.UR.y)
1585
 
        add_box(P, hb);
1586
 
    for (i = hendp->boxn - 1; i >= 0; i--)
1587
 
        add_box(P, hendp->boxes[i]);
1588
 
}
1589
 
 
1590
 
static box 
1591
 
makeflatend(box b, int side, int dir, box bb)
1592
 
{
1593
 
    box eb = { {0, 0}, {0, 0} };
1594
 
 
1595
 
    switch (side) {
1596
 
    case BOTTOM:
1597
 
        eb = boxof(b.LL.x, bb.LL.y, b.UR.x, b.LL.y);
1598
 
        if (dir == CCW)
1599
 
            eb.UR.x += (bb.UR.x - b.UR.x) / 2;
1600
 
        else
1601
 
            eb.LL.x -= (b.LL.x - bb.LL.x) / 2;
1602
 
        break;
1603
 
    case RIGHT:
1604
 
        eb = boxof(b.UR.x, b.LL.y, bb.UR.x, b.UR.y);
1605
 
        if (dir == CCW)
1606
 
            eb.UR.y += (bb.UR.y - b.UR.y) / 2;
1607
 
        else
1608
 
            eb.LL.y -= (b.LL.y - bb.LL.y) / 2;
1609
 
        break;
1610
 
    case TOP:
1611
 
        eb = boxof(b.LL.x, b.UR.y, b.UR.x, bb.UR.y);
1612
 
        if (dir == CCW)
1613
 
            eb.LL.x -= (b.LL.x - bb.LL.x) / 2;
1614
 
        else
1615
 
            eb.UR.x += (bb.UR.x - b.UR.x) / 2;
1616
 
        break;
1617
 
    case LEFT:
1618
 
        eb = boxof(bb.LL.x, b.LL.y, b.LL.x, b.UR.y);
1619
 
        if (dir == CCW)
1620
 
            eb.LL.y -= (bb.UR.y - b.UR.y) / 2;
1621
 
        else
1622
 
            eb.UR.y += (b.LL.y - bb.LL.y) / 2;
1623
 
        break;
1624
 
    }
1625
 
    return eb;
1626
 
}
1627
 
 
1628
 
static box makeflatcomponent(lb, rb, side, mode, dir, w, h)
1629
 
box lb, rb;
1630
 
int side, mode, dir, w, h;
1631
 
{
1632
 
    box b = { {0, 0}, {0, 0} };
1633
 
 
1634
 
    /* mode == -1 means use left box, 1 means use right box
1635
 
       and 0 means use mostly the left box */
1636
 
 
1637
 
    switch (side) {
1638
 
    case BOTTOM:
1639
 
        b.LL.x = lb.LL.x - w, b.UR.x = rb.UR.x + w;
1640
 
        if (mode <= 0)
1641
 
            b.LL.y = lb.LL.y - h, b.UR.y = lb.LL.y;
1642
 
        else
1643
 
            b.LL.y = rb.LL.y - h, b.UR.y = rb.LL.y;
1644
 
        break;
1645
 
    case RIGHT:
1646
 
        if (mode == -1) {
1647
 
            b.LL.x = lb.UR.x, b.UR.x = lb.UR.x + w;
1648
 
            b.LL.y = lb.LL.y, b.UR.y = lb.UR.y;
1649
 
        } else if (mode == 0) {
1650
 
            b.LL.x = lb.UR.x, b.UR.x = lb.UR.x + w;
1651
 
            if (dir == CCW)
1652
 
                b.LL.y = lb.LL.y, b.UR.y = rb.UR.y;
1653
 
            else
1654
 
                b.LL.y = rb.LL.y, b.UR.y = lb.UR.y;
1655
 
        } else {
1656
 
            b.LL.x = rb.UR.x, b.UR.x = rb.UR.x + w;
1657
 
            b.LL.y = rb.LL.y, b.UR.y = rb.UR.y;
1658
 
        }
1659
 
        break;
1660
 
    case TOP:
1661
 
        b.LL.x = lb.LL.x - w, b.UR.x = rb.UR.x + w;
1662
 
        if (mode <= 0)
1663
 
            b.LL.y = lb.UR.y, b.UR.y = lb.UR.y + h;
1664
 
        else
1665
 
            b.LL.y = rb.UR.y, b.UR.y = rb.UR.y + h;
1666
 
        break;
1667
 
    case LEFT:
1668
 
        if (mode == -1) {
1669
 
            b.LL.x = lb.LL.x - w, b.UR.x = lb.LL.x;
1670
 
            b.LL.y = lb.LL.y, b.UR.y = lb.UR.y;
1671
 
        } else if (mode == 0) {
1672
 
            b.LL.x = lb.LL.x - w, b.UR.x = lb.LL.x;
1673
 
            if (dir == CCW)
1674
 
                b.LL.y = lb.LL.y, b.UR.y = rb.UR.y;
1675
 
            else
1676
 
                b.LL.y = rb.LL.y, b.UR.y = lb.UR.y;
1677
 
        } else {
1678
 
            b.LL.x = rb.LL.x - w, b.UR.x = rb.LL.x;
1679
 
            b.LL.y = rb.LL.y, b.UR.y = rb.UR.y;
1680
 
        }
1681
 
        break;
1682
 
    }
1683
 
    return b;
1684
 
}
1685
 
static void
1686
 
completeflatpath(path* P, pathend_t* tendp, pathend_t* hendp,
1687
 
                 box* lbp, box* rbp, int w, int h)
1688
 
{
1689
 
    int i;
1690
 
    box wbox;
1691
 
    box tb, hb;
1692
 
    box lb, rb;
1693
 
    lb = *lbp;
1694
 
    rb = *rbp;
1695
 
 
1696
 
    tb = makeflatend(tendp->boxes[tendp->boxn - 1], TOP, CW, lb);
1697
 
    hb = makeflatend(hendp->boxes[hendp->boxn - 1], TOP, CCW, rb);
1698
 
 
1699
 
    wbox = makeflatcomponent(lb, rb, TOP, 0, CW, w, h);
1700
 
 
1701
 
    for (i = 0; i < tendp->boxn; i++)
1702
 
        add_box(P, tendp->boxes[i]);
1703
 
    add_box(P, tb);
1704
 
    add_box(P, wbox);
1705
 
    for (i = hendp->boxn - 1; i >= 0; i--)
1706
 
        add_box(P, hendp->boxes[i]);
1707
 
}
1708
 
#endif
 
1542
            pointfs2[i] = pointfs[i];
 
1543
        clip_and_install(e, aghead(e), pointfs2, pointn, &sinfo);
 
1544
    }
 
1545
}
1709
1546
 
1710
1547
/* regular edges */
1711
1548
 
1713
1550
#ifdef DONT_WANT_ANY_ENDPOINT_PATH_REFINEMENT
1714
1551
static void
1715
1552
completeregularpath(path * P, edge_t * first, edge_t * last,
1716
 
                    pathend_t * tendp, pathend_t * hendp, box * boxes,
 
1553
                    pathend_t * tendp, pathend_t * hendp, boxf * boxes,
1717
1554
                    int boxn, int flag)
1718
1555
{
1719
1556
    edge_t *uleft, *uright, *lleft, *lright;
1720
1557
    int i, fb, lb;
1721
1558
    splines *spl;
1722
 
    point *pp;
 
1559
    pointf *pp;
1723
1560
    int pn;
1724
1561
 
1725
1562
    fb = lb = -1;
1727
1564
    uleft = top_bound(first, -1), uright = top_bound(first, 1);
1728
1565
    if (uleft) {
1729
1566
        spl = getsplinepoints(uleft);
1730
 
        pp = spl->list[0].list, pn = spl->list[0].size;
1731
 
        P->ulpp = &pp[0];
 
1567
        pp = spl->list[0].list;
 
1568
        pn = spl->list[0].size;
1732
1569
    }
1733
1570
    if (uright) {
1734
1571
        spl = getsplinepoints(uright);
1735
 
        pp = spl->list[0].list, pn = spl->list[0].size;
1736
 
        P->urpp = &pp[0];
 
1572
        pp = spl->list[0].list;
 
1573
        pn = spl->list[0].size;
1737
1574
    }
1738
1575
    lleft = lright = NULL;
1739
1576
    lleft = bot_bound(last, -1), lright = bot_bound(last, 1);
1740
1577
    if (lleft) {
1741
1578
        spl = getsplinepoints(lleft);
1742
 
        pp = spl->list[spl->size - 1].list, pn =
1743
 
            spl->list[spl->size - 1].size;
1744
 
        P->llpp = &pp[pn - 1];
 
1579
        pp = spl->list[spl->size - 1].list;
 
1580
        pn = spl->list[spl->size - 1].size;
1745
1581
    }
1746
1582
    if (lright) {
1747
1583
        spl = getsplinepoints(lright);
1748
 
        pp = spl->list[spl->size - 1].list, pn =
1749
 
            spl->list[spl->size - 1].size;
1750
 
        P->lrpp = &pp[pn - 1];
 
1584
        pp = spl->list[spl->size - 1].list;
 
1585
        pn = spl->list[spl->size - 1].size;
1751
1586
    }
1752
1587
    for (i = 0; i < tendp->boxn; i++)
1753
1588
        add_box(P, tendp->boxes[i]);
1761
1596
}
1762
1597
#else
1763
1598
void refineregularends(edge_t * left, edge_t * right, pathend_t * endp,
1764
 
                       int dir, box b, box * boxes, int *boxnp);
 
1599
                       int dir, boxf b, boxf * boxes, int *boxnp);
1765
1600
 
1766
1601
/* box subdivision is obsolete, I think... ek */
1767
1602
static void
1768
1603
completeregularpath(path * P, edge_t * first, edge_t * last,
1769
 
                    pathend_t * tendp, pathend_t * hendp, box * boxes,
 
1604
                    pathend_t * tendp, pathend_t * hendp, boxf * boxes,
1770
1605
                    int boxn, int flag)
1771
1606
{
1772
1607
    edge_t *uleft, *uright, *lleft, *lright;
1773
 
    box uboxes[NSUB], lboxes[NSUB];
1774
 
    box b;
 
1608
    boxf uboxes[NSUB], lboxes[NSUB];
 
1609
    boxf b;
1775
1610
    int uboxn, lboxn, i, y, fb, lb;
1776
1611
 
1777
1612
    fb = lb = -1;
1778
1613
    uleft = uright = NULL;
1779
 
    if (flag || ND_rank(first->tail) + 1 != ND_rank(last->head))
 
1614
    if (flag || ND_rank(agtail(first)) + 1 != ND_rank(aghead(last)))
1780
1615
        uleft = top_bound(first, -1), uright = top_bound(first, 1);
1781
1616
    refineregularends(uleft, uright, tendp, 1, boxes[0], uboxes, &uboxn);
1782
1617
    lleft = lright = NULL;
1783
 
    if (flag || ND_rank(first->tail) + 1 != ND_rank(last->head))
 
1618
    if (flag || ND_rank(agtail(first)) + 1 != ND_rank(aghead(last)))
1784
1619
        lleft = bot_bound(last, -1), lright = bot_bound(last, 1);
1785
1620
    refineregularends(lleft, lright, hendp, -1, boxes[boxn - 1], lboxes,
1786
1621
                      &lboxn);
1787
1622
    for (i = 0; i < tendp->boxn; i++)
1788
1623
        add_box(P, tendp->boxes[i]);
1789
 
    if (ND_rank(first->tail) + 1 == ND_rank(last->head)) {
 
1624
    if (ND_rank(agtail(first)) + 1 == ND_rank(aghead(last))) {
1790
1625
        if ((!uleft && !uright) && (lleft || lright)) {
1791
1626
            b = boxes[0];
1792
1627
            y = b.UR.y - b.LL.y;
1833
1668
 * nodes in a given rank can differ in height.
1834
1669
 * for now, regular edges always go from top to bottom 
1835
1670
 */
1836
 
static box makeregularend(box b, int side, int y)
 
1671
static boxf makeregularend(boxf b, int side, int y)
1837
1672
{
1838
 
    box newb;
 
1673
    boxf newb;
1839
1674
    switch (side) {
1840
1675
    case BOTTOM:
1841
 
        newb = boxof(b.LL.x, y, b.UR.x, b.LL.y);
 
1676
        newb = boxfof(b.LL.x, y, b.UR.x, b.LL.y);
1842
1677
        break;
1843
1678
    case TOP:
1844
 
        newb = boxof(b.LL.x, b.UR.y, b.UR.x, y);
 
1679
        newb = boxfof(b.LL.x, b.UR.y, b.UR.x, y);
1845
1680
        break;
1846
1681
    }
1847
1682
    return newb;
1965
1800
 */
1966
1801
static void adjustregularpath(path * P, int fb, int lb)
1967
1802
{
1968
 
    box *bp1, *bp2;
 
1803
    boxf *bp1, *bp2;
1969
1804
    int i, x;
1970
1805
 
1971
1806
    for (i = fb-1; i < lb+1; i++) {
1995
1830
            if (bp1->UR.x - MINW < bp2->LL.x)
1996
1831
                bp1->UR.x = bp2->LL.x + MINW;
1997
1832
        } 
1998
 
#ifdef OLD
1999
 
        else {
2000
 
            if (bp1->LL.x + MINW > bp2->UR.x) {
2001
 
                x = (bp1->LL.x + bp2->UR.x) / 2;
2002
 
                bp1->LL.x = x - HALFMINW;
2003
 
                bp2->UR.x = x + HALFMINW;
2004
 
            }
2005
 
            if (bp1->UR.x - MINW < bp2->LL.x) {
2006
 
                x = (bp1->UR.x + bp2->LL.x) / 2;
2007
 
                bp1->UR.x = x + HALFMINW;
2008
 
                bp2->LL.x = x - HALFMINW;
2009
 
            }
2010
 
        }
2011
 
#endif
2012
1833
    }
2013
1834
}
2014
1835
 
2015
 
static box rank_box(spline_info_t* sp, graph_t * g, int r)
 
1836
static boxf rank_box(spline_info_t* sp, graph_t * g, int r)
2016
1837
{
2017
 
    box b;
 
1838
    boxf b;
2018
1839
    node_t /* *right0, *right1, */  * left0, *left1;
2019
1840
 
2020
1841
    b = sp->Rank_box[r];
2024
1845
        left1 = GD_rank(g)[r + 1].v[0];
2025
1846
        /* right1 = GD_rank(g)[r + 1].v[GD_rank(g)[r + 1].n - 1]; */
2026
1847
        b.LL.x = sp->LeftBound;
2027
 
        b.LL.y = ND_coord_i(left1).y + GD_rank(g)[r + 1].ht2;
 
1848
        b.LL.y = ND_coord(left1).y + GD_rank(g)[r + 1].ht2;
2028
1849
        b.UR.x = sp->RightBound;
2029
 
        b.UR.y = ND_coord_i(left0).y - GD_rank(g)[r].ht1;
 
1850
        b.UR.y = ND_coord(left0).y - GD_rank(g)[r].ht1;
2030
1851
        sp->Rank_box[r] = b;
2031
1852
    }
2032
1853
    return b;
2040
1861
 
2041
1862
    v = n;
2042
1863
    while (1) {
2043
 
        v = ND_out(v).list[0]->head;
 
1864
        v = aghead(ND_out(v).list[0]);
2044
1865
        if (ND_node_type(v) != VIRTUAL)
2045
1866
            break;
2046
1867
        if ((ND_out(v).size != 1) || (ND_in(v).size != 1))
2047
1868
            break;
2048
 
        if (ND_coord_i(v).x != ND_coord_i(n).x)
 
1869
        if (ND_coord(v).x != ND_coord(n).x)
2049
1870
            break;
2050
1871
        cnt++;
2051
1872
    }
2052
1873
    return cnt;
2053
1874
}
2054
1875
 
2055
 
static edge_t *straight_path(edge_t * e, int cnt, point * plist, int *np)
 
1876
static edge_t *straight_path(edge_t * e, int cnt, pointf * plist, int *np)
2056
1877
{
2057
1878
    int n = *np;
2058
1879
    edge_t *f = e;
2059
1880
 
2060
1881
    while (cnt--)
2061
 
        f = ND_out(f->head).list[0];
2062
 
    plist[(*np)++] = plist[n - 1];
2063
 
    plist[(*np)++] = plist[n - 1];
2064
 
    plist[(*np)] = ND_coord_i(f->tail); /* will be overwritten by next spline */
 
1882
        f = ND_out(aghead(f)).list[0];
 
1883
    plist[(*np)++] = plist[n - 1];
 
1884
    plist[(*np)++] = plist[n - 1];
 
1885
    plist[(*np)] = ND_coord(agtail(f));  /* will be overwritten by next spline */
 
1886
 
2065
1887
    return f;
2066
1888
}
2067
1889
 
2071
1893
    node_t *vn;
2072
1894
 
2073
1895
    b = 0;                      /* skip first rank box */
2074
 
    for (vn = e->head;
 
1896
    for (vn = aghead(e);
2075
1897
         ND_node_type(vn) == VIRTUAL && !sinfo.splineMerge(vn);
2076
 
         vn = ND_out(vn).list[0]->head) {
2077
 
        while ((b < p->nbox) && (p->boxes[b].LL.y > ND_coord_i(vn).y))
 
1898
         vn = aghead(ND_out(vn).list[0])) {
 
1899
        while ((b < p->nbox) && (p->boxes[b].LL.y > ND_coord(vn).y))
2078
1900
            b++;
2079
1901
        if (b >= p->nbox)
2080
1902
            break;
2081
 
        if (p->boxes[b].UR.y < ND_coord_i(vn).y)
 
1903
        if (p->boxes[b].UR.y < ND_coord(vn).y)
2082
1904
            continue;
2083
1905
        if (ND_label(vn))
2084
1906
            resize_vn(vn, p->boxes[b].LL.x, p->boxes[b].UR.x,
2085
 
                      p->boxes[b].UR.x + ND_rw_i(vn));
 
1907
                      p->boxes[b].UR.x + ND_rw(vn));
2086
1908
        else
2087
1909
            resize_vn(vn, p->boxes[b].LL.x, (p->boxes[b].LL.x +
2088
1910
                                             p->boxes[b].UR.x) / 2,
2094
1916
node_t *vn;
2095
1917
int lx, cx, rx;
2096
1918
{
2097
 
    ND_coord_i(vn).x = cx;
2098
 
    ND_lw_i(vn) = cx - lx, ND_rw_i(vn) = rx - cx;
 
1919
    ND_coord(vn).x = cx;
 
1920
    ND_lw(vn) = cx - lx, ND_rw(vn) = rx - cx;
2099
1921
}
2100
1922
 
2101
1923
/* side > 0 means right. side < 0 means left */
2104
1926
    edge_t *f, *ans = NULL;
2105
1927
    int i;
2106
1928
 
2107
 
    for (i = 0; (f = ND_out(e->tail).list[i]); i++) {
 
1929
    for (i = 0; (f = ND_out(agtail(e)).list[i]); i++) {
2108
1930
#if 0                           /* were we out of our minds? */
2109
1931
        if (ED_tail_port(e).p.x != ED_tail_port(f).p.x)
2110
1932
            continue;
2111
1933
#endif
2112
 
        if (side * (ND_order(f->head) - ND_order(e->head)) <= 0)
 
1934
        if (side * (ND_order(aghead(f)) - ND_order(aghead(e))) <= 0)
2113
1935
            continue;
2114
1936
        if ((ED_spl(f) == NULL)
2115
 
            && ((ED_to_orig(f) == NULL) || (ED_to_orig(f)->u.spl == NULL)))
 
1937
            && ((ED_to_orig(f) == NULL) || (ED_spl(ED_to_orig(f)) == NULL)))
2116
1938
            continue;
2117
1939
        if ((ans == NULL)
2118
 
            || (side * (ND_order(ans->head) - ND_order(f->head)) > 0))
 
1940
            || (side * (ND_order(aghead(ans)) - ND_order(aghead(f))) > 0))
2119
1941
            ans = f;
2120
1942
    }
2121
1943
    return ans;
2126
1948
    edge_t *f, *ans = NULL;
2127
1949
    int i;
2128
1950
 
2129
 
    for (i = 0; (f = ND_in(e->head).list[i]); i++) {
 
1951
    for (i = 0; (f = ND_in(aghead(e)).list[i]); i++) {
2130
1952
#if 0                           /* same here */
2131
1953
        if (ED_head_port(e).p.x != ED_head_port(f).p.x)
2132
1954
            continue;
2133
1955
#endif
2134
 
        if (side * (ND_order(f->tail) - ND_order(e->tail)) <= 0)
 
1956
        if (side * (ND_order(agtail(f)) - ND_order(agtail(e))) <= 0)
2135
1957
            continue;
2136
1958
        if ((ED_spl(f) == NULL)
2137
 
            && ((ED_to_orig(f) == NULL) || (ED_to_orig(f)->u.spl == NULL)))
 
1959
            && ((ED_to_orig(f) == NULL) || (ED_spl(ED_to_orig(f)) == NULL)))
2138
1960
            continue;
2139
1961
        if ((ans == NULL)
2140
 
            || (side * (ND_order(ans->tail) - ND_order(f->tail)) > 0))
 
1962
            || (side * (ND_order(agtail(ans)) - ND_order(agtail(f))) > 0))
2141
1963
            ans = f;
2142
1964
    }
2143
1965
    return ans;
2144
1966
}
2145
1967
 
2146
 
point closest(splines * spl, point p)
2147
 
{
2148
 
    int i, j, k, besti, bestj;
2149
 
    double bestdist2, d2, dlow2, dhigh2; /* squares of distance */
2150
 
    double low, high, t;
2151
 
    pointf c[4], pt2, pt;
2152
 
    point rv;
2153
 
    bezier bz;
2154
 
 
2155
 
    besti = bestj = -1;
2156
 
    bestdist2 = 1e+38;
2157
 
    P2PF(p, pt);
2158
 
    for (i = 0; i < spl->size; i++) {
2159
 
        bz = spl->list[i];
2160
 
        for (j = 0; j < bz.size; j++) {
2161
 
            pointf b;
2162
 
 
2163
 
            b.x = bz.list[j].x;
2164
 
            b.y = bz.list[j].y;
2165
 
            d2 = DIST2(b, pt);
2166
 
            if ((bestj == -1) || (d2 < bestdist2)) {
2167
 
                besti = i;
2168
 
                bestj = j;
2169
 
                bestdist2 = d2;
2170
 
            }
2171
 
        }
2172
 
    }
2173
 
 
2174
 
    bz = spl->list[besti];
2175
 
    j = bestj / 3;
2176
 
    if (j >= spl->size)
2177
 
        j--;
2178
 
    for (k = 0; k < 4; k++) {
2179
 
        c[k].x = bz.list[j + k].x;
2180
 
        c[k].y = bz.list[j + k].y;
2181
 
    }
2182
 
    low = 0.0;
2183
 
    high = 1.0;
2184
 
    dlow2 = DIST2(c[0], pt);
2185
 
    dhigh2 = DIST2(c[3], pt);
2186
 
    do {
2187
 
        t = (low + high) / 2.0;
2188
 
        pt2 = Bezier(c, 3, t, NULL, NULL);
2189
 
        if (fabs(dlow2 - dhigh2) < 1.0)
2190
 
            break;
2191
 
        if (fabs(high - low) < .00001)
2192
 
            break;
2193
 
        if (dlow2 < dhigh2) {
2194
 
            high = t;
2195
 
            dhigh2 = DIST2(pt2, pt);
2196
 
        } else {
2197
 
            low = t;
2198
 
            dlow2 = DIST2(pt2, pt);
2199
 
        }
2200
 
    } while (1);
2201
 
    PF2P(pt2, rv);
2202
 
    return rv;
2203
 
}
2204
 
 
2205
1968
/* common routines */
2206
1969
 
2207
1970
static int cl_vninside(graph_t * cl, node_t * n)
2208
1971
{
2209
 
    return (BETWEEN(GD_bb(cl).LL.x, ND_coord_i(n).x, GD_bb(cl).UR.x) &&
2210
 
            BETWEEN(GD_bb(cl).LL.y, ND_coord_i(n).y, GD_bb(cl).UR.y));
 
1972
    return (BETWEEN(GD_bb(cl).LL.x, (double)(ND_coord(n).x), GD_bb(cl).UR.x) &&
 
1973
            BETWEEN(GD_bb(cl).LL.y, (double)(ND_coord(n).y), GD_bb(cl).UR.y));
2211
1974
}
2212
1975
 
2213
1976
/* returns the cluster of (adj) that interferes with n,
2214
1977
 */
2215
 
static graph_t *cl_bound(n, adj)
 
1978
static Agraph_t *cl_bound(n, adj)
2216
1979
node_t *n, *adj;
2217
1980
{
2218
1981
    graph_t *rv, *cl, *tcl, *hcl;
2222
1985
    if (ND_node_type(n) == NORMAL)
2223
1986
        tcl = hcl = ND_clust(n);
2224
1987
    else {
2225
 
        orig = ND_out(n).list[0]->u.to_orig;
2226
 
        tcl = ND_clust(orig->tail);
2227
 
        hcl = ND_clust(orig->head);
 
1988
        orig = ED_to_orig(ND_out(n).list[0]);
 
1989
        tcl = ND_clust(agtail(orig));
 
1990
        hcl = ND_clust(aghead(orig));
2228
1991
    }
2229
1992
    if (ND_node_type(adj) == NORMAL) {
2230
1993
        cl = ND_clust(adj);
2232
1995
            rv = cl;
2233
1996
    } else {
2234
1997
        orig = ED_to_orig(ND_out(adj).list[0]);
2235
 
        cl = ND_clust(orig->tail);
 
1998
        cl = ND_clust(agtail(orig));
2236
1999
        if (cl && (cl != tcl) && (cl != hcl) && cl_vninside(cl, adj))
2237
2000
            rv = cl;
2238
2001
        else {
2239
 
            cl = ND_clust(orig->head);
 
2002
            cl = ND_clust(aghead(orig));
2240
2003
            if (cl && (cl != tcl) && (cl != hcl) && cl_vninside(cl, adj))
2241
2004
                rv = cl;
2242
2005
        }
2254
2017
 */
2255
2018
#define FUDGE 4
2256
2019
 
2257
 
static box maximal_bbox(spline_info_t* sp, node_t* vn, edge_t* ie, edge_t* oe)
 
2020
static boxf maximal_bbox(spline_info_t* sp, node_t* vn, edge_t* ie, edge_t* oe)
2258
2021
{
2259
 
    int nb, b;
2260
 
    graph_t *g = vn->graph, *left_cl, *right_cl;
 
2022
    double b, nb;
 
2023
    graph_t *g = agraphof(vn), *left_cl, *right_cl;
2261
2024
    node_t *left, *right;
2262
 
    box rv;
 
2025
    boxf rv;
2263
2026
 
2264
2027
    left_cl = right_cl = NULL;
2265
2028
 
2266
2029
    /* give this node all the available space up to its neighbors */
2267
 
    b = ND_coord_i(vn).x - ND_lw_i(vn) - FUDGE;
 
2030
    b = (double)(ND_coord(vn).x - ND_lw(vn) - FUDGE);
2268
2031
    if ((left = neighbor(vn, ie, oe, -1))) {
2269
2032
        if ((left_cl = cl_bound(vn, left)))
2270
 
            nb = GD_bb(left_cl).UR.x + sp->Splinesep;
 
2033
            nb = GD_bb(left_cl).UR.x + (double)(sp->Splinesep);
2271
2034
        else {
2272
 
            nb = ND_coord_i(left).x + ND_mval(left);
 
2035
            nb = (double)(ND_coord(left).x + ND_mval(left));
2273
2036
            if (ND_node_type(left) == NORMAL)
2274
 
                nb += GD_nodesep(g) / 2;
 
2037
                nb += GD_nodesep(g) / 2.;
2275
2038
            else
2276
 
                nb += sp->Splinesep;
 
2039
                nb += (double)(sp->Splinesep);
2277
2040
        }
2278
2041
        if (nb < b)
2279
2042
            b = nb;
2280
 
        rv.LL.x = b;
 
2043
        rv.LL.x = ROUND(b);
2281
2044
    } else
2282
 
        rv.LL.x = MIN(b, sp->LeftBound);
 
2045
        rv.LL.x = MIN(ROUND(b), sp->LeftBound);
2283
2046
 
2284
2047
    /* we have to leave room for our own label! */
2285
2048
    if ((ND_node_type(vn) == VIRTUAL) && (ND_label(vn)))
2286
 
        b = ND_coord_i(vn).x + 10;
 
2049
        b = (double)(ND_coord(vn).x + 10);
2287
2050
    else
2288
 
        b = ND_coord_i(vn).x + ND_rw_i(vn) + FUDGE;
 
2051
        b = (double)(ND_coord(vn).x + ND_rw(vn) + FUDGE);
2289
2052
    if ((right = neighbor(vn, ie, oe, 1))) {
2290
2053
        if ((right_cl = cl_bound(vn, right)))
2291
 
            nb = GD_bb(right_cl).LL.x - sp->Splinesep;
 
2054
            nb = GD_bb(right_cl).LL.x - (double)(sp->Splinesep);
2292
2055
        else {
2293
 
            nb = ND_coord_i(right).x - ND_lw_i(right);
 
2056
            nb = ND_coord(right).x - ND_lw(right);
2294
2057
            if (ND_node_type(right) == NORMAL)
2295
 
                nb -= GD_nodesep(g) / 2;
 
2058
                nb -= GD_nodesep(g) / 2.;
2296
2059
            else
2297
 
                nb -= sp->Splinesep;
 
2060
                nb -= (double)(sp->Splinesep);
2298
2061
        }
2299
2062
        if (nb > b)
2300
2063
            b = nb;
2301
 
        rv.UR.x = b;
 
2064
        rv.UR.x = ROUND(b);
2302
2065
    } else
2303
 
        rv.UR.x = MAX(b, sp->RightBound);
 
2066
        rv.UR.x = MAX(ROUND(b), sp->RightBound);
2304
2067
 
2305
2068
    if ((ND_node_type(vn) == VIRTUAL) && (ND_label(vn)))
2306
 
        rv.UR.x -= ND_rw_i(vn);
 
2069
        rv.UR.x -= ND_rw(vn);
2307
2070
 
2308
 
    rv.LL.y = ND_coord_i(vn).y - GD_rank(g)[ND_rank(vn)].ht1;
2309
 
    rv.UR.y = ND_coord_i(vn).y + GD_rank(g)[ND_rank(vn)].ht2;
 
2071
    rv.LL.y = ND_coord(vn).y - GD_rank(g)[ND_rank(vn)].ht1;
 
2072
    rv.UR.y = ND_coord(vn).y + GD_rank(g)[ND_rank(vn)].ht2;
2310
2073
    return rv;
2311
2074
}
2312
2075
 
2317
2080
{
2318
2081
    int i;
2319
2082
    node_t *n, *rv = NULL;
2320
 
    rank_t *rank = &(GD_rank(vn->graph)[ND_rank(vn)]);
 
2083
    rank_t *rank = &(GD_rank(agraphof(vn))[ND_rank(vn)]);
2321
2084
 
2322
2085
    for (i = ND_order(vn) + dir; ((i >= 0) && (i < rank->n)); i += dir) {
2323
2086
        n = rank->v[i];
2352
2115
    if (ND_out(n0).size == 1 && e1) {
2353
2116
        e0 = ND_out(n0).list[0];
2354
2117
        for (cnt = 0; cnt < 2; cnt++) {
2355
 
            if ((na = e0->head) == (nb = e1->head))
 
2118
            if ((na = aghead(e0)) == (nb = aghead(e1)))
2356
2119
                break;
2357
2120
            if (order != (ND_order(na) > ND_order(nb)))
2358
2121
                return TRUE;
2368
2131
    if (ND_in(n0).size == 1 && e1) {
2369
2132
        e0 = ND_in(n0).list[0];
2370
2133
        for (cnt = 0; cnt < 2; cnt++) {
2371
 
            if ((na = e0->tail) == (nb = e1->tail))
 
2134
            if ((na = agtail(e0)) == (nb = agtail(e1)))
2372
2135
                break;
2373
2136
            if (order != (ND_order(na) > ND_order(nb)))
2374
2137
                return TRUE;