Пример #1
0
static void svg_begin_edge(GVJ_t * job)
{
    obj_state_t *obj = job->obj;
    char *ename;

    svg_print_id_class(job, obj->id, NULL, "edge", obj->u.e);
    gvputs(job, ">\n");

    gvputs(job, "<title>");
    ename = strdup_and_subst_obj("\\E", (void *) (obj->u.e));
    gvputs(job, xml_string(ename));
    free(ename);
    gvputs(job, "</title>\n");
}
Пример #2
0
static void svg_begin_edge(GVJ_t * job)
{
    obj_state_t *obj = job->obj;
    char *ename;

    gvputs(job, "<g id=\"");
    gvputs(job, xml_string(obj->id));
    gvputs(job, "\" class=\"edge\">");

    gvputs(job, "<title>");
    ename = strdup_and_subst_obj("\\E", (void *) (obj->u.e));
    gvputs(job, xml_string(ename));
    free(ename);
    gvputs(job, "</title>\n");
}
Пример #3
0
/*
	cgraph requires 

*/
void graph_init(graph_t * g, boolean use_rankdir)
{
    char *p;
    double xf;
    static char *rankname[] = { "local", "global", "none", NULL };
    static int rankcode[] = { LOCAL, GLOBAL, NOCLUST, LOCAL };
    static char *fontnamenames[] = {"gd","ps","svg", NULL};
    static int fontnamecodes[] = {NATIVEFONTS,PSFONTS,SVGFONTS,-1};
    int rankdir;
    GD_drawing(g) = NEW(layout_t);

    /* set this up fairly early in case any string sizes are needed */
    if ((p = agget(g, "fontpath")) || (p = getenv("DOTFONTPATH"))) {
	/* overide GDFONTPATH in local environment if dot
	 * wants its own */
#ifdef HAVE_SETENV
	setenv("GDFONTPATH", p, 1);
#else
	static char *buf = 0;

	buf = grealloc(buf, strlen("GDFONTPATH=") + strlen(p) + 1);
	strcpy(buf, "GDFONTPATH=");
	strcat(buf, p);
	putenv(buf);
#endif
    }

    GD_charset(g) = findCharset (g);

    if (!HTTPServerEnVar) {
	Gvimagepath = agget (g, "imagepath");
	if (!Gvimagepath)
	    Gvimagepath = Gvfilepath;
    }

    GD_drawing(g)->quantum =
	late_double(g, agfindgraphattr(g, "quantum"), 0.0, 0.0);

    /* setting rankdir=LR is only defined in dot,
     * but having it set causes shape code and others to use it. 
     * The result is confused output, so we turn it off unless requested.
     * This effective rankdir is stored in the bottom 2 bits of g->u.rankdir.
     * Sometimes, the code really needs the graph's rankdir, e.g., neato -n
     * with record shapes, so we store the real rankdir in the next 2 bits.
     */
    rankdir = RANKDIR_TB;
    if ((p = agget(g, "rankdir"))) {
	if (streq(p, "LR"))
	    rankdir = RANKDIR_LR;
	else if (streq(p, "BT"))
	    rankdir = RANKDIR_BT;
	else if (streq(p, "RL"))
	    rankdir = RANKDIR_RL;
    }
    if (use_rankdir)
	SET_RANKDIR (g, (rankdir << 2) | rankdir);
    else
	SET_RANKDIR (g, (rankdir << 2));

    xf = late_double(g, agfindgraphattr(g, "nodesep"),
		DEFAULT_NODESEP, MIN_NODESEP);
    GD_nodesep(g) = POINTS(xf);

    p = late_string(g, agfindgraphattr(g, "ranksep"), NULL);
    if (p) {
	if (sscanf(p, "%lf", &xf) == 0)
	    xf = DEFAULT_RANKSEP;
	else {
	    if (xf < MIN_RANKSEP)
		xf = MIN_RANKSEP;
	}
	if (strstr(p, "equally"))
	    GD_exact_ranksep(g) = TRUE;
    } else
	xf = DEFAULT_RANKSEP;
    GD_ranksep(g) = POINTS(xf);

    GD_showboxes(g) = late_int(g, agfindgraphattr(g, "showboxes"), 0, 0);
    p = late_string(g, agfindgraphattr(g, "fontnames"), NULL);
    GD_fontnames(g) = maptoken(p, fontnamenames, fontnamecodes);

    setRatio(g);
    GD_drawing(g)->filled =
	getdoubles2ptf(g, "size", &(GD_drawing(g)->size));
    getdoubles2ptf(g, "page", &(GD_drawing(g)->page));

    GD_drawing(g)->centered = mapbool(agget(g, "center"));

    if ((p = agget(g, "rotate")))
	GD_drawing(g)->landscape = (atoi(p) == 90);
    else if ((p = agget(g, "orientation")))
	GD_drawing(g)->landscape = ((p[0] == 'l') || (p[0] == 'L'));
    else if ((p = agget(g, "landscape")))
	GD_drawing(g)->landscape = mapbool(p);

    p = agget(g, "clusterrank");
    CL_type = maptoken(p, rankname, rankcode);
    p = agget(g, "concentrate");
    Concentrate = mapbool(p);
    State = GVBEGIN;
    EdgeLabelsDone = 0;

    GD_drawing(g)->dpi = 0.0;
    if (((p = agget(g, "dpi")) && p[0])
	|| ((p = agget(g, "resolution")) && p[0]))
	GD_drawing(g)->dpi = atof(p);

    do_graph_label(g);

    Initial_dist = MYHUGE;

    G_ordering = agfindgraphattr(g, "ordering");
    G_gradientangle = agfindgraphattr(g,"gradientangle");
    G_margin = agfindgraphattr(g, "margin");

    /* initialize nodes */
    N_height = agfindnodeattr(g, "height");
    N_width = agfindnodeattr(g, "width");
    N_shape = agfindnodeattr(g, "shape");
    N_color = agfindnodeattr(g, "color");
    N_fillcolor = agfindnodeattr(g, "fillcolor");
    N_style = agfindnodeattr(g, "style");
    N_fontsize = agfindnodeattr(g, "fontsize");
    N_fontname = agfindnodeattr(g, "fontname");
    N_fontcolor = agfindnodeattr(g, "fontcolor");
    N_label = agfindnodeattr(g, "label");
    if (!N_label)
	N_label = agattr(g, AGNODE, "label", NODENAME_ESC);
    N_xlabel = agfindnodeattr(g, "xlabel");
    N_showboxes = agfindnodeattr(g, "showboxes");
    N_penwidth = agfindnodeattr(g, "penwidth");
    N_ordering = agfindnodeattr(g, "ordering");
    N_margin = agfindnodeattr(g, "margin");
    /* attribs for polygon shapes */
    N_sides = agfindnodeattr(g, "sides");
    N_peripheries = agfindnodeattr(g, "peripheries");
    N_skew = agfindnodeattr(g, "skew");
    N_orientation = agfindnodeattr(g, "orientation");
    N_distortion = agfindnodeattr(g, "distortion");
    N_fixed = agfindnodeattr(g, "fixedsize");
    N_imagescale = agfindnodeattr(g, "imagescale");
    N_nojustify = agfindnodeattr(g, "nojustify");
    N_layer = agfindnodeattr(g, "layer");
    N_group = agfindnodeattr(g, "group");
    N_comment = agfindnodeattr(g, "comment");
    N_vertices = agfindnodeattr(g, "vertices");
    N_z = agfindnodeattr(g, "z");
    N_gradientangle = agfindnodeattr(g,"gradientangle");

    /* initialize edges */
    E_weight = agfindedgeattr(g, "weight");
    E_color = agfindedgeattr(g, "color");
    E_fillcolor = agfindedgeattr(g, "fillcolor");
    E_fontsize = agfindedgeattr(g, "fontsize");
    E_fontname = agfindedgeattr(g, "fontname");
    E_fontcolor = agfindedgeattr(g, "fontcolor");
    E_label = agfindedgeattr(g, "label");
    E_xlabel = agfindedgeattr(g, "xlabel");
    E_label_float = agfindedgeattr(g, "labelfloat");
    /* vladimir */
    E_dir = agfindedgeattr(g, "dir");
    E_arrowhead = agfindedgeattr(g, "arrowhead");
    E_arrowtail = agfindedgeattr(g, "arrowtail");
    E_headlabel = agfindedgeattr(g, "headlabel");
    E_taillabel = agfindedgeattr(g, "taillabel");
    E_labelfontsize = agfindedgeattr(g, "labelfontsize");
    E_labelfontname = agfindedgeattr(g, "labelfontname");
    E_labelfontcolor = agfindedgeattr(g, "labelfontcolor");
    E_labeldistance = agfindedgeattr(g, "labeldistance");
    E_labelangle = agfindedgeattr(g, "labelangle");
    /* end vladimir */
    E_minlen = agfindedgeattr(g, "minlen");
    E_showboxes = agfindedgeattr(g, "showboxes");
    E_style = agfindedgeattr(g, "style");
    E_decorate = agfindedgeattr(g, "decorate");
    E_arrowsz = agfindedgeattr(g, "arrowsize");
    E_constr = agfindedgeattr(g, "constraint");
    E_layer = agfindedgeattr(g, "layer");
    E_comment = agfindedgeattr(g, "comment");
    E_tailclip = agfindedgeattr(g, "tailclip");
    E_headclip = agfindedgeattr(g, "headclip");
    E_penwidth = agfindedgeattr(g, "penwidth");

    /* background */
    GD_drawing(g)->xdots = init_xdot (g);

    /* initialize id, if any */

    if ((p = agget(g, "id")) && *p)
	GD_drawing(g)->id = strdup_and_subst_obj(p, g);
}
Пример #4
0
/* 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;
	}
    }
}
Пример #5
0
static void gv_graph_state(GVJ_t *job, graph_t *g)
{
#ifndef WITH_CGRAPH
    int i;
#endif
    int j;
    Agsym_t *a;
    gv_argvlist_t *list;

    list = &(job->selected_obj_type_name);
    j = 0;
    if (g == agroot(g)) {
        if (agisdirected(g))
            gv_argvlist_set_item(list, j++, s_digraph);
        else
            gv_argvlist_set_item(list, j++, s_graph);
    }
    else {
        gv_argvlist_set_item(list, j++, s_subgraph);
    }
    gv_argvlist_set_item(list, j++, agnameof(g));
    list->argc = j;

    list = &(job->selected_obj_attributes);
#ifndef WITH_CGRAPH
    for (i = 0, j = 0; i < dtsize(g->univ->globattr->dict); i++) {
        a = g->univ->globattr->list[i];
#else
    a = NULL;
    while ((a = agnxtattr(g, AGRAPH, a))) {
#endif
        gv_argvlist_set_item(list, j++, a->name);
#ifndef WITH_CGRAPH
        gv_argvlist_set_item(list, j++, agxget(g, a->index));
#else
        gv_argvlist_set_item(list, j++, agxget(g, a));
#endif
        gv_argvlist_set_item(list, j++, (char*)GVATTR_STRING);
    }
    list->argc = j;

    a = agfindgraphattr(g, s_href);
    if (!a)
        a = agfindgraphattr(g, s_URL);
    if (a)
#ifndef WITH_CGRAPH
        job->selected_href = strdup_and_subst_obj(agxget(g, a->index), (void*)g);
#else
        job->selected_href = strdup_and_subst_obj(agxget(g, a), (void*)g);
#endif
}

static void gv_node_state(GVJ_t *job, node_t *n)
{
#ifndef WITH_CGRAPH
    int i;
#endif
    int j;
    Agsym_t *a;
    Agraph_t *g;
    gv_argvlist_t *list;

    list = &(job->selected_obj_type_name);
    j = 0;
    gv_argvlist_set_item(list, j++, s_node);
    gv_argvlist_set_item(list, j++, agnameof(n));
    list->argc = j;

    list = &(job->selected_obj_attributes);
    g = agroot(agraphof(n));
#ifndef WITH_CGRAPH
    for (i = 0, j = 0; i < dtsize(g->univ->nodeattr->dict); i++) {
        a = g->univ->nodeattr->list[i];
#else
    a = NULL;
    while ((a = agnxtattr(g, AGNODE, a))) {
#endif
        gv_argvlist_set_item(list, j++, a->name);
#ifndef WITH_CGRAPH
        gv_argvlist_set_item(list, j++, agxget(n, a->index));
#else
        gv_argvlist_set_item(list, j++, agxget(n, a));
#endif
    }
    list->argc = j;

    a = agfindnodeattr(agraphof(n), s_href);
    if (!a)
        a = agfindnodeattr(agraphof(n), s_URL);
    if (a)
#ifndef WITH_CGRAPH
        job->selected_href = strdup_and_subst_obj(agxget(n, a->index), (void*)n);
#else
        job->selected_href = strdup_and_subst_obj(agxget(n, a), (void*)n);
#endif
}

static void gv_edge_state(GVJ_t *job, edge_t *e)
{
#ifndef WITH_CGRAPH
    int i;
#endif
    int j;
    Agsym_t *a;
    Agraph_t *g;
    gv_argvlist_t *nlist, *alist;

    nlist = &(job->selected_obj_type_name);

    /* only tail, head, and key are strictly identifying properties,
     * but we commonly alse use edge kind (e.g. "->") and tailport,headport
     * in edge names */
    j = 0;
    gv_argvlist_set_item(nlist, j++, s_edge);
    gv_argvlist_set_item(nlist, j++, agnameof(agtail(e)));
    j++; /* skip tailport slot for now */
    gv_argvlist_set_item(nlist, j++, agisdirected(agraphof(agtail(e)))?"->":"--");
    gv_argvlist_set_item(nlist, j++, agnameof(aghead(e)));
    j++; /* skip headport slot for now */
    j++; /* skip key slot for now */
    nlist->argc = j;

    alist = &(job->selected_obj_attributes);
    g = agroot(agraphof(aghead(e)));
