static void xdot_end_cluster(GVJ_t * job)
{
    Agraph_t* cluster_g = job->obj->u.sg;

    agxset(cluster_g, xd->g_draw, agxbuse(xbufs[EMIT_CDRAW]));
    if (GD_label(cluster_g))
	agxset(cluster_g, xd->g_l_draw, agxbuse(xbufs[EMIT_CLABEL]));
    penwidth[EMIT_CDRAW] = 1;
    penwidth[EMIT_CLABEL] = 1;
    textflags[EMIT_CDRAW] = 0;
    textflags[EMIT_CLABEL] = 0;
}
static void xdot_end_node(GVJ_t* job)
{
    Agnode_t* n = job->obj->u.n; 
    if (agxblen(xbufs[EMIT_NDRAW]))
	agxset(n, xd->n_draw, agxbuse(xbufs[EMIT_NDRAW]));
    if (agxblen(xbufs[EMIT_NLABEL]))
	agxset(n, xd->n_l_draw, agxbuse(xbufs[EMIT_NLABEL]));
    penwidth[EMIT_NDRAW] = 1;
    penwidth[EMIT_NLABEL] = 1;
    textflags[EMIT_NDRAW] = 0;
    textflags[EMIT_NLABEL] = 0;
}
static void xdot_style (GVJ_t *job)
{
    unsigned char buf0[BUFSIZ];
    char buf [128]; /* enough to hold a double */
    agxbuf xbuf;
    char* p, **s;
    int more;

    agxbinit(&xbuf, BUFSIZ, buf0);

    /* First, check if penwidth state is correct */
    if (job->obj->penwidth != penwidth[job->obj->emit_state]) {
	penwidth[job->obj->emit_state] = job->obj->penwidth;
	agxbput (&xbuf, "setlinewidth(");
	sprintf (buf, "%.3f", job->obj->penwidth);
	xdot_trim_zeros (buf, 0);
	agxbput(&xbuf, buf);
	agxbputc (&xbuf, ')');
        xdot_str (job, "S ", agxbuse(&xbuf));
    }

    /* now process raw style, if any */
    s = job->obj->rawstyle;
    if (!s)
	return;

    while ((p = *s++)) {
	if (streq(p, "filled") || streq(p, "bold") || streq(p, "setlinewidth")) continue;
        agxbput(&xbuf, p);
        while (*p)
            p++;
        p++;
        if (*p) {  /* arguments */
            agxbputc(&xbuf, '(');
            more = 0;
            while (*p) {
                if (more)
                    agxbputc(&xbuf, ',');
                agxbput(&xbuf, p);
                while (*p) p++;
                p++;
                more++;
            }
            agxbputc(&xbuf, ')');
        }
        xdot_str (job, "S ", agxbuse(&xbuf));
    }

    agxbfree(&xbuf);

}
Ejemplo n.º 4
0
static void 
xd_set_style (char **s)
{
    unsigned char buf[BUFSIZ];
    agxbuf xbuf;
    char* p;
    int more;

    agxbinit(&xbuf, BUFSIZ, buf);
    while ((p = *s++)) {
	agxbput(&xbuf, p);
	while (*p)
	    p++;
	p++;
	if (*p) {  /* arguments */
	    agxbputc(&xbuf, '(');
            more = 0;
	    while (*p) {
		if (more)
		    agxbputc(&xbuf, ',');
		agxbput(&xbuf, p);
	        while (*p) p++;
		p++;
		more++;
	    }
	    agxbputc(&xbuf, ')');
	}
	xd_str ("S ", agxbuse(&xbuf));
    }
    agxbfree(&xbuf);
}
Ejemplo n.º 5
0
char *gvUsername(void)
{
    char *user = NULL;
#ifndef MSWIN32
    static int first = 1;
    struct passwd *p;
    if (first) {
	agxbinit(&xb, SMALLBUF, userbuf);
	atexit(cleanup);
	first = 0;
    }
    p = (struct passwd *) getpwuid(getuid());
    if (p) {
	agxbputc(&xb, '(');
	agxbput(&xb, p->pw_name);
	agxbput(&xb, ") ");
#ifdef SVR4
	agxbput(&xb, p->pw_comment);
#else
	agxbput(&xb, p->pw_gecos);
#endif
	user = agxbuse(&xb);
    }
#endif
    if (user == NULL)
	user = "******"; //maks
    return user;
}
Ejemplo n.º 6
0
/* clustNode:
 * Generate a special cluster node representing the end node
 * of an edge to the cluster cg. n is a node whose name is the same
 * as the cluster cg. clg is the subgraph of all of
 * the original nodes, which will be deleted later.
 */
