/* find_blocks: */ static void find_blocks(Agraph_t * g, circ_state * state) { Agnode_t *n; Agnode_t *root = NULL; block_t *rootBlock = NULL; blocklist_t ublks; #ifdef USER_BLOCKS graph_t *clust_subg; graph_t *mg; edge_t *me; node_t *mm; int isRoot; #endif initBlocklist(&ublks); /* check to see if there is a node which is set to be the root */ if (state->rootname) { root = agfindnode(g, state->rootname); } if (!root && state->N_root) { for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (late_bool(ORIGN(n), state->N_root, 0)) { root = n; break; } } } #ifdef USER_BLOCKS /* process clusters first */ /* by construction, all subgraphs are blocks and are non-empty */ mm = g->meta_node; mg = mm->graph; for (me = agfstout(mg, mm); me; me = agnxtout(mg, me)) { block_t *block; clust_subg = agusergraph(me->head); isRoot = 0; block = mkBlock(clust_subg); /* block = makeBlock(g, state); */ for (n = agfstnode(clust_subg); n; n = agnxtnode(clust_subg, n)) { if (!BCDONE(n)) { /* test not necessary if blocks disjoint */ SET_BCDONE(n); BLOCK(n) = block; if (n == root) isRoot = 1; } } if (isRoot) { /* Assume blocks are disjoint, so don't check if rootBlock is * already assigned. */ rootBlock = block; insertBlock(&state->bl, block); } else { appendBlock(&state->bl, block); } } ublks.first = state->bl.first; ublks.last = state->bl.last; #endif if (!root) root = agfstnode(g); dfs(g, root, state, !rootBlock); #ifdef USER_BLOCKS /* If g has user-supplied blocks, it may be disconnected. * We then fall into the following ugly loop. * We are guaranteed !VISITED(n) and PARENT(n) has been * set to a visited node. */ if (ublks.first) { while (n = findUnvisited(&ublks)) { dfs(g, n, state, 0); } } #endif }
static void addXLabels(Agraph_t * gp) { Agnode_t *np; Agedge_t *ep; int cnt, i, n_objs, n_lbls; int n_nlbls = 0; /* # of unset node xlabels */ int n_elbls = 0; /* # of unset edge labels or xlabels */ int n_set_lbls = 0; /* # of set xlabels and edge labels */ int n_clbls = 0; /* # of set cluster labels */ boxf bb; pointf ur; textlabel_t* lp; label_params_t params; object_t* objs; xlabel_t* lbls; object_t* objp; xlabel_t* xlp; Agsym_t* force; int et = EDGE_TYPE(gp); if (!(GD_has_labels(gp) & NODE_XLABEL) && !(GD_has_labels(gp) & EDGE_XLABEL) && !(GD_has_labels(gp) & TAIL_LABEL) && !(GD_has_labels(gp) & HEAD_LABEL) && (!(GD_has_labels(gp) & EDGE_LABEL) || EdgeLabelsDone)) return; for (np = agfstnode(gp); np; np = agnxtnode(gp, np)) { if (ND_xlabel(np)) { if (ND_xlabel(np)->set) n_set_lbls++; else n_nlbls++; } for (ep = agfstout(gp, np); ep; ep = agnxtout(gp, ep)) { if (ED_xlabel(ep)) { if (ED_xlabel(ep)->set) n_set_lbls++; else if (HAVE_EDGE(ep)) n_elbls++; } if (ED_head_label(ep)) { if (ED_head_label(ep)->set) n_set_lbls++; else if (HAVE_EDGE(ep)) n_elbls++; } if (ED_tail_label(ep)) { if (ED_tail_label(ep)->set) n_set_lbls++; else if (HAVE_EDGE(ep)) n_elbls++; } if (ED_label(ep)) { if (ED_label(ep)->set) n_set_lbls++; else if (HAVE_EDGE(ep)) n_elbls++; } } } if (GD_has_labels(gp) & GRAPH_LABEL) n_clbls = countClusterLabels (gp); /* A label for each unpositioned external label */ n_lbls = n_nlbls + n_elbls; if (n_lbls == 0) return; /* An object for each node, each positioned external label, any cluster label, * and all unset edge labels and xlabels. */ n_objs = agnnodes(gp) + n_set_lbls + n_clbls + n_elbls; objp = objs = N_NEW(n_objs, object_t); xlp = lbls = N_NEW(n_lbls, xlabel_t); bb.LL = pointfof(INT_MAX, INT_MAX); bb.UR = pointfof(-INT_MAX, -INT_MAX); for (np = agfstnode(gp); np; np = agnxtnode(gp, np)) { bb = addNodeObj (np, objp, bb); if ((lp = ND_xlabel(np))) { if (lp->set) { objp++; bb = addLabelObj (lp, objp, bb); } else { addXLabel (lp, objp, xlp, 0, ur); xlp++; } } objp++; for (ep = agfstout(gp, np); ep; ep = agnxtout(gp, ep)) { if ((lp = ED_label(ep))) { if (lp->set) { bb = addLabelObj (lp, objp, bb); } else if (HAVE_EDGE(ep)) { addXLabel (lp, objp, xlp, 1, edgeMidpoint(gp, ep)); xlp++; } else { agerr(AGWARN, "no position for edge with label %s", ED_label(ep)->text); continue; } objp++; } if ((lp = ED_tail_label(ep))) { if (lp->set) { bb = addLabelObj (lp, objp, bb); } else if (HAVE_EDGE(ep)) { addXLabel (lp, objp, xlp, 1, edgeTailpoint(ep)); xlp++; } else { agerr(AGWARN, "no position for edge with tail label %s", ED_tail_label(ep)->text); continue; } objp++; } if ((lp = ED_head_label(ep))) { if (lp->set) { bb = addLabelObj (lp, objp, bb); } else if (HAVE_EDGE(ep)) { addXLabel (lp, objp, xlp, 1, edgeHeadpoint(ep)); xlp++; } else { agerr(AGWARN, "no position for edge with head label %s", ED_head_label(ep)->text); continue; } objp++; } if ((lp = ED_xlabel(ep))) { if (lp->set) { bb = addLabelObj (lp, objp, bb); } else if (HAVE_EDGE(ep)) { addXLabel (lp, objp, xlp, 1, edgeMidpoint(gp, ep)); xlp++; } else { agerr(AGWARN, "no position for edge with xlabel %s", ED_xlabel(ep)->text); continue; } objp++; } } } if (n_clbls) { cinfo_t info; info.bb = bb; info.objp = objp; info = addClusterObj (gp, info); bb = info.bb; } force = agfindgraphattr(gp, "forcelabels"); params.force = late_bool(gp, force, TRUE); params.bb = bb; placeLabels(objs, n_objs, lbls, n_lbls, ¶ms); if (Verbose) printData(objs, n_objs, lbls, n_lbls, ¶ms); xlp = lbls; cnt = 0; for (i = 0; i < n_lbls; i++) { if (xlp->set) { cnt++; lp = (textlabel_t *) (xlp->lbl); lp->set = 1; lp->pos = centerPt(xlp); updateBB (gp, lp); } xlp++; } if (Verbose) fprintf (stderr, "%d out of %d labels positioned.\n", cnt, n_lbls); else if (cnt != n_lbls) agerr(AGWARN, "%d out of %d exterior labels positioned.\n", cnt, n_lbls); free(objs); free(lbls); }