static void twopi_init_node(node_t * n) { common_init_node(n); neato_nodesize(n, GD_flip(n->graph)); ND_pos(n) = ALLOC(GD_ndim(n->graph), 0, double); ND_alg(n) = (void *) NEW(rdata); }
static void dot_init_node(node_t * n) { common_init_node(n); dot_nodesize(n, GD_flip(n->graph)); alloc_elist(4, ND_in(n)); alloc_elist(4, ND_out(n)); alloc_elist(2, ND_flat_in(n)); alloc_elist(2, ND_flat_out(n)); alloc_elist(2, ND_other(n)); ND_UF_size(n) = 1; }
static void dot_init_node(node_t * n) { agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //graph custom data common_init_node(n); gv_nodesize(n, GD_flip(agraphof(n))); alloc_elist(4, ND_in(n)); alloc_elist(4, ND_out(n)); alloc_elist(2, ND_flat_in(n)); alloc_elist(2, ND_flat_out(n)); alloc_elist(2, ND_other(n)); ND_UF_size(n) = 1; }
static int left2right(Agraph_t *g, node_t *v, node_t *w) { int rv; #ifdef NOTDEF adjmatrix_t *M; M = GD_rank(g)[ND_rank(v)].flat; if (M == NULL) rv = FALSE; else { if (GD_flip(g)) {node_t *t = v; v = w; w = t;} rv = ELT(M,flatindex(v),flatindex(w)); } #else rv = FALSE; #endif return rv; }
/* html_path: * Return a box in a table containing the given endpoint. * If the top flow is text (no internal structure), return * the box of the flow * Else return the box of the subtable containing the point. * Because of spacing, the point might not be in any subtable. * In that case, return the top flow's box. * Note that box[0] must contain the edge point. Additional boxes * move out to the boundary. * * At present, unimplemented, since the label may be inside a * non-box node and we need to figure out what this means. */ int html_path(node_t * n, port* p, int side, box * rv, int *k) { #ifdef UNIMPL point p; tbl_t *info; tbl_t *t; box b; int i; info = (tbl_t *) ND_shape_info(n); assert(info->tbls); info = info->tbls[0]; /* top-level flow */ assert(IS_FLOW(info)); b = info->box; if (info->tbl) { info = info->tbl; if (pt == 1) p = ED_tail_port(e).p; else p = ED_head_port(e).p; p = flip_pt(p, GD_rankdir(n->graph)); /* move p to node's coordinate system */ for (i = 0; (t = info->tbls[i]) != 0; i++) if (INSIDE(p, t->box)) { b = t->box; break; } } /* move box into layout coordinate system */ if (GD_flip(n->graph)) b = flip_trans_box(b, ND_coord_i(n)); else b = move_box(b, ND_coord_i(n)); *k = 1; *rv = b; if (pt == 1) return BOTTOM; else return TOP; #endif return 0; }
/* compute_bb: * Compute bounding box of g using nodes, splines, and clusters. * Assumes bb of clusters already computed. * store in GD_bb. */ void compute_bb(graph_t * g) { node_t *n; edge_t *e; box b, bb; point pt, s2; int i, j; bb.LL = pointof(MAXINT, MAXINT); bb.UR = pointof(-MAXINT, -MAXINT); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { pt = coord(n); s2.x = ND_xsize(n) / 2 + 1; s2.y = ND_ysize(n) / 2 + 1; b.LL = sub_points(pt, s2); b.UR = add_points(pt, s2); EXPANDBB(bb,b); for (e = agfstout(g, n); e; e = agnxtout(g, e)) { if (ED_spl(e) == 0) continue; for (i = 0; i < ED_spl(e)->size; i++) { for (j = 0; j < ED_spl(e)->list[i].size; j++) { pt = ED_spl(e)->list[i].list[j]; EXPANDBP(bb,pt); } } if (ED_label(e) && ED_label(e)->set) bb = addLabelBB(bb, ED_label(e), GD_flip(g)); } } for (i = 1; i <= GD_n_cluster(g); i++) { EXPANDBB(bb,GD_clust(g)[i]->u.bb); } GD_bb(g) = bb; }
void neato_init_node(node_t * n) { common_init_node(n); ND_pos(n) = ALLOC(GD_ndim(n->graph), 0, double); neato_nodesize(n, GD_flip(n->graph)); }
/* updateBB: * Reset graph's bounding box to include bounding box of the given label. * Assume the label's position has been set. */ void updateBB(graph_t * g, textlabel_t * lp) { GD_bb(g) = addLabelBB(GD_bb(g), lp, GD_flip(g)); }
/* do_graph_label: * Set characteristics of graph label if it exists. * */ void do_graph_label(graph_t * sg) { char *str, *pos, *just; int pos_ix; /* it would be nice to allow multiple graph labels in the future */ if ((str = agget(sg, "label")) && (*str != '\0')) { char pos_flag; pointf dimen; GD_has_labels(sg->root) |= GRAPH_LABEL; GD_label(sg) = make_label((void*)sg, str, (aghtmlstr(str) ? LT_HTML : LT_NONE), late_double(sg, agfindgraphattr(sg, "fontsize"), DEFAULT_FONTSIZE, MIN_FONTSIZE), late_nnstring(sg, agfindgraphattr(sg, "fontname"), DEFAULT_FONTNAME), late_nnstring(sg, agfindgraphattr(sg, "fontcolor"), DEFAULT_COLOR)); /* set label position */ pos = agget(sg, "labelloc"); if (sg != agroot(sg)) { if (pos && (pos[0] == 'b')) pos_flag = LABEL_AT_BOTTOM; else pos_flag = LABEL_AT_TOP; } else { if (pos && (pos[0] == 't')) pos_flag = LABEL_AT_TOP; else pos_flag = LABEL_AT_BOTTOM; } just = agget(sg, "labeljust"); if (just) { if (just[0] == 'l') pos_flag |= LABEL_AT_LEFT; else if (just[0] == 'r') pos_flag |= LABEL_AT_RIGHT; } GD_label_pos(sg) = pos_flag; if (sg == agroot(sg)) return; /* Set border information for cluster labels to allow space */ dimen = GD_label(sg)->dimen; PAD(dimen); if (!GD_flip(agroot(sg))) { if (GD_label_pos(sg) & LABEL_AT_TOP) pos_ix = TOP_IX; else pos_ix = BOTTOM_IX; GD_border(sg)[pos_ix] = dimen; } else { /* when rotated, the labels will be restored to TOP or BOTTOM */ if (GD_label_pos(sg) & LABEL_AT_TOP) pos_ix = RIGHT_IX; else pos_ix = LEFT_IX; GD_border(sg)[pos_ix].x = dimen.y; GD_border(sg)[pos_ix].y = dimen.x; } } }
/* gv_postprocess: * Set graph and cluster label positions. * Add space for root graph label and translate graph accordingly. * Set final nodesize using ns. * Assumes the boxes of all clusters have been computed. * When done, the bounding box of g has LL at origin. */ void gv_postprocess(Agraph_t * g, int allowTranslation) { double diff; pointf dimen = { 0., 0. }; Rankdir = GD_rankdir(g); Flip = GD_flip(g); /* Handle cluster labels */ if (Flip) place_flip_graph_label(g); else place_graph_label(g); /* Everything has been placed except the root graph label, if any. * The graph positions have not yet been rotated back if necessary. */ addXLabels(g); /* Add space for graph label if necessary */ if (GD_label(g) && !GD_label(g)->set) { dimen = GD_label(g)->dimen; PAD(dimen); if (Flip) { if (GD_label_pos(g) & LABEL_AT_TOP) { GD_bb(g).UR.x += dimen.y; } else { GD_bb(g).LL.x -= dimen.y; } if (dimen.x > (GD_bb(g).UR.y - GD_bb(g).LL.y)) { diff = dimen.x - (GD_bb(g).UR.y - GD_bb(g).LL.y); diff = diff / 2.; GD_bb(g).LL.y -= diff; GD_bb(g).UR.y += diff; } } else { if (GD_label_pos(g) & LABEL_AT_TOP) { if (Rankdir == RANKDIR_TB) GD_bb(g).UR.y += dimen.y; else GD_bb(g).LL.y -= dimen.y; } else { if (Rankdir == RANKDIR_TB) GD_bb(g).LL.y -= dimen.y; else GD_bb(g).UR.y += dimen.y; } if (dimen.x > (GD_bb(g).UR.x - GD_bb(g).LL.x)) { diff = dimen.x - (GD_bb(g).UR.x - GD_bb(g).LL.x); diff = diff / 2.; GD_bb(g).LL.x -= diff; GD_bb(g).UR.x += diff; } } } if (allowTranslation) { switch (Rankdir) { case RANKDIR_TB: Offset = GD_bb(g).LL; break; case RANKDIR_LR: Offset = pointfof(-GD_bb(g).UR.y, GD_bb(g).LL.x); break; case RANKDIR_BT: Offset = pointfof(GD_bb(g).LL.x, -GD_bb(g).UR.y); break; case RANKDIR_RL: Offset = pointfof(GD_bb(g).LL.y, GD_bb(g).LL.x); break; } translate_drawing(g); } if (GD_label(g) && !GD_label(g)->set) place_root_label(g, dimen); if (Show_boxes) { char buf[BUFSIZ]; if (Flip) sprintf(buf, M2, Offset.x, Offset.y, Offset.x, Offset.y); else sprintf(buf, M1, Offset.y, Offset.x, Offset.y, Offset.x, -Offset.x, -Offset.y); Show_boxes[0] = strdup(buf); } }
/* do_graph_label: * Set characteristics of graph label if it exists. * */ void do_graph_label(graph_t * sg) { char *p, *pos, *just; int pos_ix; /* it would be nice to allow multiple graph labels in the future */ if ((p = agget(sg, "label"))) { char pos_flag; int lbl_kind = LT_NONE; point dpt; pointf dimen; if (aghtmlstr(p)) lbl_kind = LT_HTML; GD_has_labels(sg->root) |= GRAPH_LABEL; if (lbl_kind) p = strdup (p); else p = strdup_and_subst_obj(p, (void*)sg); GD_label(sg) = make_label(sg->root, lbl_kind, p, late_double(sg, agfindattr(sg, "fontsize"), DEFAULT_FONTSIZE, MIN_FONTSIZE), late_nnstring(sg, agfindattr(sg, "fontname"), DEFAULT_FONTNAME), late_nnstring(sg, agfindattr(sg, "fontcolor"), DEFAULT_COLOR)); if (lbl_kind) { if (make_html_label(sg->root, GD_label(sg), sg) == 1) agerr(AGPREV, "in label of graph %s\n", sg->name); } /* set label position */ pos = agget(sg, "labelloc"); if (sg != sg->root) { if (pos && (pos[0] == 'b')) pos_flag = LABEL_AT_BOTTOM; else pos_flag = LABEL_AT_TOP; } else { if (pos && (pos[0] == 't')) pos_flag = LABEL_AT_TOP; else pos_flag = LABEL_AT_BOTTOM; } just = agget(sg, "labeljust"); if (just) { if (just[0] == 'l') pos_flag |= LABEL_AT_LEFT; else if (just[0] == 'r') pos_flag |= LABEL_AT_RIGHT; } GD_label_pos(sg) = pos_flag; if (sg == sg->root) return; /* Set border information for cluster labels to allow space */ dimen = GD_label(sg)->dimen; PAD(dimen); PF2P(dimen, dpt); if (!GD_flip(sg->root)) { if (GD_label_pos(sg) & LABEL_AT_TOP) pos_ix = TOP_IX; else pos_ix = BOTTOM_IX; GD_border(sg)[pos_ix] = dpt; } else { /* when rotated, the labels will be restored to TOP or BOTTOM */ if (GD_label_pos(sg) & LABEL_AT_TOP) pos_ix = RIGHT_IX; else pos_ix = LEFT_IX; GD_border(sg)[pos_ix].x = dpt.y; GD_border(sg)[pos_ix].y = dpt.x; } } }
/* dotneato_postprocess: * Set graph and cluster label positions. * Add space for root graph label and translate graph accordingly. * Set final nodesize using ns. * Assumes the boxes of all clusters have been computed. * When done, the bounding box of g has LL at origin. */ void dotneato_postprocess(Agraph_t * g) { int diff; pointf dimen; point d = { 0, 0 }; Rankdir = GD_rankdir(g); Flip = GD_flip(g); if (Flip) place_flip_graph_label(g); else place_graph_label(g); if (GD_label(g) && !GD_label(g)->set) { dimen = GD_label(g)->dimen; PAD(dimen); PF2P(dimen, d); if (Flip) { if (GD_label_pos(g) & LABEL_AT_TOP) { GD_bb(g).UR.x += d.y; } else { GD_bb(g).LL.x -= d.y; } if (d.x > GD_bb(g).UR.y - GD_bb(g).LL.y) { diff = d.x - (GD_bb(g).UR.y - GD_bb(g).LL.y); diff = diff / 2; GD_bb(g).LL.y -= diff; GD_bb(g).UR.y += diff; } } else { if (GD_label_pos(g) & LABEL_AT_TOP) { if (Rankdir == RANKDIR_TB) GD_bb(g).UR.y += d.y; else GD_bb(g).LL.y -= d.y; } else { if (Rankdir == RANKDIR_TB) GD_bb(g).LL.y -= d.y; else GD_bb(g).UR.y += d.y; } if (d.x > GD_bb(g).UR.x - GD_bb(g).LL.x) { diff = d.x - (GD_bb(g).UR.x - GD_bb(g).LL.x); diff = diff / 2; GD_bb(g).LL.x -= diff; GD_bb(g).UR.x += diff; } } } switch (Rankdir) { case RANKDIR_TB: Offset = GD_bb(g).LL; break; case RANKDIR_LR: Offset = pointof(-GD_bb(g).UR.y, GD_bb(g).LL.x); break; case RANKDIR_BT: Offset = pointof(GD_bb(g).LL.x, -GD_bb(g).UR.y); break; case RANKDIR_RL: Offset = pointof(GD_bb(g).LL.y, GD_bb(g).LL.x); break; } translate_drawing(g); if (GD_label(g) && !GD_label(g)->set) place_root_label(g, d); if (Show_boxes) { char buf[BUFSIZ]; if (Flip) sprintf(buf, M2, Offset.x, Offset.y, Offset.x, Offset.y); else sprintf(buf, M1, Offset.y, Offset.x, Offset.y, Offset.x, -Offset.x, -Offset.y); Show_boxes[0] = strdup(buf); } }
/* compute_bb: * Compute bounding box of g using nodes, splines, and clusters. * Assumes bb of clusters already computed. * store in GD_bb. */ void compute_bb(graph_t * g) { node_t *n; edge_t *e; boxf b, bb; boxf BF; pointf ptf, s2; int i, j; if ((agnnodes(g) == 0) && (GD_n_cluster(g) ==0)) { bb.LL = pointfof(0, 0); bb.UR = pointfof(0, 0); return; } bb.LL = pointfof(INT_MAX, INT_MAX); bb.UR = pointfof(-INT_MAX, -INT_MAX); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { ptf = coord(n); s2.x = ND_xsize(n) / 2.0; s2.y = ND_ysize(n) / 2.0; b.LL = sub_pointf(ptf, s2); b.UR = add_pointf(ptf, s2); EXPANDBB(bb,b); if (ND_xlabel(n) && ND_xlabel(n)->set) { bb = addLabelBB(bb, ND_xlabel(n), GD_flip(g)); } for (e = agfstout(g, n); e; e = agnxtout(g, e)) { if (ED_spl(e) == 0) continue; for (i = 0; i < ED_spl(e)->size; i++) { for (j = 0; j < (((Agedgeinfo_t*)AGDATA(e))->spl)->list[i].size; j++) { ptf = ED_spl(e)->list[i].list[j]; EXPANDBP(bb,ptf); } } if (ED_label(e) && ED_label(e)->set) { bb = addLabelBB(bb, ED_label(e), GD_flip(g)); } if (ED_head_label(e) && ED_head_label(e)->set) { bb = addLabelBB(bb, ED_head_label(e), GD_flip(g)); } if (ED_tail_label(e) && ED_tail_label(e)->set) { bb = addLabelBB(bb, ED_tail_label(e), GD_flip(g)); } if (ED_xlabel(e) && ED_xlabel(e)->set) { bb = addLabelBB(bb, ED_xlabel(e), GD_flip(g)); } } } for (i = 1; i <= GD_n_cluster(g); i++) { B2BF(GD_bb(GD_clust(g)[i]), BF); EXPANDBB(bb,BF); } if (GD_label(g) && GD_label(g)->set) { bb = addLabelBB(bb, GD_label(g), GD_flip(g)); } GD_bb(g) = bb; }