static node_t *clustNode(node_t * n, graph_t * cg, agxbuf * xb,
			 graph_t * clg)
{
    node_t *cn;
    static int idx = 0;
    char num[100];

    agxbput(xb, "__");
    sprintf(num, "%d", idx++);
    agxbput(xb, num);
    agxbputc(xb, ':');
    agxbput(xb, agnameof(cg));

    cn = agnode(agroot(cg), agxbuse(xb), 1);
    agbindrec(cn, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE);

    SET_CLUST_NODE(cn);
	agsubnode(cg,cn,1);
	//aginsert(cg, cn);
	agsubnode(clg,n,1);
	//aginsert(clg, n);

    /* set attributes */
    N_label = setAttr(agraphof(cn), cn, "label", "", N_label);
    N_style = setAttr(agraphof(cn), cn, "style", "invis", N_style);
    N_shape = setAttr(agraphof(cn), cn, "shape", "box", N_shape);
    /* N_width = setAttr (cn->graph, cn, "width", "0.0001", N_width); */

    return cn;
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
/* clustNode:
 * Generate a special cluster node representing the end node
 * of an edge to the cluster cg. n is a node whose name is the same
 * as the cluster cg. clg is the subgraph of all of
 * the original nodes, which will be deleted later.
 */
static node_t *clustNode(node_t * n, graph_t * cg, agxbuf * xb,
			 graph_t * clg)
{
    node_t *cn;
    static int idx = 0;
    char num[100];

    agxbput(xb, "__");
    sprintf(num, "%d", idx++);
    agxbput(xb, num);
    agxbputc(xb, ':');
    agxbput(xb, cg->name);

    cn = agnode(cg->root, agxbuse(xb));
    SET_CLUST_NODE(cn);
    aginsert(cg, cn);
    aginsert(clg, n);

    /* set attributes */
    N_label = setAttr(cn->graph, cn, "label", "", N_label);
    N_style = setAttr(cn->graph, cn, "style", "invis", N_style);
    N_shape = setAttr(cn->graph, cn, "shape", "box", N_shape);
    /* N_width = setAttr (cn->graph, cn, "width", "0.0001", N_width); */

    return cn;
}
Ejemplo n.º 9
0
int htmllex()
{
#ifdef HAVE_EXPAT
    static char *begin_html = "<HTML>";
    static char *end_html = "</HTML>";

    char *s;
    char *endp = 0;
    int len, llen;
    int rv;

    state.tok = 0;
    do {
	if (state.mode == 2)
	    return EOF;
	if (state.mode == 0) {
	    state.mode = 1;
	    s = begin_html;
	    len = strlen(s);
	    endp = 0;
	} else {
	    s = state.ptr;
	    if (*s == '\0') {
		state.mode = 2;
		s = end_html;
		len = strlen(s);
	    } else {
		endp = findNext(s,&state.lb);
		len = endp - s;
	    }
	}
	state.prevtok = state.currtok;
	state.prevtoklen = state.currtoklen;
	state.currtok = s;
	state.currtoklen = len;
	if ((llen = agxblen(&state.lb)))
	    rv = XML_Parse(state.parser, agxbuse(&state.lb),llen, 0);
	else
	    rv = XML_Parse(state.parser, s, len, (len ? 0 : 1));
	if (rv == XML_STATUS_ERROR) {
	    if (!state.error) {
		agerr(AGERR, "%s in line %d \n",
		      XML_ErrorString(XML_GetErrorCode(state.parser)),
		      htmllineno());
		error_context();
		state.error = 1;
		state.tok = T_error;
	    }
	}
	if (endp)
	    state.ptr = endp;
    } while (state.tok == 0);
#if DEBUG
    printTok (state.tok);
#endif
    return state.tok;
#else
    return EOF;
#endif
}
Ejemplo n.º 10
0
/* error_context:
 * Print the last 2 "token"s seen.
 */
static void error_context(void)
{
    agxbclear(state.xb);
    if (state.prevtoklen > 0)
	agxbput_n(state.xb, state.prevtok, state.prevtoklen);
    agxbput_n(state.xb, state.currtok, state.currtoklen);
    agerr(AGPREV, "... %s ...\n", agxbuse(state.xb));
}
Ejemplo n.º 11
0
static void xdot_end_cluster(GVJ_t * job)
{
    Agraph_t* cluster_g = job->obj->u.sg;

#ifndef WITH_CGRAPH
    agxset(cluster_g, xd->g_draw->index, agxbuse(xbufs[EMIT_CDRAW]));
#else /* WITH_CGRAPH */
    agxset(cluster_g, xd->g_draw, agxbuse(xbufs[EMIT_CDRAW]));
#endif /* WITH_CGRAPH */
    if (GD_label(cluster_g))
#ifndef WITH_CGRAPH
	agxset(cluster_g, xd->g_l_draw->index, agxbuse(xbufs[EMIT_CLABEL]));
#else /* WITH_CGRAPH */
	agxset(cluster_g, xd->g_l_draw, agxbuse(xbufs[EMIT_CLABEL]));
#endif /* WITH_CGRAPH */
    penwidth[EMIT_CDRAW] = 1;
    penwidth[EMIT_CLABEL] = 1;
}
Ejemplo n.º 12
0
static void xdot_end_node(GVJ_t* job)
{
    Agnode_t* n = job->obj->u.n; 
    if (agxblen(xbufs[EMIT_NDRAW]))
#ifndef WITH_CGRAPH
	agxset(n, xd->n_draw->index, agxbuse(xbufs[EMIT_NDRAW]));
#else /* WITH_CGRAPH */
	agxset(n, xd->n_draw, agxbuse(xbufs[EMIT_NDRAW]));
#endif /* WITH_CGRAPH */
    if (agxblen(xbufs[EMIT_NLABEL]))
#ifndef WITH_CGRAPH
	agxset(n, xd->n_l_draw->index, agxbuse(xbufs[EMIT_NLABEL]));
#else /* WITH_CGRAPH */
	agxset(n, xd->n_l_draw, agxbuse(xbufs[EMIT_NLABEL]));
#endif /* WITH_CGRAPH */
    penwidth[EMIT_NDRAW] = 1;
    penwidth[EMIT_NLABEL] = 1;
}
Ejemplo n.º 13
0
/* Returns the font corresponding to a Graphviz PS font. 
   AvantGarde-Book may return URW Gothic L, book
   Returns NULL if no appropriate font found.
*/
static char *gv_get_font(availfont_t* gv_af_p,
		  PostscriptAlias * ps_alias, agxbuf* xb, agxbuf *xb2)
{
    char *avail_faces;
    int i;

    for (i = 0; i < GV_FONT_LIST_SIZE; i++) {
	/* Searches the array of available system fonts for the one that
	   corresponds to the current Graphviz PS font name. Sets up the
	   font string with the available font name and the installed font 
	   faces that match what are required by the Graphviz PS font.
	 */
	if (gv_af_p[i].faces && strstr(ps_alias->name, gv_af_p[i].gv_ps_fontname)) {
	    agxbput(xb2, gv_af_p[i].fontname);
	    agxbput(xb2, ", ");
	    avail_faces = get_avail_faces(gv_af_p[i].faces, xb);
	    if (ps_alias->weight) {
		if (strcasestr(avail_faces, ps_alias->weight)) {
		    agxbputc(xb2, ' ');
		    copyUpper(xb2, ps_alias->weight);
		}
	    } else if (strcasestr(avail_faces, "REGULAR")) {
		agxbputc(xb2, ' ');
		agxbput(xb2, "REGULAR");
	    } else if (strstr(avail_faces, "ROMAN")) {
		agxbputc(xb2, ' ');
		agxbput(xb2, "ROMAN");
	    }
	    if (ps_alias->stretch) {
		if (strcasestr(avail_faces, ps_alias->stretch)) {
		    agxbputc(xb2, ' ');
		    copyUpper(xb2, ps_alias->stretch);
		}
	    }
	    if (ps_alias->style) {
		if (strcasestr(avail_faces, ps_alias->style)) {
		    agxbputc(xb2, ' ');
		    copyUpper(xb2, ps_alias->style);
		} else if (!strcasecmp(ps_alias->style, "ITALIC")) {
                    /* try to use ITALIC in place of OBLIQUE & visa versa */
		    if (strcasestr(avail_faces, "OBLIQUE")) {
			agxbputc(xb2, ' ');
			agxbput(xb2, "OBLIQUE");
		    }
		} else if (!strcasecmp(ps_alias->style, "OBLIQUE")) {
		    if (strcasestr(avail_faces, "ITALIC")) {
			agxbputc(xb2, ' ');
			agxbput(xb2, "ITALIC");
		    }
		}
	    }
	    return strdup(agxbuse(xb2));
	}
    }
    return NULL;
}
Ejemplo n.º 14
0
/* Construct the list of font faces */
static char *get_avail_faces(int faces, agxbuf* xb)
{
    int i;
    for (i = 0; i < FACELIST_SZ; i++) {
	if (faces & facelist[i].flag) {
	    agxbput (xb, facelist[i].name); 
	    agxbputc(xb, ' ');
	}
    }
    return agxbuse (xb);
}
static void xdot_end_graph(graph_t* g)
{
    int i;

    if (agxblen(xbufs[EMIT_GDRAW])) {
	if (!xd->g_draw)
	    xd->g_draw = safe_dcl(g, AGRAPH, "_draw_", "");
	agxset(g, xd->g_draw, agxbuse(xbufs[EMIT_GDRAW]));
    }
    if (GD_label(g))
	agxset(g, xd->g_l_draw, agxbuse(xbufs[EMIT_GLABEL]));
    agsafeset (g, "xdotversion", xd->version_s, "");

    for (i = 0; i < NUMXBUFS; i++)
	agxbfree(xbuf+i);
    free (xd);
    penwidth[EMIT_GDRAW] = 1;
    penwidth[EMIT_GLABEL] = 1;
    textflags[EMIT_GDRAW] = 0;
    textflags[EMIT_GLABEL] = 0;
}
static void xdot_end_edge(GVJ_t* job)
{
    Agedge_t* e = job->obj->u.e; 

    if (agxblen(xbufs[EMIT_EDRAW]))
	agxset(e, xd->e_draw, agxbuse(xbufs[EMIT_EDRAW]));
    if (agxblen(xbufs[EMIT_TDRAW]))
	agxset(e, xd->t_draw, agxbuse(xbufs[EMIT_TDRAW]));
    if (agxblen(xbufs[EMIT_HDRAW]))
	agxset(e, xd->h_draw, agxbuse(xbufs[EMIT_HDRAW]));
    if (agxblen(xbufs[EMIT_ELABEL]))
	agxset(e, xd->e_l_draw,agxbuse(xbufs[EMIT_ELABEL]));
    if (agxblen(xbufs[EMIT_TLABEL]))
	agxset(e, xd->tl_draw, agxbuse(xbufs[EMIT_TLABEL]));
    if (agxblen(xbufs[EMIT_HLABEL]))
	agxset(e, xd->hl_draw, agxbuse(xbufs[EMIT_HLABEL]));
    penwidth[EMIT_EDRAW] = 1;
    penwidth[EMIT_ELABEL] = 1;
    penwidth[EMIT_TDRAW] = 1;
    penwidth[EMIT_HDRAW] = 1;
    penwidth[EMIT_TLABEL] = 1;
    penwidth[EMIT_HLABEL] = 1;
    textflags[EMIT_EDRAW] = 0;
    textflags[EMIT_ELABEL] = 0;
    textflags[EMIT_TDRAW] = 0;
    textflags[EMIT_HDRAW] = 0;
    textflags[EMIT_TLABEL] = 0;
    textflags[EMIT_HLABEL] = 0;
}
Ejemplo n.º 17
0
/* stoj:
 * Convert dot string to a valid json string embedded in double quotes.
 */
static char* stoj (char* ins, state_t* sp)
{
    char* s;
    char* input;
    static agxbuf xb;
    unsigned char c;

    if (sp->isLatin)
	input = latin1ToUTF8 (ins);
    else
	input = ins;

    if (xb.buf == NULL)
	agxbinit(&xb, BUFSIZ, NULL);
    for (s = input; (c = *s); s++) {
	switch (c) {
	case '"' :
	    agxbput(&xb, "\\\"");
	    break;
	case '\\' :
	    agxbput(&xb, "\\\\");
	    break;
	case '/' :
	    agxbput(&xb, "\\/");
	    break;
	case '\b' :
	    agxbput(&xb, "\\b");
	    break;
	case '\f' :
	    agxbput(&xb, "\\f");
	    break;
	case '\n' :
	    agxbput(&xb, "\\n");
	    break;
	case '\r' :
	    agxbput(&xb, "\\r");
	    break;
	case '\t' :
	    agxbput(&xb, "\\t");
	    break;
	default :
	    agxbputc(&xb, c);
	    break;
	}
    }
    s = agxbuse(&xb);

    if (sp->isLatin)
	free (input);
    return s;
}
Ejemplo n.º 18
0
static void global_def(agxbuf* xb, char *dcl, int kind,
         attrsym_t * ((*dclfun) (Agraph_t *, int kind, char *, char *)) )
{
    char *p;
    char *rhs = "true";

    attrsym_t *sym;
    if ((p = strchr(dcl, '='))) {
	agxbput_n (xb, dcl, p-dcl);
        rhs = p+1;
    }
    else
	agxbput (xb, dcl);
    sym = dclfun(NULL, kind, agxbuse (xb), rhs);
    sym->fixed = 1;
}
Ejemplo n.º 19
0
/* initAnchor:
 * Save current map values
 * Initialize fields in job->obj pertaining to anchors.
 * In particular, this also sets the output rectangle.
 * If there is something to do, close current anchor if
 * necessary, start the anchor and returns 1.
 * Otherwise, it returns 0.
 *
 * FIX: Should we provide a tooltip if none is set, as is done
 * for nodes, edges, etc. ?
 */
static int
initAnchor (GVJ_t* job, htmlenv_t* env, htmldata_t* data, boxf b, htmlmap_data_t* save,
    int closePrev)
{
    obj_state_t *obj = job->obj;
    int changed;
    char* id;
    static int anchorId;
    int internalId = 0;
    agxbuf xb;
    char intbuf[30];  /* hold 64-bit decimal integer */
    unsigned char buf[SMALLBUF];

    save->url = obj->url; 
    save->tooltip = obj->tooltip;
    save->target = obj->target;
    save->id = obj->id;
    save->explicit_tooltip = obj->explicit_tooltip;
    id = data->id;
    if (!id || !*id) { /* no external id, so use the internal one */
	agxbinit(&xb, SMALLBUF, buf);
	if (!env->objid) {
	    env->objid = strdup (getObjId (job, obj->u.n, &xb));
	    env->objid_set = 1;
	}
	agxbput (&xb, env->objid);
	sprintf (intbuf, "_%d", anchorId++);
	agxbput (&xb, intbuf);
	id = agxbuse (&xb);
	internalId = 1;
    }
    changed = initMapData (job, NULL, data->href, data->title, data->target, id, obj->u.g);
    if (internalId)
	agxbfree (&xb);

    if (changed) {
	if (closePrev && (save->url || save->explicit_tooltip))
	    gvrender_end_anchor(job);
	if (obj->url || obj->explicit_tooltip) {
	    emit_map_rect(job, b);
	    gvrender_begin_anchor(job,
		obj->url, obj->tooltip, obj->target, obj->id);
	}
    }
    return changed;
}
Ejemplo n.º 20
0
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);
}
Ejemplo n.º 21
0
static void xdot_end_edge(GVJ_t* job)
{
    Agedge_t* e = job->obj->u.e; 

    if (agxblen(xbufs[EMIT_EDRAW]))
#ifndef WITH_CGRAPH
	agxset(e, xd->e_draw->index, agxbuse(xbufs[EMIT_EDRAW]));
#else /* WITH_CGRAPH */
	agxset(e, xd->e_draw, agxbuse(xbufs[EMIT_EDRAW]));
#endif /* WITH_CGRAPH */
    if (agxblen(xbufs[EMIT_TDRAW]))
#ifndef WITH_CGRAPH
	agxset(e, xd->t_draw->index, agxbuse(xbufs[EMIT_TDRAW]));
#else /* WITH_CGRAPH */
	agxset(e, xd->t_draw, agxbuse(xbufs[EMIT_TDRAW]));
#endif /* WITH_CGRAPH */
    if (agxblen(xbufs[EMIT_HDRAW]))
#ifndef WITH_CGRAPH
	agxset(e, xd->h_draw->index, agxbuse(xbufs[EMIT_HDRAW]));
#else /* WITH_CGRAPH */
	agxset(e, xd->h_draw, agxbuse(xbufs[EMIT_HDRAW]));
#endif /* WITH_CGRAPH */
    if (agxblen(xbufs[EMIT_ELABEL]))
#ifndef WITH_CGRAPH
	agxset(e, xd->e_l_draw->index,agxbuse(xbufs[EMIT_ELABEL]));
#else /* WITH_CGRAPH */
	agxset(e, xd->e_l_draw,agxbuse(xbufs[EMIT_ELABEL]));
#endif /* WITH_CGRAPH */
    if (agxblen(xbufs[EMIT_TLABEL]))
#ifndef WITH_CGRAPH
	agxset(e, xd->tl_draw->index, agxbuse(xbufs[EMIT_TLABEL]));
#else /* WITH_CGRAPH */
	agxset(e, xd->tl_draw, agxbuse(xbufs[EMIT_TLABEL]));
#endif /* WITH_CGRAPH */
    if (agxblen(xbufs[EMIT_HLABEL]))
#ifndef WITH_CGRAPH
	agxset(e, xd->hl_draw->index, agxbuse(xbufs[EMIT_HLABEL]));
#else /* WITH_CGRAPH */
	agxset(e, xd->hl_draw, agxbuse(xbufs[EMIT_HLABEL]));
#endif /* WITH_CGRAPH */
    penwidth[EMIT_EDRAW] = 1;
    penwidth[EMIT_ELABEL] = 1;
    penwidth[EMIT_TDRAW] = 1;
    penwidth[EMIT_HDRAW] = 1;
    penwidth[EMIT_TLABEL] = 1;
    penwidth[EMIT_HLABEL] = 1;
}
Ejemplo n.º 22
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;
}
static void xdot_gradient_fillcolor (GVJ_t* job, int filled, pointf* A, int n)
{
    unsigned char buf0[BUFSIZ];
    agxbuf xbuf;
    obj_state_t* obj = job->obj;
    float angle = obj->gradient_angle * M_PI / 180;
    float r1,r2;
    pointf G[2],c1,c2;

    if (xd->version < 14) {
	xdot_fillcolor (job);
	return;
    }

    agxbinit(&xbuf, BUFSIZ, buf0);
    if (filled == GRADIENT) {
	get_gradient_points(A, G, n, angle, 2);
	agxbputc (&xbuf, '[');
	xdot_point (&xbuf, G[0]);
	xdot_point (&xbuf, G[1]);
    }
    else {
	get_gradient_points(A, G, n, 0, 3);
	  //r1 is inner radius, r2 is outer radius
	r1 = G[1].x;
	r2 = G[1].y;
	if (angle == 0) {
	    c1.x = G[0].x;
	    c1.y = G[0].y;
	}
	else {
	    c1.x = G[0].x +  (r2/4) * cos(angle);
	    c1.y = G[0].y +  (r2/4) * sin(angle);
	}
	c2.x = G[0].x;
	c2.y = G[0].y;
	r1 = r2/4;
	agxbputc(&xbuf, '(');
	xdot_point (&xbuf, c1);
	xdot_num (&xbuf, r1);
	xdot_point (&xbuf, c2);
	xdot_num (&xbuf, r2);
    }
    
    agxbput(&xbuf, "2 ");
    if (obj->gradient_frac > 0) {
	xdot_color_stop (&xbuf, obj->gradient_frac, &obj->fillcolor);
	xdot_color_stop (&xbuf, obj->gradient_frac, &obj->stopcolor);
    }
    else {
	xdot_color_stop (&xbuf, 0, &obj->fillcolor);
	xdot_color_stop (&xbuf, 1, &obj->stopcolor);
    }
    agxbpop(&xbuf);
    if (filled == GRADIENT)
	agxbputc(&xbuf, ']');
    else
	agxbputc(&xbuf, ')');
    xdot_str (job, "C ", agxbuse(&xbuf));
    agxbfree(&xbuf);
}
Ejemplo n.º 24
0
static boolean pango_textlayout(textspan_t * span, char **fontpath)
{
    static char buf[1024];  /* returned in fontpath, only good until next call */
    static PangoFontMap *fontmap;
    static PangoContext *context;
    static PangoFontDescription *desc;
    static char *fontname;
    static double fontsize;
    static gv_font_map* gv_fmap;
    char *fnt, *psfnt = NULL;
    PangoLayout *layout;
    PangoRectangle logical_rect;
    cairo_font_options_t* options;
    PangoFont *font;
#ifdef ENABLE_PANGO_MARKUP
    PangoAttrList *attrs;
    GError *error = NULL;
    int flags;
#endif
    char *text;
    double textlayout_scale;
    PostscriptAlias *pA;

    if (!context) {
	fontmap = pango_cairo_font_map_new();
	gv_fmap = get_font_mapping(fontmap);
#ifdef HAVE_PANGO_FONT_MAP_CREATE_CONTEXT
	context = pango_font_map_create_context (fontmap);
#else
	context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
#endif
	options=cairo_font_options_create();
	cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY);
	cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON);
	cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR);
	pango_cairo_context_set_font_options(context, options);
	pango_cairo_context_set_resolution(context, FONT_DPI);
	cairo_font_options_destroy(options);
	g_object_unref(fontmap);
    }

    if (!fontname || strcmp(fontname, span->font->name) != 0 || fontsize != span->font->size) {
	fontname = span->font->name;
	fontsize = span->font->size;
	pango_font_description_free (desc);

	pA = span->font->postscript_alias;
	if (pA) {
	    psfnt = fnt = gv_fmap[pA->xfig_code].gv_font;
	    if(!psfnt)
		psfnt = fnt = pango_psfontResolve (pA);
	}
	else
	    fnt = fontname;

	desc = pango_font_description_from_string(fnt);
        /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */
        pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE));

        if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) {  /* -v support */
	    const char *fontclass;

	    fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font));

	    buf[0] = '\0';
	    if (psfnt) {
		strcat(buf, "(ps:pango  ");
		strcat(buf, psfnt);
		strcat(buf, ") ");
	    }
	    strcat(buf, "(");
	    strcat(buf, fontclass);
	    strcat(buf, ") ");
