Example #1
0
static void undoCompound(edge_t * e, graph_t * clg)
{
    node_t *t = agtail(e);
    node_t *h = aghead(e);
    node_t *ntail;
    node_t *nhead;
    edge_t* ce;

    if (!(IS_CLUST_NODE(t) || IS_CLUST_NODE(h)))
	return;
    ntail = mapN(t, clg);
    nhead = mapN(h, clg);
    ce = cloneEdge(e, ntail, nhead);

    /* transfer drawing information */
    ED_spl(ce) = ED_spl(e);
    ED_spl(e) = NULL;
    ED_label(ce) = ED_label(e);
    ED_label(e) = NULL;
    ED_xlabel(ce) = ED_xlabel(e);
    ED_xlabel(e) = NULL;
    ED_head_label(ce) = ED_head_label(e);
    ED_head_label(e) = NULL;
    ED_tail_label(ce) = ED_tail_label(e);
    ED_tail_label(e) = NULL;
    gv_cleanup_edge(e);
}
Example #2
0
/* makeSelfArcs:
 * Generate loops. We use the library routine makeSelfEdge
 * which also places the labels.
 * We have to handle port labels here.
 * as well as update the bbox from edge labels.
 */
void makeSelfArcs(path * P, edge_t * e, int stepx)
{
    int cnt = ED_count(e);

    if ((cnt == 1) || Concentrate) {
	edge_t *edges1[1];
	edges1[0] = e;
	makeSelfEdge(P, edges1, 0, 1, stepx, stepx, &sinfo);
	if (ED_label(e))
	    updateBB(agraphof(agtail(e)), ED_label(e));
	makePortLabels(e);
    } else {
	int i;
	edge_t **edges = N_GNEW(cnt, edge_t *);
	for (i = 0; i < cnt; i++) {
	    edges[i] = e;
	    e = ED_to_virt(e);
	}
	makeSelfEdge(P, edges, 0, cnt, stepx, stepx, &sinfo);
	for (i = 0; i < cnt; i++) {
	    e = edges[i];
	    if (ED_label(e))
		updateBB(agraphof(agtail(e)), ED_label(e));
	    makePortLabels(e);
	}
	free(edges);
    }
}
Example #3
0
static void map_edge(edge_t * e)
{
    int j, k;
    bezier bz;

    if (ED_spl(e) == NULL) {
	if ((Concentrate == FALSE) && (ED_edge_type(e) != IGNORED))
	    agerr(AGERR, "lost %s %s edge\n", agnameof(agtail(e)),
		  agnameof(aghead(e)));
	return;
    }
    for (j = 0; j < ED_spl(e)->size; j++) {
	bz = ED_spl(e)->list[j];
	for (k = 0; k < bz.size; k++)
	    bz.list[k] = map_point(bz.list[k]);
	if (bz.sflag)
	    ED_spl(e)->list[j].sp = map_point(ED_spl(e)->list[j].sp);
	if (bz.eflag)
	    ED_spl(e)->list[j].ep = map_point(ED_spl(e)->list[j].ep);
    }
    if (ED_label(e))
	ED_label(e)->pos = map_point(ED_label(e)->pos);
    if (ED_xlabel(e))
	ED_xlabel(e)->pos = map_point(ED_xlabel(e)->pos);
    /* vladimir */
    if (ED_head_label(e))
	ED_head_label(e)->pos = map_point(ED_head_label(e)->pos);
    if (ED_tail_label(e))
	ED_tail_label(e)->pos = map_point(ED_tail_label(e)->pos);
}
Example #4
0
static void 
dot_cleanup_edge(edge_t * e)
{
    dot_free_splines(e);
    free_label(ED_label(e));
    memset(&(e->u), 0, sizeof(Agedgeinfo_t));
}
Example #5
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;
}
Example #6
0
QPointF GVEdge::getGVEdgeLabelPosition(QPointF offset)
{
    QPointF position(0,0);

#ifdef USE_LIBGRAPH_NOT_LIBCGRAPH
    position = QPointF(this->gv_edge->u.label->pos.x,
                       this->layout->getGVGraph()->u.bb.UR.y - this->gv_edge->u.label->pos.y);
#else
    qreal a = 0;
    qreal b = 0;
    textlabel_t* edgelabel = ED_label(this->gv_edge);
    if (edgelabel != NULL) {
        a = edgelabel->pos.x;
    } else {
        DBG() << "Warning: edge label doesn't exist in this->gv_edge...";
    }
    //char* l = agget (this->gv_edge, (char*)"label");
    b = (GD_bb(this->layout->getGVGraph()).UR.y - ED_label(this->gv_edge)->pos.y);
    position = QPointF(a,b);
#endif

    position -= offset;
    return position;
}
Example #7
0
static void
attachOrthoEdges (Agraph_t* g, maze* mp, int n_edges, route* route_list, splineInfo *sinfo, epair_t es[], int doLbls)
{
    int irte = 0;
    int i, ipt, npts;
    pointf* ispline = 0;
    int splsz = 0;
    pointf p, p1, q1;
    route rte;
    segment* seg;
    Agedge_t* e;
    textlabel_t* lbl;

    for (; irte < n_edges; irte++) {
	e = es[irte].e;
	p1 = addPoints(ND_coord(agtail(e)), ED_tail_port(e).p);
	q1 = addPoints(ND_coord(aghead(e)), ED_head_port(e).p);

	rte = route_list[irte];
	npts = 1 + 3*rte.n;
	if (npts > splsz) {
		if (ispline) free (ispline);
		ispline = N_GNEW(npts, pointf);
		splsz = npts;
	}
	    
	seg = rte.segs;
	if (seg->isVert) {
		p.x = vtrack(seg, mp);
		p.y = p1.y;
	}
	else {
		p.y = htrack(seg, mp);
		p.x = p1.x;
	}
	ispline[0] = ispline[1] = p;
	ipt = 2;

	for (i = 1;i<rte.n;i++) {
		seg = rte.segs+i;
		if (seg->isVert)
		    p.x = vtrack(seg, mp);
		else
		    p.y = htrack(seg, mp);
		ispline[ipt+2] = ispline[ipt+1] = ispline[ipt] = p;
		ipt += 3;
	}

	if (seg->isVert) {
		p.x = vtrack(seg, mp);
		p.y = q1.y;
	}
	else {
		p.y = htrack(seg, mp);
		p.x = q1.x;
	}
	ispline[ipt] = ispline[ipt+1] = p;
	if (Verbose > 1)
	    fprintf(stderr, "ortho %s %s\n", agnameof(agtail(e)),agnameof(aghead(e)));
	clip_and_install(e, aghead(e), ispline, npts, sinfo);
	if (doLbls && (lbl = ED_label(e)) && !lbl->set)
	    addEdgeLabels(g, e, p1, q1);
    }
    free(ispline);
}
Example #8
0
/* return TRUE if edge has label */
int common_init_edge(edge_t * e)
{
    char *s;
    int html = 0, r = 0;
    struct fontinfo fi;
    struct fontinfo lfi;

    fi.fontname = NULL;
    lfi.fontname = NULL;
    if (E_label && (s = agxget(e, E_label->index)) && (s[0])) {
	r = 1;
	html = aghtmlstr(s);
	if (html)
	    s = strdup(s);
	else
	    s = strdup_and_subst_edge(s, e);
	initFontEdgeAttr(e, &fi);
	ED_label(e) = make_label(html, s,
				 fi.fontsize, fi.fontname, fi.fontcolor,
				 e->tail->graph);
	
#ifdef ENABLE_HTML //maks
	if (html) {
	    if (make_html_label(ED_label(e), e) == 1)
		edgeError(e, "label");
	}
#endif

	GD_has_labels(e->tail->graph) |= EDGE_LABEL;
	ED_label_ontop(e) =
	    mapbool(late_string(e, E_label_float, "false"));
    }


    /* vladimir */
    if (E_headlabel && (s = agxget(e, E_headlabel->index)) && (s[0])) {
	html = aghtmlstr(s);
	if (html)
	    s = strdup(s);
	else
	    s = strdup_and_subst_edge(s, e);
	initFontLabelEdgeAttr(e, &fi, &lfi);
	ED_head_label(e) = make_label(html, s,
				      lfi.fontsize, lfi.fontname,
				      lfi.fontcolor, e->tail->graph);
	
#ifdef ENABLE_HTML //maks
	if (html) {
	    if (make_html_label(ED_head_label(e), e) == 1)
		edgeError(e, "head label");
	}
#endif

	GD_has_labels(e->tail->graph) |= HEAD_LABEL;
    }
    if (E_taillabel && (s = agxget(e, E_taillabel->index)) && (s[0])) {
	html = aghtmlstr(s);
	if (html)
	    s = strdup(s);
	else
	    s = strdup_and_subst_edge(s, e);
	if (!lfi.fontname)
	    initFontLabelEdgeAttr(e, &fi, &lfi);
	ED_tail_label(e) = make_label(html, s,
				      lfi.fontsize, lfi.fontname,
				      lfi.fontcolor, e->tail->graph);

#ifdef ENABLE_HTML //maks
	if (html) {
	    if (make_html_label(ED_tail_label(e), e) == 1)
		edgeError(e, "tail label");
	}
#endif

	GD_has_labels(e->tail->graph) |= TAIL_LABEL;
    }
    /* end vladimir */

    /* We still accept ports beginning with colons but this is deprecated */
    s = agget(e, TAIL_ID);
    if (s[0])
	ND_has_port(e->tail) = TRUE;
    ED_tail_port(e) = chkPort (ND_shape(e->tail)->fns->portfn,e->tail, s);
    if (noClip(e, E_tailclip))
	ED_tail_port(e).clip = FALSE;
    s = agget(e, HEAD_ID);
    if (s[0])
	ND_has_port(e->head) = TRUE;
    ED_head_port(e) = chkPort(ND_shape(e->head)->fns->portfn,e->head, s);
    if (noClip(e, E_headclip))
	ED_head_port(e).clip = FALSE;

    return r;
}
Example #9
0
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, &params);
    if (Verbose)
	printData(objs, n_objs, lbls, n_lbls, &params);

    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);
}
Example #10
0
/* return true if edge has label */
int common_init_edge(edge_t * e)
{
    char *str;
    int r = 0;
    struct fontinfo fi;
    struct fontinfo lfi;
    graph_t *sg = agraphof(agtail(e));

    fi.fontname = NULL;
    lfi.fontname = NULL;
    if (E_label && (str = agxget(e, E_label)) && (str[0])) {
	r = 1;
	initFontEdgeAttr(e, &fi);
	ED_label(e) = make_label((void*)e, str, (aghtmlstr(str) ? LT_HTML : LT_NONE),
				fi.fontsize, fi.fontname, fi.fontcolor);
	GD_has_labels(sg) |= EDGE_LABEL;
	ED_label_ontop(e) =
	    mapbool(late_string(e, E_label_float, "false"));
    }

    if (E_xlabel && (str = agxget(e, E_xlabel)) && (str[0])) {
	if (!fi.fontname)
	    initFontEdgeAttr(e, &fi);
	ED_xlabel(e) = make_label((void*)e, str, (aghtmlstr(str) ? LT_HTML : LT_NONE),
				fi.fontsize, fi.fontname, fi.fontcolor);
	GD_has_labels(sg) |= EDGE_XLABEL;
    }


    /* vladimir */
    if (E_headlabel && (str = agxget(e, E_headlabel)) && (str[0])) {
	initFontLabelEdgeAttr(e, &fi, &lfi);
	ED_head_label(e) = make_label((void*)e, str, (aghtmlstr(str) ? LT_HTML : LT_NONE),
				lfi.fontsize, lfi.fontname, lfi.fontcolor);
	GD_has_labels(sg) |= HEAD_LABEL;
    }
    if (E_taillabel && (str = agxget(e, E_taillabel)) && (str[0])) {
	if (!lfi.fontname)
	    initFontLabelEdgeAttr(e, &fi, &lfi);
	ED_tail_label(e) = make_label((void*)e, str, (aghtmlstr(str) ? LT_HTML : LT_NONE),
				lfi.fontsize, lfi.fontname, lfi.fontcolor);
	GD_has_labels(sg) |= TAIL_LABEL;
    }
    /* end vladimir */

    /* We still accept ports beginning with colons but this is deprecated 
     * That is, we allow tailport = ":abc" as well as the preferred 
     * tailport = "abc".
     */
    str = agget(e, TAIL_ID);
    /* libgraph always defines tailport/headport; libcgraph doesn't */
    if (!str) str = "";
    if (str && str[0])
	ND_has_port(agtail(e)) = TRUE;
    ED_tail_port(e) = chkPort (ND_shape(agtail(e))->fns->portfn, agtail(e), str);
    if (noClip(e, E_tailclip))
	ED_tail_port(e).clip = FALSE;
    str = agget(e, HEAD_ID);
    /* libgraph always defines tailport/headport; libcgraph doesn't */
    if (!str) str = "";
    if (str && str[0])
	ND_has_port(aghead(e)) = TRUE;
    ED_head_port(e) = chkPort(ND_shape(aghead(e))->fns->portfn, aghead(e), str);
    if (noClip(e, E_headclip))
	ED_head_port(e).clip = FALSE;

    return r;
}
Example #11
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;
}
Example #12
0
/* _write_plain:
 */
