void QGVNode::updateLayout() { prepareGeometryChange(); qreal width = ND_width(_node->node()) * (DotDefaultDPI); qreal height = ND_height(_node->node()) * (DotDefaultDPI); //Node Position (center) qreal gheight = QGVCore::graphHeight(_scene->_graph->graph()); QPointF pos = QGVCore::centerToOrigin(QGVCore::toPoint(ND_coord(_node->node()), gheight), width, height); setPos(pos); //Node on top setZValue(1); //Node path if (0 == strcmp(ND_shape(_node->node())->name, "record")) { this->is_record = true; _record_desc = QGVCore::to_record_label((field_t *) ND_shape_info(_node->node()), width, height); _bounding_rect = _record_desc.first().first; } else { this->is_record = false; _path = QGVCore::toPath(ND_shape(_node->node())->name, (polygon_t *) ND_shape_info(_node->node()), width, height); _bounding_rect = _path.boundingRect(); } _pen.setWidth(1); _brush.setStyle(QGVCore::toBrushStyle(getAttribute("style"))); _brush.setColor(QGVCore::toColor(getAttribute("fillcolor"))); _pen.setColor(QGVCore::toColor(getAttribute("color"))); setToolTip(getAttribute("tooltip")); }
//------------------------------------------------------------------------------ // Name: make_polygon_helper // Desc: //------------------------------------------------------------------------------ void GraphNode::make_polygon_helper(node_t *node, QPainterPath &path) const { auto poly = static_cast<polygon_t *>(ND_shape_info(node)); if(poly->peripheries != 1) { qWarning("unsupported number of peripheries %d", poly->peripheries); } const int sides = poly->sides; const pointf* vertices = poly->vertices; QPolygonF polygon; for (int side = 0; side < sides; side++) { polygon.append(graph_->gToQ(vertices[side], false)); } polygon.append(polygon[0]); path.addPolygon(polygon); }
/* 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; }
//------------------------------------------------------------------------------ // Name: make_ellipse_helper // Desc: //------------------------------------------------------------------------------ void GraphNode::make_ellipse_helper(node_t *node, QPainterPath &path) const { auto poly = static_cast<polygon_t *>(ND_shape_info(node)); if(poly->peripheries != 1) { qWarning("unsupported number of peripheries %d", poly->peripheries); } const int sides = poly->sides; const pointf* vertices = poly->vertices; QPolygonF polygon; for (int side = 0; side < sides; side++) { polygon.append(graph_->gToQ(vertices[side], false)); } QRectF ellipse_bounds(polygon[0], polygon[1]); for (int i = 0; i < poly->peripheries; ++i) { path.addEllipse(ellipse_bounds.adjusted(-2 * i, 2 * i, 2 * i, -2 * i)); } }
void QGVNode::updateLayout() { prepareGeometryChange(); qreal width = ND_width(_node->node())*DotDefaultDPI; qreal height = ND_height(_node->node())*DotDefaultDPI; //Node Position (center) qreal gheight = QGVCore::graphHeight(_scene->_graph->graph()); setPos(QGVCore::centerToOrigin(QGVCore::toPoint(ND_coord(_node->node()), gheight), width, height)); //Node on top setZValue(1); //Node path _path = QGVCore::toPath(ND_shape(_node->node())->name, (polygon_t*)ND_shape_info(_node->node()), width, height); _pen.setWidth(1); _brush.setStyle(QGVCore::toBrushStyle(getAttribute("style"))); _brush.setColor(QGVCore::toColor(getAttribute("fillcolor"))); _pen.setColor(QGVCore::toColor(getAttribute("color"))); setToolTip(getAttribute("tooltip")); }
int makePoly(Poly * pp, Agnode_t * n, float xmargin, float ymargin) { int i; int sides; Point *verts; polygon_t *poly; boxf b; if (ND_clust(n)) { Point b; sides = 4; b.x = ND_width(n) / 2.0; b.y = ND_height(n) / 2.0; pp->kind = BOX; verts = N_GNEW(sides, Point); PUTPT(verts[0], b.x, b.y); PUTPT(verts[1], -b.x, b.y); PUTPT(verts[2], -b.x, -b.y); PUTPT(verts[3], b.x, -b.y); } else switch (shapeOf(n)) { case SH_POLY: poly = (polygon_t *) ND_shape_info(n); sides = poly->sides; if (sides >= 3) { /* real polygon */ verts = N_GNEW(sides, Point); for (i = 0; i < sides; i++) { verts[i].x = PS2INCH(poly->vertices[i].x); verts[i].y = PS2INCH(poly->vertices[i].y); } } else verts = genRound(n, &sides, 0, 0); if (streq(ND_shape(n)->name, "box")) pp->kind = BOX; else if (streq(ND_shape(n)->name, "polygon") && isBox(verts, sides)) pp->kind = BOX; else if ((poly->sides < 3) && poly->regular) pp->kind = CIRCLE; else pp->kind = 0; break; case SH_RECORD: sides = 4; verts = N_GNEW(sides, Point); b = ((field_t *) ND_shape_info(n))->b; verts[0] = makeScaledPoint(b.LL.x, b.LL.y); verts[1] = makeScaledPoint(b.UR.x, b.LL.y); verts[2] = makeScaledPoint(b.UR.x, b.UR.y); verts[3] = makeScaledPoint(b.LL.x, b.UR.y); pp->kind = BOX; break; case SH_POINT: pp->kind = CIRCLE; verts = genRound(n, &sides, 0, 0); break; default: agerr(AGERR, "makePoly: unknown shape type %s\n", ND_shape(n)->name); return 1; } #ifdef OLD if (margin != 0.0) inflatePts(verts, sides, margin); #else if ((xmargin != 1.0) || (ymargin != 1.0)) inflatePts(verts, sides, xmargin, ymargin); #endif pp->verts = verts; pp->nverts = sides; bbox(verts, sides, &pp->origin, &pp->corner); if (sides > maxcnt) maxcnt = sides; return 0; }
int makeAddPoly(Poly * pp, Agnode_t * n, float xmargin, float ymargin) { int i; int sides; Point *verts; polygon_t *poly; boxf b; if (ND_clust(n)) { Point b; sides = 4; b.x = ND_width(n) / 2.0 + xmargin; b.y = ND_height(n) / 2.0 + ymargin; pp->kind = BOX; verts = N_GNEW(sides, Point); PUTPT(verts[0], b.x, b.y); PUTPT(verts[1], -b.x, b.y); PUTPT(verts[2], -b.x, -b.y); PUTPT(verts[3], b.x, -b.y); } else switch (shapeOf(n)) { case SH_POLY: poly = (polygon_t *) ND_shape_info(n); sides = poly->sides; if (streq(ND_shape(n)->name, "box")) pp->kind = BOX; else if (streq(ND_shape(n)->name, "polygon") && isBox(poly->vertices, sides)) pp->kind = BOX; else if ((poly->sides < 3) && poly->regular) pp->kind = CIRCLE; else pp->kind = 0; if (sides >= 3) { /* real polygon */ verts = N_GNEW(sides, Point); if (pp->kind == BOX) { /* To do an additive margin, we rely on knowing that * the vertices are CCW starting from the UR */ verts[0].x = PS2INCH(poly->vertices[0].x) + xmargin; verts[0].y = PS2INCH(poly->vertices[0].y) + ymargin; verts[1].x = PS2INCH(poly->vertices[1].x) - xmargin; verts[1].y = PS2INCH(poly->vertices[1].y) + ymargin; verts[2].x = PS2INCH(poly->vertices[2].x) - xmargin; verts[2].y = PS2INCH(poly->vertices[2].y) - ymargin; verts[3].x = PS2INCH(poly->vertices[3].x) + xmargin; verts[3].y = PS2INCH(poly->vertices[3].y) - ymargin; } else { for (i = 0; i < sides; i++) { double h = LEN(poly->vertices[i].x,poly->vertices[i].y); verts[i].x = poly->vertices[i].x * (1.0 + xmargin/h); verts[i].y = poly->vertices[i].y * (1.0 + ymargin/h); verts[i].x = PS2INCH(verts[i].x); verts[i].y = PS2INCH(verts[i].y); } } } else verts = genRound(n, &sides, xmargin, ymargin); break; case SH_RECORD: sides = 4; verts = N_GNEW(sides, Point); b = ((field_t *) ND_shape_info(n))->b; verts[0] = makeScaledTransPoint(b.LL.x, b.LL.y, -xmargin, -ymargin); verts[1] = makeScaledTransPoint(b.UR.x, b.LL.y, xmargin, -ymargin); verts[2] = makeScaledTransPoint(b.UR.x, b.UR.y, xmargin, ymargin); verts[3] = makeScaledTransPoint(b.LL.x, b.UR.y, -xmargin, ymargin); pp->kind = BOX; break; case SH_POINT: pp->kind = CIRCLE; verts = genRound(n, &sides, xmargin, ymargin); break; default: agerr(AGERR, "makeAddPoly: unknown shape type %s\n", ND_shape(n)->name); return 1; } pp->verts = verts; pp->nverts = sides; bbox(verts, sides, &pp->origin, &pp->corner); if (sides > maxcnt) maxcnt = sides; return 0; }
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; }
/* makeObstacle: * Given a node, return an obstacle reflecting the * node's geometry. pmargin specifies how much space to allow * around the polygon. * Returns the constructed polygon on success, NULL on failure. * Failure means the node shape is not supported. * * If isOrtho is true, we have to use the bounding box of each node. * * The polygon has its vertices in CW order. * */ Ppoly_t *makeObstacle(node_t * n, expand_t* pmargin, boolean isOrtho) { Ppoly_t *obs; polygon_t *poly; double adj = 0.0; int j, sides; pointf polyp; boxf b; pointf pt; field_t *fld; epsf_t *desc; int isPoly; pointf* verts; pointf vs[4]; pointf p; pointf margin; switch (shapeOf(n)) { case SH_POLY: case SH_POINT: obs = NEW(Ppoly_t); poly = (polygon_t *) ND_shape_info(n); if (isOrtho) { isPoly = 1; sides = 4; verts = vs; margin.x = margin.y = 0; /* For fixedshape, we can't use the width and height, as this includes * the label. We only want to use the actual node shape. */ if (poly->option & FIXEDSHAPE) { b = polyBB (poly); vs[0] = b.LL; vs[1].x = b.UR.x; vs[1].y = b.LL.y; vs[2] = b.UR; vs[3].x = b.LL.x; vs[3].y = b.UR.y; } else { p.x = -ND_lw(n); p.y = -ND_ht(n)/2.0; vs[0] = p; p.x = ND_lw(n); vs[1] = p; p.y = ND_ht(n)/2.0; vs[2] = p; p.x = -ND_lw(n); vs[3] = p; } } else if (poly->sides >= 3) { isPoly = 1; sides = poly->sides; verts = poly->vertices; margin.x = pmargin->x; margin.y = pmargin->y; } else { /* ellipse */ isPoly = 0; sides = 8; adj = drand48() * .01; } obs->pn = sides; obs->ps = N_NEW(sides, Ppoint_t); /* assuming polys are in CCW order, and pathplan needs CW */ for (j = 0; j < sides; j++) { double xmargin = 0.0, ymargin = 0.0; if (isPoly) { if (pmargin->doAdd) { if (sides == 4) { switch (j) { case 0 : xmargin = margin.x; ymargin = margin.y; break; case 1 : xmargin = -margin.x; ymargin = margin.y; break; case 2 : xmargin = -margin.x; ymargin = -margin.y; break; case 3 : xmargin = margin.x; ymargin = -margin.y; break; } polyp.x = verts[j].x + xmargin; polyp.y = verts[j].y + ymargin; } else { double h = LEN(verts[j].x,verts[j].y); polyp.x = verts[j].x * (1.0 + margin.x/h); polyp.y = verts[j].y * (1.0 + margin.y/h); } } else { polyp.x = verts[j].x * margin.x; polyp.y = verts[j].y * margin.y; } } else { double c, s; c = cos(2.0 * M_PI * j / sides + adj); s = sin(2.0 * M_PI * j / sides + adj); if (pmargin->doAdd) { polyp.x = c*(ND_lw(n)+ND_rw(n)+pmargin->x) / 2.0; polyp.y = s*(ND_ht(n)+pmargin->y) / 2.0; } else { polyp.x = pmargin->x * c * (ND_lw(n) + ND_rw(n)) / 2.0; polyp.y = pmargin->y * s * ND_ht(n) / 2.0; } } obs->ps[sides - j - 1].x = polyp.x + ND_coord(n).x; obs->ps[sides - j - 1].y = polyp.y + ND_coord(n).y; } break; case SH_RECORD: fld = (field_t *) ND_shape_info(n); b = fld->b; obs = NEW(Ppoly_t); obs->pn = 4; obs->ps = N_NEW(4, Ppoint_t); /* CW order */ pt = ND_coord(n); if (pmargin->doAdd) { obs->ps[0] = genPt(b.LL.x-pmargin->x, b.LL.y-pmargin->y, pt); obs->ps[1] = genPt(b.LL.x-pmargin->x, b.UR.y+pmargin->y, pt); obs->ps[2] = genPt(b.UR.x+pmargin->x, b.UR.y+pmargin->y, pt); obs->ps[3] = genPt(b.UR.x+pmargin->x, b.LL.y-pmargin->y, pt); } else { obs->ps[0] = recPt(b.LL.x, b.LL.y, pt, pmargin); obs->ps[1] = recPt(b.LL.x, b.UR.y, pt, pmargin); obs->ps[2] = recPt(b.UR.x, b.UR.y, pt, pmargin); obs->ps[3] = recPt(b.UR.x, b.LL.y, pt, pmargin); } break; case SH_EPSF: desc = (epsf_t *) (ND_shape_info(n)); obs = NEW(Ppoly_t); obs->pn = 4; obs->ps = N_NEW(4, Ppoint_t); /* CW order */ pt = ND_coord(n); if (pmargin->doAdd) { obs->ps[0] = genPt(-ND_lw(n)-pmargin->x, -ND_ht(n)-pmargin->y,pt); obs->ps[1] = genPt(-ND_lw(n)-pmargin->x, ND_ht(n)+pmargin->y,pt); obs->ps[2] = genPt(ND_rw(n)+pmargin->x, ND_ht(n)+pmargin->y,pt); obs->ps[3] = genPt(ND_rw(n)+pmargin->x, -ND_ht(n)-pmargin->y,pt); } else { obs->ps[0] = recPt(-ND_lw(n), -ND_ht(n), pt, pmargin); obs->ps[1] = recPt(-ND_lw(n), ND_ht(n), pt, pmargin); obs->ps[2] = recPt(ND_rw(n), ND_ht(n), pt, pmargin); obs->ps[3] = recPt(ND_rw(n), -ND_ht(n), pt, pmargin); } break; default: obs = NULL; break; } return obs; }
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); }