예제 #1
0
static char *nameOf(void *obj, agxbuf * xb)
{
    Agedge_t *ep;
    switch (agobjkind(obj)) {
#ifndef WITH_CGRAPH
    case AGGRAPH:
#else
    case AGRAPH:
#endif
	agxbput(xb, agnameof(((Agraph_t *) obj)));
	break;
    case AGNODE:
	agxbput(xb, agnameof(((Agnode_t *) obj)));
	break;
    case AGEDGE:
	ep = (Agedge_t *) obj;
	agxbput(xb, agnameof(agtail(ep)));
	agxbput(xb, agnameof(aghead(ep)));
	if (agisdirected(agraphof(aghead(ep))))
	    agxbput(xb, "->");
	else
	    agxbput(xb, "--");
	break;
    }
    return agxbuse(xb);
}
예제 #2
0
/* setAttr:
 * Sets object's name attribute to the given value.
 * Creates the attribute if not already set.
 */
static Agsym_t *setAttr(graph_t * g, void *obj, char *name, char *value,
			Agsym_t * ap)
{
    if (ap == NULL) {
	switch (agobjkind(obj)) {
	case AGGRAPH:
	    ap = agraphattr(g, name, "");
	    break;
	case AGNODE:
	    ap = agnodeattr(g, name, "");
	    break;
	case AGEDGE:
	    ap = agedgeattr(g, name, "");
	    break;
	}
    }
    agxset(obj, ap->index, value);
    return ap;
}
예제 #3
0
파일: utils.c 프로젝트: jho1965us/graphviz
/* setAttr:
 * Sets object's name attribute to the given value.
 * Creates the attribute if not already set.
 */
Agsym_t *setAttr(graph_t * g, void *obj, char *name, char *value,
			Agsym_t * ap)
{
    if (ap == NULL) {
	switch (agobjkind(obj)) {
	case AGRAPH:
	    ap = agattr(g, AGRAPH,name, "");
	    break;
	case AGNODE:
	    ap = agattr(g,AGNODE, name, "");
	    break;
	case AGEDGE:
	    ap = agattr(g,AGEDGE, name, "");
	    break;
	}
    }
    agxset(obj, ap, value);
    return ap;
}
예제 #4
0
static int repkeycmp(Dt_t *d, void *arg0, void *arg1, Dtdisc_t *disc)
{
	void *key0 = ((repkey_t*)arg0)->key;
	void *key1 = ((repkey_t*)arg1)->key;
	int		rv;
	switch(agobjkind(key0)) {
	case AGNODE:
		rv = ((Agnode_t*)key0)->id - ((Agnode_t*)key1)->id;
		break;
	case AGEDGE:
		rv = ((Agedge_t*)key0)->id - ((Agedge_t*)key1)->id;
		break;
	case AGRAPH:
		/* in libgraph we don't seem to have graph ids, so use pointer */
		rv = (unsigned long)key0 - (unsigned long) key1;
		break;
	default:
		rv = 0;
	}
	return rv;
}
예제 #5
0
파일: htmltable.c 프로젝트: Chaduke/bah.mod
static char *nameOf(void *obj, agxbuf * xb)
{
    Agedge_t *ep;
    switch (agobjkind(obj)) {
    case AGGRAPH:
	agxbput(xb, ((Agraph_t *) obj)->name);
	break;
    case AGNODE:
	agxbput(xb, ((Agnode_t *) obj)->name);
	break;
    case AGEDGE:
	ep = (Agedge_t *) obj;
	agxbput(xb, ep->tail->name);
	agxbput(xb, ep->head->name);
	if (AG_IS_DIRECTED(ep->tail->graph))
	    agxbput(xb, "->");
	else
	    agxbput(xb, "--");
	break;
    }
    return agxbuse(xb);
}
예제 #6
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;
}
예제 #7
0
/* make_label:
 * Assume str is freshly allocated for this instance, so it
 * can be freed in free_label.
 */