void write_plain(GVJ_t * job, graph_t * g, FILE * f, bool extend)
{
    int i, j, splinePoints;
    char *tport, *hport;
    node_t *n;
    edge_t *e;
    bezier bz;
    point pt;
    char *lbl;

//    setup_graph(job, g);
    setYInvert(g);
    pt = GD_bb(g).UR;
    fprintf(f, "graph %.3f %.3f %.3f\n", job->zoom, PS2INCH(pt.x), PS2INCH(pt.y));
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (IS_CLUST_NODE(n))
	    continue;
	fprintf(f, "node %s ", agcanonical(n->name));
	printptf(f, ND_coord_i(n));
	if (ND_label(n)->html)   /* if html, get original text */
	    lbl = agxget(n, N_label->index);
	else
	    lbl = ND_label(n)->text;
	if (lbl)
	    lbl = agcanonical(lbl);
	else
	    lbl = "\"\"";
	fprintf(f, " %.3f %.3f %s %s %s %s %s\n",
		ND_width(n), ND_height(n), lbl,
		late_nnstring(n, N_style, "solid"),
		ND_shape(n)->name,
		late_nnstring(n, N_color, DEFAULT_COLOR),
		late_nnstring(n, N_fillcolor, DEFAULT_FILL));
    }
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	    if (extend && e->attr) {
		tport = e->attr[TAILX];
		hport = e->attr[HEADX];
	    } else
		tport = hport = "";
	    if (ED_spl(e)) {
		splinePoints = 0;
		for (i = 0; i < ED_spl(e)->size; i++) {
		    bz = ED_spl(e)->list[i];
		    splinePoints += bz.size;
		}
		fprintf(f, "edge ");
		writenodeandport(f, e->tail, tport);
		fprintf(f, " ");
		writenodeandport(f, e->head, hport);
		fprintf(f, " %d", splinePoints);
		for (i = 0; i < ED_spl(e)->size; i++) {
		    bz = ED_spl(e)->list[i];
		    for (j = 0; j < bz.size; j++)
			printptf(f, bz.list[j]);
		}
	    }
	    if (ED_label(e)) {
		fprintf(f, " %s", agcanonical(ED_label(e)->text));
		printptf(f, ED_label(e)->p);
	    }
	    fprintf(f, " %s %s\n", late_nnstring(e, E_style, "solid"),
		    late_nnstring(e, E_color, DEFAULT_COLOR));
	}
    }
    fprintf(f, "stop\n");
}
Example #13
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;
    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;
}
/* 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;
}
Example #15
0
/* _write_plain:
 */