#ifndef WITH_CGRAPH
    for (i = 0, j = 0; i < dtsize(g->univ->edgeattr->dict); i++) {
        a = g->univ->edgeattr->list[i];
#else
    a = NULL;
    while ((a = agnxtattr(g, AGEDGE, a))) {
#endif

        /* tailport and headport can be shown as part of the name, but they
         * are not identifying properties of the edge so we
         * also list them as modifyable attributes. */
        if (strcmp(a->name,s_tailport) == 0)
#ifndef WITH_CGRAPH
            gv_argvlist_set_item(nlist, 2, agxget(e, a->index));
#else
            gv_argvlist_set_item(nlist, 2, agxget(e, a));
#endif
        else if (strcmp(a->name,s_headport) == 0)
#ifndef WITH_CGRAPH
            gv_argvlist_set_item(nlist, 5, agxget(e, a->index));
#else
            gv_argvlist_set_item(nlist, 5, agxget(e, a));
#endif

        /* key is strictly an identifying property to distinguish multiple
         * edges between the same node pair.   Its non-writable, so
         * no need to list it as an attribute as well. */
        else if (strcmp(a->name,s_key) == 0) {
#ifndef WITH_CGRAPH
            gv_argvlist_set_item(nlist, 6, agxget(e, a->index));
#else
            gv_argvlist_set_item(nlist, 6, agxget(e, a));
#endif
            continue;
        }

        gv_argvlist_set_item(alist, j++, a->name);
#ifndef WITH_CGRAPH
        gv_argvlist_set_item(alist, j++, agxget(e, a->index));
#else
        gv_argvlist_set_item(alist, j++, agxget(e, a));
#endif
    }
Пример #6
0
static int 
size_html_txt(graph_t *g, htmltxt_t* ftxt, htmlenv_t* env)
{
    double xsize = 0.0; /* width of text block */
    double ysize = 0.0; /* height of text block */
    double fsize;
    double lsize;    /* height of current line */
    double mxfsize;  /* max. font size for the current line */
    double curbline = 0; /* dist. of current base line from top */
    pointf sz;
    int i, j, w, width;
    char *fname;
    textpara_t lp;

    for (i = 0; i < ftxt->nparas; i++) {
	width = w = 0;
	mxfsize = 0;
	for (j = 0; j < ftxt->paras[i].nitems; j++) {
	    lp.str = strdup_and_subst_obj (ftxt->paras[i].items[j].str, env->obj);
	    if (ftxt->paras[i].items[j].font) {
		if (ftxt->paras[i].items[j].font->size > 0)
		    fsize = ftxt->paras[i].items[j].font->size;
		else
		    fsize = env->finfo.size;
		if (ftxt->paras[i].items[j].font->name)
		    fname = ftxt->paras[i].items[j].font->name;
		else
		    fname = env->finfo.name;
	    } else {
		fsize = env->finfo.size;
		fname = env->finfo.name;
	    }
	    sz = textsize(g, &lp, fname, fsize);
	    free (ftxt->paras[i].items[j].str);
	    ftxt->paras[i].items[j].str = lp.str;
	    ftxt->paras[i].items[j].size = sz.x;
	    ftxt->paras[i].items[j].xshow = lp.xshow;
	    ftxt->paras[i].items[j].postscript_alias = lp.postscript_alias;
	    ftxt->paras[i].items[j].layout = lp.layout;
	    ftxt->paras[i].items[j].free_layout = lp.free_layout;
	    width += sz.x;
	    mxfsize = MAX(fsize, mxfsize);
	}
	lsize = mxfsize * LINESPACING;
	ftxt->paras[i].size = (double) width;
	    /* ysize - curbline is the distance from the previous
	     * baseline to the bottom of the previous line.
	     * Then, in the current line, we set the baseline to
	     * be 5/6 of the max. font size. Thus, lfsize gives the
	     * distance from the previous baseline to the new one.
	     */
	ftxt->paras[i].lfsize = 5*mxfsize/6 + ysize - curbline;
	curbline += ftxt->paras[i].lfsize;
	xsize = MAX(width, xsize);
	ysize += lsize;
    }
    ftxt->box.UR.x = xsize;
    if (ftxt->nparas == 1)
	ftxt->box.UR.y = (int) (mxfsize);
    else
	ftxt->box.UR.y = (int) (ysize);
    return 0;
}