#ifdef HAVE_PANGO_FC_FONT_LOCK_FACE
	    if (strcmp(fontclass, "PangoCairoFcFont") == 0) {
	        FT_Face face;
	        PangoFcFont *fcfont;
	        FT_Stream stream;
	        FT_StreamDesc streamdesc;
	        fcfont = PANGO_FC_FONT(font);
	        face = pango_fc_font_lock_face(fcfont);
	        if (face) {
		    strcat(buf, "\"");
		    strcat(buf, face->family_name);
		    strcat(buf, ", ");
		    strcat(buf, face->style_name);
		    strcat(buf, "\" ");
    
		    stream = face->stream;
		    if (stream) {
			streamdesc = stream->pathname;
			if (streamdesc.pointer)
			    strcat(buf, (char*)streamdesc.pointer);
		        else
			    strcat(buf, "*no pathname available*");
		    }
		    else
			strcat(buf, "*no stream available*");
		}
	        pango_fc_font_unlock_face(fcfont);
	    }
	    else
#endif
	    {
    		PangoFontDescription *tdesc;
		char *tfont;
		
	        tdesc = pango_font_describe(font);
	        tfont = pango_font_description_to_string(tdesc);
	        strcat(buf, "\"");
	        strcat(buf, tfont);
	        strcat(buf, "\" ");
	        g_free(tfont);
	    }
            *fontpath = buf;
        }
    }

