45
50
ED_edge_type(newp) = VIRTUAL; \
46
51
ED_to_orig(newp) = old; \
49
#define P2PF(p, pf) (pf.x = p.x, pf.y = p.y)
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},
72
#define AVG(a, b) ((a + b) / 2)
74
static box boxes[1000];
53
#else /* WITH_CGRAPH */
54
#define MAKEFWDEDGE(new, 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; \
65
#endif /* WITH_CGRAPH */
67
static boxf boxes[1000];
76
69
int LeftBound, RightBound, Splinesep, Multisep;
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 *);
84
static void chooseflatsides(pathend_t *, pathend_t *, 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);
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);
110
95
#define GROWEDGES (edges = ALLOC (n_edges + CHUNK, edges, edge_t*))
550
562
if ((rv = portcmp(ED_head_port(ea), ED_head_port(eb))))
552
v0 = ED_tree_index(e0) & GRAPHTYPEMASK;
553
v1 = ED_tree_index(e1) & GRAPHTYPEMASK;
565
et0 = ED_tree_index(e0) & GRAPHTYPEMASK;
566
et1 = ED_tree_index(e1) & GRAPHTYPEMASK;
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);
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.
568
fledgecmp(edge_t** ptr0, edge_t** ptr1)
571
point tp0, tp1, hp0, hp1;
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;
588
else if ((tp0.x >= tp1.x) && (hp0.x <= hp1.x)) {
589
if (tp0.y <= 0) return 1;
593
return (e0->id - e1->id);
597
#define LABEL_SPACE 8
600
* Create middle boxes for routing using ordered list of edges going from
602
* Also, set label positions.
605
setFlatAdjPos (edge_t** edges, int n_edges, int flip, box* boxes, edge_t* e0)
607
int r, i, x, boxw, availht;
609
double y, wd, ht, totalht = 0;
615
tn = e0->tail, hn = e0->head;
617
x = (ND_coord_i(tn).x + ND_coord_i(hn).x)/2;
618
y = ND_coord_i(tn).y;
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;
633
boxw = MAX(boxw, wd);
635
for (i = 0; i < n_edges; i++) {
638
if (GD_flip(g)) ht = lbl->dimen.x;
639
else ht = lbl->dimen.y;
641
lbl->p.y = ROUND(y - ht/2);
642
y -= ht + LABEL_SPACE;
573
return (AGID(e0) - AGID(e1));
684
625
GD_nodesep(auxg) = GD_nodesep(g);
685
626
GD_ranksep(auxg) = GD_ranksep(g);
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 */
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 */
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;
783
762
makeSimpleFlat (node_t* tn, node_t* hn, edge_t** edges, int ind, int cnt, int et)
785
764
edge_t* e = edges[ind];
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;
769
tp = add_pointf(ND_coord(tn), ED_tail_port(e).p);
770
hp = add_pointf(ND_coord(hn), ED_head_port(e).p);
772
stepy = (cnt > 1) ? ND_ht(tn) / (double)(cnt - 1) : 0.;
773
dy = tp.y - ((cnt > 1) ? ND_ht(tn) / 2. : 0.);
791
775
for (i = 0; i < cnt; i++) {
792
776
e = edges[ind + i];
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;
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;
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 */
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);
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);
939
941
for (j = 0; j < auxbz->size; ) {
941
pt = bz->list[j] = transform(auxbz->list[j], del, GD_flip(g));
943
cp[0] = bz->list[j] = transformf(auxbz->list[j], del, GD_flip(g));
944
945
if ( j >= auxbz->size )
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));
949
pt2 = bz->list[j] = transform(auxbz->list[j], del, GD_flip(g));
951
pt.x = ( pt1.x + pt2.x ) / 2;
952
pt.y = ( pt1.y + pt2.y ) / 2;
947
cp[1] = bz->list[j] = transformf(auxbz->list[j], del, GD_flip(g));
949
cp[2] = bz->list[j] = transformf(auxbz->list[j], del, GD_flip(g));
951
cp[3] = transformf(auxbz->list[j], del, GD_flip(g));
952
update_bb_bz(&GD_bb(g), cp);
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));
1277
1284
* multiple edges better.
1280
makeLineEdge(edge_t* fe, point* points, node_t** hp)
1287
makeLineEdge(edge_t* fe, pointf* points, node_t** hp)
1285
1292
edge_t* e = fe;
1286
point startp, endp, lp;
1293
pointf startp, endp, lp;
1288
1295
double width, height;
1290
1297
while (ED_edge_type(e) != NORMAL)
1291
1298
e = ED_to_orig(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)))
1297
if (fe->tail == e->tail) {
1304
if (agtail(fe) == agtail(e)) {
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);
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);
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;
1349
1356
node_t *tn, *hn;
1350
1357
edge_t fwdedgea, fwdedgeb, fwdedge, *e, *fe, *le, *segfirst;
1352
1359
pathend_t tend, hend;
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];
1359
1366
e = edges[ind];
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) {
1364
1371
if (ED_tree_index(e) & BWDEDGE) {
1365
1372
MAKEFWDEDGE(&fwdedgeb, e);
1366
fwdedgea.tail = e->head;
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 */
1370
1383
fwdedgea.tail = e->tail;
1384
#else /* WITH_CGRAPH */
1385
agtail(&fwdedgea) = agtail(e);
1386
#endif /* WITH_CGRAPH */
1372
1388
le = getmainedge(e);
1373
1389
while (ED_to_virt(le))
1374
1390
le = ED_to_virt(le);
1375
fwdedgea.head = le->head;
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 */
1381
1405
hackflag = TRUE;
1489
for (i = 0; i < pn; i++)
1490
points[pointn++] = ps[i];
1514
for (i = 0; i < pn; i++) {
1515
pointfs[pointn++] = ps[i];
1491
1517
recover_slack(segfirst, P);
1492
hn = hackflag ? fwdedgeb.head : e->head;
1518
hn = hackflag ? aghead(&fwdedgeb) : aghead(e);
1495
1521
/* make copies of the spline points, one per multi-edge */
1497
1523
if (cnt == 1) {
1498
clip_and_install(fe, hn, points, pointn, &sinfo);
1524
clip_and_install(fe, hn, pointfs, pointn, &sinfo);
1501
1527
dx = sp->Multisep * (cnt - 1) / 2;
1502
1528
for (i = 1; i < pointn - 1; i++)
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) {
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);
1525
chooseflatsides(pathend_t* tendp, pathend_t *hendp,
1526
int* tsidep, int* hsidep, int* msidep, int* tdirp,
1527
int* hdirp, int* crossp)
1531
for (i = 0; i < 16; i++)
1532
if ((flatsidemap[i][0] & tendp->sidemask) &&
1533
(flatsidemap[i][1] & hendp->sidemask))
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];
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)
1556
tb = makeflatend(tendp->boxes[tendp->boxn - 1], tside, tdir, lb);
1557
hb = makeflatend(hendp->boxes[hendp->boxn - 1], hside, OTHERDIR(hdir),
1561
for (side = tside;; side = NEXTSIDE(side, tdir)) {
1562
boxes[boxn++] = makeflatcomponent(lb, rb, side,
1563
(side == mside) ? 0 : -1, tdir,
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);
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)
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)
1586
for (i = hendp->boxn - 1; i >= 0; i--)
1587
add_box(P, hendp->boxes[i]);
1591
makeflatend(box b, int side, int dir, box bb)
1593
box eb = { {0, 0}, {0, 0} };
1597
eb = boxof(b.LL.x, bb.LL.y, b.UR.x, b.LL.y);
1599
eb.UR.x += (bb.UR.x - b.UR.x) / 2;
1601
eb.LL.x -= (b.LL.x - bb.LL.x) / 2;
1604
eb = boxof(b.UR.x, b.LL.y, bb.UR.x, b.UR.y);
1606
eb.UR.y += (bb.UR.y - b.UR.y) / 2;
1608
eb.LL.y -= (b.LL.y - bb.LL.y) / 2;
1611
eb = boxof(b.LL.x, b.UR.y, b.UR.x, bb.UR.y);
1613
eb.LL.x -= (b.LL.x - bb.LL.x) / 2;
1615
eb.UR.x += (bb.UR.x - b.UR.x) / 2;
1618
eb = boxof(bb.LL.x, b.LL.y, b.LL.x, b.UR.y);
1620
eb.LL.y -= (bb.UR.y - b.UR.y) / 2;
1622
eb.UR.y += (b.LL.y - bb.LL.y) / 2;
1628
static box makeflatcomponent(lb, rb, side, mode, dir, w, h)
1630
int side, mode, dir, w, h;
1632
box b = { {0, 0}, {0, 0} };
1634
/* mode == -1 means use left box, 1 means use right box
1635
and 0 means use mostly the left box */
1639
b.LL.x = lb.LL.x - w, b.UR.x = rb.UR.x + w;
1641
b.LL.y = lb.LL.y - h, b.UR.y = lb.LL.y;
1643
b.LL.y = rb.LL.y - h, b.UR.y = rb.LL.y;
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;
1652
b.LL.y = lb.LL.y, b.UR.y = rb.UR.y;
1654
b.LL.y = rb.LL.y, b.UR.y = lb.UR.y;
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;
1661
b.LL.x = lb.LL.x - w, b.UR.x = rb.UR.x + w;
1663
b.LL.y = lb.UR.y, b.UR.y = lb.UR.y + h;
1665
b.LL.y = rb.UR.y, b.UR.y = rb.UR.y + h;
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;
1674
b.LL.y = lb.LL.y, b.UR.y = rb.UR.y;
1676
b.LL.y = rb.LL.y, b.UR.y = lb.UR.y;
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;
1686
completeflatpath(path* P, pathend_t* tendp, pathend_t* hendp,
1687
box* lbp, box* rbp, int w, int h)
1696
tb = makeflatend(tendp->boxes[tendp->boxn - 1], TOP, CW, lb);
1697
hb = makeflatend(hendp->boxes[hendp->boxn - 1], TOP, CCW, rb);
1699
wbox = makeflatcomponent(lb, rb, TOP, 0, CW, w, h);
1701
for (i = 0; i < tendp->boxn; i++)
1702
add_box(P, tendp->boxes[i]);
1705
for (i = hendp->boxn - 1; i >= 0; i--)
1706
add_box(P, hendp->boxes[i]);
1542
pointfs2[i] = pointfs[i];
1543
clip_and_install(e, aghead(e), pointfs2, pointn, &sinfo);
1710
1547
/* regular edges */
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);
1766
1601
/* box subdivision is obsolete, I think... ek */
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)
1772
1607
edge_t *uleft, *uright, *lleft, *lright;
1773
box uboxes[NSUB], lboxes[NSUB];
1608
boxf uboxes[NSUB], lboxes[NSUB];
1775
1610
int uboxn, lboxn, i, y, fb, lb;
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,
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)) {
1792
1627
y = b.UR.y - b.LL.y;
2126
1948
edge_t *f, *ans = NULL;
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)
2134
if (side * (ND_order(f->tail) - ND_order(e->tail)) <= 0)
1956
if (side * (ND_order(agtail(f)) - ND_order(agtail(e))) <= 0)
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)))
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))
2146
point closest(splines * spl, point p)
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;
2158
for (i = 0; i < spl->size; i++) {
2160
for (j = 0; j < bz.size; j++) {
2166
if ((bestj == -1) || (d2 < bestdist2)) {
2174
bz = spl->list[besti];
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;
2184
dlow2 = DIST2(c[0], pt);
2185
dhigh2 = DIST2(c[3], pt);
2187
t = (low + high) / 2.0;
2188
pt2 = Bezier(c, 3, t, NULL, NULL);
2189
if (fabs(dlow2 - dhigh2) < 1.0)
2191
if (fabs(high - low) < .00001)
2193
if (dlow2 < dhigh2) {
2195
dhigh2 = DIST2(pt2, pt);
2198
dlow2 = DIST2(pt2, pt);
2205
1968
/* common routines */
2207
1970
static int cl_vninside(graph_t * cl, node_t * n)
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));
2213
1976
/* returns the cluster of (adj) that interferes with n,
2215
static graph_t *cl_bound(n, adj)
1978
static Agraph_t *cl_bound(n, adj)
2216
1979
node_t *n, *adj;
2218
1981
graph_t *rv, *cl, *tcl, *hcl;
2255
2018
#define FUDGE 4
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)
2260
graph_t *g = vn->graph, *left_cl, *right_cl;
2023
graph_t *g = agraphof(vn), *left_cl, *right_cl;
2261
2024
node_t *left, *right;
2264
2027
left_cl = right_cl = NULL;
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);
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.;
2276
nb += sp->Splinesep;
2039
nb += (double)(sp->Splinesep);
2282
rv.LL.x = MIN(b, sp->LeftBound);
2045
rv.LL.x = MIN(ROUND(b), sp->LeftBound);
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);
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);
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.;
2297
nb -= sp->Splinesep;
2060
nb -= (double)(sp->Splinesep);
2303
rv.UR.x = MAX(b, sp->RightBound);
2066
rv.UR.x = MAX(ROUND(b), sp->RightBound);
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);
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;