textlabel_t *make_label(void *obj, char *str, int kind, double fontsize, char *fontname, char *fontcolor)
{
    textlabel_t *rv = NEW(textlabel_t);
    graph_t *g = NULL, *sg = NULL;
    node_t *n = NULL;
    edge_t *e = NULL;
        char *s;

    switch (agobjkind(obj)) {
    case AGRAPH:
        sg = (graph_t*)obj;
	g = sg->root;
	break;
    case AGNODE:
        n = (node_t*)obj;
	g = agroot(agraphof(n));
	break;
    case AGEDGE:
        e = (edge_t*)obj;
	g = agroot(agraphof(aghead(e)));
	break;
    }
    rv->fontname = fontname;
    rv->fontcolor = fontcolor;
    rv->fontsize = fontsize;
    rv->charset = GD_charset(g);
    if (kind & LT_RECD) {
	rv->text = strdup(str);
        if (kind & LT_HTML) {
	    rv->html = TRUE;
	}
    }
    else if (kind == LT_HTML) {
	rv->text = strdup(str);
	rv->html = TRUE;
	if (make_html_label(obj, rv)) {
	    switch (agobjkind(obj)) {
	    case AGRAPH:
	        agerr(AGPREV, "in label of graph %s\n",agnameof(sg));
		break;
	    case AGNODE:
	        agerr(AGPREV, "in label of node %s\n", agnameof(n));
		break;
	    case AGEDGE:
		agerr(AGPREV, "in label of edge %s %s %s\n",
		        agnameof(agtail(e)), agisdirected(g)?"->":"--", agnameof(aghead(e)));
		break;
	    }
	}
    }
    else {
        assert(kind == LT_NONE);
	/* This call just processes the graph object based escape sequences. The formatting escape
         * sequences (\n, \l, \r) are processed in make_simple_label. That call also replaces \\ with \.
         */
	rv->text = strdup_and_subst_obj0(str, obj, 0);
        switch (rv->charset) {
	case CHAR_LATIN1:
	    s = latin1ToUTF8(rv->text);
	    break;
	default: /* UTF8 */
	    s = htmlEntityUTF8(rv->text, g);
	    break;
	}
        free(rv->text);
        rv->text = s;
	make_simple_label(GD_gvc(g), rv);
    }
    return rv;
}
예제 #8
0
파일: htmltable.c 프로젝트: Chaduke/bah.mod
/* make_html_label:
 * Return non-zero if problem parsing HTML. In this case, use object name.
 */
int make_html_label(graph_t *g, textlabel_t * lp, void *obj)
{
    int rv;
    int wd2, ht2;
    box box;
    htmllabel_t *lbl;
    htmlenv_t env;

    env.obj = obj;
    switch (agobjkind(obj)) {
    case AGGRAPH:
	env.g = ((Agraph_t *) obj)->root;
	break;
    case AGNODE:
	env.g = ((Agnode_t *) obj)->graph;
	break;
    case AGEDGE:
	env.g = ((Agedge_t *) obj)->head->graph;
	break;
    }
    env.finfo.size = lp->fontsize;
    env.finfo.name = lp->fontname;
    env.finfo.color = lp->fontcolor;

    lbl = parseHTML(lp->text, &rv, GD_charset(env.g));
    if (!lbl) {
	/* Parse of label failed; revert to simple text label */
	agxbuf xb;
	unsigned char buf[SMALLBUF];
	agxbinit(&xb, SMALLBUF, buf);
	lp->html = FALSE;
	lp->text = strdup(nameOf(obj, &xb));
	size_label(env.g, lp);
	agxbfree(&xb);
	return rv;
    }

    if (lbl->kind == HTML_TBL) {
	lbl->u.tbl->data.pencolor = getPenColor(obj);
	rv |= size_html_tbl(g, lbl->u.tbl, NULL, &env);
	wd2 = (lbl->u.tbl->data.box.UR.x + 1) / 2;
	ht2 = (lbl->u.tbl->data.box.UR.y + 1) / 2;
	box = boxof(-wd2, -ht2, wd2, ht2);
	pos_html_tbl(lbl->u.tbl, box, BOTTOM | RIGHT | TOP | LEFT);
	lp->dimen.x = box.UR.x - box.LL.x;
	lp->dimen.y = box.UR.y - box.LL.y;
    } else {
	rv |= size_html_txt(g, lbl->u.txt, &env);
	wd2 = (lbl->u.txt->box.UR.x + 1) / 2;
	ht2 = (lbl->u.txt->box.UR.y + 1) / 2;
	box = boxof(-wd2, -ht2, wd2, ht2);
	lbl->u.txt->box = box;
	lp->dimen.x = box.UR.x - box.LL.x;
	lp->dimen.y = box.UR.y - box.LL.y;
    }

    lp->u.html = lbl;

    /* If the label is a table, replace label text because this may
     * be used for the title and alt fields in image maps.
     */
    if (lbl->kind == HTML_TBL) {
	free (lp->text);
	lp->text = strdup ("<TABLE>");
    }

    return rv;
}
예제 #9
0
/* make_html_label:
 * Return non-zero if problem parsing HTML. In this case, use object name.
 */