#ifdef ENABLE_PANGO_MARKUP
    if ((span->font) && (flags = span->font->flags)) {
	unsigned char buf[BUFSIZ];
	agxbuf xb;

	agxbinit(&xb, BUFSIZ, buf);
	agxbput(&xb,"<span");

	if (flags & HTML_BF)
	    agxbput(&xb," weight=\"bold\"");
	if (flags & HTML_IF)
	    agxbput(&xb," style=\"italic\"");
	if (flags & HTML_UL)
	    agxbput(&xb," underline=\"single\"");
	if (flags & HTML_S)
	    agxbput(&xb," strikethrough=\"true\"");
	agxbput (&xb,">");

	if (flags & HTML_SUP)
	    agxbput(&xb,"<sup>");
	if (flags & HTML_SUB)
	    agxbput(&xb,"<sub>");

	agxbput (&xb,xml_string0(span->str, TRUE));

	if (flags & HTML_SUB)
	    agxbput(&xb,"</sub>");
	if (flags & HTML_SUP)
	    agxbput(&xb,"</sup>");

	agxbput (&xb,"</span>");
	if (!pango_parse_markup (agxbuse(&xb), -1, 0, &attrs, &text, NULL, &error)) {
	    fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message);
	    text = span->str;
	    attrs = NULL;
	}
	agxbfree (&xb);
    }
    else {
	text = span->str;
	attrs = NULL;
    }
