36 #define GRAPHTYPEMASK 192
38 #define MAKEFWDEDGE(new, old) { \
42 info = (Agedgeinfo_t*)newp->base.data; \
43 *info = *(Agedgeinfo_t*)old->base.data; \
45 newp->base.data = (Agrec_t*)info; \
46 AGTAIL(newp) = AGHEAD(old); \
47 AGHEAD(newp) = AGTAIL(old); \
48 ED_tail_port(newp) = ED_head_port(old); \
49 ED_head_port(newp) = ED_tail_port(old); \
50 ED_edge_type(newp) = VIRTUAL; \
51 ED_to_orig(newp) = old; \
54 static boxf boxes[1000];
60 static void adjustregularpath(
path *,
int,
int);
70 static boxf makeregularend(
boxf,
int,
double);
73 static void place_vnlabel(
Agnode_t *);
76 static void resize_vn(
Agnode_t *,
int,
int,
int);
77 static void setflags(
Agedge_t *,
int,
int,
int);
82 #define GROWEDGES (edges = ALLOC (n_edges + CHUNK, edges, edge_t*))
95 static boolean spline_merge(
node_t * n)
101 static boolean swap_ends_p(
edge_t * e)
114 static splineInfo sinfo = { swap_ends_p, spline_merge };
123 rv = p0.
p.
x - p1.
p.
x;
125 rv = p0.
p.
y - p1.
p.
y;
141 olp = old->
list + (sz - 1);
142 for (i = 0; i < sz; i++) {
148 new->sflag = old->
eflag;
149 new->eflag = old->
sflag;
156 static void swap_spline(
splines *
s)
166 olp = s->
list + (sz - 1);
167 for (i = 0; i < sz; i++) {
168 swap_bezier(olp--, lp++);
172 for (i = 0; i < sz; i++)
185 static void edge_normalize(
graph_t * g)
211 double tmp =
ND_rw(n);
256 int i, j, k, n_nodes, n_edges, ind, cnt;
260 edge_t *e, *e0, *e1, *ea, *eb, *le0, *le1, **edges =
NULL;
271 agerr (
AGWARN,
"edge labels with splines=curved not supported in dot - use xlabels\n");
297 n_edges = n_nodes = 0;
307 for (j = 0; j <
GD_rank(g)[i].n; j++) {
321 for (k = 0; (e =
ND_out(n).list[k]); k++) {
326 edges[n_edges++] = e;
327 if (n_edges %
CHUNK == 0)
333 edges[n_edges++] = e;
334 if (n_edges %
CHUNK == 0)
344 double tmp =
ND_rw(n);
348 for (k = 0; (e =
ND_other(n).list[k]); k++) {
350 edges[n_edges++] = e;
351 if (n_edges %
CHUNK == 0)
364 qsort((
char *) &edges[0], n_edges,
sizeof(edges[0]),
380 for (i = 0; i < n_edges;) {
382 le0 = getmainedge((e0 = edges[i++]));
392 for (cnt = 1; i < n_edges; cnt++, i++) {
393 if (le0 != (le1 = getmainedge((e1 = edges[i]))))
424 edgelist[0] = getmainedge((edges+ind)[0]);
425 for (ii = 1; ii < cnt; ii++)
426 edgelist[ii] = (edges+ind)[ii];
447 sizey =
MIN(upy, dwny);
450 for (b = 0; b < cnt; b++) {
457 make_flat_edge(g, &sd, P, edges, ind, cnt, et);
460 make_regular_edge(g, &sd, P, edges, ind, cnt, et);
534 if (
ND_in(n).size == 0)
546 setflags(
edge_t *e,
int hint1,
int hint2,
int f3)
590 edge_t *e0, *e1, *ea, *eb, *le0, *le1;
591 int et0, et1, v0, v1, rv;
603 le0 = getmainedge(e0);
604 le1 = getmainedge(e1);
827 setState (auxg, attr_state);
895 int lbllen = strlen(
ND_label(orign)->text);
896 char* buf =
N_GNEW(lbllen+3,
char);
897 sprintf (buf,
"{%s}",
ND_label(orign)->text);
898 agset (n,
"label", buf);
936 return add_pointf(p, del);
957 if (sz0.
x > sz1.
x)
return -1;
958 else if (sz0.
x < sz1.
x)
return 1;
959 else if (sz0.
y > sz1.
y)
return -1;
960 else if (sz0.
y < sz1.
y)
return 1;
982 makeSimpleFlatLabels (
node_t* tn,
node_t* hn,
edge_t** edges,
int ind,
int cnt,
int et,
int n_lbls)
988 pointf points[10], tp, hp;
990 double leftend, rightend, ctrx, ctry, miny, maxy;
992 double lminx=0.0, lmaxx=0.0;
996 for (i = 0; i < cnt; i++) {
997 earray[i] = edges[ind + i];
1005 leftend = tp.
x+
ND_rw(tn);
1006 rightend = hp.
x-
ND_lw(hn);
1007 ctrx = (leftend + rightend)/2.0;
1012 points[pointn++] = tp;
1013 points[pointn++] = tp;
1014 points[pointn++] = hp;
1015 points[pointn++] = hp;
1022 maxy = miny +
ED_label(e)->dimen.y;
1023 uminx = ctrx - (
ED_label(e)->dimen.x)/2.0;
1024 umaxx = ctrx + (
ED_label(e)->dimen.x)/2.0;
1026 for (i = 1; i < n_lbls; i++) {
1030 lminx = ctrx - (
ED_label(e)->dimen.x)/2.0;
1031 lmaxx = ctrx + (
ED_label(e)->dimen.x)/2.0;
1038 points[2].
y = points[1].
y;
1040 points[4].
x = lmaxx;
1042 points[5].
x = lmaxx;
1044 points[6].
x = lminx;
1046 points[7].
x = lminx;
1048 ctry = miny + (
ED_label(e)->dimen.y)/2.0;
1052 points[1].
x = uminx;
1054 points[2].
x = uminx;
1056 points[3].
x = umaxx;
1058 points[4].
x = umaxx;
1066 ctry = maxy + (
ED_label(e)->dimen.y)/2.0 + LBL_SPACE;
1072 if (pn == 0)
return;
1080 for (; i < cnt; i++) {
1084 lminx = (2*leftend + rightend)/3.0;
1085 lmaxx = (leftend + 2*rightend)/3.0;
1092 points[2].
y = points[1].
y;
1094 points[4].
x = lmaxx;
1096 points[5].
x = lmaxx;
1098 points[6].
x = lminx;
1100 points[7].
x = lminx;
1105 points[1].
x = uminx;
1107 points[2].
x = uminx;
1109 points[3].
x = umaxx;
1111 points[4].
x = umaxx;
1124 if (pn == 0)
return;
1137 pointf points[10], tp, hp;
1144 stepy = (cnt > 1) ?
ND_ht(tn) / (double)(cnt - 1) : 0.;
1145 dy = tp.
y - ((cnt > 1) ?
ND_ht(tn) / 2. : 0.);
1147 for (i = 0; i < cnt; i++) {
1151 points[pointn++] = tp;
1152 points[pointn++] = pointfof((2 * tp.
x + hp.
x) / 3, dy);
1153 points[pointn++] = pointfof((2 * hp.
x + tp.
x) / 3, dy);
1154 points[pointn++] = hp;
1157 points[pointn++] = tp;
1158 points[pointn++] = tp;
1159 points[pointn++] = pointfof((2 * tp.
x + hp.
x) / 3, dy);
1160 points[pointn++] = pointfof((2 * tp.
x + hp.
x) / 3, dy);
1161 points[pointn++] = pointfof((2 * tp.
x + hp.
x) / 3, dy);
1162 points[pointn++] = pointfof((2 * hp.
x + tp.
x) / 3, dy);
1163 points[pointn++] = pointfof((2 * hp.
x + tp.
x) / 3, dy);
1164 points[pointn++] = pointfof((2 * hp.
x + tp.
x) / 3, dy);
1165 points[pointn++] = hp;
1166 points[pointn++] = hp;
1189 int labels = 0, ports = 0;
1194 int i, j, midx, midy, leftx, rightx;
1204 agerr (
AGWARN,
"flat edge between adjacent nodes one of which has a record shape - replace records with HTML-like labels\n");
1211 for (i = 0; i < cnt; i++) {
1220 makeSimpleFlat (tn, hn, edges, ind, cnt, et);
1224 makeSimpleFlatLabels (tn, hn, edges, ind, cnt, et, labels);
1230 auxg = cloneGraph (g, attrs);
1231 subg =
agsubg (auxg,
"xxx",1);
1233 agset (subg,
"rank",
"source");
1242 auxt = cloneNode(subg, tn,
GD_flip(g));
1243 auxh = cloneNode(auxg, hn,
GD_flip(g));
1244 for (i = 0; i < cnt; i++) {
1248 auxe = cloneEdge (auxg, auxt, auxh, e);
1250 auxe = cloneEdge (auxg, auxh, auxt, e);
1278 else if (n == auxh) {
1285 _dot_splines(auxg, 0);
1297 for (i = 0; i < cnt; i++) {
1304 if ((auxe == hvye) & !
ED_alg(auxe))
continue;
1305 auxbz =
ED_spl(auxe)->list;
1311 for (j = 0; j < auxbz->
size; ) {
1315 if ( j >= auxbz->
size )
1321 cp[3] = transformf(auxbz->
list[j], del,
GD_flip(g));
1331 cleanupCloneGraph (auxg, attrs);
1342 b = endp->
nb = maximal_bbox(g, sp, n,
NULL, e);
1360 b = endp->
nb = maximal_bbox(g, sp, n,
NULL, e);
1381 int boxn, i, pn, ydelta;
1401 points[1] = points[0] = startp;
1402 points[2] = points[3] = points[4] = lp;
1403 points[5] = points[6] = endp;
1417 makeFlatEnd (g, sp, P, tn, e, &tend,
TRUE);
1418 makeFlatEnd (g, sp, P, hn, e, &hend,
FALSE);
1422 boxes[boxn].
UR.
x = lb.
LL.
x;
1423 boxes[boxn].
UR.
y = lb.
LL.
y;
1426 boxes[boxn].
LL.
y = lb.
LL.
y;
1428 boxes[boxn].
UR.
y = lb.
UR.
y;
1430 boxes[boxn].
LL.
x = lb.
UR.
x;
1431 boxes[boxn].
UR.
y = lb.
LL.
y;
1437 for (i = 0; i < boxn; i++)
add_box(P, boxes[i]);
1442 if (pn == 0)
return;
1455 double stepx, stepy, vspace;
1472 stepx = ((double)(sp->
Multisep)) / (cnt+1);
1473 stepy = vspace / (cnt+1);
1475 makeBottomFlatEnd (g, sp, P, tn, e, &tend,
TRUE);
1476 makeBottomFlatEnd (g, sp, P, hn, e, &hend,
FALSE);
1478 for (i = 0; i < cnt; i++) {
1485 boxes[boxn].
LL.
x = b.
LL.
x;
1486 boxes[boxn].
UR.
y = b.
LL.
y;
1487 boxes[boxn].
UR.
x = b.
UR.
x + (i + 1) * stepx;
1488 boxes[boxn].
LL.
y = b.
LL.
y - (i + 1) * stepy;
1491 boxes[boxn].
UR.
y = boxes[boxn-1].
LL.
y;
1493 boxes[boxn].
LL.
y = boxes[boxn].
UR.
y - stepy;
1496 boxes[boxn].
UR.
x = b.
UR.
x;
1497 boxes[boxn].
UR.
y = b.
LL.
y;
1498 boxes[boxn].
LL.
x = b.
LL.
x - (i + 1) * stepx;
1499 boxes[boxn].
LL.
y = boxes[boxn-1].
UR.
y;
1503 for (j = 0; j < boxn; j++)
add_box(P, boxes[j]);
1531 int j, i, r, isAdjacent;
1532 double stepx, stepy, vspace;
1533 int tside, hside, pn;
1546 for (i = 1; i < cnt; i++) {
1556 make_flat_adj_edges (g, P, edges, ind, cnt, e, et);
1560 make_flat_labeled_edge (g, sp, P, e, et);
1565 makeSimpleFlat (
agtail(e),
aghead(e), edges, ind, cnt, et);
1571 if (((tside ==
BOTTOM) && (hside !=
TOP)) ||
1572 ((hside ==
BOTTOM) && (tside !=
TOP))) {
1573 make_flat_bottom_edges (g, sp, P, edges, ind, cnt, e, et ==
ET_SPLINE);
1591 stepx = ((double)sp->
Multisep) / (cnt+1);
1592 stepy = vspace / (cnt+1);
1594 makeFlatEnd (g, sp, P, tn, e, &tend,
TRUE);
1595 makeFlatEnd (g, sp, P, hn, e, &hend,
FALSE);
1597 for (i = 0; i < cnt; i++) {
1604 boxes[boxn].
LL.
x = b.
LL.
x;
1605 boxes[boxn].
LL.
y = b.
UR.
y;
1606 boxes[boxn].
UR.
x = b.
UR.
x + (i + 1) * stepx;
1607 boxes[boxn].
UR.
y = b.
UR.
y + (i + 1) * stepy;
1610 boxes[boxn].
LL.
y = boxes[boxn-1].
UR.
y;
1612 boxes[boxn].
UR.
y = boxes[boxn].
LL.
y + stepy;
1615 boxes[boxn].
UR.
x = b.
UR.
x;
1616 boxes[boxn].
LL.
y = b.
UR.
y;
1617 boxes[boxn].
LL.
x = b.
LL.
x - (i + 1) * stepx;
1618 boxes[boxn].
UR.
y = boxes[boxn-1].
LL.
y;
1622 for (j = 0; j < boxn; j++)
add_box(P, boxes[j]);
1642 d = ((p1.
y - p2.
y) * (p3.
x - p2.
x)) -
1643 ((p3.
y - p2.
y) * (p1.
x - p2.
x));
1671 double width, height;
1703 if (leftOf (endp,startp,lp)) {
1712 points[1] = points[0] = startp;
1713 points[2] = points[3] = points[4] = lp;
1714 points[5] = points[6] = endp;
1718 points[1] = points[0] = startp;
1719 points[3] = points[2] = endp;
1740 int boxn, sl, si, smode, i, j, dx, pn, hackflag, longedge;
1776 le = getmainedge(e);
1796 if ((et ==
ET_LINE) && (pointn = makeLineEdge (g, fe, pointfs, &hn))) {
1805 b = tend.
nb = maximal_bbox(g, sp, tn,
NULL, e);
1809 b = makeregularend(b,
BOTTOM,
1814 smode =
FALSE, si = -1;
1817 boxes[boxn++] = rank_box(sp, g,
ND_rank(tn));
1819 && ((sl = straight_len(hn)) >=
1824 if (!smode || si > 0) {
1826 boxes[boxn++] = maximal_bbox(g, sp, hn, e,
ND_out(hn).list[0]);
1832 hend.
nb = maximal_bbox(g, sp, hn, e,
ND_out(hn).list[0]);
1839 completeregularpath(P, segfirst, e, &tend, &hend, boxes, boxn, 1);
1843 if ((et ==
ET_LINE) && (pn > 4)) {
1845 ps[3] = ps[2] = ps[pn-1];
1852 if (pointn + pn > numpts) {
1856 numpts = 2*(pointn+pn);
1859 for (i = 0; i < pn; i++) {
1860 pointfs[pointn++] = ps[i];
1862 e = straight_path(
ND_out(hn).list[0], sl, pointfs, &pointn);
1863 recover_slack(segfirst, P);
1868 tend.
nb = maximal_bbox(g, sp, tn,
ND_in(tn).list[0], e);
1877 boxes[boxn++] = rank_box(sp, g,
ND_rank(tn));
1878 b = hend.
nb = maximal_bbox(g, sp, hn, e,
NULL);
1882 b = makeregularend(b,
TOP,
1886 completeregularpath(P, segfirst, e, &tend, &hend, boxes, boxn,
1890 if ((et ==
ET_LINE) && (pn > 4)) {
1896 ps[3] = ps[2] = ps[pn-1];
1901 if (pointn + pn > numpts) {
1902 numpts = 2*(pointn+pn);
1905 for (i = 0; i < pn; i++) {
1906 pointfs[pointn++] = ps[i];
1908 recover_slack(segfirst, P);
1919 for (i = 1; i < pointn - 1; i++)
1922 if (numpts > numpts2) {
1926 for (i = 0; i < pointn; i++)
1927 pointfs2[i] = pointfs[i];
1929 for (j = 1; j < cnt; j++) {
1935 for (i = 1; i < pointn - 1; i++)
1937 for (i = 0; i < pointn; i++)
1938 pointfs2[i] = pointfs[i];
1945 #define DONT_WANT_ANY_ENDPOINT_PATH_REFINEMENT
1946 #ifdef DONT_WANT_ANY_ENDPOINT_PATH_REFINEMENT
1952 edge_t *uleft, *uright, *lleft, *lright;
1959 uleft = uright =
NULL;
1960 uleft = top_bound(first, -1), uright = top_bound(first, 1);
1971 lleft = lright =
NULL;
1972 lleft = bot_bound(last, -1), lright = bot_bound(last, 1);
1983 for (i = 0; i < tendp->
boxn; i++)
1987 for (i = 0; i < boxn; i++)
1989 for (i = hendp->
boxn - 1; i >= 0; i--)
1991 adjustregularpath(P, fb, lb);
1995 int dir,
boxf b,
boxf * boxes,
int *boxnp);
2003 edge_t *uleft, *uright, *lleft, *lright;
2006 int uboxn, lboxn, i, y, fb, lb;
2009 uleft = uright =
NULL;
2011 uleft = top_bound(first, -1), uright = top_bound(first, 1);
2012 refineregularends(uleft, uright, tendp, 1, boxes[0], uboxes, &uboxn);
2013 lleft = lright =
NULL;
2015 lleft = bot_bound(last, -1), lright = bot_bound(last, 1);
2016 refineregularends(lleft, lright, hendp, -1, boxes[boxn - 1], lboxes,
2018 for (i = 0; i < tendp->
boxn; i++)
2021 if ((!uleft && !uright) && (lleft || lright)) {
2024 for (i = 0; i <
NSUB; i++) {
2027 uboxes[i].
LL.
y = b.
UR.
y - y * (i + 1) / NSUB;
2030 }
else if ((uleft || uright) && (!lleft && !lright)) {
2031 b = boxes[boxn - 1];
2033 for (i = 0; i <
NSUB; i++) {
2036 lboxes[i].
LL.
y = b.
UR.
y - y * (i + 1) / NSUB;
2040 for (i = 0; i < uboxn; i++) {
2041 uboxes[i].
LL.
x =
MAX(uboxes[i].LL.x, lboxes[i].
LL.
x);
2042 uboxes[i].
UR.
x =
MIN(uboxes[i].UR.x, lboxes[i].
UR.
x);
2044 for (i = 0; i < uboxn; i++)
2047 for (i = 0; i < uboxn; i++)
2051 for (i = 1; i < boxn - 1; i++)
2053 for (i = 0; i < lboxn; i++)
2056 for (i = hendp->
boxn - 1; i >= 0; i--)
2058 adjustregularpath(P, fb, lb);
2067 static boxf makeregularend(
boxf b,
int side,
double y)
2072 newb = boxfof(b.
LL.
x, y, b.
UR.
x, b.
LL.
y);
2075 newb = boxfof(b.
LL.
x, b.
UR.
y, b.
UR.
x, y);
2081 #ifndef DONT_WANT_ANY_ENDPOINT_PATH_REFINEMENT
2082 void refineregularends(
left,
right, endp, dir, b, boxes, boxnp)
2090 splines *lspls, *rspls;
2098 if ((y == 1) || (!left && !right)) {
2104 for (i = 0; i < nsub; i++) {
2106 boxes[i].
UR.
y = b.
UR.
y - y * i / nsub;
2107 boxes[i].
LL.
y = b.
UR.
y - y * (i + 1) / nsub;
2108 if (boxes[i].UR.y == boxes[i].
LL.
y)
2113 for (j = 0; j < endp->
boxn; j++) {
2114 eb = endp->
boxes[j];
2116 #ifdef STEVE_AND_LEFTY_GRASPING_AT_STRAWS
2123 for (k = endp->
boxn - 1; k > j; k--)
2124 endp->
boxes[k + (nsub - 1)] = endp->
boxes[k];
2125 for (i = 0; i < nsub; i++) {
2126 bp = &endp->
boxes[j + ((dir == 1) ? i : (nsub - i - 1))];
2128 bp->
UR.
y = eb.
UR.
y - y * i / nsub;
2129 bp->
LL.
y = eb.
UR.
y - y * (i + 1) / nsub;
2130 if (bp->
UR.
y == bp->
LL.
y)
2133 endp->
boxn += (nsub - 1);
2139 for (i = 0; i < nsub; i++) {
2147 for (i = 1; i < endp->
boxn; i++) {
2153 i = (dir == 1) ? 0 : *boxnp - 1;
2160 for (i = 0; i < nsub; i++) {
2168 for (i = 1; i < endp->
boxn; i++) {
2174 i = (dir == 1) ? 0 : *boxnp - 1;
2197 static void adjustregularpath(
path * P,
int fb,
int lb)
2202 for (i = fb-1; i < lb+1; i++) {
2204 if ((i - fb) % 2 == 0) {
2205 if (bp1->
LL.
x >= bp1->
UR.
x) {
2206 x = (bp1->
LL.
x + bp1->
UR.
x) / 2;
2211 x = (bp1->
LL.
x + bp1->
UR.
x) / 2;
2216 for (i = 0; i < P->
nbox - 1; i++) {
2218 if (i >= fb && i <= lb && (i - fb) % 2 == 0) {
2221 if (bp1->
UR.
x - MINW < bp2->LL.x)
2223 }
else if (i + 1 >= fb && i < lb && (i + 1 - fb) % 2 == 0) {
2226 if (bp1->
UR.
x - MINW < bp2->LL.x)
2241 left1 =
GD_rank(g)[r + 1].v[0];
2253 static int straight_len(
node_t * n)
2263 if ((
ND_out(v).size != 1) || (
ND_in(v).size != 1))
2279 plist[(*np)++] = plist[n - 1];
2280 plist[(*np)++] = plist[n - 1];
2286 static void recover_slack(
edge_t * e,
path * p)
2311 static void resize_vn(vn, lx, cx, rx)
2347 for (i = 0; (f =
ND_in(
aghead(e)).list[i]); i++) {
2377 #define REAL_CLUSTER(n) (ND_clust(n)==g?NULL:ND_clust(n))
2396 if (cl && (cl != tcl) && (cl != hcl))
2401 if (cl && (cl != tcl) && (cl != hcl) && cl_vninside(cl, adj))
2405 if (cl && (cl != tcl) && (cl != hcl) && cl_vninside(cl, adj))
2429 left_cl = right_cl =
NULL;
2433 if ((left = neighbor(g, vn, ie, oe, -1))) {
2434 if ((left_cl = cl_bound(g, vn, left)))
2454 if ((right = neighbor(g, vn, ie, oe, 1))) {
2455 if ((right_cl = cl_bound(g, vn, right)))
2487 for (i =
ND_order(vn) + dir; ((i >= 0) && (i < rank->n)); i += dir) {
2497 if (pathscross(n, vn, ie, oe) ==
FALSE) {
2505 static boolean pathscross(n0, n1, ie1, oe1)
2517 if (
ND_out(n0).size == 1 && e1) {
2519 for (cnt = 0; cnt < 2; cnt++) {
2533 if (
ND_in(n0).size == 1 && e1) {
2534 e0 =
ND_in(n0).list[0];
2535 for (cnt = 0; cnt < 2; cnt++) {
2542 e0 =
ND_in(na).list[0];
2545 e1 =
ND_in(nb).list[0];
2552 void showpath(
path * p)
2557 fprintf(stderr,
"%%!PS\n");
2558 for (i = 0; i < p->
nbox; i++) {
2562 "newpath %.04f %.04f moveto %.04f %.04f lineto %.04f %.04f lineto %.04f %.04f lineto closepath stroke\n",
2563 LL.
x, LL.
y, UR.
x, LL.
y, UR.
x, UR.
y, LL.
x, UR.
y);
2565 fprintf(stderr,
"showpage\n");
void dotneato_postprocess(Agraph_t *g)
int portcmp(port p0, port p1)
bezier * new_spline(edge_t *e, int sz)
EXTERN Agsym_t * N_showboxes
CGRAPH_API Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
pointf * routesplines(path *, int *)
#define RALLOC(size, ptr, type)
CGRAPH_API Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
EXTERN Agsym_t * E_labelfontcolor
Agsym_t * agattr(Agraph_t *g, int kind, char *name, char *value)
EXTERN Agsym_t * E_tailclip
Agsym_t * agnxtattr(Agraph_t *g, int kind, Agsym_t *attr)
EXTERN Agsym_t * N_fontname
EXTERN Agsym_t * N_fontcolor
shape_kind shapeOf(node_t *)
CGRAPH_API Agedge_t * agfstin(Agraph_t *g, Agnode_t *n)
int agxset(void *obj, Agsym_t *sym, char *value)
splines * getsplinepoints(edge_t *e)
EXTERN Agsym_t * N_fontsize
pointf * routepolylines(path *pp, int *npoints)
boolean(* swapEnds)(edge_t *e)
EXTERN Agsym_t * N_height
EXTERN Agsym_t * N_peripheries
#define SET_RANKDIR(g, rd)
EXTERN Agsym_t * E_labelfontname
void beginpath(path *, Agedge_t *, int, pathend_t *, boolean)
void dot_sameports(Agraph_t *)
CGRAPH_API int agisdirected(Agraph_t *g)
EXTERN Agsym_t * G_ordering
attrsym_t * E_label_float
EXTERN Agsym_t * E_labeldistance
EXTERN Agsym_t * E_labelangle
void makeStraightEdges(graph_t *g, edge_t **edges, int e_cnt, int et, splineInfo *sinfo)
EXTERN Agsym_t * E_headlabel
void dot_splines(Agraph_t *)
void endpath(path *, Agedge_t *, int, pathend_t *, boolean)
void clip_and_install(edge_t *fe, node_t *hn, pointf *ps, int pn, splineInfo *info)
EXTERN Agsym_t * E_fontcolor
attrsym_t * E_labelfontsize
EXTERN Agsym_t * E_label_float
int agerr(agerrlevel_t level, const char *fmt,...)
pointf * simpleSplineRoute(pointf, pointf, Ppoly_t, int *, int)
EXTERN Agsym_t * E_constr
void add_box(path *, boxf)
CGRAPH_API Agraph_t * agroot(void *obj)
CGRAPH_API Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
EXTERN Agsym_t * E_sametail
CGRAPH_API Agdesc_t Agundirected
int routesplinesinit(void)
CGRAPH_API Agraph_t * agraphof(void *obj)
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
CGRAPH_API Agdesc_t Agdirected
int normalize(graph_t *g)
CGRAPH_API Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
int agset(void *obj, char *name, char *value)
int rank(graph_t *g, int balance, int maxiter)
CGRAPH_API Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
EXTERN Agsym_t * E_taillabel
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
void routesplinesterm(void)
EXTERN Agsym_t * E_xlabel
CGRAPH_API int agclose(Agraph_t *g)
CGRAPH_API char * agnameof(void *)
void mark_lowclusters(Agraph_t *root)
void dot_rank(Agraph_t *, aspect_t *)
attrsym_t * N_peripheries
EXTERN Agsym_t * N_xlabel
void update_bb_bz(boxf *bb, pointf *cp)
#define MAKEFWDEDGE(new, old)
int(* qsort_cmpf)(const void *, const void *)
#define agfindedgeattr(g, a)
EXTERN Agsym_t * N_orientation
CGRAPH_API Agnode_t * agfstnode(Agraph_t *g)
EXTERN Agsym_t * E_minlen
attrsym_t * N_orientation
int agcopyattr(void *oldobj, void *newobj)
void dot_cleanup(graph_t *g)
#define agfindgraphattr(g, a)
EXTERN Agsym_t * E_weight
void dot_init_node_edge(graph_t *g)
EXTERN Agsym_t * E_fontname
EXTERN Agsym_t * N_nojustify
void makeSelfEdge(path *P, edge_t *edges[], int ind, int cnt, double sizex, double sizey, splineInfo *sinfo)
boolean(* splineMerge)(node_t *n)
attrsym_t * E_labelfontcolor
CGRAPH_API Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
void updateBB(graph_t *g, textlabel_t *lp)
EXTERN Agsym_t * N_ordering
EXTERN Agsym_t * E_labelfontsize
CGRAPH_API void * agbindrec(void *obj, char *name, unsigned int size, int move_to_front)
EXTERN Agsym_t * E_headclip
void setEdgeType(graph_t *g, int dflt)
CGRAPH_API Agedge_t * agnxtin(Agraph_t *g, Agedge_t *e)
EXTERN Agsym_t * E_samehead
int place_portlabel(edge_t *e, boolean head_p)
EXTERN Agsym_t * E_fontsize
CGRAPH_API Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
attrsym_t * E_labelfontname
void dot_position(Agraph_t *, aspect_t *)
#define agfindnodeattr(g, a)
EXTERN int EdgeLabelsDone
pointf spline_at_y(splines *spl, double y)
EXTERN Agsym_t * N_distortion
void dot_mincross(Agraph_t *, int)