void write_plain(GVJ_t * job, graph_t * g, FILE * f, boolean extend)
{
    int i, j, splinePoints;
    char *tport, *hport;
    node_t *n;
    edge_t *e;
    bezier bz;
    pointf pt;
    char *lbl;
    char* fillcolor;

    putstr = g->clos->disc.io->putstr;
//    setup_graph(job, g);
    setYInvert(g);
    pt = GD_bb(g).UR;
    printdouble(f, "graph ", job->zoom);
    printdouble(f, " ", PS2INCH(pt.x));
    printdouble(f, " ", PS2INCH(pt.y));
    agputc('\n', f);
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (IS_CLUST_NODE(n))
	    continue;
	printstring(f, "node ", agcanonStr(agnameof(n)));
	printpoint(f, ND_coord(n));
	if (ND_label(n)->html)   /* if html, get original text */
	    lbl = agcanonStr (agxget(n, N_label));
	else
	    lbl = canon(agraphof(n),ND_label(n)->text);
        printdouble(f, " ", ND_width(n));
        printdouble(f, " ", ND_height(n));
        printstring(f, " ", lbl);
	printstring(f, " ", late_nnstring(n, N_style, "solid"));
	printstring(f, " ", ND_shape(n)->name);
	printstring(f, " ", late_nnstring(n, N_color, DEFAULT_COLOR));
	fillcolor = late_nnstring(n, N_fillcolor, "");
        if (fillcolor[0] == '\0')
	    fillcolor = late_nnstring(n, N_color, DEFAULT_FILL);
	printstring(f, " ", fillcolor);
	agputc('\n', f);
    }
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {

	    if (extend) {		//assuming these two attrs have already been created by cgraph
		if (!(tport = agget(e,"tailport")))
		    tport = "";
		if (!(hport = agget(e,"headport")))
		    hport = "";
	    }
	    else
		tport = hport = "";
	    if (ED_spl(e)) {
		splinePoints = 0;
		for (i = 0; i < ED_spl(e)->size; i++) {
		    bz = ED_spl(e)->list[i];
		    splinePoints += bz.size;
		}
		printstring(f, NULL, "edge");
		writenodeandport(f, agtail(e), tport);
		writenodeandport(f, aghead(e), hport);
		printint(f, " ", splinePoints);
		for (i = 0; i < ED_spl(e)->size; i++) {
		    bz = ED_spl(e)->list[i];
		    for (j = 0; j < bz.size; j++)
			printpoint(f, bz.list[j]);
		}
	    }
	    if (ED_label(e)) {
		printstring(f, " ", canon(agraphof(agtail(e)),ED_label(e)->text));
		printpoint(f, ED_label(e)->pos);
	    }
	    printstring(f, " ", late_nnstring(e, E_style, "solid"));
	    printstring(f, " ", late_nnstring(e, E_color, DEFAULT_COLOR));
	    agputc('\n', f);
	}
    }
    agputs("stop\n", f);
}
Example #16
0
SEXP getEdgeLocs(Agraph_t *g) {
    SEXP outList, curCP, curEP, pntList, pntSet, curXY, curLab;
    SEXP epClass, cpClass, xyClass, labClass;
    Agnode_t *node, *head;
    Agedge_t *edge;
    char *tmpString;
    bezier bez;
    int nodes;
    int i,k,l,pntLstEl;
    int curEle = 0;

    epClass = MAKE_CLASS("AgEdge");
    cpClass = MAKE_CLASS("BezierCurve");
    xyClass = MAKE_CLASS("xyPoint");
    labClass = MAKE_CLASS("AgTextLabel");

    /* tmpString is used to convert a char to a char* w/ labels */
    tmpString = (char *)R_alloc(2, sizeof(char));
    if (tmpString == NULL) error("Allocation error in getEdgeLocs");

    PROTECT(outList = allocVector(VECSXP, agnedges(g)));

    nodes = agnnodes(g);
    node = agfstnode(g);

    for (i = 0; i < nodes; i++) {
        edge = agfstout(g, node);
        while (edge != NULL && edge->u.spl != NULL) {
            PROTECT(curEP = NEW_OBJECT(epClass));
            bez = edge->u.spl->list[0];
            PROTECT(pntList = allocVector(VECSXP, ((bez.size-1)/3)));
            pntLstEl = 0;

            /* There are really (bez.size-1)/3 sets of control */
            /* points, with the first set containing teh first 4 */
            /* points, and then every other set starting with the */
            /* last point from the previous set and then the next 3 */
            for (k = 1; k < bez.size; k += 3) {
                PROTECT(curCP = NEW_OBJECT(cpClass));
                PROTECT(pntSet = allocVector(VECSXP, 4));
                for (l = -1; l < 3; l++) {
                    PROTECT(curXY = NEW_OBJECT(xyClass));
                    SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(bez.list[k+l].x));
                    SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(bez.list[k+l].y));
                    SET_ELEMENT(pntSet, l+1, curXY);
                    UNPROTECT(1);
                }
                SET_SLOT(curCP, Rf_install("cPoints"), pntSet);
                SET_ELEMENT(pntList, pntLstEl++, curCP);
                UNPROTECT(2);
            }
            SET_SLOT(curEP, Rf_install("splines"), pntList);
            /* get the sp and ep */
            PROTECT(curXY = NEW_OBJECT(xyClass));
            SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(bez.sp.x));
            SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(bez.sp.y));
            SET_SLOT(curEP, Rf_install("sp"), curXY);
            UNPROTECT(1);
            PROTECT(curXY = NEW_OBJECT(xyClass));
            SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(bez.ep.x));
            SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(bez.ep.y));
            SET_SLOT(curEP, Rf_install("ep"), curXY);
            UNPROTECT(1);

            SET_SLOT(curEP, Rf_install("tail"), Rgraphviz_ScalarStringOrNull(node->name));
            head = edge->head;
            SET_SLOT(curEP, Rf_install("head"), Rgraphviz_ScalarStringOrNull(head->name));

            /* TODO: clean up the use of attrs: dir, arrowhead, arrowtail.
             * the following are for interactive plotting in R-env, not needed
             * for output to files.  The existing codes set "dir"-attr, but use
             * "arrowhead"/"arrowtail" instead.  Quite confusing.
             */
            SET_SLOT(curEP, Rf_install("dir"), Rgraphviz_ScalarStringOrNull(agget(edge, "dir")));
            SET_SLOT(curEP, Rf_install("arrowhead"), Rgraphviz_ScalarStringOrNull(agget(edge, "arrowhead")));
            SET_SLOT(curEP, Rf_install("arrowtail"), Rgraphviz_ScalarStringOrNull(agget(edge, "arrowtail")));
            SET_SLOT(curEP, Rf_install("arrowsize"), Rgraphviz_ScalarStringOrNull(agget(edge, "arrowsize")));

            SET_SLOT(curEP, Rf_install("color"), Rgraphviz_ScalarStringOrNull(agget(edge, "color")));

            /* get lty/lwd info */
            if ( agget(edge, "lty") )
               SET_SLOT(curEP, Rf_install("lty"), Rgraphviz_ScalarStringOrNull(agget(edge, "lty")));

            if ( agget(edge, "lwd") )
               SET_SLOT(curEP, Rf_install("lwd"), Rgraphviz_ScalarStringOrNull(agget(edge, "lwd")));

            /* Get the label information */
            if (edge->u.label != NULL) {
                PROTECT(curLab = NEW_OBJECT(labClass));
                SET_SLOT(curLab, Rf_install("labelText"),
                         Rgraphviz_ScalarStringOrNull(ED_label(edge)->text));
                /* Get the X/Y location of the label */
                PROTECT(curXY = NEW_OBJECT(xyClass));
#if GRAPHVIZ_MAJOR == 2 && GRAPHVIZ_MINOR > 20
                SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(ED_label(edge)->pos.x));
                SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(ED_label(edge)->pos.y));