#else
    text = span->str;
#endif

    layout = pango_layout_new (context);
    span->layout = (void *)layout;    /* layout free with textspan - see labels.c */
    span->free_layout = pango_free_layout;    /* function for freeing pango layout */

    pango_layout_set_text (layout, text, -1);
    pango_layout_set_font_description (layout, desc);
#ifdef ENABLE_PANGO_MARKUP
    if (attrs)
	pango_layout_set_attributes (layout, attrs);
#endif

    pango_layout_get_extents (layout, NULL, &logical_rect);

    /* if pango doesn't like the font then it sets width=0 but height = garbage */
    if (logical_rect.width == 0)
	logical_rect.height = 0;

    textlayout_scale = POINTS_PER_INCH / (FONT_DPI * PANGO_SCALE);
    span->size.x = (int)(logical_rect.width * textlayout_scale + 1);    /* round up so that width/height are never too small */
    span->size.y = (int)(logical_rect.height * textlayout_scale + 1);

    /* FIXME  -- Horrible kluge !!! */

    /* For now we are using pango for single line blocks only.
     * The logical_rect.height seems to be too high from the font metrics on some platforms.
     * Use an assumed height based on the point size.
     */

    span->size.y = (int)(span->font->size * 1.1 + .5);

    /* The y offset from baseline to 0,0 of the bitmap representation */