int make_html_label(void *obj, textlabel_t * lp)
{
    int rv;
    double wd2, ht2;
    boxf box;
    graph_t *g;
    htmllabel_t *lbl;
    htmlenv_t env;
    char *s;

    env.obj = obj;
    switch (agobjkind(obj)) {
#ifdef WITH_CGRAPH
    case AGRAPH:
#else
    case AGGRAPH:
#endif
        env.g = ((Agraph_t *) obj)->root;
        break;
    case AGNODE:
        env.g = agraphof(((Agnode_t *) obj));
        break;
    case AGEDGE:
        env.g = agraphof(aghead (((Agedge_t *) obj)));
        break;
    }
    g = env.g->root;

    env.finfo.size = lp->fontsize;
    env.finfo.name = lp->fontname;
    env.finfo.color = lp->fontcolor;
    lbl = parseHTML(lp->text, &rv, GD_charset(env.g));
    if (!lbl) {
	/* Parse of label failed; revert to simple text label */
	agxbuf xb;
	unsigned char buf[SMALLBUF];
	agxbinit(&xb, SMALLBUF, buf);
	lp->html = FALSE;
	lp->text = strdup(nameOf(obj, &xb));
	switch (lp->charset) {
	case CHAR_LATIN1:
	    s = latin1ToUTF8(lp->text);
	    break;
	default: /* UTF8 */
	    s = htmlEntityUTF8(lp->text, env.g);
	    break;
	}
	free(lp->text);
	lp->text = s;
	make_simple_label(g, lp);
	agxbfree(&xb);
	return rv;
    }

    if (lbl->kind == HTML_TBL) {
	if (! lbl->u.tbl->data.pencolor && getPenColor(obj))
	    lbl->u.tbl->data.pencolor = strdup(getPenColor(obj));
	rv |= size_html_tbl(g, lbl->u.tbl, NULL, &env);
	wd2 = (lbl->u.tbl->data.box.UR.x + 1) / 2;
	ht2 = (lbl->u.tbl->data.box.UR.y + 1) / 2;
	box = boxfof(-wd2, -ht2, wd2, ht2);
	pos_html_tbl(lbl->u.tbl, box, BOTTOM | RIGHT | TOP | LEFT);
	lp->dimen.x = box.UR.x - box.LL.x;
	lp->dimen.y = box.UR.y - box.LL.y;
    } else {
	rv |= size_html_txt(g, lbl->u.txt, &env);
	wd2 = (lbl->u.txt->box.UR.x + 1) / 2;
	ht2 = (lbl->u.txt->box.UR.y + 1) / 2;
	box = boxfof(-wd2, -ht2, wd2, ht2);
	lbl->u.txt->box = box;
	lp->dimen.x = box.UR.x - box.LL.x;
	lp->dimen.y = box.UR.y - box.LL.y;
    }

    lp->u.html = lbl;

    /* If the label is a table, replace label text because this may
     * be used for the title and alt fields in image maps.
     */
    if (lbl->kind == HTML_TBL) {
	free (lp->text);
	lp->text = strdup ("<TABLE>");
    }

    return rv;
}