#else
                SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(edge->u.label->p.x));
                SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(edge->u.label->p.y));
#endif
                SET_SLOT(curLab, Rf_install("labelLoc"), curXY);
                UNPROTECT(1);

                snprintf(tmpString, 2, "%c",ED_label(edge)->u.txt.para->just);
                SET_SLOT(curLab, Rf_install("labelJust"),
                         Rgraphviz_ScalarStringOrNull(tmpString));

                SET_SLOT(curLab, Rf_install("labelWidth"),
                         Rf_ScalarInteger(ED_label(edge)->u.txt.para->width));

                SET_SLOT(curLab, Rf_install("labelColor"),
                         Rgraphviz_ScalarStringOrNull(edge->u.label->fontcolor));

                SET_SLOT(curLab, Rf_install("labelFontsize"), Rf_ScalarReal(edge->u.label->fontsize));

                SET_SLOT(curEP, Rf_install("txtLabel"), curLab);
                UNPROTECT(1);
            }

            SET_ELEMENT(outList, curEle++, curEP);
            UNPROTECT(2);
            edge = agnxtout(g, edge);
        }
        node = agnxtnode(g, node);
    }
    UNPROTECT(1);

    return(outList);
}
Example #17
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;
    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);
}
Example #18
0
void neato_cleanup_edge(edge_t * e)
{
    neato_free_splines(e);
    free_label(ED_label(e));
    memset(&(e->u), 0, sizeof(Agedgeinfo_t));
}
Example #19
0
/* orthoEdges:
 * For edges without position information, construct an orthogonal routing.
 * If doLbls is true, use edge label info when available to guide routing, 
 * and set label pos for those edges for which this info is not available.
 */