#if !defined(WIN32) && defined PANGO_VERSION_MAJOR && (PANGO_VERSION_MAJOR >= 1)
    span->yoffset_layout = pango_layout_get_baseline (layout) * textlayout_scale;
#else
    {
	/* do it the hard way on rhel5/centos5 */
	PangoLayoutIter *iter = pango_layout_get_iter (layout);
	span->yoffset_layout = pango_layout_iter_get_baseline (iter) * textlayout_scale;
    }
#endif

    /* The distance below midline for y centering of text strings */
    span->yoffset_centerline = 0.2 * span->font->size;

    if (logical_rect.width == 0)
	return FALSE;
    return TRUE;
}
Ejemplo n.º 25
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);
}
Ejemplo n.º 26
0
static void xd_end_cluster(void)
{
    agxset(cluster_g, g_draw->index, agxbuse(xbufs[EMIT_CDRAW]));
    if (GD_label(cluster_g))
	agxset(cluster_g, g_l_draw->index, agxbuse(xbufs[EMIT_CLABEL]));
}
Ejemplo n.º 27
0
/* 
 * John M. suggests:
 * You might want to add four more:
 *
 * _ohdraw_ (optional head-end arrow for edges)
 * _ohldraw_ (optional head-end label for edges)
 * _otdraw_ (optional tail-end arrow for edges)
 * _otldraw_ (optional tail-end label for edges)
 * 
 * that would be generated when an additional option is supplied to 
 * dot, etc. and 
 * these would be the arrow/label positions to use if a user want to flip the 
 * direction of an edge (as sometimes is there want).
 * 
 * N.B. John M. asks:
 *   By the way, I don't know if you ever plan to add other letters for 
 * the xdot spec, but could you reserve "a" and also "A" (for  attribute), 
 * "n" and also "N" (for numeric), "w" (for sWitch),  "s" (for string) 
 * and "t" (for tooltip) and "x" (for position). We use  those letters in 
 * our drawing spec (and also "<" and ">"), so if you  start generating 
 * output with them, it could break what we have. 
 */
