From: ellson Date: Mon, 6 Mar 2006 19:04:31 +0000 (+0000) Subject: Split GVC_t into GVC_t and GVG_t. X-Git-Tag: LAST_LIBGRAPH~32^2~6757 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=946f9c8a122a21af28f8708905c9a42128027515;p=graphviz Split GVC_t into GVC_t and GVG_t. GVG_t is a new struct to support multiple different graphs open at the same time. GVC_t contains the context for all graphs, e.g. plugins. GVG_t contains the context for a single graph GVJ_t contains teh context for a single rendering of a single graph --- diff --git a/cmd/dot/dot.c b/cmd/dot/dot.c index d0b94cf26..79bd29b78 100644 --- a/cmd/dot/dot.c +++ b/cmd/dot/dot.c @@ -168,7 +168,7 @@ int main(int argc, char **argv) } assert(0); /* should never exit loop */ } else { - while ((G = next_input_graph())) { + while ((G = gvNextInputGraph(Gvc))) { if (prev) { gvFreeLayout(Gvc, prev); agclose(prev); diff --git a/lib/common/arrows.c b/lib/common/arrows.c index 897233eee..44713a88d 100644 --- a/lib/common/arrows.c +++ b/lib/common/arrows.c @@ -549,13 +549,13 @@ void arrow_newgen(GVJ_t * job, int state, pointf p, pointf u, double scale, int int f; int oldstate; - oldstate = job->gvc->emit_state; - job->gvc->emit_state = state; + oldstate = job->gvg->emit_state; + job->gvg->emit_state = state; /* Dotted and dashed styles on the arrowhead are ugly (dds) */ /* linewidth needs to be reset */ gvrender_begin_context(job); - gvrender_set_style(job, job->gvc->defaultlinestyle); + gvrender_set_style(job, job->gvg->defaultlinestyle); /* generate arrowhead vector */ u.x -= p.x; @@ -578,7 +578,7 @@ void arrow_newgen(GVJ_t * job, int state, pointf p, pointf u, double scale, int gvrender_end_context(job); - job->gvc->emit_state = oldstate; + job->gvg->emit_state = oldstate; } /* FIXME emit.c and output.c require wrapper for int point coords */ diff --git a/lib/common/diagen.c b/lib/common/diagen.c index b7c31c0ec..3812e6f37 100644 --- a/lib/common/diagen.c +++ b/lib/common/diagen.c @@ -264,7 +264,7 @@ static void dia_end_job(void) { } -static void dia_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void dia_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { Rootgraph = g; PB.LL.x = PB.LL.y = 0; diff --git a/lib/common/emit.c b/lib/common/emit.c index 6204aa8d7..fe0b88a10 100644 --- a/lib/common/emit.c +++ b/lib/common/emit.c @@ -27,38 +27,38 @@ int emitState; /* parse_layers: * Split input string into tokens, with separators specified by - * the layersep attribute. Store the values in the gvc->layerIDs array, + * the layersep attribute. Store the values in the gvg->layerIDs array, * starting at index 1, and return the count. * Free previously stored list. Note that there is no mechanism * to free the memory before exit. */ -static int parse_layers(GVC_t *gvc, graph_t * g, char *p) +static int parse_layers(GVG_t *gvg, graph_t * g, char *p) { int ntok; char *tok; int sz; - gvc->layerDelims = agget(g, "layersep"); - if (!gvc->layerDelims) - gvc->layerDelims = DEFAULT_LAYERSEP; + gvg->layerDelims = agget(g, "layersep"); + if (!gvg->layerDelims) + gvg->layerDelims = DEFAULT_LAYERSEP; ntok = 0; sz = 0; - gvc->layers = strdup(p); + gvg->layers = strdup(p); - for (tok = strtok(gvc->layers, gvc->layerDelims); tok; - tok = strtok(NULL, gvc->layerDelims)) { + for (tok = strtok(gvg->layers, gvg->layerDelims); tok; + tok = strtok(NULL, gvg->layerDelims)) { ntok++; if (ntok > sz) { sz += SMALLBUF; - gvc->layerIDs = ALLOC(sz, gvc->layerIDs, char *); + gvg->layerIDs = ALLOC(sz, gvg->layerIDs, char *); } - gvc->layerIDs[ntok] = tok; + gvg->layerIDs[ntok] = tok; } if (ntok) { - gvc->layerIDs = RALLOC(ntok + 2, gvc->layerIDs, char *); /* shrink to minimum size */ - gvc->layerIDs[0] = NULL; - gvc->layerIDs[ntok + 1] = NULL; + gvg->layerIDs = RALLOC(ntok + 2, gvg->layerIDs, char *); /* shrink to minimum size */ + gvg->layerIDs[0] = NULL; + gvg->layerIDs[ntok + 1] = NULL; } return ntok; @@ -121,27 +121,27 @@ static void init_job_flags(GVJ_t * job, graph_t * g) } } -static void init_layering(GVC_t * gvc, graph_t * g) +static void init_layering(GVG_t * gvg, graph_t * g) { char *str; /* free layer strings and pointers from previous graph */ - if (gvc->layers) - free(gvc->layers); - if (gvc->layerIDs) - free(gvc->layerIDs); + if (gvg->layers) + free(gvg->layers); + if (gvg->layerIDs) + free(gvg->layerIDs); if ((str = agget(g, "layers")) != 0) { - gvc->numLayers = parse_layers(gvc, g, str); + gvg->numLayers = parse_layers(gvg, g, str); } else { - gvc->layerIDs = NULL; - gvc->numLayers = 1; + gvg->layerIDs = NULL; + gvg->numLayers = 1; } } static void firstlayer(GVJ_t *job) { - job->numLayers = job->gvc->numLayers; + job->numLayers = job->gvg->numLayers; if ((job->numLayers > 1) && (! (gvrender_features(job) & GVRENDER_DOES_LAYERS))) { agerr(AGWARN, "layers not supported in %s output\n", @@ -187,7 +187,7 @@ static point pagecode(GVJ_t *job, char c) static void init_job_pagination(GVJ_t * job, graph_t *g) { - GVC_t *gvc = job->gvc; + GVG_t *gvg = job->gvg; point pageSize; /* page size for the graph - device units */ point imageSize; /* image size on one page of the graph - device units */ point margin; /* margin for a page of the graph - device units */ @@ -199,10 +199,10 @@ static void init_job_pagination(GVJ_t * job, graph_t *g) imageSize = exch_xy(imageSize); /* determine pagination */ - if (gvc->graph_sets_pageSize) { + if (gvg->graph_sets_pageSize) { /* page was set by user */ - pageSize.x = ROUND(gvc->pageSize.x * job->dpi.x / POINTS_PER_INCH); - pageSize.y = ROUND(gvc->pageSize.y * job->dpi.y / POINTS_PER_INCH); + pageSize.x = ROUND(gvg->pageSize.x * job->dpi.x / POINTS_PER_INCH); + pageSize.y = ROUND(gvg->pageSize.y * job->dpi.y / POINTS_PER_INCH); /* we don't want graph page to exceed its bounding box */ pageSize.x = MIN(pageSize.x, imageSize.x); @@ -267,13 +267,13 @@ fprintf(stderr,"margin = %d,%d imageSize = %d,%d boundingBox = %d,%d %d,%d\n", job->pagesArrayMajor.x = job->pagesArrayMajor.y = job->pagesArrayMinor.x = job->pagesArrayMinor.y = 0; job->pagesArrayFirst.x = job->pagesArrayFirst.y = 0; - job->pagesArrayMajor = pagecode(job, gvc->pagedir[0]); - job->pagesArrayMinor = pagecode(job, gvc->pagedir[1]); + job->pagesArrayMajor = pagecode(job, gvg->pagedir[0]); + job->pagesArrayMinor = pagecode(job, gvg->pagedir[1]); if ((abs(job->pagesArrayMajor.x + job->pagesArrayMinor.x) != 1) || (abs(job->pagesArrayMajor.y + job->pagesArrayMinor.y) != 1)) { job->pagesArrayMajor = pagecode(job, 'B'); job->pagesArrayMinor = pagecode(job, 'L'); - agerr(AGWARN, "pagedir=%s ignored\n", gvc->pagedir); + agerr(AGWARN, "pagedir=%s ignored\n", gvg->pagedir); } #if 0 @@ -294,7 +294,7 @@ fprintf(stderr,"width,height = %d,%d (device units)\n", job->width, job->height); fprintf (stderr,"pagedir = %s, pagesArrayMajor = %d,%d pagesArrayMinor = %d,%d\n", - gvc->pagedir, + gvg->pagedir, job->pagesArrayMajor.x, job->pagesArrayMajor.y, job->pagesArrayMinor.x, @@ -456,25 +456,24 @@ static bool is_natural_number(char *sstr) return TRUE; } -static int layer_index(GVC_t *gvc, char *str, int all) +static int layer_index(GVG_t *gvg, char *str, int all) { - GVJ_t *job = gvc->job; int i; if (streq(str, "all")) return all; if (is_natural_number(str)) return atoi(str); - if (gvc->layerIDs) - for (i = 1; i <= job->numLayers; i++) - if (streq(str, gvc->layerIDs[i])) + if (gvg->layerIDs) + for (i = 1; i <= gvg->numLayers; i++) + if (streq(str, gvg->layerIDs[i])) return i; return -1; } static bool selectedlayer(GVJ_t *job, char *spec) { - GVC_t *gvc = job->gvc; + GVG_t *gvg = job->gvg; int n0, n1; unsigned char buf[SMALLBUF]; char *w0, *w1; @@ -483,20 +482,20 @@ static bool selectedlayer(GVJ_t *job, char *spec) agxbinit(&xb, SMALLBUF, buf); agxbput(&xb, spec); - w1 = w0 = strtok(agxbuse(&xb), gvc->layerDelims); + w1 = w0 = strtok(agxbuse(&xb), gvg->layerDelims); if (w0) - w1 = strtok(NULL, gvc->layerDelims); + w1 = strtok(NULL, gvg->layerDelims); switch ((w0 != NULL) + (w1 != NULL)) { case 0: rval = FALSE; break; case 1: - n0 = layer_index(gvc, w0, job->layerNum); + n0 = layer_index(gvg, w0, job->layerNum); rval = (n0 == job->layerNum); break; case 2: - n0 = layer_index(gvc, w0, 0); - n1 = layer_index(gvc, w1, job->numLayers); + n0 = layer_index(gvg, w0, 0); + n1 = layer_index(gvg, w1, job->numLayers); if ((n0 < 0) || (n1 < 0)) rval = TRUE; else if (n0 > n1) { @@ -580,18 +579,18 @@ static bool node_in_box(node_t *n, boxf b) static void emit_node(GVJ_t * job, node_t * n) { - GVC_t *gvc = job->gvc; + GVG_t *gvg = job->gvg; char *s, *url = NULL, *tooltip = NULL, *target = NULL; int oldstate, explicit_tooltip = 0; if (ND_shape(n) == NULL) return; - oldstate = gvc->emit_state; - gvc->emit_state = EMIT_NDRAW; + oldstate = gvg->emit_state; + gvg->emit_state = EMIT_NDRAW; if (node_in_layer(job, n->graph, n) && node_in_box(n, job->pageBoxClip) - && (ND_state(n) != gvc->viewNum)) { + && (ND_state(n) != gvg->viewNum)) { gvrender_comment(job, n->name); @@ -619,7 +618,7 @@ static void emit_node(GVJ_t * job, node_t * n) setColorScheme (agget (n, "colorscheme")); gvrender_begin_context(job); ND_shape(n)->fns->codefn(job, n); - ND_state(n) = gvc->viewNum; + ND_state(n) = gvg->viewNum; gvrender_end_context(job); if (url || explicit_tooltip) @@ -629,7 +628,7 @@ static void emit_node(GVJ_t * job, node_t * n) free(target); gvrender_end_node(job); } - gvc->emit_state = oldstate; + gvg->emit_state = oldstate; } #define EPSILON .0001 @@ -686,7 +685,7 @@ static void emit_attachment(GVJ_t * job, textlabel_t * lp, splines * spl) A[1] = pointof(A[0].x - sz.x, A[0].y); A[2] = dotneato_closest(spl, lp->p); /* Don't use edge style to draw attachment */ - gvrender_set_style(job, job->gvc->defaultlinestyle); + gvrender_set_style(job, job->gvg->defaultlinestyle); /* Use font color to draw attachment - need something unambiguous in case of multicolored parallel edges - defaults to black for html-like labels @@ -754,8 +753,8 @@ void emit_edge_graphics(GVJ_t * job, edge_t * e) #define SEP 2.0 - oldstate = job->gvc->emit_state; - job->gvc->emit_state = EMIT_EDRAW; + oldstate = job->gvg->emit_state; + job->gvg->emit_state = EMIT_EDRAW; style = late_string(e, E_style, ""); /* We shortcircuit drawing an invisible edge because the arrowhead * code resets the style to solid, and most of the code generators @@ -953,7 +952,7 @@ void emit_edge_graphics(GVJ_t * job, edge_t * e) if (saved) gvrender_end_context(job); - job->gvc->emit_state = oldstate; + job->gvg->emit_state = oldstate; } static bool edge_in_box(edge_t *e, boxf b) @@ -981,8 +980,8 @@ static void emit_edge(GVJ_t * job, edge_t * e) if (! edge_in_box(e, job->pageBoxClip) || ! edge_in_layer(job, e->head->graph, e)) return; - oldstate = job->gvc->emit_state; - job->gvc->emit_state = EMIT_EDRAW; + oldstate = job->gvg->emit_state; + job->gvg->emit_state = EMIT_EDRAW; s = malloc(strlen(e->tail->name) + 2 + strlen(e->head->name) + 1); strcpy(s,e->tail->name); if (AG_IS_DIRECTED(e->tail->graph)) @@ -1019,77 +1018,77 @@ static void emit_edge(GVJ_t * job, edge_t * e) free(tooltip); free(target); gvrender_end_edge(job); - job->gvc->emit_state = oldstate; + job->gvg->emit_state = oldstate; } -static void init_gvc(GVC_t * gvc, graph_t * g) +static void init_gvg(GVG_t * gvg, graph_t * g) { double xf, yf; char *p; int i; - - gvc->g = g; + + gvg->g = g; /* margins */ - gvc->graph_sets_margin = FALSE; + gvg->graph_sets_margin = FALSE; if ((p = agget(g, "margin"))) { i = sscanf(p, "%lf,%lf", &xf, &yf); if (i > 0) { - gvc->margin.x = gvc->margin.y = xf * POINTS_PER_INCH; + gvg->margin.x = gvg->margin.y = xf * POINTS_PER_INCH; if (i > 1) - gvc->margin.y = yf * POINTS_PER_INCH; - gvc->graph_sets_margin = TRUE; + gvg->margin.y = yf * POINTS_PER_INCH; + gvg->graph_sets_margin = TRUE; } } /* pagesize */ - gvc->graph_sets_pageSize = FALSE; - P2PF(GD_drawing(g)->page, gvc->pageSize); + gvg->graph_sets_pageSize = FALSE; + P2PF(GD_drawing(g)->page, gvg->pageSize); if ((GD_drawing(g)->page.x > 0) && (GD_drawing(g)->page.y > 0)) { - gvc->graph_sets_pageSize = TRUE; + gvg->graph_sets_pageSize = TRUE; } /* rotation */ if (GD_drawing(g)->landscape) { - gvc->rotation = 90; + gvg->rotation = 90; /* we expect the user to have swapped x,y coords of pagesize and margin */ - gvc->pageSize = exch_xyf(gvc->pageSize); - gvc->margin = exch_xyf(gvc->margin); + gvg->pageSize = exch_xyf(gvg->pageSize); + gvg->margin = exch_xyf(gvg->margin); } else { - gvc->rotation = 0; + gvg->rotation = 0; } /* pagedir */ - gvc->pagedir = "BL"; + gvg->pagedir = "BL"; if ((p = agget(g, "pagedir")) && p[0]) - gvc->pagedir = p; + gvg->pagedir = p; /* bounding box */ - B2BF(GD_bb(g),gvc->bb); + B2BF(GD_bb(g),gvg->bb); /* clusters have peripheries */ G_peripheries = agfindattr(g, "peripheries"); /* default font */ - gvc->defaultfontname = late_nnstring(g->proto->n, + gvg->defaultfontname = late_nnstring(g->proto->n, N_fontname, DEFAULT_FONTNAME); - gvc->defaultfontsize = late_double(g->proto->n, + gvg->defaultfontsize = late_double(g->proto->n, N_fontsize, DEFAULT_FONTSIZE, MIN_FONTSIZE); /* default line style */ - gvc->defaultlinestyle = defaultlinestyle; + gvg->defaultlinestyle = defaultlinestyle; - gvc->graphname = g->name; - gvc->lib = Lib; + gvg->graphname = g->name; + gvg->lib = Lib; } static void init_job_margin(GVJ_t *job) { - GVC_t *gvc = job->gvc; + GVG_t *gvg = job->gvg; - if (gvc->graph_sets_margin) { - job->margin = gvc->margin; + if (gvg->graph_sets_margin) { + job->margin = gvg->margin; } else { /* set default margins depending on format */ @@ -1186,7 +1185,7 @@ static void init_job_viewport(GVJ_t * job, graph_t * g) job->zoom = Z; /* scaling factor */ job->focus.x = x; /* graph coord of focus - points */ job->focus.y = y; - job->rotation = job->gvc->rotation; + job->rotation = job->gvg->rotation; #if 0 fprintf(stderr,"bb = %d,%d %d,%d size %d,%d (graph units)\n", @@ -1250,13 +1249,13 @@ static void emit_colors(GVJ_t * job, graph_t * g) void emit_view(GVJ_t * job, graph_t * g, int flags) { - GVC_t * gvc = job->gvc; + GVG_t * gvg = job->gvg; node_t *n; edge_t *e; char *s, *url = NULL, *tooltip = NULL, *target = NULL; int explicit_tooltip = 0; - gvc->viewNum++; + gvg->viewNum++; if (((s = agget(g, "href")) && s[0]) || ((s = agget(g, "URL")) && s[0])) url = strdup_and_subst_graph(s, g); if ((s = agget(g, "target")) && s[0]) @@ -1338,7 +1337,7 @@ void emit_graph(GVJ_t * job, graph_t * g) node_t *n; char *s; int flags = job->flags; - GVC_t *gvc = job->gvc; + GVG_t *gvg = job->gvg; s = late_string(g, agfindattr(g, "comment"), ""); gvrender_comment(job, s); @@ -1361,7 +1360,7 @@ void emit_graph(GVJ_t * job, graph_t * g) if (job->numLayers == 1) emit_background(job, g); gvrender_set_pencolor(job, DEFAULT_COLOR); - gvrender_set_font(job, gvc->defaultfontname, gvc->defaultfontsize); + gvrender_set_font(job, gvg->defaultfontname, gvg->defaultfontsize); if (boxf_overlap(job->clip, job->pageBox)) emit_view(job,g,flags); } @@ -1416,10 +1415,10 @@ void emit_jobs_eof(GVC_t * gvc) for (job = gvrender_first_job(gvc); job; job = gvrender_next_job(gvc)) { if (job->output_file) { - if (gvc->viewNum > 0) { + if (job->gvg->viewNum > 0) { gvrender_end_job(job); emit_once_reset(); - gvc->viewNum = 0; + job->gvg->viewNum = 0; } fclose(job->output_file); job->output_file = NULL; @@ -1468,8 +1467,8 @@ void emit_clusters(GVJ_t * job, Agraph_t * g, int flags) char *s, *url, *tooltip, *target; int oldstate, explicit_tooltip; - oldstate = job->gvc->emit_state; - job->gvc->emit_state = EMIT_CDRAW; + oldstate = job->gvg->emit_state; + job->gvg->emit_state = EMIT_CDRAW; for (c = 1; c <= GD_n_cluster(g); c++) { sg = GD_clust(g)[c]; if (clust_in_layer(job, sg) == FALSE) @@ -1588,7 +1587,7 @@ void emit_clusters(GVJ_t * job, Agraph_t * g, int flags) if (!(flags & EMIT_CLUSTERS_LAST)) emit_clusters(job, sg, flags); } - job->gvc->emit_state = oldstate; + job->gvg->emit_state = oldstate; } static bool is_style_delim(int c) @@ -1747,7 +1746,7 @@ static void emit_job(GVJ_t * job, graph_t * g) init_job_viewport(job, g); init_job_pagination(job, g); - job->gvc->emit_state = EMIT_GDRAW; + job->gvg->emit_state = EMIT_GDRAW; gvrender_begin_job(job); switch (job->output_lang) { @@ -1886,6 +1885,7 @@ extern gvdevice_callbacks_t gvdevice_callbacks; int gvRenderJobs (GVC_t * gvc, graph_t * g) { GVJ_t *job, *prev_job; + GVG_t *gvg = gvc->gvg; if (!GD_drawing(g)) { agerr (AGERR, "Layout was not done. Missing layout plugins? \n"); @@ -1893,12 +1893,12 @@ int gvRenderJobs (GVC_t * gvc, graph_t * g) } init_bb(g); - init_gvc(gvc, g); - init_layering(gvc, g); + init_gvg(gvg, g); + init_layering(gvg, g); gvc->keybindings = gvevent_key_binding; gvc->numkeys = gvevent_key_binding_size; - gvc->active_jobs = NULL; /* clear active list */ + gvg->active_jobs = NULL; /* clear active list */ prev_job = NULL; for (job = gvrender_first_job(gvc); job; job = gvrender_next_job(gvc)) { if (!job->output_file) { /* if not yet opened */ @@ -1915,17 +1915,17 @@ int gvRenderJobs (GVC_t * gvc, graph_t * g) } /* if we already have an active job list to a different output device */ - if (gvc->active_jobs - && strcmp(job->output_langname,gvc->active_jobs->output_langname) != 0) { + if (gvg->active_jobs + && strcmp(job->output_langname,gvg->active_jobs->output_langname) != 0) { gvdevice_finalize(gvc); /* finalize previous jobs */ - gvc->active_jobs = NULL; /* clear active list */ + gvg->active_jobs = NULL; /* clear active list */ prev_job = NULL; } if (prev_job) prev_job->next_active = job; /* insert job in active list */ else - gvc->active_jobs = job; /* first job of new list */ + gvg->active_jobs = job; /* first job of new list */ job->next_active = NULL; /* terminate active list */ prev_job = job; diff --git a/lib/common/figgen.c b/lib/common/figgen.c index b6087753c..f36e00a8c 100644 --- a/lib/common/figgen.c +++ b/lib/common/figgen.c @@ -192,7 +192,7 @@ static void fig_end_job(void) fprintf(Output_file, "# end of FIG file\n"); } -static void fig_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void fig_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { PB = bb; if (onetime) { diff --git a/lib/common/gdgen.c b/lib/common/gdgen.c index 0ed7bee81..8018e5a75 100644 --- a/lib/common/gdgen.c +++ b/lib/common/gdgen.c @@ -136,19 +136,19 @@ static void gd_end_job(void) #endif } -static void init1_gd(GVC_t * gvc, graph_t * g, box bb, point pb) +static void init1_gd(GVG_t * gvg, 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; + Viewport.x = gvg->job->width; + Viewport.y = gvg->job->height; #if 0 if (Viewport.x) { - Zoom = gvc->job->zoom; - GraphFocus = gvc->job->focus; + Zoom = gvg->job->zoom; + GraphFocus = gvg->job->focus; } else { Viewport.x = (bb.UR.x - bb.LL.x + 2 * GD_drawing(g)->margin.x) * DevScale + 2; @@ -159,8 +159,8 @@ static void init1_gd(GVC_t * gvc, graph_t * g, box bb, point pb) Zoom = 1.0; } #else - Zoom = gvc->job->zoom; - GraphFocus = gvc->job->focus; + Zoom = gvg->job->zoom; + GraphFocus = gvg->job->focus; #endif CompScale = Zoom * DevScale; } @@ -218,20 +218,21 @@ static bool is_format_truecolor_capable(int Output_lang) return rv; } -static void gd_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void gd_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { char *bgcolor_str = NULL; char *truecolor_str; bool truecolor_p = FALSE; /* try to use cheaper paletted mode */ bool bg_transparent_p = FALSE; int bgcolor; + GVG_t *gvg = job->gvg; - external_surface = gvc->job->external_surface; + external_surface = gvg->job->external_surface; - init1_gd(gvc, g, bb, pb); + init1_gd(gvg, g, bb, pb); if (external_surface) { - im = (gdImagePtr)gvc->job->surface; + im = (gdImagePtr)gvg->job->surface; } else { truecolor_str = agget(g, "truecolor"); /* allow user to force truecolor */ bgcolor_str = agget(g, "bgcolor"); diff --git a/lib/common/hpglgen.c b/lib/common/hpglgen.c index ff7971065..18eac463e 100644 --- a/lib/common/hpglgen.c +++ b/lib/common/hpglgen.c @@ -404,7 +404,7 @@ hpgl_begin_job(FILE * ofp, graph_t * g, char **lib, char *user, N_pages = pages.x * pages.y; } -static void hpgl_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void hpgl_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { PB = bb; PageWidth = pb.x; diff --git a/lib/common/htmltable.c b/lib/common/htmltable.c index 61e02ff74..0fea27d0c 100644 --- a/lib/common/htmltable.c +++ b/lib/common/htmltable.c @@ -448,7 +448,7 @@ emit_html_label(GVJ_t * job, htmllabel_t * lp, textlabel_t * tp, void *obj) /* set basic graphics context */ gvrender_begin_context(job); /* Need to override line style set by node. */ - gvrender_set_style(job, job->gvc->defaultlinestyle); + gvrender_set_style(job, job->gvg->defaultlinestyle); if (tbl->data.pencolor) gvrender_set_pencolor(job, tbl->data.pencolor); else diff --git a/lib/common/input.c b/lib/common/input.c index 77c8de9a5..68a6c1e8a 100644 --- a/lib/common/input.c +++ b/lib/common/input.c @@ -296,13 +296,13 @@ void dotneato_args_initialize(GVC_t * gvc, int argc, char **argv) } /* if no -Txxx, then set default format */ - if (!gvc->jobs || !gvc->jobs->output_langname) { + if (!gvc->gvg->jobs || !gvc->gvg->jobs->output_langname) { v = gvrender_output_langname_job(gvc, "dot"); assert(v); /* "dot" should always be available as an output format */ } #if !defined(DISABLE_CODEGENS) && !defined(HAVE_GD_FREETYPE) - Output_codegen = gvc->jobs->codegen; + Output_codegen = gvc->gvg->jobs->codegen; #endif /* set persistent attributes here (if not already set from command line options) */ @@ -358,6 +358,7 @@ void getdouble(graph_t * g, char *name, double *result) } } +#if 0 static FILE *next_input_file(void) { static int ctr = 0; @@ -399,6 +400,7 @@ graph_t *next_input_graph(void) } return g; } +#endif /* findCharset: * Check if the charset attribute is defined for the graph and, if diff --git a/lib/common/labels.c b/lib/common/labels.c index f8d689e2e..5033fa682 100644 --- a/lib/common/labels.c +++ b/lib/common/labels.c @@ -226,8 +226,8 @@ void emit_label(GVJ_t * job, int state, textlabel_t * lp, void *obj) pointf p; int oldstate; - oldstate = job->gvc->emit_state; - job->gvc->emit_state = state; + oldstate = job->gvg->emit_state; + job->gvg->emit_state = state; if (lp->html) { emit_html_label(job, lp->u.html, lp, obj); @@ -246,7 +246,7 @@ void emit_label(GVJ_t * job, int state, textlabel_t * lp, void *obj) emit_textlines(job, lp->u.txt.nlines, lp->u.txt.line, p, halfwidth_x, lp->fontname, lp->fontsize, lp->fontcolor); - job->gvc->emit_state = oldstate; + job->gvg->emit_state = oldstate; } diff --git a/lib/common/mapgen.c b/lib/common/mapgen.c index 9532e38df..cb00d332b 100644 --- a/lib/common/mapgen.c +++ b/lib/common/mapgen.c @@ -298,18 +298,18 @@ map_begin_job(FILE * ofp, graph_t * g, char **lib, char *user, isLatin1 = (GD_charset(g) == CHAR_LATIN1); } -static void map_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void map_begin_graph(GVJ_t * job, 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; + Viewport.x = job->width; + Viewport.y = job->height; if (Viewport.x) { - Zoom = gvc->job->zoom; - GraphFocus = gvc->job->focus; + Zoom = job->zoom; + GraphFocus = job->focus; } else { Viewport.x = (bb.UR.x - bb.LL.x + 2 * GD_drawing(g)->margin.x) * DevScale + diff --git a/lib/common/mifgen.c b/lib/common/mifgen.c index 861c91f20..7e666fa7e 100644 --- a/lib/common/mifgen.c +++ b/lib/common/mifgen.c @@ -311,7 +311,7 @@ static void mif_end_job(void) fprintf(Output_file, "# end of MIFFile\n"); } -static void mif_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void mif_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { PB = bb; if (onetime) { diff --git a/lib/common/mpgen.c b/lib/common/mpgen.c index 1496f86d2..335910e4d 100644 --- a/lib/common/mpgen.c +++ b/lib/common/mpgen.c @@ -80,7 +80,7 @@ static void mp_comment(char *str) fprintf(Output_file, "%% %s\n", str); } -static void mp_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void mp_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { /* PB = bb; */ if (onetime) { diff --git a/lib/common/picgen.c b/lib/common/picgen.c index 1c694cd5e..cd081ed83 100644 --- a/lib/common/picgen.c +++ b/lib/common/picgen.c @@ -172,7 +172,7 @@ static void pic_begin_job(FILE * ofp, graph_t * g, char **lib, char *user, fprintf(Output_file, "%s Title: %s\n", EscComment, g->name); } -static void pic_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void pic_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { BB = bb; diff --git a/lib/common/psgen.c b/lib/common/psgen.c index c7cd3825e..6f6f0a21c 100644 --- a/lib/common/psgen.c +++ b/lib/common/psgen.c @@ -109,7 +109,7 @@ static void ps_comment(char *str) fprintf(Output_file, "%% %s\n", str); } -static void ps_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void ps_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { char *s; diff --git a/lib/common/svggen.c b/lib/common/svggen.c index 2a4e0c07e..357b85631 100644 --- a/lib/common/svggen.c +++ b/lib/common/svggen.c @@ -475,12 +475,12 @@ svg_begin_job(FILE * ofp, graph_t * g, char **lib, char *user, svg_fputs(") -->\n"); } -static void svg_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void svg_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { - Viewport.x = gvc->job->width; - Viewport.y = gvc->job->height; - CompScale = gvc->job->compscale; - Offset = gvc->job->offset; + Viewport.x = job->width; + Viewport.y = job->height; + CompScale = job->compscale; + Offset = job->offset; if (onetime) { init_svg(); @@ -490,13 +490,13 @@ static void svg_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) svg_fputs("\n", N_pages); - if (ROUND(gvc->job->dpi.x) == POINTS_PER_INCH && ROUND(gvc->job->dpi.y) == POINTS_PER_INCH) + if (ROUND(job->dpi.x) == POINTS_PER_INCH && ROUND(job->dpi.y) == POINTS_PER_INCH) svg_printf("job->dpi.x * Viewport.x / POINTS_PER_INCH), - ROUND(gvc->job->dpi.y * Viewport.y / POINTS_PER_INCH)); + ROUND(job->dpi.x * Viewport.x / POINTS_PER_INCH), + ROUND(job->dpi.y * Viewport.y / POINTS_PER_INCH)); /* establish absolute units in points */ svg_printf(" viewBox = \"%d %d %d %d\"\n", 0, 0, Viewport.x, Viewport.y); /* namespace of svg */ diff --git a/lib/common/types.h b/lib/common/types.h index 4134ee27b..52ac1c1aa 100644 --- a/lib/common/types.h +++ b/lib/common/types.h @@ -194,7 +194,7 @@ extern "C" { void (*begin_job) (FILE * ofp, graph_t * g, char **lib, char *user, char *info[], point pages); void (*end_job) (void); - void (*begin_graph) (GVC_t * gvc, graph_t * g, box bb, point pb); + void (*begin_graph) (GVJ_t * job, graph_t * g, box bb, point pb); void (*end_graph) (void); void (*begin_page) (graph_t * g, point page, double scale, int rot, point offset); diff --git a/lib/common/vrmlgen.c b/lib/common/vrmlgen.c index 04c6f1219..70f3ae126 100644 --- a/lib/common/vrmlgen.c +++ b/lib/common/vrmlgen.c @@ -234,7 +234,7 @@ static void vrml_begin_job(FILE * ofp, graph_t * g, char **lib, char *user, fprintf(Output_file, "#VRML V2.0 utf8\n"); } -static void vrml_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void vrml_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { g = g; diff --git a/lib/common/vtxgen.c b/lib/common/vtxgen.c index 26d36b94c..1e8606371 100644 --- a/lib/common/vtxgen.c +++ b/lib/common/vtxgen.c @@ -236,7 +236,7 @@ vtx_begin_job(FILE * ofp, graph_t * g, char **lib, char *user, free(date); } -static void vtx_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void vtx_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { /* PB = bb; */ if (onetime) { diff --git a/lib/common/xdgen.c b/lib/common/xdgen.c index bb435861b..a66b2bada 100644 --- a/lib/common/xdgen.c +++ b/lib/common/xdgen.c @@ -19,7 +19,7 @@ #define XDOTVERSION "1.1" -static GVC_t *gvc; +static GVG_t *gvg; static agxbuf xbuf0; static agxbuf xbuf1; static agxbuf xbuf2; @@ -93,7 +93,7 @@ void extend_attrs(GVJ_t * job, graph_t *g, int s_arrows, int e_arrows) unsigned char buf4[BUFSIZ]; unsigned char buf5[BUFSIZ]; - gvc = job->gvc; + gvg = job->gvg; agsafeset (g, "xdotversion", XDOTVERSION, ""); if (GD_has_labels(g) & GRAPH_LABEL) @@ -177,9 +177,9 @@ static void xd_str (char* pfx, char* s) char buf[BUFSIZ]; sprintf (buf, "%s%d -", pfx, (int)strlen(s)); - agxbput(xbufs[gvc->emit_state], buf); - agxbput(xbufs[gvc->emit_state], s); - agxbputc(xbufs[gvc->emit_state], ' '); + agxbput(xbufs[gvg->emit_state], buf); + agxbput(xbufs[gvg->emit_state], s); + agxbputc(xbufs[gvg->emit_state], ' '); } static void xd_textline(point p, textline_t * line) @@ -200,7 +200,7 @@ static void xd_textline(point p, textline_t * line) break; } sprintf(buf, "T %d %d %d %d ", p.x, YDIR(p.y), j, (int) line->width); - agxbput(xbufs[gvc->emit_state], buf); + agxbput(xbufs[gvg->emit_state], buf); xd_str ("", line->str); } @@ -208,9 +208,9 @@ static void xd_ellipse(point p, int rx, int ry, int filled) { char buf[BUFSIZ]; - agxbputc(xbufs[gvc->emit_state], (filled ? 'E' : 'e')); + agxbputc(xbufs[gvg->emit_state], (filled ? 'E' : 'e')); sprintf(buf, " %d %d %d %d ", p.x, YDIR(p.y), rx, ry); - agxbput(xbufs[gvc->emit_state], buf); + agxbput(xbufs[gvg->emit_state], buf); } static void xd_points(char c, point * A, int n) @@ -219,13 +219,13 @@ static void xd_points(char c, point * A, int n) int i; point p; - agxbputc(xbufs[gvc->emit_state], c); + agxbputc(xbufs[gvg->emit_state], c); sprintf(buf, " %d ", n); - agxbput(xbufs[gvc->emit_state], buf); + agxbput(xbufs[gvg->emit_state], buf); for (i = 0; i < n; i++) { p = A[i]; sprintf(buf, "%d %d ", p.x, YDIR(p.y)); - agxbput(xbufs[gvc->emit_state], buf); + agxbput(xbufs[gvg->emit_state], buf); } } @@ -254,7 +254,7 @@ xd_set_font (char *fontname, double fontsize) char buf[BUFSIZ]; sprintf(buf, "F %f ", fontsize); - agxbput(xbufs[gvc->emit_state], buf); + agxbput(xbufs[gvg->emit_state], buf); xd_str ("", fontname); } diff --git a/lib/gvc/Makefile.am b/lib/gvc/Makefile.am index d13a90174..a20900888 100644 --- a/lib/gvc/Makefile.am +++ b/lib/gvc/Makefile.am @@ -12,7 +12,7 @@ AM_CPPFLAGS = \ LIBS = $(LIBLTDL) $(SOCKET_LIBS) -pkginclude_HEADERS = gvc.h gvcext.h gvplugin.h gvcjob.h gvcint.h \ +pkginclude_HEADERS = gvc.h gvcext.h gvplugin.h gvj.h gvg.h gvcint.h \ gvplugin_render.h \ gvplugin_layout.h \ gvplugin_textlayout.h \ @@ -27,7 +27,7 @@ libgvc_la_LDFLAGS = ${libgvc_builtins_la_LDFLAGS} -no-undefined libgvc_builtins_la_SOURCES = gvrender.c gvlayout.c gvtextlayout.c gvdevice.c \ gvcontext.c gvjobs.c gvevent.c gvplugin.c gvconfig.c gvusershape.c \ - gvc.c + gvc.c gvgraphs.c libgvc_la_SOURCES = ${libgvc_builtins_la_SOURCES} no_builtins.c libgvc_builtins_la_LIBADD = \ diff --git a/lib/gvc/gvc.c b/lib/gvc/gvc.c index ee2be9d8b..c232741d4 100644 --- a/lib/gvc/gvc.c +++ b/lib/gvc/gvc.c @@ -97,7 +97,7 @@ int gvRender(GVC_t *gvc, graph_t *g, char *format, FILE *out) return -1; } - job = gvc->job; + job = gvc->gvg->job; job->output_lang = gvrender_select(job, job->output_langname); if (!GD_drawing(g) && job->output_lang != CANONICAL_DOT) { fprintf(stderr, "Layout was not done\n"); @@ -105,7 +105,7 @@ int gvRender(GVC_t *gvc, graph_t *g, char *format, FILE *out) } job->output_file = out; gvRenderJobs(gvc, g); - if (gvc->active_jobs) + if (gvc->gvg->active_jobs) gvdevice_finalize(gvc); gvrender_delete_jobs(gvc); @@ -127,7 +127,7 @@ int gvRenderFilename(GVC_t *gvc, graph_t *g, char *format, char *filename) return -1; } - job = gvc->job; + job = gvc->gvg->job; job->output_lang = gvrender_select(job, job->output_langname); if (!GD_drawing(g) && job->output_lang != CANONICAL_DOT) { fprintf(stderr, "Layout was not done\n"); @@ -135,7 +135,7 @@ int gvRenderFilename(GVC_t *gvc, graph_t *g, char *format, char *filename) } gvrender_output_filename_job(gvc, filename); gvRenderJobs(gvc, g); - if (gvc->active_jobs) + if (gvc->gvg->active_jobs) gvdevice_finalize(gvc); gvrender_delete_jobs(gvc); diff --git a/lib/gvc/gvcext.h b/lib/gvc/gvcext.h index 77bc91c05..3c2221913 100644 --- a/lib/gvc/gvcext.h +++ b/lib/gvc/gvcext.h @@ -28,8 +28,9 @@ extern "C" { typedef struct codegen_info_s codegen_info_t; #endif - typedef struct GVJ_s GVJ_t; typedef struct GVC_s GVC_t; + typedef struct GVG_s GVG_t; + typedef struct GVJ_s GVJ_t; typedef struct { const char *name; diff --git a/lib/gvc/gvcint.h b/lib/gvc/gvcint.h index 996539d2e..565a5ed75 100644 --- a/lib/gvc/gvcint.h +++ b/lib/gvc/gvcint.h @@ -23,7 +23,7 @@ extern "C" { #endif -#include "gvcjob.h" +#include "gvg.h" typedef struct { int flags; @@ -64,27 +64,16 @@ extern "C" { or NULL if not yet loaded */ }; -#define MAXNEST 4 - struct GVC_s { /* gvNEWcontext() */ char *user; char **info; + void (*errorfn) (char *fmt, ...); + char *config_path; bool config_found; - /* gvrender_config() */ - GVJ_t *jobs; /* linked list of jobs */ - GVJ_t *job; /* current job */ - void (*errorfn) (char *fmt, ...); - - int emit_state; /* current emit_state */ - graph_t *g; /* current graph */ - graph_t *sg; /* current subgraph/cluster */ - node_t *n; /* current node */ - edge_t *e; /* current edge */ - /* plugins */ #define ELEM(x) +1 /* APIS expands to "+1 +1 ... +1" to give the number of APIs */ @@ -97,45 +86,13 @@ extern "C" { gvplugin_active_usershape_t usershape; gvplugin_active_layout_t layout; - char *graphname; /* name from graph */ - GVJ_t *active_jobs; /* linked list of active jobs */ - - char **lib; - - /* pagination */ - char *pagedir; /* pagination order */ - pointf margin; /* margins in graph units */ - pointf pageSize; /* pageSize in graph units, not including margins */ - point pb; /* page size - including margins (inches) */ - boxf bb; /* graph bb in graph units, not including margins */ - int rotation; /* rotation - 0 = portrait, 90 = landscape */ - bool graph_sets_margin, graph_sets_pageSize, graph_sets_rotation; - - /* layers */ - char *layerDelims; /* delimiters in layer names */ - char *layers; /* null delimited list of layer names */ - char **layerIDs; /* array of layer names */ - int numLayers; /* number of layers */ - - int viewNum; /* current view - 1 based count of views, - all pages in all layers */ - /* default font */ - char *defaultfontname; - double defaultfontsize; - - /* default line style */ - char **defaultlinestyle; - - gvstyle_t styles[MAXNEST]; /* style stack - reused by each job */ - int SP; - - /* render defaults set from graph */ - gvcolor_t bgcolor; /* background color */ - /* keybindings for keyboard events */ gvevent_key_binding_t *keybindings; int numkeys; void *keycodes; + + /* gvrender_config() */ + GVG_t *gvg; }; #ifdef __cplusplus diff --git a/lib/gvc/gvcontext.c b/lib/gvc/gvcontext.c index c434e65d2..1b47ae154 100644 --- a/lib/gvc/gvcontext.c +++ b/lib/gvc/gvcontext.c @@ -17,7 +17,7 @@ /* A gvcontext is a single instance of a GVC_t data structure providing for a set of plugins for processing one graph at a time, and a job - description provividing for a sequence of graph jobs. + description providing for a sequence of graph jobs. Sometime in the future it may become the basis for a thread. */ @@ -49,18 +49,22 @@ GVC_t *gvNEWcontext(char **info, char *user) gvc->info = info; gvc->user = user; gvc->errorfn = agerrorf; + gvc->gvg = zmalloc(sizeof(GVG_t)); /* FIXME - this will be allocated by the args parser */ + gvc->gvg->gvc = gvc; /* link back to parent */ } return gvc; } int gvFreeContext(GVC_t * gvc) { - if (gvc->active_jobs) + if (gvc->gvg->active_jobs) gvdevice_finalize(gvc); emit_jobs_eof(gvc); gvrender_delete_jobs(gvc); if (gvc->config_path) free(gvc->config_path); + if (gvc->gvg) /* FIXME - this be be a list of gvg's eventually */ + free(gvc->gvg); free(gvc); return (graphviz_errors + agerrors()); } diff --git a/lib/gvc/gvdevice.c b/lib/gvc/gvdevice.c index 4eb0f1d38..bd04eaa14 100644 --- a/lib/gvc/gvdevice.c +++ b/lib/gvc/gvdevice.c @@ -34,7 +34,7 @@ int gvdevice_select(GVJ_t * job, char *str) { - GVC_t *gvc = job->gvc; + GVC_t *gvc = job->gvg->gvc; gvplugin_available_t *plugin; gvplugin_installed_t *typeptr; #ifndef DISABLE_CODEGENS @@ -75,7 +75,7 @@ int gvdevice_features(GVJ_t * job) void gvdevice_finalize(GVC_t * gvc) { - GVJ_t *firstjob = gvc->active_jobs; + GVJ_t *firstjob = gvc->gvg->active_jobs; gvdevice_engine_t *gvde = firstjob->device.engine; if (gvde) { diff --git a/lib/gvc/gvevent.c b/lib/gvc/gvevent.c index b6597897f..e0c5499c2 100644 --- a/lib/gvc/gvevent.c +++ b/lib/gvc/gvevent.c @@ -174,7 +174,7 @@ static void gv_edge_state(GVJ_t *job, edge_t *e) static void gvevent_refresh(GVJ_t * job) { - graph_t *g = job->gvc->g; + graph_t *g = job->gvg->g; if (!job->selected_obj) { job->selected_obj = g; @@ -313,7 +313,7 @@ static void gvevent_find_current_obj(GVJ_t * job, pointf pointer) b.LL.x = p.x - closeenough; b.LL.y = p.y - closeenough; - obj = gvevent_find_obj(job->gvc->g, b); + obj = gvevent_find_obj(job->gvg->g, b); if (obj != job->current_obj) { gvevent_leave_obj(job); job->current_obj = obj; @@ -536,30 +536,30 @@ static void gvevent_delete (GVJ_t * job) static void gvevent_read (GVJ_t * job, char *filename, char *layout) { FILE *f; - GVC_t *gvc; gvlayout_engine_t *gvle; + GVG_t *gvg = job->gvg; + GVC_t *gvc = gvg->gvc; - gvc = job->gvc; - if (gvc->g) { + if (gvg->g) { gvle = gvc->layout.engine; if (gvle && gvle->cleanup) - gvle->cleanup(gvc->g); - graph_cleanup(gvc->g); - agclose(gvc->g); + gvle->cleanup(gvg->g); + graph_cleanup(gvg->g); + agclose(gvg->g); } if (!filename) { - gvc->g = agopen("G", AGDIGRAPH); + gvg->g = agopen("G", AGDIGRAPH); job->output_filename = "new.dot"; } else { f = fopen(filename, "r"); if (!f) return; /* FIXME - need some error handling */ - gvc->g = agread(f); + gvg->g = agread(f); fclose(f); } - GD_gvc(gvc->g) = gvc; - gvLayout(gvc, gvc->g, layout); + GD_gvc(gvg->g) = gvc; + gvLayout(gvc, gvg->g, layout); job->selected_obj = NULL; job->current_obj = NULL; job->needs_refresh = 1; @@ -567,12 +567,12 @@ static void gvevent_read (GVJ_t * job, char *filename, char *layout) static void gvevent_layout (GVJ_t * job, char *layout) { - gvLayout(job->gvc, job->gvc->g, layout); + gvLayout(job->gvg->gvc, job->gvg->g, layout); } static void gvevent_render (GVJ_t * job, char *format, char *filename) { - gvRenderFilename(job->gvc, job->gvc->g, format, filename); + gvRenderFilename(job->gvg->gvc, job->gvg->g, format, filename); } diff --git a/lib/gvc/gvg.h b/lib/gvc/gvg.h new file mode 100644 index 000000000..7c40ddc91 --- /dev/null +++ b/lib/gvc/gvg.h @@ -0,0 +1,84 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +/* per graph structure in gvc */ + +#ifndef GVG_H +#define GVG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "gvj.h" + + struct GVG_s { + + GVC_t *gvc; /* parent gvc */ + + GVJ_t *jobs; /* linked list of jobs on this graph */ + GVJ_t *job; /* current job */ + GVJ_t *active_jobs; /* linked list of active jobs + (e.g. multiple open windows on same graph) */ + + int emit_state; /* current emit_state */ + graph_t *g; /* current graph */ + graph_t *sg; /* current subgraph/cluster */ + node_t *n; /* current node */ + edge_t *e; /* current edge */ + + char *inputFilename; /* NULL if from stdin */ + char *graphname; /* name from graph */ + + char **lib; + + /* pagination */ + char *pagedir; /* pagination order */ + pointf margin; /* margins in graph units */ + pointf pageSize; /* pageSize in graph units, not including margins */ + point pb; /* page size - including margins (inches) */ + boxf bb; /* graph bb in graph units, not including margins */ + int rotation; /* rotation - 0 = portrait, 90 = landscape */ + bool graph_sets_margin, graph_sets_pageSize, graph_sets_rotation; + + /* layers */ + char *layerDelims; /* delimiters in layer names */ + char *layers; /* null delimited list of layer names */ + char **layerIDs; /* array of layer names */ + int numLayers; /* number of layers */ + + int viewNum; /* current view - 1 based count of views, + all pages in all layers */ + /* default font */ + char *defaultfontname; + double defaultfontsize; + + /* default line style */ + char **defaultlinestyle; + +#define MAXNEST 4 + + gvstyle_t styles[MAXNEST]; /* style stack - reused by each job */ + int SP; + + /* render defaults set from graph */ + gvcolor_t bgcolor; /* background color */ + }; + +#ifdef __cplusplus +} +#endif +#endif /* GVG_H */ diff --git a/lib/gvc/gvgraphs.c b/lib/gvc/gvgraphs.c new file mode 100644 index 000000000..ea1953f15 --- /dev/null +++ b/lib/gvc/gvgraphs.c @@ -0,0 +1,74 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +/* + A gvgraph (GVG_t*) is a single graph within a gvcontext (GVC_t *) + which can support multiple graphs. + + Each gvgraph (GVG_t *) may have multiple gvjobs (GVJ_t *) which correspond + to the renderings of that graph. + */ + +#include "render.h" +#include "gvcint.h" + +static FILE *gvNextInputFile(GVC_t *gvc) +{ + static int ctr = 0; + FILE *rv = NULL; + + if (Files[0] == NULL) { + if (ctr++ == 0) + rv = stdin; + } else { + rv = NULL; + while (Files[ctr]) { + if ((rv = fopen(Files[ctr++], "r"))) + break; + else { + agerr(AGERR, "%s: can't open %s\n", CmdName, + Files[ctr - 1]); + graphviz_errors++; + } + } + } + if (rv) { + agsetfile(Files[0] ? Files[ctr - 1] : ""); + if (Files[0]) + gvc->gvg->inputFilename = Files[ctr - 1]; + else + gvc->gvg->inputFilename = NULL; + } + return rv; +} + +graph_t *gvNextInputGraph(GVC_t *gvc) +{ + graph_t *g; + static FILE *fp; + + if (fp == NULL) + fp = gvNextInputFile(gvc); + g = NULL; + + while (fp != NULL) { + if ((g = agread(fp))) + break; + fp = gvNextInputFile(gvc); + } + return g; +} + diff --git a/lib/gvc/gvcjob.h b/lib/gvc/gvj.h similarity index 98% rename from lib/gvc/gvcjob.h rename to lib/gvc/gvj.h index eff43f0c9..f13f60653 100644 --- a/lib/gvc/gvcjob.h +++ b/lib/gvc/gvj.h @@ -16,8 +16,8 @@ /* Common header used by both clients and plugins */ -#ifndef GVCJOB_H -#define GVCJOB_H +#ifndef GVJ_H +#define GVJ_H #ifdef __cplusplus extern "C" { @@ -134,7 +134,7 @@ extern "C" { } gvevent_key_binding_t; struct GVJ_s { - GVC_t *gvc; /* parent gvc */ + GVG_t *gvg; /* parent gvg */ GVJ_t *next; /* linked list of jobs */ GVJ_t *next_active; /* linked list of active jobs (e.g. multiple windows) */ char *output_filename; @@ -222,4 +222,4 @@ extern "C" { #ifdef __cplusplus } #endif -#endif /* GVCJOB_H */ +#endif /* GVJ_H */ diff --git a/lib/gvc/gvjobs.c b/lib/gvc/gvjobs.c index 9676a0cdc..aeeecec2a 100644 --- a/lib/gvc/gvjobs.c +++ b/lib/gvc/gvjobs.c @@ -48,12 +48,14 @@ static GVJ_t *output_langname_job; /* -o switches */ void gvrender_output_filename_job(GVC_t * gvc, char *name) { - if (!gvc->jobs) { - output_filename_job = gvc->job = gvc->jobs = + GVG_t *gvg = gvc->gvg; + + if (!gvg->jobs) { + output_filename_job = gvg->job = gvg->jobs = zmalloc(sizeof(GVJ_t)); } else { if (!output_filename_job) { - output_filename_job = gvc->jobs; + output_filename_job = gvg->jobs; } else { if (!output_filename_job->next) { output_filename_job->next = @@ -63,18 +65,20 @@ void gvrender_output_filename_job(GVC_t * gvc, char *name) } } output_filename_job->output_filename = name; - output_filename_job->gvc = gvc; + output_filename_job->gvg = gvg; } /* -T switches */ bool gvrender_output_langname_job(GVC_t * gvc, char *name) { - if (!gvc->jobs) { - output_langname_job = gvc->job = gvc->jobs = + GVG_t *gvg = gvc->gvg; + + if (!gvg->jobs) { + output_langname_job = gvg->job = gvg->jobs = zmalloc(sizeof(GVJ_t)); } else { if (!output_langname_job) { - output_langname_job = gvc->jobs; + output_langname_job = gvg->jobs; } else { if (!output_langname_job->next) { output_langname_job->next = @@ -84,7 +88,7 @@ bool gvrender_output_langname_job(GVC_t * gvc, char *name) } } output_langname_job->output_langname = name; - output_langname_job->gvc = gvc; + output_langname_job->gvg = gvg; /* load it now to check that it exists */ if (gvplugin_load(gvc, API_render, name)) @@ -94,20 +98,23 @@ bool gvrender_output_langname_job(GVC_t * gvc, char *name) GVJ_t *gvrender_first_job(GVC_t * gvc) { - return (gvc->job = gvc->jobs); + GVG_t *gvg = gvc->gvg; + + return (gvg->job = gvg->jobs); } GVJ_t *gvrender_next_job(GVC_t * gvc) { - GVJ_t *job = gvc->job->next; + GVG_t *gvg = gvc->gvg; + GVJ_t *job = gvg->job->next; if (job) { /* if langname not specified, then repeat previous value */ if (!job->output_langname) - job->output_langname = gvc->job->output_langname; + job->output_langname = gvg->job->output_langname; /* if filename not specified, then leave NULL to indicate stdout */ } - return (gvc->job = job); + return (gvg->job = job); } gv_argvlist_t *gvNEWargvlist(void) @@ -143,8 +150,9 @@ void gv_argvlist_free(gv_argvlist_t *list) void gvrender_delete_jobs(GVC_t * gvc) { GVJ_t *job, *j; + GVG_t *gvg = gvc->gvg; - job = gvc->jobs; + job = gvg->jobs; while ((j = job)) { job = job->next; gv_argvlist_reset(&(j->selected_obj_attributes)); @@ -155,6 +163,6 @@ void gvrender_delete_jobs(GVC_t * gvc) free(j->selected_href); free(j); } - gvc->jobs = gvc->job = gvc->active_jobs = output_filename_job = output_langname_job = + gvg->jobs = gvg->job = gvg->active_jobs = output_filename_job = output_langname_job = NULL; } diff --git a/lib/gvc/gvplugin_device.h b/lib/gvc/gvplugin_device.h index a073ed0c7..99b47713e 100644 --- a/lib/gvc/gvplugin_device.h +++ b/lib/gvc/gvplugin_device.h @@ -18,7 +18,7 @@ #define GVDEVICE_PLUGIN_H #include "gvplugin.h" -#include "gvcjob.h" +#include "gvj.h" #ifdef __cplusplus extern "C" { diff --git a/lib/gvc/gvplugin_render.h b/lib/gvc/gvplugin_render.h index aba4aa4b4..a7dc1c4e4 100644 --- a/lib/gvc/gvplugin_render.h +++ b/lib/gvc/gvplugin_render.h @@ -18,7 +18,7 @@ #define GVRENDER_PLUGIN_H #include "gvplugin.h" -#include "gvcjob.h" +#include "gvj.h" #ifdef __cplusplus extern "C" { diff --git a/lib/gvc/gvrender.c b/lib/gvc/gvrender.c index 4bf7a7155..76f4485f0 100644 --- a/lib/gvc/gvrender.c +++ b/lib/gvc/gvrender.c @@ -53,7 +53,7 @@ static int sizeA; int gvrender_select(GVJ_t * job, char *str) { - GVC_t *gvc = job->gvc; + GVC_t *gvc = job->gvg->gvc; gvplugin_available_t *plugin; gvplugin_installed_t *typeptr; char *device; @@ -124,10 +124,11 @@ int gvrender_features(GVJ_t * job) void gvrender_begin_job(GVJ_t * job) { - GVC_t *gvc = job->gvc; + GVG_t *gvg = job->gvg; + GVC_t *gvc = gvg->gvc; gvrender_engine_t *gvre = job->render.engine; - job->bb = gvc->bb; + job->bb = gvg->bb; if (gvre) { if (gvre->begin_job) gvre->begin_job(job); @@ -137,7 +138,7 @@ void gvrender_begin_job(GVJ_t * job) codegen_t *cg = job->codegen; if (cg && cg->begin_job) - cg->begin_job(job->output_file, gvc->g, gvc->lib, gvc->user, + cg->begin_job(job->output_file, gvg->g, gvg->lib, gvc->user, gvc->info, job->pagesArraySize); } #endif @@ -157,7 +158,7 @@ void gvrender_end_job(GVJ_t * job) cg->end_job(); } #endif - job->gvc->lib = NULL; + job->gvg->lib = NULL; } /* font modifiers */ @@ -227,7 +228,7 @@ static void gvrender_resolve_color(gvrender_features_t * features, void gvrender_begin_graph(GVJ_t * job, graph_t * g) { - GVC_t *gvc = job->gvc; + GVG_t *gvg = job->gvg; gvrender_engine_t *gvre = job->render.engine; char *str; double sx, sy; @@ -235,7 +236,7 @@ void gvrender_begin_graph(GVJ_t * job, graph_t * g) sx = job->width / (job->zoom * 2.); sy = job->height / (job->zoom * 2.); - gvc->sg = g; /* current subgraph/cluster */ + gvg->sg = g; /* current subgraph/cluster */ job->compscale.x = job->zoom * job->dpi.x / POINTS_PER_INCH; job->compscale.y = job->zoom * job->dpi.y / POINTS_PER_INCH; job->compscale.y *= (job->flags & GVRENDER_Y_GOES_DOWN) ? -1. : 1.; @@ -272,19 +273,19 @@ void gvrender_begin_graph(GVJ_t * job, graph_t * g) if (gvre) { /* render specific init */ if (gvre->begin_graph) - gvre->begin_graph(job, gvc->graphname); + gvre->begin_graph(job, gvg->graphname); /* background color */ if (((str = agget(g, "bgcolor")) != 0) && str[0]) { gvrender_resolve_color(job->render.features, str, - &(gvc->bgcolor)); + &(gvg->bgcolor)); if (gvre->resolve_color) - gvre->resolve_color(job, &(gvc->bgcolor)); + gvre->resolve_color(job, &(gvg->bgcolor)); } /* init stack */ - gvc->SP = 0; - job->style = &(gvc->styles[0]); + gvg->SP = 0; + job->style = &(gvg->styles[0]); gvrender_set_pencolor(job, DEFAULT_COLOR); gvrender_set_fillcolor(job, DEFAULT_FILL); job->style->fontfam = DEFAULT_FONTNAME; @@ -309,7 +310,7 @@ fprintf(stderr,"pb = %d,%d %d,%d\n", #endif if (cg && cg->begin_graph) - cg->begin_graph(gvc, g, job->boundingBox, gvc->pb); + cg->begin_graph(job, g, job->boundingBox, gvg->pb); } #endif } @@ -328,7 +329,7 @@ void gvrender_end_graph(GVJ_t * job) cg->end_graph(); } #endif - job->gvc->sg = NULL; + job->gvg->sg = NULL; } void gvrender_begin_page(GVJ_t * job) @@ -345,7 +346,7 @@ void gvrender_begin_page(GVJ_t * job) PF2P(job->pageOffset, offset); if (cg && cg->begin_page) - cg->begin_page(job->gvc->g, job->pagesArrayElem, + cg->begin_page(job->gvg->g, job->pagesArrayElem, job->zoom, job->rotation, offset); } #endif @@ -372,13 +373,13 @@ void gvrender_begin_layer(GVJ_t * job) gvrender_engine_t *gvre = job->render.engine; if (gvre && gvre->begin_layer) - gvre->begin_layer(job, job->gvc->layerIDs[job->layerNum], job->layerNum, job->numLayers); + gvre->begin_layer(job, job->gvg->layerIDs[job->layerNum], job->layerNum, job->numLayers); #ifndef DISABLE_CODEGENS else { codegen_t *cg = job->codegen; if (cg && cg->begin_layer) - cg->begin_layer(job->gvc->layerIDs[job->layerNum], job->layerNum, job->numLayers); + cg->begin_layer(job->gvg->layerIDs[job->layerNum], job->layerNum, job->numLayers); } #endif } @@ -403,7 +404,7 @@ void gvrender_begin_cluster(GVJ_t * job, graph_t * sg) { gvrender_engine_t *gvre = job->render.engine; - job->gvc->sg = sg; /* set current cluster graph object */ + job->gvg->sg = sg; /* set current cluster graph object */ #ifndef DISABLE_CODEGENS Obj = CLST; #endif @@ -434,7 +435,7 @@ void gvrender_end_cluster(GVJ_t * job, graph_t *g) } Obj = NONE; #endif - job->gvc->sg = g; /* reset current cluster to parent graph or cluster */ + job->gvg->sg = g; /* reset current cluster to parent graph or cluster */ } void gvrender_begin_nodes(GVJ_t * job) @@ -508,7 +509,7 @@ void gvrender_begin_node(GVJ_t * job, node_t * n) #ifndef DISABLE_CODEGENS Obj = NODE; #endif - job->gvc->n = n; /* set current node */ + job->gvg->n = n; /* set current node */ if (gvre && gvre->begin_node) gvre->begin_node(job, n->name, n->id); #ifndef DISABLE_CODEGENS @@ -536,7 +537,7 @@ void gvrender_end_node(GVJ_t * job) } Obj = NONE; #endif - job->gvc->n = NULL; /* clear current node */ + job->gvg->n = NULL; /* clear current node */ } void gvrender_begin_edge(GVJ_t * job, edge_t * e) @@ -546,7 +547,7 @@ void gvrender_begin_edge(GVJ_t * job, edge_t * e) #ifndef DISABLE_CODEGENS Obj = EDGE; #endif - job->gvc->e = e; /* set current edge */ + job->gvg->e = e; /* set current edge */ if (gvre && gvre->begin_edge) gvre->begin_edge(job, e->tail->name, e->tail->graph->root->kind & AGFLAG_DIRECTED, @@ -576,19 +577,19 @@ void gvrender_end_edge(GVJ_t * job) } Obj = NONE; #endif - job->gvc->e = NULL; /* clear current edge */ + job->gvg->e = NULL; /* clear current edge */ } void gvrender_begin_context(GVJ_t * job) { - GVC_t *gvc = job->gvc; + GVG_t *gvg = job->gvg; gvrender_engine_t *gvre = job->render.engine; if (gvre) { - (gvc->SP)++; - assert((gvc->SP) < MAXNEST); - gvc->styles[gvc->SP] = gvc->styles[(gvc->SP) - 1]; - job->style = &(gvc->styles[gvc->SP]); + (gvg->SP)++; + assert((gvg->SP) < MAXNEST); + gvg->styles[gvg->SP] = gvg->styles[(gvg->SP) - 1]; + job->style = &(gvg->styles[gvg->SP]); } #ifndef DISABLE_CODEGENS else { @@ -602,13 +603,13 @@ void gvrender_begin_context(GVJ_t * job) void gvrender_end_context(GVJ_t * job) { - GVC_t *gvc = job->gvc; + GVG_t *gvg = job->gvg; gvrender_engine_t *gvre = job->render.engine; if (gvre) { - gvc->SP--; - assert(gvc->SP >= 0); - job->style = &(gvc->styles[gvc->SP]); + gvg->SP--; + assert(gvg->SP >= 0); + job->style = &(gvg->styles[gvg->SP]); } #ifndef DISABLE_CODEGENS else { diff --git a/tclpkg/tcldot/tcldot.c b/tclpkg/tcldot/tcldot.c index ca428f264..f6b711648 100644 --- a/tclpkg/tcldot/tcldot.c +++ b/tclpkg/tcldot/tcldot.c @@ -1085,10 +1085,10 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp, (char *) 0); return TCL_ERROR; } - gvc->active_jobs = gvc->job; + gvc->gvg->active_jobs = gvc->gvg->job; - gvc->job->surface = (void *)(&tkgendata); - gvc->job->external_surface = TRUE; + gvc->gvg->job->surface = (void *)(&tkgendata); + gvc->gvg->job->external_surface = TRUE; /* make sure that layout is done */ g = g->root; @@ -1116,14 +1116,14 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp, (char *) 0); return TCL_ERROR; } - gvc->active_jobs = gvc->job; + gvc->gvg->active_jobs = gvc->gvg->job; if (! (hdl = tclhandleXlate(GDHandleTable, argv[2]))) { Tcl_AppendResult(interp, "GD Image not found.", (char *) NULL); return TCL_ERROR; } - gvc->job->surface = *hdl; - gvc->job->external_surface = TRUE; + gvc->gvg->job->surface = *hdl; + gvc->gvg->job->external_surface = TRUE; /* make sure that layout is done */ g = g->root; @@ -1254,19 +1254,19 @@ static int graphcmd(ClientData clientData, Tcl_Interp * interp, "\". Use one of:", s, (char *)NULL); return TCL_ERROR; } - gvc->active_jobs = gvc->job; + gvc->gvg->active_jobs = gvc->gvg->job; /* populate new job struct with output language and output file data */ - gvc->job->output_lang = - gvrender_select(gvc->job, gvc->job->output_langname); + gvc->gvg->job->output_lang = + gvrender_select(gvc->gvg->job, gvc->gvg->job->output_langname); if (Tcl_GetOpenFile (interp, argv[2], 1, 1, - (ClientData *) &(gvc->job->output_file)) != TCL_OK) + (ClientData *) &(gvc->gvg->job->output_file)) != TCL_OK) return TCL_ERROR; /* make sure that layout is done - unless canonical output */ if ((!GD_drawing(g) || argc > 4) - && gvc->job->output_lang != CANONICAL_DOT) { + && gvc->gvg->job->output_lang != CANONICAL_DOT) { tcldot_layout(gvc, g, (argc > 4) ? argv[4] : (char *) NULL); } diff --git a/tclpkg/tcldot/tkgen.c b/tclpkg/tcldot/tkgen.c index 106d971be..a7877ea6f 100644 --- a/tclpkg/tcldot/tkgen.c +++ b/tclpkg/tcldot/tkgen.c @@ -184,21 +184,21 @@ static void tk_end_job(void) { } -static void tk_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb) +static void tk_begin_graph(GVJ_t * job, graph_t * g, box bb, point pb) { double dpi = GD_drawing(g)->dpi; - Tkgendata = (tkgendata_t *)gvc->job->surface; + Tkgendata = (tkgendata_t *)job->surface; if (dpi < 1.0) dpi = DEFAULT_DPI; DevScale = dpi / POINTS_PER_INCH; - Viewport.x = gvc->job->width; - Viewport.y = gvc->job->height; + Viewport.x = job->width; + Viewport.y = job->height; if (Viewport.x) { - Zoom = gvc->job->zoom; - GraphFocus = gvc->job->focus; + Zoom = job->zoom; + GraphFocus = job->focus; } else { Viewport.x = (bb.UR.x - bb.LL.x + 2 * GD_drawing(g)->margin.x) * DevScale +