From: erg Date: Tue, 8 Mar 2005 23:34:10 +0000 (+0000) Subject: Make many functions in dotprocs.h static to help me keep my sanity X-Git-Tag: LAST_LIBGRAPH~32^2~7840 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=27d52a6c13fa04eb5aacfe2181f4f2e772d95fec;p=graphviz Make many functions in dotprocs.h static to help me keep my sanity trying to track down who can be called. --- diff --git a/lib/dotgen/class2.c b/lib/dotgen/class2.c index 9339af438..eb7ccce70 100644 --- a/lib/dotgen/class2.c +++ b/lib/dotgen/class2.c @@ -19,6 +19,156 @@ #include "dot.h" +static node_t* +label_vnode(graph_t * g, edge_t * orig) +{ + node_t *v; + pointf dimen; + + dimen = ED_label(orig)->dimen; + v = virtual_node(g); + ND_label(v) = ED_label(orig); + ND_lw_i(v) = GD_nodesep(v->graph); + if (!ED_label_ontop(orig)) { + if (GD_flip(g)) { + ND_ht_i(v) = dimen.x; + ND_rw_i(v) = dimen.y; + } else { + ND_ht_i(v) = dimen.y; + ND_rw_i(v) = dimen.x; + } + } + return v; +} + +static void +incr_width(graph_t * g, node_t * v) +{ + int width = GD_nodesep(g) / 2; + ND_lw_i(v) += width; + ND_rw_i(v) += width; +} + +static node_t* +plain_vnode(graph_t * g, edge_t * orig) +{ + node_t *v; + orig = orig; + v = virtual_node(g); + incr_width(g, v); + return v; +} + +static node_t* +leader_of(graph_t * g, node_t * v) +{ + graph_t *clust; + node_t *rv; + + if (ND_ranktype(v) != CLUSTER) { + /*assert(v == UF_find(v)); could be leaf, so comment out */ + rv = UF_find(v); + } else { + clust = ND_clust(v); + rv = GD_rankleader(clust)[ND_rank(v)]; + } + return rv; +} + +static void +make_chain(graph_t * g, node_t * from, node_t * to, edge_t * orig) +{ + int r, label_rank; + node_t *u, *v; + edge_t *e; + + u = from; + if (ED_label(orig)) + label_rank = (ND_rank(from) + ND_rank(to)) / 2; + else + label_rank = -1; + assert(ED_to_virt(orig) == NULL); + for (r = ND_rank(from) + 1; r <= ND_rank(to); r++) { + if (r < ND_rank(to)) { + if (r == label_rank) + v = label_vnode(g, orig); + else + v = plain_vnode(g, orig); + ND_rank(v) = r; + } else + v = to; + e = virtual_edge(u, v, orig); + virtual_weight(e); + u = v; + } + assert(ED_to_virt(orig) != NULL); +} + +static void +interclrep(graph_t * g, edge_t * e) +{ + node_t *t, *h; + edge_t *ve; + + t = leader_of(g, e->tail); + h = leader_of(g, e->head); + if (ND_rank(t) > ND_rank(h)) { + node_t *t0 = t; + t = h; + h = t0; + } + if (ND_clust(t) != ND_clust(h)) { + if ((ve = find_fast_edge(t, h))) { + merge_chain(g, e, ve, TRUE); + return; + } + if (ND_rank(t) == ND_rank(h)) + return; + make_chain(g, t, h, e); + + /* mark as cluster edge */ + for (ve = ED_to_virt(e); ve && (ND_rank(ve->head) <= ND_rank(h)); + ve = ND_out(ve->head).list[0]) + ED_edge_type(ve) = CLUSTER_EDGE; + } + /* else ignore intra-cluster edges at this point */ +} + +static int +is_cluster_edge(edge_t * e) +{ + return ((ND_ranktype(e->tail) == CLUSTER) + || (ND_ranktype(e->head) == CLUSTER)); +} + +void merge_chain(graph_t * g, edge_t * e, edge_t * f, int flag) +{ + edge_t *rep; + int lastrank = MAX(ND_rank(e->tail), ND_rank(e->head)); + + assert(ED_to_virt(e) == NULL); + ED_to_virt(e) = f; + rep = f; + do { + /* interclust multi-edges are not counted now */ + if (flag) + ED_count(rep) += ED_count(e); + ED_xpenalty(rep) += ED_xpenalty(e); + ED_weight(rep) += ED_weight(e); + if (ND_rank(rep->head) == lastrank) + break; + incr_width(g, rep->head); + rep = ND_out(rep->head).list[0]; + } while (rep); +} + +int mergeable(edge_t * e, edge_t * f) +{ + if (e && f && (e->tail == f->tail) && (e->head == f->head) && + (ED_label(e) == ED_label(f)) && ports_eq(e, f)) + return TRUE; + return FALSE; +} void class2(graph_t * g) { @@ -156,146 +306,3 @@ void class2(graph_t * g) } } -node_t *label_vnode(graph_t * g, edge_t * orig) -{ - node_t *v; - pointf dimen; - - dimen = ED_label(orig)->dimen; - v = virtual_node(g); - ND_label(v) = ED_label(orig); - ND_lw_i(v) = GD_nodesep(v->graph); - if (!ED_label_ontop(orig)) { - if (GD_flip(g)) { - ND_ht_i(v) = dimen.x; - ND_rw_i(v) = dimen.y; - } else { - ND_ht_i(v) = dimen.y; - ND_rw_i(v) = dimen.x; - } - } - return v; -} - -node_t *plain_vnode(graph_t * g, edge_t * orig) -{ - node_t *v; - orig = orig; - v = virtual_node(g); - incr_width(g, v); - return v; -} - -void incr_width(graph_t * g, node_t * v) -{ - int width = GD_nodesep(g) / 2; - ND_lw_i(v) += width; - ND_rw_i(v) += width; -} - -void make_chain(graph_t * g, node_t * from, node_t * to, edge_t * orig) -{ - int r, label_rank; - node_t *u, *v; - edge_t *e; - - u = from; - if (ED_label(orig)) - label_rank = (ND_rank(from) + ND_rank(to)) / 2; - else - label_rank = -1; - assert(ED_to_virt(orig) == NULL); - for (r = ND_rank(from) + 1; r <= ND_rank(to); r++) { - if (r < ND_rank(to)) { - if (r == label_rank) - v = label_vnode(g, orig); - else - v = plain_vnode(g, orig); - ND_rank(v) = r; - } else - v = to; - e = virtual_edge(u, v, orig); - virtual_weight(e); - u = v; - } - assert(ED_to_virt(orig) != NULL); -} - -void merge_chain(graph_t * g, edge_t * e, edge_t * f, int flag) -{ - edge_t *rep; - int lastrank = MAX(ND_rank(e->tail), ND_rank(e->head)); - - assert(ED_to_virt(e) == NULL); - ED_to_virt(e) = f; - rep = f; - do { - /* interclust multi-edges are not counted now */ - if (flag) - ED_count(rep) += ED_count(e); - ED_xpenalty(rep) += ED_xpenalty(e); - ED_weight(rep) += ED_weight(e); - if (ND_rank(rep->head) == lastrank) - break; - incr_width(g, rep->head); - rep = ND_out(rep->head).list[0]; - } while (rep); -} - -node_t *leader_of(graph_t * g, node_t * v) -{ - graph_t *clust; - node_t *rv; - - if (ND_ranktype(v) != CLUSTER) { - /*assert(v == UF_find(v)); could be leaf, so comment out */ - rv = UF_find(v); - } else { - clust = ND_clust(v); - rv = GD_rankleader(clust)[ND_rank(v)]; - } - return rv; -} - -void interclrep(graph_t * g, edge_t * e) -{ - node_t *t, *h; - edge_t *ve; - - t = leader_of(g, e->tail); - h = leader_of(g, e->head); - if (ND_rank(t) > ND_rank(h)) { - node_t *t0 = t; - t = h; - h = t0; - } - if (ND_clust(t) != ND_clust(h)) { - if ((ve = find_fast_edge(t, h))) { - merge_chain(g, e, ve, TRUE); - return; - } - if (ND_rank(t) == ND_rank(h)) - return; - make_chain(g, t, h, e); - - /* mark as cluster edge */ - for (ve = ED_to_virt(e); ve && (ND_rank(ve->head) <= ND_rank(h)); - ve = ND_out(ve->head).list[0]) - ED_edge_type(ve) = CLUSTER_EDGE; - } - /* else ignore intra-cluster edges at this point */ -} - -int is_cluster_edge(edge_t * e) -{ - return ((ND_ranktype(e->tail) == CLUSTER) - || (ND_ranktype(e->head) == CLUSTER)); -} - -int mergeable(edge_t * e, edge_t * f) -{ - if (e && f && (e->tail == f->tail) && (e->head == f->head) && - (ED_label(e) == ED_label(f)) && ports_eq(e, f)) - return TRUE; - return FALSE; -} diff --git a/lib/dotgen/cluster.c b/lib/dotgen/cluster.c index 0aeeef434..27a135acf 100644 --- a/lib/dotgen/cluster.c +++ b/lib/dotgen/cluster.c @@ -17,134 +17,21 @@ #include "dot.h" - -/* delete virtual nodes of a cluster, and install real nodes or sub-clusters */ -void expand_cluster(graph_t * subg) -{ - /* build internal structure of the cluster */ - class2(subg); - GD_comp(subg).size = 1; - GD_comp(subg).list[0] = GD_nlist(subg); - allocate_ranks(subg); - build_ranks(subg, 0); - merge_ranks(subg); - - /* build external structure of the cluster */ - interclexp(subg); - remove_rankleaders(subg); -} - -/* this function marks every node in with its top-level cluster under */ -void mark_clusters(graph_t * g) -{ - int c; - node_t *n, *vn; - edge_t *orig, *e; - graph_t *clust; - - /* remove sub-clusters below this level */ - for (n = agfstnode(g); n; n = agnxtnode(g, n)) { - if (ND_ranktype(n) == CLUSTER) - UF_singleton(n); - ND_clust(n) = NULL; - } - - for (c = 1; c <= GD_n_cluster(g); c++) { - clust = GD_clust(g)[c]; - for (n = agfstnode(clust); n; n = agnxtnode(clust, n)) { - if (ND_ranktype(n) != NORMAL) { - agerr(AGWARN, - "%s was already in a rankset, ignored in cluster %s\n", - n->name, g->name); - continue; - } - UF_setname(n, GD_leader(clust)); - ND_clust(n) = clust; - ND_ranktype(n) = CLUSTER; - - /* here we mark the vnodes of edges in the cluster */ - for (orig = agfstout(clust, n); orig; - orig = agnxtout(clust, orig)) { - if ((e = ED_to_virt(orig))) { - while (e && (vn = e->head)->u.node_type == VIRTUAL) { - ND_clust(vn) = clust; - e = ND_out(e->head).list[0]; - /* trouble if concentrators and clusters are mixed */ - } - } - } - } - } -} - -void build_skeleton(graph_t * g, graph_t * subg) +static node_t* +map_interclust_node(node_t * n) { - int r; - node_t *v, *prev, *rl; - edge_t *e; - - prev = NULL; - GD_rankleader(subg) = N_NEW(GD_maxrank(subg) + 2, node_t *); - for (r = GD_minrank(subg); r <= GD_maxrank(subg); r++) { - v = GD_rankleader(subg)[r] = virtual_node(g); - ND_rank(v) = r; - ND_ranktype(v) = CLUSTER; - ND_clust(v) = subg; - if (prev) { - e = virtual_edge(prev, v, NULL); - ED_xpenalty(e) *= CL_CROSS; - } - prev = v; - } - - /* set the counts on virtual edges of the cluster skeleton */ - for (v = agfstnode(subg); v; v = agnxtnode(subg, v)) { - rl = GD_rankleader(subg)[ND_rank(v)]; - ND_UF_size(rl)++; - for (e = agfstout(subg, v); e; e = agnxtout(subg, e)) { - for (r = ND_rank(e->tail); r < ND_rank(e->head); r++) { - ED_count(ND_out(rl).list[0])++; - } - } - } - for (r = GD_minrank(subg); r <= GD_maxrank(subg); r++) { - rl = GD_rankleader(subg)[r]; - if (ND_UF_size(rl) > 1) - ND_UF_size(rl)--; - } -} - -void merge_ranks(graph_t * subg) -{ - int i, d, r, pos, ipos; - node_t *v; - graph_t *root; + node_t *rv; - root = subg->root; - if (GD_minrank(subg) > 0) - ND_rank(root)[GD_minrank(subg) - 1].valid = FALSE; - for (r = GD_minrank(subg); r <= GD_maxrank(subg); r++) { - d = GD_rank(subg)[r].n; - ipos = pos = GD_rankleader(subg)[r]->u.order; - make_slots(root, r, pos, d); - for (i = 0; i < GD_rank(subg)[r].n; i++) { - v = ND_rank(root)[r].v[pos] = GD_rank(subg)[r].v[i]; - ND_order(v) = pos++; - v->graph = subg->root; - delete_fast_node(subg, v); - fast_node(subg->root, v); - GD_n_nodes(subg->root)++; - } - GD_rank(subg)[r].v = ND_rank(root)[r].v + ipos; - ND_rank(root)[r].valid = FALSE; - } - if (r < GD_maxrank(root)) - GD_rank(root)[r].valid = FALSE; - GD_expanded(subg) = TRUE; + if ((ND_clust(n) == NULL) || (ND_clust(n)->u.expanded)) + rv = n; + else + rv = ND_clust(n)->u.rankleader[ND_rank(n)]; + return rv; } /* make d slots starting at position pos (where 1 already exists) */ -void make_slots(graph_t * root, int r, int pos, int d) +static void +make_slots(graph_t * root, int r, int pos, int d) { int i; node_t *v, **vlist; @@ -170,99 +57,8 @@ void make_slots(graph_t * root, int r, int pos, int d) ND_rank(root)[r].n += d - 1; } -/* - * attach and install edges between clusters. - * essentially, class2() for interclust edges. - */ -void interclexp(graph_t * subg) -{ - graph_t *g; - node_t *n; - edge_t *e, *prev; - - g = subg->root; - for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) { - - /* N.B. n may be in a sub-cluster of subg */ - prev = NULL; - for (e = agfstedge(subg->root, n); e; - e = agnxtedge(subg->root, e, n)) { - if (agcontains(subg, e)) - continue; - - /* short/flat multi edges */ - if (mergeable(prev, e)) { - if (ND_rank(e->tail) == ND_rank(e->head)) - ED_to_virt(e) = prev; - else - ED_to_virt(e) = NULL; - if (ED_to_virt(prev) == NULL) - continue; /* internal edge */ - merge_chain(subg, e, ED_to_virt(prev), FALSE); - safe_other_edge(e); - continue; - } - - /* flat edges */ - if (ND_rank(e->tail) == ND_rank(e->head)) { - if (find_flat_edge(e->tail, e->head) == NULL) { - flat_edge(g, e); - prev = e; - } else - prev = NULL; - continue; - } - - assert(ED_to_virt(e) != NULL); - - /* forward edges */ - if (ND_rank(e->head) > ND_rank(e->tail)) { - make_interclust_chain(g, e->tail, e->head, e); - prev = e; - continue; - } - - /* backward edges */ - else { -/* -I think that make_interclust_chain should create call other_edge(e) anyway - if (agcontains(subg,e->tail) - && agfindedge(subg->root,e->head,e->tail)) other_edge(e); -*/ - make_interclust_chain(g, e->head, e->tail, e); - prev = e; - } - } - } -} - -node_t *map_interclust_node(node_t * n) -{ - node_t *rv; - - if ((ND_clust(n) == NULL) || (ND_clust(n)->u.expanded)) - rv = n; - else - rv = ND_clust(n)->u.rankleader[ND_rank(n)]; - return rv; -} - -void make_interclust_chain(graph_t * g, node_t * from, node_t * to, - edge_t * orig) -{ - int newtype; - node_t *u, *v; - - u = map_interclust_node(from); - v = map_interclust_node(to); - if ((u == from) && (v == to)) - newtype = VIRTUAL; - else - newtype = CLUSTER_EDGE; - map_path(u, v, orig, ED_to_virt(orig), newtype); -} - -node_t *clone_vn(graph_t * g, node_t * vn) +static node_t* +clone_vn(graph_t * g, node_t * vn) { node_t *rv; int r; @@ -278,8 +74,8 @@ node_t *clone_vn(graph_t * g, node_t * vn) return rv; } -void map_path(node_t * from, node_t * to, edge_t * orig, edge_t * ve, - int type) +static void +map_path(node_t * from, node_t * to, edge_t * orig, edge_t * ve, int type) { int r; node_t *u, *v; @@ -349,22 +145,119 @@ void map_path(node_t * from, node_t * to, edge_t * orig, edge_t * ve, } } -void install_cluster(graph_t * g, node_t * n, int pass, queue * q) +static void +make_interclust_chain(graph_t * g, node_t * from, node_t * to, edge_t * orig) { - int r; - graph_t *clust; + int newtype; + node_t *u, *v; - clust = ND_clust(n); - if (GD_installed(clust) != pass + 1) { - for (r = GD_minrank(clust); r <= GD_maxrank(clust); r++) - install_in_rank(g, GD_rankleader(clust)[r]); - for (r = GD_minrank(clust); r <= GD_maxrank(clust); r++) - enqueue_neighbors(q, GD_rankleader(clust)[r], pass); - GD_installed(clust) = pass + 1; + u = map_interclust_node(from); + v = map_interclust_node(to); + if ((u == from) && (v == to)) + newtype = VIRTUAL; + else + newtype = CLUSTER_EDGE; + map_path(u, v, orig, ED_to_virt(orig), newtype); +} + +/* + * attach and install edges between clusters. + * essentially, class2() for interclust edges. + */ +void interclexp(graph_t * subg) +{ + graph_t *g; + node_t *n; + edge_t *e, *prev; + + g = subg->root; + for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) { + + /* N.B. n may be in a sub-cluster of subg */ + prev = NULL; + for (e = agfstedge(subg->root, n); e; + e = agnxtedge(subg->root, e, n)) { + if (agcontains(subg, e)) + continue; + + /* short/flat multi edges */ + if (mergeable(prev, e)) { + if (ND_rank(e->tail) == ND_rank(e->head)) + ED_to_virt(e) = prev; + else + ED_to_virt(e) = NULL; + if (ED_to_virt(prev) == NULL) + continue; /* internal edge */ + merge_chain(subg, e, ED_to_virt(prev), FALSE); + safe_other_edge(e); + continue; + } + + /* flat edges */ + if (ND_rank(e->tail) == ND_rank(e->head)) { + if (find_flat_edge(e->tail, e->head) == NULL) { + flat_edge(g, e); + prev = e; + } else + prev = NULL; + continue; + } + + assert(ED_to_virt(e) != NULL); + + /* forward edges */ + if (ND_rank(e->head) > ND_rank(e->tail)) { + make_interclust_chain(g, e->tail, e->head, e); + prev = e; + continue; + } + + /* backward edges */ + else { +/* +I think that make_interclust_chain should create call other_edge(e) anyway + if (agcontains(subg,e->tail) + && agfindedge(subg->root,e->head,e->tail)) other_edge(e); +*/ + make_interclust_chain(g, e->head, e->tail, e); + prev = e; + } + } } } -void remove_rankleaders(graph_t * g) +static void +merge_ranks(graph_t * subg) +{ + int i, d, r, pos, ipos; + node_t *v; + graph_t *root; + + root = subg->root; + if (GD_minrank(subg) > 0) + ND_rank(root)[GD_minrank(subg) - 1].valid = FALSE; + for (r = GD_minrank(subg); r <= GD_maxrank(subg); r++) { + d = GD_rank(subg)[r].n; + ipos = pos = GD_rankleader(subg)[r]->u.order; + make_slots(root, r, pos, d); + for (i = 0; i < GD_rank(subg)[r].n; i++) { + v = ND_rank(root)[r].v[pos] = GD_rank(subg)[r].v[i]; + ND_order(v) = pos++; + v->graph = subg->root; + delete_fast_node(subg, v); + fast_node(subg->root, v); + GD_n_nodes(subg->root)++; + } + GD_rank(subg)[r].v = ND_rank(root)[r].v + ipos; + ND_rank(root)[r].valid = FALSE; + } + if (r < GD_maxrank(root)) + GD_rank(root)[r].valid = FALSE; + GD_expanded(subg) = TRUE; +} + +static void +remove_rankleaders(graph_t * g) { int r; node_t *v; @@ -383,6 +276,117 @@ void remove_rankleaders(graph_t * g) } } +/* delete virtual nodes of a cluster, and install real nodes or sub-clusters */ +void expand_cluster(graph_t * subg) +{ + /* build internal structure of the cluster */ + class2(subg); + GD_comp(subg).size = 1; + GD_comp(subg).list[0] = GD_nlist(subg); + allocate_ranks(subg); + build_ranks(subg, 0); + merge_ranks(subg); + + /* build external structure of the cluster */ + interclexp(subg); + remove_rankleaders(subg); +} + +/* this function marks every node in with its top-level cluster under */ +void mark_clusters(graph_t * g) +{ + int c; + node_t *n, *vn; + edge_t *orig, *e; + graph_t *clust; + + /* remove sub-clusters below this level */ + for (n = agfstnode(g); n; n = agnxtnode(g, n)) { + if (ND_ranktype(n) == CLUSTER) + UF_singleton(n); + ND_clust(n) = NULL; + } + + for (c = 1; c <= GD_n_cluster(g); c++) { + clust = GD_clust(g)[c]; + for (n = agfstnode(clust); n; n = agnxtnode(clust, n)) { + if (ND_ranktype(n) != NORMAL) { + agerr(AGWARN, + "%s was already in a rankset, ignored in cluster %s\n", + n->name, g->name); + continue; + } + UF_setname(n, GD_leader(clust)); + ND_clust(n) = clust; + ND_ranktype(n) = CLUSTER; + + /* here we mark the vnodes of edges in the cluster */ + for (orig = agfstout(clust, n); orig; + orig = agnxtout(clust, orig)) { + if ((e = ED_to_virt(orig))) { + while (e && (vn = e->head)->u.node_type == VIRTUAL) { + ND_clust(vn) = clust; + e = ND_out(e->head).list[0]; + /* trouble if concentrators and clusters are mixed */ + } + } + } + } + } +} + +void build_skeleton(graph_t * g, graph_t * subg) +{ + int r; + node_t *v, *prev, *rl; + edge_t *e; + + prev = NULL; + GD_rankleader(subg) = N_NEW(GD_maxrank(subg) + 2, node_t *); + for (r = GD_minrank(subg); r <= GD_maxrank(subg); r++) { + v = GD_rankleader(subg)[r] = virtual_node(g); + ND_rank(v) = r; + ND_ranktype(v) = CLUSTER; + ND_clust(v) = subg; + if (prev) { + e = virtual_edge(prev, v, NULL); + ED_xpenalty(e) *= CL_CROSS; + } + prev = v; + } + + /* set the counts on virtual edges of the cluster skeleton */ + for (v = agfstnode(subg); v; v = agnxtnode(subg, v)) { + rl = GD_rankleader(subg)[ND_rank(v)]; + ND_UF_size(rl)++; + for (e = agfstout(subg, v); e; e = agnxtout(subg, e)) { + for (r = ND_rank(e->tail); r < ND_rank(e->head); r++) { + ED_count(ND_out(rl).list[0])++; + } + } + } + for (r = GD_minrank(subg); r <= GD_maxrank(subg); r++) { + rl = GD_rankleader(subg)[r]; + if (ND_UF_size(rl) > 1) + ND_UF_size(rl)--; + } +} + +void install_cluster(graph_t * g, node_t * n, int pass, queue * q) +{ + int r; + graph_t *clust; + + clust = ND_clust(n); + if (GD_installed(clust) != pass + 1) { + for (r = GD_minrank(clust); r <= GD_maxrank(clust); r++) + install_in_rank(g, GD_rankleader(clust)[r]); + for (r = GD_minrank(clust); r <= GD_maxrank(clust); r++) + enqueue_neighbors(q, GD_rankleader(clust)[r], pass); + GD_installed(clust) = pass + 1; + } +} + static void mark_lowcluster_basic(Agraph_t * g); void mark_lowclusters(Agraph_t * root) { diff --git a/lib/dotgen/compound.c b/lib/dotgen/compound.c index f1805be57..43789b9fe 100644 --- a/lib/dotgen/compound.c +++ b/lib/dotgen/compound.c @@ -334,9 +334,6 @@ static void makeCompoundEdge(graph_t * g, edge_t * e) point pts[4]; point p; int fixed; - inside_t inside_context; - - inside_context.e = e; /* find head and tail target clusters, if defined */ lh = getCluster(g, agget(e, "lhead")); @@ -396,7 +393,7 @@ static void makeCompoundEdge(graph_t * g, edge_t * e) bez->list[2] = midPt(bez->list[1], p); if (bez->eflag) endi = - arrowEndClip(&inside_context, bez->list, + arrowEndClip(e, bez->list, starti, 0, nbez, bez->eflag); endi += 3; fixed = 1; @@ -412,7 +409,7 @@ static void makeCompoundEdge(graph_t * g, edge_t * e) } else { if (bez->eflag) endi = - arrowEndClip(&inside_context, bez->list, + arrowEndClip(e, bez->list, starti, endi, nbez, bez->eflag); endi += 3; } @@ -460,7 +457,7 @@ static void makeCompoundEdge(graph_t * g, edge_t * e) midPt(bez->list[starti + 2], p); if (bez->sflag) starti = - arrowStartClip(&inside_context, bez->list, + arrowStartClip(e, bez->list, starti, endi - 3, nbez, bez->sflag); fixed = 1; @@ -483,7 +480,7 @@ static void makeCompoundEdge(graph_t * g, edge_t * e) starti -= 3; if (bez->sflag) starti = - arrowStartClip(&inside_context, bez->list, + arrowStartClip(e, bez->list, starti, endi - 3, nbez, bez->sflag); }