void
orthoEdges (Agraph_t* g, int doLbls)
{
    sgraph* sg;
    maze* mp;
    int n_edges;
    route* route_list;
    int i, gstart;
    Agnode_t* n;
    Agedge_t* e;
    snode* sn;
    snode* dn;
    epair_t* es = N_GNEW(agnedges(g), epair_t);
    cell* start;
    cell* dest;
    PointSet* ps;
    textlabel_t* lbl;

    if (Concentrate) 
	ps = newPS();

#ifdef DEBUG
    {
	char* s = agget(g, "odb");
        char c;
	odb_flags = 0;
	if (s && (*s != '\0')) {
	    while ((c = *s++)) {
		switch (c) {
		case 'c' :
		    odb_flags |= ODB_CHANG;     // emit channel graph 
		    break;
		case 'i' :
		    odb_flags |= (ODB_SGRAPH|ODB_IGRAPH);  // emit search graphs
		    break;
		case 'm' :
		    odb_flags |= ODB_MAZE;      // emit maze
		    break;
		case 'r' :
		    odb_flags |= ODB_ROUTE;     // emit routes in maze
		    break;
		case 's' :
		    odb_flags |= ODB_SGRAPH;    // emit search graph 
		    break;
		}
	    }
	}
    }
#endif
    if (doLbls) {
	agerr(AGWARN, "Orthogonal edges do not currently handle edge labels. Try using xlabels.\n");
	doLbls = 0;
    }
    mp = mkMaze (g, doLbls);
    sg = mp->sg;
#ifdef DEBUG
    if (odb_flags & ODB_SGRAPH) emitSearchGraph (stderr, sg);
#endif

    /* store edges to be routed in es, along with their lengths */
    n_edges = 0;
    for (n = agfstnode (g); n; n = agnxtnode(g, n)) {
        for (e = agfstout(g, n); e; e = agnxtout(g,e)) {
	    if ((Nop == 2) && ED_spl(e)) continue;
	    if (Concentrate) {
		int ti = AGID(agtail(e));
		int hi = AGID(aghead(e));
		if (ti <= hi) {
		    if (isInPS (ps,ti,hi)) continue;
		    else addPS (ps,ti,hi);
		}
		else {
		    if (isInPS (ps,hi,ti)) continue;
		    else addPS (ps,hi,ti);
		}
	    }
	    es[n_edges].e = e;
	    es[n_edges].d = edgeLen (e);
	    n_edges++;
	}
    }

    route_list = N_NEW (n_edges, route);

    qsort((char *)es, n_edges, sizeof(epair_t), (qsort_cmpf) edgecmp);

    gstart = sg->nnodes;
    PQgen (sg->nnodes+2);
    sn = &sg->nodes[gstart];
    dn = &sg->nodes[gstart+1];
    for (i = 0; i < n_edges; i++) {
#ifdef DEBUG
	if ((i > 0) && (odb_flags & ODB_IGRAPH)) emitSearchGraph (stderr, sg);
#endif
	e = es[i].e;
        start = CELL(agtail(e));
        dest = CELL(aghead(e));

	if (doLbls && (lbl = ED_label(e)) && lbl->set) {
	}
	else {
	    if (start == dest)
		addLoop (sg, start, dn, sn);
	    else {
       		addNodeEdges (sg, dest, dn);
		addNodeEdges (sg, start, sn);
	    }
       	    if (shortPath (sg, dn, sn)) goto orthofinish;
	}
	    
       	route_list[i] = convertSPtoRoute(sg, sn, dn);
       	reset (sg);
    }
    PQfree ();

    mp->hchans = extractHChans (mp);
    mp->vchans = extractVChans (mp);
    assignSegs (n_edges, route_list, mp);
    if (setjmp(jbuf))
	goto orthofinish;
    assignTracks (n_edges, route_list, mp);
#ifdef DEBUG
    if (odb_flags & ODB_ROUTE) emitGraph (stderr, mp, n_edges, route_list, es);
#endif
    attachOrthoEdges (g, mp, n_edges, route_list, &sinfo, es, doLbls);

orthofinish:
    if (Concentrate)
	freePS (ps);

    for (i=0; i < n_edges; i++)
	free (route_list[i].segs);
    free (route_list);
    freeMaze (mp);
}