void extend_attrs(GVJ_t * job, graph_t *g, int s_arrows, int e_arrows)
{
    node_t *n;
    edge_t *e;
    attrsym_t *n_draw = NULL;
    attrsym_t *n_l_draw = NULL;
    attrsym_t *e_draw = NULL;
    attrsym_t *h_draw = NULL;
    attrsym_t *t_draw = NULL;
    attrsym_t *e_l_draw = NULL;
    attrsym_t *hl_draw = NULL;
    attrsym_t *tl_draw = NULL;
    unsigned char buf0[BUFSIZ];
    unsigned char buf1[BUFSIZ];
    unsigned char buf2[BUFSIZ];
    unsigned char buf3[BUFSIZ];
    unsigned char buf4[BUFSIZ];
    unsigned char buf5[BUFSIZ];

    gvc = job->gvc;

    agsafeset (g, "xdotversion", XDOTVERSION, "");
    if (GD_has_labels(g) & GRAPH_LABEL)
	g_l_draw = safe_dcl(g, g, "_ldraw_", "", agraphattr);
    else
	g_l_draw = NULL;
    if (GD_n_cluster(g))
	g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
    else
	g_draw = NULL;

    n_draw = safe_dcl(g, g->proto->n, "_draw_", "", agnodeattr);
    n_l_draw = safe_dcl(g, g->proto->n, "_ldraw_", "", agnodeattr);

    e_draw = safe_dcl(g, g->proto->e, "_draw_", "", agedgeattr);
    if (e_arrows)
	h_draw = safe_dcl(g, g->proto->e, "_hdraw_", "", agedgeattr);
    if (s_arrows)
	t_draw = safe_dcl(g, g->proto->e, "_tdraw_", "", agedgeattr);
    if (GD_has_labels(g) & EDGE_LABEL)
	e_l_draw = safe_dcl(g, g->proto->e, "_ldraw_", "", agedgeattr);
    if (GD_has_labels(g) & HEAD_LABEL)
	hl_draw = safe_dcl(g, g->proto->e, "_hldraw_", "", agedgeattr);
    if (GD_has_labels(g) & TAIL_LABEL)
	tl_draw = safe_dcl(g, g->proto->e, "_tldraw_", "", agedgeattr);

    agxbinit(&xbuf0, BUFSIZ, buf0);
    agxbinit(&xbuf1, BUFSIZ, buf1);
    agxbinit(&xbuf2, BUFSIZ, buf2);
    agxbinit(&xbuf3, BUFSIZ, buf3);
    agxbinit(&xbuf4, BUFSIZ, buf4);
    agxbinit(&xbuf5, BUFSIZ, buf5);

    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (ND_shape(n) && !isInvis(late_string(n, N_style, ""))) {
	    ND_shape(n)->fns->codefn(job, n);
	    agxset(n, n_draw->index, agxbuse(xbufs[EMIT_NDRAW]));
	    agxset(n, n_l_draw->index, agxbuse(xbufs[EMIT_NLABEL]));
	}
	if (State < GVSPLINES)
	    continue;
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	    if (ED_edge_type(e) == IGNORED)
		continue;
	    if (isInvis(late_string(e, E_style, "")))
		continue;
	    if (ED_spl(e) == NULL)
		continue;

	    emit_edge_graphics (job, e);
	    agxset(e, e_draw->index, agxbuse(xbufs[EMIT_EDRAW]));
	    if (t_draw) agxset(e, t_draw->index, agxbuse(xbufs[EMIT_TDRAW]));
	    if (h_draw) agxset(e, h_draw->index, agxbuse(xbufs[EMIT_HDRAW]));
	    if (e_l_draw) agxset(e, e_l_draw->index,agxbuse(xbufs[EMIT_ELABEL]));
	    if (tl_draw) agxset(e, tl_draw->index, agxbuse(xbufs[EMIT_TLABEL]));
	    if (hl_draw) agxset(e, hl_draw->index, agxbuse(xbufs[EMIT_HLABEL]));
	}
    }
  
    emit_background(job, g);
    if (agxblen(xbufs[EMIT_GDRAW])) {
	if (!g_draw)
	    g_draw = safe_dcl(g, g, "_draw_", "", agraphattr);
	agxset(g, g_draw->index, agxbuse(xbufs[EMIT_GDRAW]));
    }
    if (GD_label(g)) {
	emit_label(job, EMIT_GLABEL, GD_label(g), (void *) g);
	agxset(g, g_l_draw->index, agxbuse(xbufs[EMIT_GLABEL]));
    }
    emit_clusters(job, g, 0);
    agxbfree(&xbuf0);
    agxbfree(&xbuf1);
    agxbfree(&xbuf2);
    agxbfree(&xbuf3);
    agxbfree(&xbuf4);
    agxbfree(&xbuf5);
}