void graph_cleanup(graph_t *g) { free(GD_drawing(g)); GD_drawing(g) = NULL; free_label(GD_label(g)); memset(&(g->u), 0, sizeof(Agraphinfo_t)); }
static void init1_gd(GVC_t * gvc, graph_t * g, box bb, point pb) { Dpi = GD_drawing(g)->dpi; if (Dpi < 1.0) Dpi = DEFAULT_DPI; DevScale = Dpi / POINTS_PER_INCH; Viewport.x = gvc->job->width; Viewport.y = gvc->job->height; #if 0 if (Viewport.x) { Zoom = gvc->job->zoom; GraphFocus = gvc->job->focus; } else { Viewport.x = (bb.UR.x - bb.LL.x + 2 * GD_drawing(g)->margin.x) * DevScale + 2; Viewport.y = (bb.UR.y - bb.LL.y + 2 * GD_drawing(g)->margin.y) * DevScale + 2; GraphFocus.x = (GD_bb(g).UR.x - GD_bb(g).LL.x) / 2.; GraphFocus.y = (GD_bb(g).UR.y - GD_bb(g).LL.y) / 2.; Zoom = 1.0; } #else Zoom = gvc->job->zoom; GraphFocus = gvc->job->focus; #endif CompScale = Zoom * DevScale; }
/* doDot: * Assume g has nodes. */ static void doDot (Agraph_t* g) { Agraph_t **ccs; Agraph_t *sg; int ncc; int i; pack_info pinfo; int Pack = getPack(g, -1, CL_OFFSET); pack_mode mode = getPackModeInfo (g, l_undef, &pinfo); getPackInfo(g, l_node, CL_OFFSET, &pinfo); if ((mode == l_undef) && (Pack < 0)) { /* No pack information; use old dot with components * handled during layout */ dotLayout(g); } else { /* fill in default values */ if (mode == l_undef) pinfo.mode = l_node; else if (Pack < 0) Pack = CL_OFFSET; pinfo.margin = Pack; pinfo.fixed = 0; /* components using clusters */ ccs = cccomps(g, &ncc, 0); if (ncc == 1) { dotLayout(g); } else if (GD_drawing(g)->ratio_kind == R_NONE) { pinfo.doSplines = 1; for (i = 0; i < ncc; i++) { sg = ccs[i]; initSubg (sg, g); dotLayout (sg); } attachPos (g); packSubgraphs(ncc, ccs, g, &pinfo); resetCoord (g); } else { /* Not sure what semantics should be for non-trivial ratio * attribute with multiple components. * One possibility is to layout nodes, pack, then apply the ratio * adjustment. We would then have to re-adjust all positions. */ dotLayout(g); } for (i = 0; i < ncc; i++) { free (GD_drawing(ccs[i])); agdelete(g, ccs[i]); } free(ccs); } }
static void initSubg (Agraph_t* sg, Agraph_t* g) { agbindrec(sg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); GD_drawing(sg) = NEW(layout_t); GD_drawing(sg)->quantum = GD_drawing(g)->quantum; GD_drawing(sg)->dpi = GD_drawing(g)->dpi; GD_gvc(sg) = GD_gvc (g); GD_charset(sg) = GD_charset (g); GD_rankdir2(sg) = GD_rankdir2 (g); GD_nodesep(sg) = GD_nodesep(g); GD_ranksep(sg) = GD_ranksep(g); GD_fontnames(sg) = GD_fontnames(g); }
static void gd_begin_graph(graph_t* g, box bb, point pb) { Viewport = GD_drawing(g)->viewport.size; if (Viewport.x) { GraphFocus = GD_drawing(g)->viewport.focus; Zoom = GD_drawing(g)->viewport.zoom; } else { Viewport.x = (bb.UR.x - bb.LL.x + 2*GD_drawing(g)->margin.x) * SCALE + 1; Viewport.y = (bb.UR.y - bb.LL.y + 2*GD_drawing(g)->margin.y) * SCALE + 1; GraphFocus.x = (GD_bb(g).UR.x - GD_bb(g).LL.x) / 2.; GraphFocus.y = (GD_bb(g).UR.y - GD_bb(g).LL.y) / 2.; Zoom = SCALE; } }
/* gvLayout: * Selects layout based on engine and binds it to gvc; * does the layout and sets the graph's bbox. * Return 0 on success. */ int gvLayout(GVC_t *gvc, graph_t *g, const char *engine) { char buf[256]; int rc; rc = gvlayout_select(gvc, engine); if (rc == NO_SUPPORT) { agerr (AGERR, "Layout type: \"%s\" not recognized. Use one of:%s\n", engine, gvplugin_list(gvc, API_layout, engine)); return -1; } if (gvLayoutJobs(gvc, g) == -1) return -1; /* set bb attribute for basic layout. * doesn't yet include margins, scaling or page sizes because * those depend on the renderer being used. */ if (GD_drawing(g)->landscape) sprintf(buf, "%d %d %d %d", ROUND(GD_bb(g).LL.y), ROUND(GD_bb(g).LL.x), ROUND(GD_bb(g).UR.y), ROUND(GD_bb(g).UR.x)); else sprintf(buf, "%d %d %d %d", ROUND(GD_bb(g).LL.x), ROUND(GD_bb(g).LL.y), ROUND(GD_bb(g).UR.x), ROUND(GD_bb(g).UR.y)); agsafeset(g, "bb", buf, ""); return 0; }
/* Render layout in a specified format to an external context */ int gvRenderContext(GVC_t *gvc, graph_t *g, const char *format, void *context) { int rc; GVJ_t *job; g = g->root; /* create a job for the required format */ rc = gvjobs_output_langname(gvc, format); job = gvc->job; if (rc == NO_SUPPORT) { agerr(AGERR, "Format: \"%s\" not recognized. Use one of:%s\n", format, gvplugin_list(gvc, API_device, format)); return -1; } job->output_lang = gvrender_select(job, job->output_langname); if (!GD_drawing(g) && !(job->flags & LAYOUT_NOT_REQUIRED)) { fprintf(stderr, "Layout was not done\n"); return -1; } job->context = context; job->external_context = TRUE; gvRenderJobs(gvc, g); gvrender_end_job(job); gvdevice_finalize(job); gvjobs_delete(gvc); return 0; }
void graph_cleanup(graph_t *g) { if (GD_drawing(g) && GD_drawing(g)->xdots) freeXDot ((xdot*)GD_drawing(g)->xdots); if (GD_drawing(g) && GD_drawing(g)->id) free (GD_drawing(g)->id); free(GD_drawing(g)); GD_drawing(g) = NULL; free_label(GD_label(g)); //FIX HERE , STILL SHALLOW //memset(&(g->u), 0, sizeof(Agraphinfo_t)); agclean(g, AGRAPH,"Agraphinfo_t"); }
/* setRatio: * Checks "ratio" attribute, if any, and sets enum type. */ static void setRatio(graph_t * g) { char *p, c; double ratio; if ((p = agget(g, "ratio")) && ((c = p[0]))) { switch (c) { case 'a': if (streq(p, "auto")) GD_drawing(g)->ratio_kind = R_AUTO; break; case 'c': if (streq(p, "compress")) GD_drawing(g)->ratio_kind = R_COMPRESS; break; case 'e': if (streq(p, "expand")) GD_drawing(g)->ratio_kind = R_EXPAND; break; case 'f': if (streq(p, "fill")) GD_drawing(g)->ratio_kind = R_FILL; break; default: ratio = atof(p); if (ratio > 0.0) { GD_drawing(g)->ratio_kind = R_VALUE; GD_drawing(g)->ratio = ratio; } break; } } }
void tcldot_layout(GVC_t *gvc, Agraph_t * g, char *engine) { char buf[256]; Agsym_t *a; int rc; gvFreeLayout(gvc, g); /* in case previously drawn */ /* support old behaviors if engine isn't specified*/ if (!engine || *engine == '\0') { if (agisdirected(g)) rc = gvlayout_select(gvc, "dot"); else rc = gvlayout_select(gvc, "neato"); } else { if (strcasecmp(engine, "nop") == 0) { Nop = 2; PSinputscale = POINTS_PER_INCH; rc = gvlayout_select(gvc, "neato"); } else { rc = gvlayout_select(gvc, engine); } if (rc == NO_SUPPORT) rc = gvlayout_select(gvc, "dot"); } if (rc == NO_SUPPORT) { fprintf(stderr, "Layout type: \"%s\" not recognized. Use one of:%s\n", engine, gvplugin_list(gvc, API_layout, engine)); return; } gvLayoutJobs(gvc, g); /* set bb attribute for basic layout. * doesn't yet include margins, scaling or page sizes because * those depend on the renderer being used. */ if (GD_drawing(g)->landscape) sprintf(buf, "%d %d %d %d", ROUND(GD_bb(g).LL.y), ROUND(GD_bb(g).LL.x), ROUND(GD_bb(g).UR.y), ROUND(GD_bb(g).UR.x)); else sprintf(buf, "%d %d %d %d", ROUND(GD_bb(g).LL.x), ROUND(GD_bb(g).LL.y), ROUND(GD_bb(g).UR.x), ROUND(GD_bb(g).UR.y)); if (!(a = agattr(g, AGRAPH, "bb", NULL))) a = agattr(g, AGRAPH, "bb", ""); agxset(g, a, buf); }
/* Render layout in a specified format to a malloc'ed string */ int gvRenderData(GVC_t *gvc, graph_t *g, const char *format, char **result, unsigned int *length) { int rc; GVJ_t *job; g = g->root; /* create a job for the required format */ rc = gvjobs_output_langname(gvc, format); job = gvc->job; if (rc == NO_SUPPORT) { agerr(AGERR, "Format: \"%s\" not recognized. Use one of:%s\n", format, gvplugin_list(gvc, API_device, format)); return -1; } job->output_lang = gvrender_select(job, job->output_langname); if (!GD_drawing(g) && !(job->flags & LAYOUT_NOT_REQUIRED)) { fprintf(stderr, "Layout was not done\n"); return -1; } /* page size on Linux, Mac OS X and Windows */ #define OUTPUT_DATA_INITIAL_ALLOCATION 4096 if(!result || !(*result = malloc(OUTPUT_DATA_INITIAL_ALLOCATION))) { agerr(AGERR, "failure malloc'ing for result string"); return -1; } job->output_data = *result; job->output_data_allocated = OUTPUT_DATA_INITIAL_ALLOCATION; job->output_data_position = 0; gvRenderJobs(gvc, g); gvrender_end_job(job); *result = job->output_data; *length = job->output_data_position; gvjobs_delete(gvc); return 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); }
void free_ugraph(graph_t* g) { free(GD_drawing(g)); GD_drawing(g) = NULL; }
void init_ugraph(graph_t *g) { char *p; double xf; static char *rankname[] = {"local","global","none",NULL}; static int rankcode[] = {LOCAL, GLOBAL, NOCLUST, LOCAL}; double X,Y,Z,x,y; 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_drawing(g)->quantum = late_double(g,agfindattr(g,"quantum"),0.0,0.0); GD_drawing(g)->font_scale_adj = 1.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. */ if (UseRankdir) GD_left_to_right(g) = ((p = agget(g,"rankdir")) && streq(p,"LR")); else GD_left_to_right(g) = FALSE; do_graph_label(g); xf = late_double(g,agfindattr(g,"nodesep"),DEFAULT_NODESEP,MIN_NODESEP); GD_nodesep(g) = POINTS(xf); p = late_string(g,agfindattr(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,agfindattr(g,"showboxes"),0,0); Epsilon = .0001 * agnnodes(g); getdoubles2pt(g,"size",&(GD_drawing(g)->size)); getdoubles2pt(g,"page",&(GD_drawing(g)->page)); getdouble(g,"epsilon",&Epsilon); getdouble(g,"nodesep",&Nodesep); getdouble(g,"nodefactor",&Nodefactor); X = Y = Z = x = y = 0.0; if ((p = agget(g,"viewport"))) sscanf(p,"%lf,%lf,%lf,%lf,%lf",&X,&Y,&Z,&x,&y); GD_drawing(g)->viewport.size.x = ROUND(X); /* viewport size in dev units - pixels */ GD_drawing(g)->viewport.size.y = ROUND(Y); GD_drawing(g)->viewport.zoom = Z; /* scaling factor */ GD_drawing(g)->viewport.focus.x = x; /* graph coord of focus - points */ GD_drawing(g)->viewport.focus.y = y; GD_drawing(g)->centered = mapbool(agget(g,"center")); if ((p = agget(g,"rotate"))) GD_drawing(g)->landscape = (atoi(p) == 90); else { /* today we learned the importance of backward compatibilty */ if ((p = agget(g,"orientation"))) GD_drawing(g)->landscape = ((p[0] == 'l') || (p[0] == 'L')); } p = agget(g,"clusterrank"); CL_type = maptoken(p,rankname,rankcode); p = agget(g,"concentrate"); Concentrate = mapbool(p); Nodesep = 1.0; Nodefactor = 1.0; Initial_dist = MYHUGE; }
void initDPI(graph_t * g) { _dpi = GD_drawing(g)->dpi; }