/* place_graph_label: * Put cluster labels recursively in the non-flip case. * The adjustments to the bounding boxes should no longer * be necessary, since we now guarantee the label fits in * the cluster. */ void place_graph_label(graph_t * g) { int c; pointf p, d; if ((g != agroot(g)) && (GD_label(g)) && !GD_label(g)->set) { if (GD_label_pos(g) & LABEL_AT_TOP) { d = GD_border(g)[TOP_IX]; p.y = GD_bb(g).UR.y - d.y / 2; } else { d = GD_border(g)[BOTTOM_IX]; p.y = GD_bb(g).LL.y + d.y / 2; } if (GD_label_pos(g) & LABEL_AT_RIGHT) { p.x = GD_bb(g).UR.x - d.x / 2; } else if (GD_label_pos(g) & LABEL_AT_LEFT) { p.x = GD_bb(g).LL.x + d.x / 2; } else { p.x = (GD_bb(g).LL.x + GD_bb(g).UR.x) / 2; } GD_label(g)->pos = p; GD_label(g)->set = TRUE; } for (c = 1; c <= GD_n_cluster(g); c++) place_graph_label(GD_clust(g)[c]); }
/* place_graph_label: * Put cluster labels recursively in the non-flip case. * The adjustments to the bounding boxes should no longer * be necessary, since we now guarantee the label fits in * the cluster. */ void place_graph_label(graph_t * g) { int c; #ifdef OLD int minx, maxx; #endif point p, d; if ((g != g->root) && (GD_label(g)) && !GD_label(g)->set) { if (GD_label_pos(g) & LABEL_AT_TOP) { d = GD_border(g)[TOP_IX]; p.y = GD_bb(g).UR.y - d.y / 2; } else { d = GD_border(g)[BOTTOM_IX]; p.y = GD_bb(g).LL.y + d.y / 2; } if (GD_label_pos(g) & LABEL_AT_RIGHT) { p.x = GD_bb(g).UR.x - d.x / 2; #ifdef OLD minx = p.x - d.x / 2; if (GD_bb(g).LL.x > minx) GD_bb(g).LL.x = minx; if (GD_bb(g->root).LL.x > minx) GD_bb(g->root).LL.x = minx; #endif } else if (GD_label_pos(g) & LABEL_AT_LEFT) { p.x = GD_bb(g).LL.x + d.x / 2; #ifdef OLD maxx = p.x + d.x / 2; if (GD_bb(g).UR.x < maxx) GD_bb(g).UR.x = maxx; if (GD_bb(g->root).UR.x < maxx) GD_bb(g->root).UR.x = maxx; #endif } else { p.x = (GD_bb(g).LL.x + GD_bb(g).UR.x) / 2; #ifdef OLD maxx = p.x + d.x / 2; minx = p.x - d.x / 2; if (GD_bb(g).UR.x < maxx) GD_bb(g).UR.x = maxx; if (GD_bb(g).LL.x > minx) GD_bb(g).LL.x = minx; if (GD_bb(g->root).UR.x < maxx) GD_bb(g->root).UR.x = maxx; if (GD_bb(g->root).LL.x > minx) GD_bb(g->root).LL.x = minx; #endif } GD_label(g)->p = p; GD_label(g)->set = TRUE; } for (c = 1; c <= GD_n_cluster(g); c++) place_graph_label(GD_clust(g)[c]); }
static int countClusterLabels (Agraph_t* g) { int c, i = 0; if ((g != agroot(g)) && (GD_label(g)) && GD_label(g)->set) i++; for (c = 1; c <= GD_n_cluster(g); c++) i += countClusterLabels (GD_clust(g)[c]); return i; }
static cinfo_t addClusterObj (Agraph_t* g, cinfo_t info) { int c; for (c = 1; c <= GD_n_cluster(g); c++) info = addClusterObj (GD_clust(g)[c], info); if ((g != agroot(g)) && (GD_label(g)) && GD_label(g)->set) { object_t* objp = info.objp; info.bb = addLabelObj (GD_label(g), objp, info.bb); info.objp++; } return info; }
void graph_cleanup(graph_t *g) { free(GD_drawing(g)); GD_drawing(g) = NULL; free_label(GD_label(g)); memset(&(g->u), 0, sizeof(Agraphinfo_t)); }
void QGVSubGraph::updateLayout() { prepareGeometryChange(); //SubGraph box boxf box = GD_bb(_sgraph->graph()); pointf p1 = box.UR; pointf p2 = box.LL; _width = p1.x - p2.x; _height = p1.y - p2.y; qreal gheight = QGVCore::graphHeight(_scene->_graph->graph()); setPos(p2.x, gheight - p1.y); _pen.setWidth(1); _brush.setStyle(QGVCore::toBrushStyle(getAttribute("style"))); _brush.setColor(QGVCore::toColor(getAttribute("fillcolor"))); _pen.setColor(QGVCore::toColor(getAttribute("color"))); //SubGraph label textlabel_t *xlabel = GD_label(_sgraph->graph()); if(xlabel) { _label = xlabel->text; _label_rect.setSize(QSize(xlabel->dimen.x, xlabel->dimen.y)); _label_rect.moveCenter(QGVCore::toPoint(xlabel->pos, QGVCore::graphHeight(_scene->_graph->graph())) - pos()); } }
static void rec_attach_bb(graph_t * g) { int c; char buf[BUFSIZ]; point pt; sprintf(buf, "%d,%d,%d,%d", GD_bb(g).LL.x, GD_bb(g).LL.y, GD_bb(g).UR.x, GD_bb(g).UR.y); agset(g, "bb", buf); if (GD_label(g) && GD_label(g)->text[0]) { pt = GD_label(g)->p; sprintf(buf, "%d,%d", pt.x, YDIR(pt.y)); agset(g, "lp", buf); } for (c = 1; c <= GD_n_cluster(g); c++) rec_attach_bb(GD_clust(g)[c]); }
void translate_bb(graph_t * g, int rankdir) { int c; boxf bb, new_bb; bb = GD_bb(g); if (rankdir == RANKDIR_LR || rankdir == RANKDIR_BT) { new_bb.LL = map_point(pointfof(bb.LL.x, bb.UR.y)); new_bb.UR = map_point(pointfof(bb.UR.x, bb.LL.y)); } else { new_bb.LL = map_point(pointfof(bb.LL.x, bb.LL.y)); new_bb.UR = map_point(pointfof(bb.UR.x, bb.UR.y)); } GD_bb(g) = new_bb; if (GD_label(g)) { GD_label(g)->pos = map_point(GD_label(g)->pos); } for (c = 1; c <= GD_n_cluster(g); c++) translate_bb(GD_clust(g)[c], rankdir); }
/* place_root_label: * Set position of root graph label. * Note that at this point, after translate_drawing, a * flipped drawing has been transposed, so we don't have * to worry about switching x and y. */ static void place_root_label(graph_t * g, pointf d) { pointf p; if (GD_label_pos(g) & LABEL_AT_RIGHT) { p.x = GD_bb(g).UR.x - d.x / 2; } else if (GD_label_pos(g) & LABEL_AT_LEFT) { p.x = GD_bb(g).LL.x + d.x / 2; } else { p.x = (GD_bb(g).LL.x + GD_bb(g).UR.x) / 2; } if (GD_label_pos(g) & LABEL_AT_TOP) { p.y = GD_bb(g).UR.y - d.y / 2; } else { p.y = GD_bb(g).LL.y + d.y / 2; } GD_label(g)->pos = p; GD_label(g)->set = TRUE; }
static void xdot_end_cluster(GVJ_t * job) { Agraph_t* cluster_g = job->obj->u.sg; agxset(cluster_g, xd->g_draw, agxbuse(xbufs[EMIT_CDRAW])); if (GD_label(cluster_g)) agxset(cluster_g, xd->g_l_draw, agxbuse(xbufs[EMIT_CLABEL])); penwidth[EMIT_CDRAW] = 1; penwidth[EMIT_CLABEL] = 1; textflags[EMIT_CDRAW] = 0; textflags[EMIT_CLABEL] = 0; }
static void rec_attach_bb(graph_t * g, Agsym_t* bbsym) { int c; char buf[BUFSIZ]; pointf pt; sprintf(buf, "%.5g,%.5g,%.5g,%.5g", GD_bb(g).LL.x, YDIR(GD_bb(g).LL.y), GD_bb(g).UR.x, YDIR(GD_bb(g).UR.y)); agxset(g, bbsym, buf); if (GD_label(g) && GD_label(g)->text[0]) { pt = GD_label(g)->pos; sprintf(buf, "%.5g,%.5g", pt.x, YDIR(pt.y)); agset(g, "lp", buf); pt = GD_label(g)->dimen; sprintf(buf, "%.2f", PS2INCH(pt.x)); agset (g, "lwidth", buf); sprintf(buf, "%.2f", PS2INCH(pt.y)); agset (g, "lheight", buf); } for (c = 1; c <= GD_n_cluster(g); c++) rec_attach_bb(GD_clust(g)[c], bbsym); }
void graph_cleanup(graph_t *g) { if (GD_drawing(g) && GD_drawing(g)->xdots) freeXDot ((xdot*)GD_drawing(g)->xdots); if (GD_drawing(g) && GD_drawing(g)->id) free (GD_drawing(g)->id); free(GD_drawing(g)); GD_drawing(g) = NULL; free_label(GD_label(g)); //FIX HERE , STILL SHALLOW //memset(&(g->u), 0, sizeof(Agraphinfo_t)); agclean(g, AGRAPH,"Agraphinfo_t"); }
void QGVScene::clear() { _nodes.clear(); _edges.clear(); _subGraphs.clear(); textlabel_t* label = GD_label(_graph->graph()); char* name = new char[strlen(label->text)+1]; strncpy(name, label->text, strlen(label->text)+1); agclose (_graph->graph()); _graph->setGraph(agopen(name, Agdirected, NULL)); delete[] name; QGraphicsScene::clear(); _label = NULL; }
static void xdot_end_cluster(GVJ_t * job) { Agraph_t* cluster_g = job->obj->u.sg; #ifndef WITH_CGRAPH agxset(cluster_g, xd->g_draw->index, agxbuse(xbufs[EMIT_CDRAW])); #else /* WITH_CGRAPH */ agxset(cluster_g, xd->g_draw, agxbuse(xbufs[EMIT_CDRAW])); #endif /* WITH_CGRAPH */ if (GD_label(cluster_g)) #ifndef WITH_CGRAPH agxset(cluster_g, xd->g_l_draw->index, agxbuse(xbufs[EMIT_CLABEL])); #else /* WITH_CGRAPH */ agxset(cluster_g, xd->g_l_draw, agxbuse(xbufs[EMIT_CLABEL])); #endif /* WITH_CGRAPH */ penwidth[EMIT_CDRAW] = 1; penwidth[EMIT_CLABEL] = 1; }
static void cleanup_subgs(graph_t * g) { graph_t *mg; edge_t *me; node_t *mn; graph_t *subg; mg = g->meta_node->graph; for (me = agfstout(mg, g->meta_node); me; me = agnxtout(mg, me)) { mn = me->head; subg = agusergraph(mn); free_label(GD_label(subg)); if (GD_alg(subg)) { free(PORTS(subg)); free(GD_alg(subg)); } cleanup_subgs(subg); } }
void QGVScene::applyLayout(const QString &algorithm) { if(gvLayout(_context->context(), _graph->graph(), algorithm.toLocal8Bit().data()) != 0) { /* * Si plantage ici : * - Verifier que les dll sont dans le repertoire d'execution * - Verifie que le fichier "configN" est dans le repertoire d'execution ! */ qCritical()<<"Layout render error"<<agerrors()<<QString::fromLocal8Bit(aglasterr()); return; } //Debug output //gvRenderFilename(_context->context(), _graph->graph(), "canon", "debug.dot"); //gvRenderFilename(_context->context(), _graph->graph(), "png", "debug.png"); //Update items layout foreach(QGVNode* node, _nodes) node->updateLayout(); foreach(QGVEdge* edge, _edges) edge->updateLayout(); foreach(QGVSubGraph* sgraph, _subGraphs) sgraph->updateLayout(); //Graph label textlabel_t *xlabel = GD_label(_graph->graph()); if(xlabel) { if (_label == NULL) _label = addText(xlabel->text); else _label->setPlainText (xlabel->text); _label->setPos(QGVCore::centerToOrigin(QGVCore::toPoint(xlabel->pos, QGVCore::graphHeight(_graph->graph())), xlabel->dimen.x, -4)); } update(); }
static void xdot_end_graph(graph_t* g) { int i; if (agxblen(xbufs[EMIT_GDRAW])) { if (!xd->g_draw) xd->g_draw = safe_dcl(g, AGRAPH, "_draw_", ""); agxset(g, xd->g_draw, agxbuse(xbufs[EMIT_GDRAW])); } if (GD_label(g)) agxset(g, xd->g_l_draw, agxbuse(xbufs[EMIT_GLABEL])); agsafeset (g, "xdotversion", xd->version_s, ""); for (i = 0; i < NUMXBUFS; i++) agxbfree(xbuf+i); free (xd); penwidth[EMIT_GDRAW] = 1; penwidth[EMIT_GLABEL] = 1; textflags[EMIT_GDRAW] = 0; textflags[EMIT_GLABEL] = 0; }
/* strdup_and_subst_obj0: * Replace various escape sequences with the name of the associated * graph object. A double backslash \\ can be used to avoid a replacement. * If escBackslash is true, convert \\ to \; else leave alone. All other dyads * of the form \. are passed through unchanged. */ static char *strdup_and_subst_obj0 (char *str, void *obj, int escBackslash) { char c, *s, *p, *t, *newstr; char *tp_str = "", *hp_str = ""; char *g_str = "\\G", *n_str = "\\N", *e_str = "\\E", *h_str = "\\H", *t_str = "\\T", *l_str = "\\L"; int g_len = 2, n_len = 2, e_len = 2, h_len = 2, t_len = 2, l_len = 2, tp_len = 0, hp_len = 0; int newlen = 0; int isEdge = 0; textlabel_t *tl; port pt; /* prepare substitution strings */ switch (agobjkind(obj)) { case AGRAPH: g_str = agnameof((graph_t *)obj); g_len = strlen(g_str); tl = GD_label((graph_t *)obj); if (tl) { l_str = tl->text; if (str) l_len = strlen(l_str); } break; case AGNODE: g_str = agnameof(agraphof((node_t *)obj)); g_len = strlen(g_str); n_str = agnameof((node_t *)obj); n_len = strlen(n_str); tl = ND_label((node_t *)obj); if (tl) { l_str = tl->text; if (str) l_len = strlen(l_str); } break; case AGEDGE: isEdge = 1; g_str = agnameof(agroot(agraphof(agtail(((edge_t *)obj))))); g_len = strlen(g_str); t_str = agnameof(agtail(((edge_t *)obj))); t_len = strlen(t_str); pt = ED_tail_port((edge_t *)obj); if ((tp_str = pt.name)) tp_len = strlen(tp_str); h_str = agnameof(aghead(((edge_t *)obj))); h_len = strlen(h_str); pt = ED_head_port((edge_t *)obj); if ((hp_str = pt.name)) hp_len = strlen(hp_str); h_len = strlen(h_str); tl = ED_label((edge_t *)obj); if (tl) { l_str = tl->text; if (str) l_len = strlen(l_str); } if (agisdirected(agroot(agraphof(agtail(((edge_t*)obj)))))) e_str = "->"; else e_str = "--"; e_len = t_len + (tp_len?tp_len+1:0) + 2 + h_len + (hp_len?hp_len+1:0); break; } /* two passes over str. * * first pass prepares substitution strings and computes * total length for newstring required from malloc. */ for (s = str; (c = *s++);) { if (c == '\\') { switch (c = *s++) { case 'G': newlen += g_len; break; case 'N': newlen += n_len; break; case 'E': newlen += e_len; break; case 'H': newlen += h_len; break; case 'T': newlen += t_len; break; case 'L': newlen += l_len; break; case '\\': if (escBackslash) { newlen += 1; break; } /* Fall through */ default: /* leave other escape sequences unmodified, e.g. \n \l \r */ newlen += 2; } } else { newlen++; } } /* allocate new string */ newstr = gmalloc(newlen + 1); /* second pass over str assembles new string */ for (s = str, p = newstr; (c = *s++);) { if (c == '\\') { switch (c = *s++) { case 'G': for (t = g_str; (*p = *t++); p++); break; case 'N': for (t = n_str; (*p = *t++); p++); break; case 'E': if (isEdge) { for (t = t_str; (*p = *t++); p++); if (tp_len) { *p++ = ':'; for (t = tp_str; (*p = *t++); p++); } for (t = e_str; (*p = *t++); p++); for (t = h_str; (*p = *t++); p++); if (hp_len) { *p++ = ':'; for (t = hp_str; (*p = *t++); p++); } } break; case 'T': for (t = t_str; (*p = *t++); p++); break; case 'H': for (t = h_str; (*p = *t++); p++); break; case 'L': for (t = l_str; (*p = *t++); p++); break; case '\\': if (escBackslash) { *p++ = '\\'; break; } /* Fall through */ default: /* leave other escape sequences unmodified, e.g. \n \l \r */ *p++ = '\\'; *p++ = c; break; } } else { *p++ = c; } } *p++ = '\0'; return newstr; }
/* 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; } } }
/* finalCC: * Set graph bounding box given list of connected * components, each with its bounding box set. * If c_cnt > 1, then pts != NULL and gives translations for components. * Add margin about whole graph unless isRoot is true. * Reposition nodes based on final position of * node's connected component. * Also, entire layout is translated to origin. */ static void finalCC(graph_t * g, int c_cnt, graph_t ** cc, point * pts, graph_t * rg, layout_info* infop) { attrsym_t * G_width = infop->G_width; attrsym_t * G_height = infop->G_height; graph_t *cg; box b, bb; boxf bbf; point pt; int margin; graph_t **cp = cc; point *pp = pts; int isRoot = (rg == infop->rootg); int isEmpty = 0; /* compute graph bounding box in points */ if (c_cnt) { cg = *cp++; BF2B(GD_bb(cg), bb); if (c_cnt > 1) { pt = *pp++; bb.LL.x += pt.x; bb.LL.y += pt.y; bb.UR.x += pt.x; bb.UR.y += pt.y; while ((cg = *cp++)) { BF2B(GD_bb(cg), b); pt = *pp++; b.LL.x += pt.x; b.LL.y += pt.y; b.UR.x += pt.x; b.UR.y += pt.y; bb.LL.x = MIN(bb.LL.x, b.LL.x); bb.LL.y = MIN(bb.LL.y, b.LL.y); bb.UR.x = MAX(bb.UR.x, b.UR.x); bb.UR.y = MAX(bb.UR.y, b.UR.y); } } } else { /* empty graph */ bb.LL.x = 0; bb.LL.y = 0; bb.UR.x = late_int(rg, G_width, POINTS(DEFAULT_NODEWIDTH), 3); bb.UR.y = late_int(rg, G_height, POINTS(DEFAULT_NODEHEIGHT), 3); isEmpty = 1; } if (GD_label(rg)) { point p; int d; isEmpty = 0; PF2P(GD_label(rg)->dimen, p); d = p.x - (bb.UR.x - bb.LL.x); if (d > 0) { /* height of label added below */ d /= 2; bb.LL.x -= d; bb.UR.x += d; } } if (isRoot || isEmpty) margin = 0; else margin = late_int (g, G_margin, CL_OFFSET, 0); pt.x = -bb.LL.x + margin; pt.y = -bb.LL.y + margin + GD_border(rg)[BOTTOM_IX].y; bb.LL.x = 0; bb.LL.y = 0; bb.UR.x += pt.x + margin; bb.UR.y += pt.y + margin + GD_border(rg)[TOP_IX].y; /* translate nodes */ if (c_cnt) { cp = cc; pp = pts; while ((cg = *cp++)) { point p; node_t *n; pointf del; if (pp) { p = *pp++; p.x += pt.x; p.y += pt.y; } else { p = pt; } del.x = PS2INCH(p.x); del.y = PS2INCH(p.y); for (n = agfstnode(cg); n; n = agnxtnode(cg, n)) { ND_pos(n)[0] += del.x; ND_pos(n)[1] += del.y; } } } bbf.LL.x = PS2INCH(bb.LL.x); bbf.LL.y = PS2INCH(bb.LL.y); bbf.UR.x = PS2INCH(bb.UR.x); bbf.UR.y = PS2INCH(bb.UR.y); BB(g) = bbf; }
void attach_attrs_and_arrows(graph_t* g, int* sp, int* ep) { int e_arrows; /* graph has edges with end arrows */ int s_arrows; /* graph has edges with start arrows */ int i, j, sides; char buf[BUFSIZ]; /* Used only for small strings */ unsigned char xbuffer[BUFSIZ]; /* Initial buffer for xb */ agxbuf xb; node_t *n; edge_t *e; pointf ptf; int dim3 = (GD_odim(g) >= 3); Agsym_t* bbsym; gv_fixLocale (1); e_arrows = s_arrows = 0; setYInvert(g); agxbinit(&xb, BUFSIZ, xbuffer); safe_dcl(g, AGNODE, "pos", ""); safe_dcl(g, AGNODE, "rects", ""); N_width = safe_dcl(g, AGNODE, "width", ""); N_height = safe_dcl(g, AGNODE, "height", ""); safe_dcl(g, AGEDGE, "pos", ""); if (GD_has_labels(g) & NODE_XLABEL) safe_dcl(g, AGNODE, "xlp", ""); if (GD_has_labels(g) & EDGE_LABEL) safe_dcl(g, AGEDGE, "lp", ""); if (GD_has_labels(g) & EDGE_XLABEL) safe_dcl(g, AGEDGE, "xlp", ""); if (GD_has_labels(g) & HEAD_LABEL) safe_dcl(g, AGEDGE, "head_lp", ""); if (GD_has_labels(g) & TAIL_LABEL) safe_dcl(g, AGEDGE, "tail_lp", ""); if (GD_label(g)) { safe_dcl(g, AGRAPH, "lp", ""); safe_dcl(g, AGRAPH, "lwidth", ""); safe_dcl(g, AGRAPH, "lheight", ""); if (GD_label(g)->text[0]) { ptf = GD_label(g)->pos; sprintf(buf, "%.5g,%.5g", ptf.x, YDIR(ptf.y)); agset(g, "lp", buf); ptf = GD_label(g)->dimen; sprintf(buf, "%.2f", PS2INCH(ptf.x)); agset(g, "lwidth", buf); sprintf(buf, "%.2f", PS2INCH(ptf.y)); agset(g, "lheight", buf); } } bbsym = safe_dcl(g, AGRAPH, "bb", ""); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (dim3) { int k; sprintf(buf, "%.5g,%.5g,%.5g", ND_coord(n).x, YDIR(ND_coord(n).y), POINTS_PER_INCH*(ND_pos(n)[2])); agxbput (&xb, buf); for (k = 3; k < GD_odim(g); k++) { sprintf(buf, ",%.5g", POINTS_PER_INCH*(ND_pos(n)[k])); agxbput (&xb, buf); } agset(n, "pos", agxbuse(&xb)); } else { sprintf(buf, "%.5g,%.5g", ND_coord(n).x, YDIR(ND_coord(n).y)); agset(n, "pos", buf); } sprintf(buf, "%.5g", PS2INCH(ND_ht(n))); agxset(n, N_height, buf); sprintf(buf, "%.5g", PS2INCH(ND_lw(n) + ND_rw(n))); agxset(n, N_width, buf); if (ND_xlabel(n) && ND_xlabel(n)->set) { ptf = ND_xlabel(n)->pos; sprintf(buf, "%.5g,%.5g", ptf.x, YDIR(ptf.y)); agset(n, "xlp", buf); } if (strcmp(ND_shape(n)->name, "record") == 0) { set_record_rects(n, ND_shape_info(n), &xb); agxbpop(&xb); /* get rid of last space */ agset(n, "rects", agxbuse(&xb)); } else { polygon_t *poly; int i; if (N_vertices && isPolygon(n)) { poly = (polygon_t *) ND_shape_info(n); sides = poly->sides; if (sides < 3) { char *p = agget(n, "samplepoints"); if (p) sides = atoi(p); else sides = 8; if (sides < 3) sides = 8; } for (i = 0; i < sides; i++) { if (i > 0) agxbputc(&xb, ' '); if (poly->sides >= 3) sprintf(buf, "%.5g %.5g", PS2INCH(poly->vertices[i].x), YFDIR(PS2INCH(poly->vertices[i].y))); else sprintf(buf, "%.5g %.5g", ND_width(n) / 2.0 * cos(i / (double) sides * M_PI * 2.0), YFDIR(ND_height(n) / 2.0 * sin(i / (double) sides * M_PI * 2.0))); agxbput(&xb, buf); } agxset(n, N_vertices, agxbuse(&xb)); } } if (State >= GVSPLINES) { for (e = agfstout(g, n); e; e = agnxtout(g, e)) { if (ED_edge_type(e) == IGNORED) continue; if (ED_spl(e) == NULL) continue; /* reported in postproc */ for (i = 0; i < ED_spl(e)->size; i++) { if (i > 0) agxbputc(&xb, ';'); if (ED_spl(e)->list[i].sflag) { s_arrows = 1; sprintf(buf, "s,%.5g,%.5g ", ED_spl(e)->list[i].sp.x, YDIR(ED_spl(e)->list[i].sp.y)); agxbput(&xb, buf); } if (ED_spl(e)->list[i].eflag) { e_arrows = 1; sprintf(buf, "e,%.5g,%.5g ", ED_spl(e)->list[i].ep.x, YDIR(ED_spl(e)->list[i].ep.y)); agxbput(&xb, buf); } for (j = 0; j < ED_spl(e)->list[i].size; j++) { if (j > 0) agxbputc(&xb, ' '); ptf = ED_spl(e)->list[i].list[j]; sprintf(buf, "%.5g,%.5g", ptf.x, YDIR(ptf.y)); agxbput(&xb, buf); } } agset(e, "pos", agxbuse(&xb)); if (ED_label(e)) { ptf = ED_label(e)->pos; sprintf(buf, "%.5g,%.5g", ptf.x, YDIR(ptf.y)); agset(e, "lp", buf); } if (ED_xlabel(e) && ED_xlabel(e)->set) { ptf = ED_xlabel(e)->pos; sprintf(buf, "%.5g,%.5g", ptf.x, YDIR(ptf.y)); agset(e, "xlp", buf); } if (ED_head_label(e)) { ptf = ED_head_label(e)->pos; sprintf(buf, "%.5g,%.5g", ptf.x, YDIR(ptf.y)); agset(e, "head_lp", buf); } if (ED_tail_label(e)) { ptf = ED_tail_label(e)->pos; sprintf(buf, "%.5g,%.5g", ptf.x, YDIR(ptf.y)); agset(e, "tail_lp", buf); } } } } rec_attach_bb(g, bbsym); agxbfree(&xb); if (HAS_CLUST_EDGE(g)) undoClusterEdges(g); *sp = s_arrows; *ep = e_arrows; gv_fixLocale (0); }
QString QGVSubGraph::name() const { return QString::fromLocal8Bit(GD_label(_sgraph->graph())->text); }
/* 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); } }
/* place_flip_graph_label: * Put cluster labels recursively in the flip case. */ static void place_flip_graph_label(graph_t * g) { int c; point p, d; #ifdef OLD int maxx, minx; int maxy, miny; pointf dimen; #endif if ((g != g->root) && (GD_label(g)) && !GD_label(g)->set) { if (GD_label_pos(g) & LABEL_AT_TOP) { d = GD_border(g)[RIGHT_IX]; p.x = GD_bb(g).UR.x - d.x / 2; #ifdef OLD maxx = GD_bb(g).UR.x + d.y; GD_bb(g).UR.x = maxx; if (GD_bb(g->root).UR.x < maxx) GD_bb(g->root).UR.x = maxx; #endif } else { d = GD_border(g)[LEFT_IX]; p.x = GD_bb(g).LL.x + d.x / 2; #ifdef OLD minx = GD_bb(g).LL.x - d.y; GD_bb(g).LL.x = minx; if (GD_bb(g->root).LL.x > minx) GD_bb(g->root).LL.x = minx; #endif } if (GD_label_pos(g) & LABEL_AT_RIGHT) { p.y = GD_bb(g).LL.y + d.y / 2; #ifdef OLD maxy = p.y + d.x / 2; if (GD_bb(g->root).UR.y < maxy) GD_bb(g->root).UR.y = maxy; #endif } else if (GD_label_pos(g) & LABEL_AT_LEFT) { p.y = GD_bb(g).UR.y - d.y / 2; #ifdef OLD miny = p.y - d.x / 2; if (GD_bb(g->root).LL.y > miny) GD_bb(g->root).LL.y = miny; #endif } else { p.y = (GD_bb(g).LL.y + GD_bb(g).UR.y) / 2; #ifdef OLD maxy = p.y + d.x / 2; miny = p.y - d.x / 2; #endif } GD_label(g)->p = p; GD_label(g)->set = TRUE; } for (c = 1; c <= GD_n_cluster(g); c++) place_flip_graph_label(GD_clust(g)[c]); }
/* 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); } }
static void xd_end_cluster(void) { agxset(cluster_g, g_draw->index, agxbuse(xbufs[EMIT_CDRAW])); if (GD_label(cluster_g)) agxset(cluster_g, g_l_draw->index, agxbuse(xbufs[EMIT_CLABEL])); }
/* * John M. suggests: * You might want to add four more: * * _ohdraw_ (optional head-end arrow for edges) * _ohldraw_ (optional head-end label for edges) * _otdraw_ (optional tail-end arrow for edges) * _otldraw_ (optional tail-end label for edges) * * that would be generated when an additional option is supplied to * dot, etc. and * these would be the arrow/label positions to use if a user want to flip the * direction of an edge (as sometimes is there want). * * N.B. John M. asks: * By the way, I don't know if you ever plan to add other letters for * the xdot spec, but could you reserve "a" and also "A" (for attribute), * "n" and also "N" (for numeric), "w" (for sWitch), "s" (for string) * and "t" (for tooltip) and "x" (for position). We use those letters in * our drawing spec (and also "<" and ">"), so if you start generating * output with them, it could break what we have. */ void extend_attrs(GVJ_t * job, graph_t *g, int s_arrows, int e_arrows) { node_t *n; edge_t *e; attrsym_t *n_draw = NULL; attrsym_t *n_l_draw = NULL; attrsym_t *e_draw = NULL; attrsym_t *h_draw = NULL; attrsym_t *t_draw = NULL; attrsym_t *e_l_draw = NULL; attrsym_t *hl_draw = NULL; attrsym_t *tl_draw = NULL; unsigned char buf0[BUFSIZ]; unsigned char buf1[BUFSIZ]; unsigned char buf2[BUFSIZ]; unsigned char buf3[BUFSIZ]; unsigned char buf4[BUFSIZ]; unsigned char buf5[BUFSIZ]; gvc = job->gvc; agsafeset (g, "xdotversion", XDOTVERSION, ""); if (GD_has_labels(g) & GRAPH_LABEL) g_l_draw = safe_dcl(g, g, "_ldraw_", "", agraphattr); else g_l_draw = NULL; if (GD_n_cluster(g)) g_draw = safe_dcl(g, g, "_draw_", "", agraphattr); else g_draw = NULL; n_draw = safe_dcl(g, g->proto->n, "_draw_", "", agnodeattr); n_l_draw = safe_dcl(g, g->proto->n, "_ldraw_", "", agnodeattr); e_draw = safe_dcl(g, g->proto->e, "_draw_", "", agedgeattr); if (e_arrows) h_draw = safe_dcl(g, g->proto->e, "_hdraw_", "", agedgeattr); if (s_arrows) t_draw = safe_dcl(g, g->proto->e, "_tdraw_", "", agedgeattr); if (GD_has_labels(g) & EDGE_LABEL) e_l_draw = safe_dcl(g, g->proto->e, "_ldraw_", "", agedgeattr); if (GD_has_labels(g) & HEAD_LABEL) hl_draw = safe_dcl(g, g->proto->e, "_hldraw_", "", agedgeattr); if (GD_has_labels(g) & TAIL_LABEL) tl_draw = safe_dcl(g, g->proto->e, "_tldraw_", "", agedgeattr); agxbinit(&xbuf0, BUFSIZ, buf0); agxbinit(&xbuf1, BUFSIZ, buf1); agxbinit(&xbuf2, BUFSIZ, buf2); agxbinit(&xbuf3, BUFSIZ, buf3); agxbinit(&xbuf4, BUFSIZ, buf4); agxbinit(&xbuf5, BUFSIZ, buf5); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (ND_shape(n) && !isInvis(late_string(n, N_style, ""))) { ND_shape(n)->fns->codefn(job, n); agxset(n, n_draw->index, agxbuse(xbufs[EMIT_NDRAW])); agxset(n, n_l_draw->index, agxbuse(xbufs[EMIT_NLABEL])); } if (State < GVSPLINES) continue; for (e = agfstout(g, n); e; e = agnxtout(g, e)) { if (ED_edge_type(e) == IGNORED) continue; if (isInvis(late_string(e, E_style, ""))) continue; if (ED_spl(e) == NULL) continue; emit_edge_graphics (job, e); agxset(e, e_draw->index, agxbuse(xbufs[EMIT_EDRAW])); if (t_draw) agxset(e, t_draw->index, agxbuse(xbufs[EMIT_TDRAW])); if (h_draw) agxset(e, h_draw->index, agxbuse(xbufs[EMIT_HDRAW])); if (e_l_draw) agxset(e, e_l_draw->index,agxbuse(xbufs[EMIT_ELABEL])); if (tl_draw) agxset(e, tl_draw->index, agxbuse(xbufs[EMIT_TLABEL])); if (hl_draw) agxset(e, hl_draw->index, agxbuse(xbufs[EMIT_HLABEL])); } } emit_background(job, g); if (agxblen(xbufs[EMIT_GDRAW])) { if (!g_draw) g_draw = safe_dcl(g, g, "_draw_", "", agraphattr); agxset(g, g_draw->index, agxbuse(xbufs[EMIT_GDRAW])); } if (GD_label(g)) { emit_label(job, EMIT_GLABEL, GD_label(g), (void *) g); agxset(g, g_l_draw->index, agxbuse(xbufs[EMIT_GLABEL])); } emit_clusters(job, g, 0); agxbfree(&xbuf0); agxbfree(&xbuf1); agxbfree(&xbuf2); agxbfree(&xbuf3); agxbfree(&xbuf4); agxbfree(&xbuf5); }
/* 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; } } }
/* do_graph_label: * If the ifdef'ed parts are added, clusters are guaranteed not * to overlap and have sufficient room for the label. The problem * is this approach does not use the actual size of the cluster, so * the resulting cluster tends to be far too large. */ void do_graph_label(graph_t* sg) { char *p, *pos, *just; int pos_ix; GVC_t *gvc = GD_gvc(sg->root); /* it would be nice to allow multiple graph labels in the future */ if ((p = agget(sg,"label"))) { char pos_flag; int html = aghtmlstr(p); GD_has_labels(sg->root) |= GRAPH_LABEL; GD_label(sg) = make_label(gvc, html,strdup_and_subst_graph(p,sg), 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),sg); if (html) { if (make_html_label(gvc, GD_label(sg), sg)) 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(!GD_left_to_right(sg->root)) { point dpt; dpt = cvt2pt(GD_label(sg)->dimen); if (GD_label_pos(sg) & LABEL_AT_TOP) pos_ix = TOP_IX; else pos_ix = BOTTOM_IX; GD_border(sg)[pos_ix] = dpt; #if 0 if(g != g->root) { GD_border(g)[LEFT_IX].x = dpt.x/2; GD_border(g)[RIGHT_IX].x = dpt.x/2; GD_border(g)[LEFT_IX].y = 0; GD_border(g)[RIGHT_IX].y = 0; } #endif } else { point dpt; dpt = cvt2pt(GD_label(sg)->dimen); /* 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; #if 0 if(g != g->root) { GD_border(g)[TOP_IX].y = dpt.x/2; GD_border(g)[BOTTOM_IX].y = dpt.x/2; GD_border(g)[TOP_IX].x = 0; GD_border(g)[BOTTOM_IX].x = 0; } #endif } } }
void attach_attrs_and_arrows(graph_t* g, int* sp, int* ep) { int e_arrows; /* graph has edges with end arrows */ int s_arrows; /* graph has edges with start arrows */ int i, j, sides; char buf[BUFSIZ]; /* Used only for small strings */ unsigned char xbuffer[BUFSIZ]; /* Initial buffer for xb */ agxbuf xb; node_t *n; edge_t *e; point pt; e_arrows = s_arrows = 0; setYInvert(g); agxbinit(&xb, BUFSIZ, xbuffer); safe_dcl(g, g->proto->n, "pos", "", agnodeattr); safe_dcl(g, g->proto->n, "rects", "", agnodeattr); N_width = safe_dcl(g, g->proto->n, "width", "", agnodeattr); N_height = safe_dcl(g, g->proto->n, "height", "", agnodeattr); safe_dcl(g, g->proto->e, "pos", "", agedgeattr); if (GD_has_labels(g) & EDGE_LABEL) safe_dcl(g, g->proto->e, "lp", "", agedgeattr); if (GD_has_labels(g) & HEAD_LABEL) safe_dcl(g, g->proto->e, "head_lp", "", agedgeattr); if (GD_has_labels(g) & TAIL_LABEL) safe_dcl(g, g->proto->e, "tail_lp", "", agedgeattr); if (GD_label(g)) { safe_dcl(g, g, "lp", "", agraphattr); if (GD_label(g)->text[0]) { pt = GD_label(g)->p; sprintf(buf, "%d,%d", pt.x, YDIR(pt.y)); agset(g, "lp", buf); } } safe_dcl(g, g, "bb", "", agraphattr); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { sprintf(buf, "%d,%d", ND_coord_i(n).x, YDIR(ND_coord_i(n).y)); agset(n, "pos", buf); sprintf(buf, "%.2f", PS2INCH(ND_ht_i(n))); agxset(n, N_height->index, buf); sprintf(buf, "%.2f", PS2INCH(ND_lw_i(n) + ND_rw_i(n))); agxset(n, N_width->index, buf); if (strcmp(ND_shape(n)->name, "record") == 0) { set_record_rects(n, ND_shape_info(n), &xb); agxbpop(&xb); /* get rid of last space */ agset(n, "rects", agxbuse(&xb)); } else { polygon_t *poly; int i; if (N_vertices && isPolygon(n)) { poly = (polygon_t *) ND_shape_info(n); sides = poly->sides; if (sides < 3) { char *p = agget(n, "samplepoints"); if (p) sides = atoi(p); else sides = 8; if (sides < 3) sides = 8; } for (i = 0; i < sides; i++) { if (i > 0) agxbputc(&xb, ' '); if (poly->sides >= 3) sprintf(buf, "%.3f %.3f", PS2INCH(poly->vertices[i].x), YFDIR(PS2INCH(poly->vertices[i].y))); else sprintf(buf, "%.3f %.3f", ND_width(n) / 2.0 * cos(i / (double) sides * PI * 2.0), YFDIR(ND_height(n) / 2.0 * sin(i / (double) sides * PI * 2.0))); agxbput(&xb, buf); } agxset(n, N_vertices->index, agxbuse(&xb)); } } if (State >= GVSPLINES) { for (e = agfstout(g, n); e; e = agnxtout(g, e)) { if (ED_edge_type(e) == IGNORED) continue; if (ED_spl(e) == NULL) continue; /* reported in postproc */ for (i = 0; i < ED_spl(e)->size; i++) { if (i > 0) agxbputc(&xb, ';'); if (ED_spl(e)->list[i].sflag) { s_arrows = 1; sprintf(buf, "s,%d,%d ", ED_spl(e)->list[i].sp.x, YDIR(ED_spl(e)->list[i].sp.y)); agxbput(&xb, buf); } if (ED_spl(e)->list[i].eflag) { e_arrows = 1; sprintf(buf, "e,%d,%d ", ED_spl(e)->list[i].ep.x, YDIR(ED_spl(e)->list[i].ep.y)); agxbput(&xb, buf); } for (j = 0; j < ED_spl(e)->list[i].size; j++) { if (j > 0) agxbputc(&xb, ' '); pt = ED_spl(e)->list[i].list[j]; sprintf(buf, "%d,%d", pt.x, YDIR(pt.y)); agxbput(&xb, buf); } } agset(e, "pos", agxbuse(&xb)); if (ED_label(e)) { pt = ED_label(e)->p; sprintf(buf, "%d,%d", pt.x, YDIR(pt.y)); agset(e, "lp", buf); } if (ED_head_label(e)) { pt = ED_head_label(e)->p; sprintf(buf, "%d,%d", pt.x, YDIR(pt.y)); agset(e, "head_lp", buf); } if (ED_tail_label(e)) { pt = ED_tail_label(e)->p; sprintf(buf, "%d,%d", pt.x, YDIR(pt.y)); agset(e, "tail_lp", buf); } } } } rec_attach_bb(g); agxbfree(&xb); if (HAS_CLUST_EDGE(g)) undoClusterEdges(g); *sp = s_arrows; *ep = e_arrows; }