Graphviz 13.1.0~dev.20250626.0830
Loading...
Searching...
No Matches
output.c
Go to the documentation of this file.
1
3/*************************************************************************
4 * Copyright (c) 2011 AT&T Intellectual Property
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * which accompanies this distribution, and is available at
8 * https://www.eclipse.org/legal/epl-v10.html
9 *
10 * Contributors: Details at https://graphviz.org
11 *************************************************************************/
12
13#include <cgraph/agstrcanon.h>
14#include <common/render.h>
15#include <gvc/gvc.h>
16#include <stdarg.h>
17#include <stdbool.h>
18#include <stdlib.h>
19#include <string.h>
20#include <util/agxbuf.h>
21#include <util/prisize_t.h>
22
24typedef struct {
25 double Y;
26 double YF;
27} offsets_t;
28
29static double YFDIR(offsets_t offsets, double y) {
30 return Y_invert ? offsets.YF - y : y;
31}
32
33double yDir(double y, double Y_off) {
34 return Y_invert ? Y_off - y : y;
35}
36
37static void agputs(int (*putstr)(void *chan, const char *str), const char* s,
38 void* fp) {
39 putstr(fp, s);
40}
41
42static void agputc(int (*putstr)(void *chan, const char *str), char c,
43 void *fp) {
44 char buf[] = {c, '\0'};
45 putstr(fp, buf);
46}
47
48static void printstring(int (*putstr)(void *chan, const char *str), void *f,
49 char *prefix, char *s) {
50 if (prefix) agputs(putstr, prefix, f);
51 agputs(putstr, s, f);
52}
53
54static void printint(int (*putstr)(void *chan, const char *str), void *f,
55 char *prefix, size_t i) {
56 agxbuf buf = {0};
57
58 if (prefix) agputs(putstr, prefix, f);
59 agxbprint(&buf, "%" PRISIZE_T, i);
60 agputs(putstr, agxbuse(&buf), f);
61 agxbfree(&buf);
62}
63
64static void printdouble(int (*putstr)(void *chan, const char *str), void *f,
65 char *prefix, double v) {
66 agxbuf buf = {0};
67
68 if (prefix) agputs(putstr, prefix, f);
69 agxbprint(&buf, "%.5g", v);
70 agputs(putstr, agxbuse(&buf), f);
71 agxbfree(&buf);
72}
73
74static void printpoint(int (*putstr)(void *chan, const char *str), void *f,
75 pointf p, double yOff) {
76 printdouble(putstr, f, " ", PS2INCH(p.x));
77 printdouble(putstr, f, " ", PS2INCH(yDir(p.y, yOff)));
78}
79
80/* setYInvert:
81 * Set parameters used to flip coordinate system (y=0 at top).
82 * Values do not need to be unset, since if Y_invert is set, it's
83 * set for * all graphs during current run, so each will
84 * reinitialize the values for its bbox.
85 */
87 offsets_t rv = {0};
88 if (Y_invert) {
89 rv.Y = GD_bb(g).UR.y + GD_bb(g).LL.y;
90 rv.YF = PS2INCH(rv.Y);
91 }
92 return rv;
93}
94
95/* canon:
96 * Canonicalize a string which may not have been allocated using agstrdup.
97 *
98 * @param buffer Scratch space to use during canonicalization. This must be at
99 * least `agstrcanon_bytes(s)` bytes.
100 */
101static char *canon(graph_t *g, char *s, char *buffer) {
102 char* ns = agstrdup (g, s);
103 char *const cs = agstrcanon(ns, buffer);
104 agstrfree(g, ns, false);
105 return cs;
106}
107
108static void writenodeandport(int (*putstr)(void *chan, const char *str),
109 FILE *f, node_t *node, char *portname) {
110 char *name;
111 char *const value =
112 IS_CLUST_NODE(node) ? strchr(agnameof(node), ':') + 1 : agnameof(node);
113 char *const buffer = agstrcanon_buffer(value);
114 if (IS_CLUST_NODE(node)) {
115 name = canon(agraphof(node), value, buffer);
116 } else
117 name = agstrcanon(value, buffer);
118 printstring(putstr, f, " ", name); /* slimey i know */
119 free(buffer);
120 if (portname && *portname) {
121 char *const buffer2 = agstrcanon_buffer(portname);
122 printstring(putstr, f, ":", agstrcanon(portname, buffer2));
123 free(buffer2);
124 }
125}
126
127void write_plain(GVJ_t *job, graph_t *g, void *f, bool extend) {
128 char *tport, *hport;
129 node_t *n;
130 edge_t *e;
131 bezier bz;
132 pointf pt;
133 char *lbl;
134 char* fillcolor;
135
136 int (*putstr)(void *chan, const char *str) = g->clos->disc.io->putstr;
137 const offsets_t offsets = setYInvert(g);
138 pt = GD_bb(g).UR;
139 printdouble(putstr, f, "graph ", job->zoom);
140 printdouble(putstr, f, " ", PS2INCH(pt.x));
141 printdouble(putstr, f, " ", PS2INCH(pt.y));
142 agputc(putstr, '\n', f);
143 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
144 if (IS_CLUST_NODE(n))
145 continue;
146 char *const node_buffer = agstrcanon_buffer(agnameof(n));
147 printstring(putstr, f, "node ", agstrcanon(agnameof(n), node_buffer));
148 free(node_buffer);
149 printpoint(putstr, f, ND_coord(n), offsets.Y);
150 // if HTML, get original text
151 char *const value = ND_label(n)->html ? agxget(n, N_label) : ND_label(n)->text;
152 char *const buffer = agstrcanon_buffer(value);
153 if (ND_label(n)->html) {
154 lbl = agstrcanon(value, buffer);
155 } else {
156 lbl = canon(agraphof(n), value, buffer);
157 }
158 printdouble(putstr, f, " ", ND_width(n));
159 printdouble(putstr, f, " ", ND_height(n));
160 printstring(putstr, f, " ", lbl);
161 free(buffer);
162 printstring(putstr, f, " ", late_nnstring(n, N_style, "solid"));
163 printstring(putstr, f, " ", ND_shape(n)->name);
164 printstring(putstr, f, " ", late_nnstring(n, N_color, DEFAULT_COLOR));
165 fillcolor = late_nnstring(n, N_fillcolor, "");
166 if (fillcolor[0] == '\0')
167 fillcolor = late_nnstring(n, N_color, DEFAULT_FILL);
168 printstring(putstr, f, " ", fillcolor);
169 agputc(putstr, '\n', f);
170 }
171 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
172 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
173
174 if (extend) { //assuming these two attrs have already been created by cgraph
175 if (!(tport = agget(e,"tailport")))
176 tport = "";
177 if (!(hport = agget(e,"headport")))
178 hport = "";
179 }
180 else
181 tport = hport = "";
182 if (ED_spl(e)) {
183 size_t splinePoints = 0;
184 for (size_t i = 0; i < ED_spl(e)->size; i++) {
185 bz = ED_spl(e)->list[i];
186 splinePoints += bz.size;
187 }
188 printstring(putstr, f, NULL, "edge");
189 writenodeandport(putstr, f, agtail(e), tport);
190 writenodeandport(putstr, f, aghead(e), hport);
191 printint(putstr, f, " ", splinePoints);
192 for (size_t i = 0; i < ED_spl(e)->size; i++) {
193 bz = ED_spl(e)->list[i];
194 for (size_t j = 0; j < bz.size; j++)
195 printpoint(putstr, f, bz.list[j], offsets.Y);
196 }
197 }
198 if (ED_label(e)) {
199 char *const buffer = agstrcanon_buffer(ED_label(e)->text);
200 printstring(putstr, f, " ", canon(agraphof(agtail(e)), ED_label(e)->text,
201 buffer));
202 free(buffer);
203 printpoint(putstr, f, ED_label(e)->pos, offsets.Y);
204 }
205 printstring(putstr, f, " ", late_nnstring(e, E_style, "solid"));
206 printstring(putstr, f, " ", late_nnstring(e, E_color, DEFAULT_COLOR));
207 agputc(putstr, '\n', f);
208 }
209 }
210 agputs(putstr, "stop\n", f);
211}
212
213static void set_record_rects(node_t *n, field_t *f, agxbuf *xb, double yOff) {
214 int i;
215
216 if (f->n_flds == 0) {
217 agxbprint(xb, "%.5g,%.5g,%.5g,%.5g ",
218 f->b.LL.x + ND_coord(n).x,
219 yDir(f->b.LL.y + ND_coord(n).y, yOff),
220 f->b.UR.x + ND_coord(n).x,
221 yDir(f->b.UR.y + ND_coord(n).y, yOff));
222 }
223 for (i = 0; i < f->n_flds; i++)
224 set_record_rects(n, f->fld[i], xb, yOff);
225}
226
227static void rec_attach_bb(graph_t *g, Agsym_t *bbsym, Agsym_t *lpsym,
228 Agsym_t *lwsym, Agsym_t *lhsym, double yOff) {
229 int c;
230 agxbuf buf = {0};
231 pointf pt;
232
233 agxbprint(&buf, "%.5g,%.5g,%.5g,%.5g", GD_bb(g).LL.x,
234 yDir(GD_bb(g).LL.y, yOff), GD_bb(g).UR.x,
235 yDir(GD_bb(g).UR.y, yOff));
236 agxset(g, bbsym, agxbuse(&buf));
237 if (GD_label(g) && GD_label(g)->text[0]) {
238 pt = GD_label(g)->pos;
239 agxbprint(&buf, "%.5g,%.5g", pt.x, yDir(pt.y, yOff));
240 agxset(g, lpsym, agxbuse(&buf));
241 pt = GD_label(g)->dimen;
242 agxbprint(&buf, "%.2f", PS2INCH(pt.x));
243 agxset(g, lwsym, agxbuse(&buf));
244 agxbprint(&buf, "%.2f", PS2INCH(pt.y));
245 agxset(g, lhsym, agxbuse(&buf));
246 }
247 for (c = 1; c <= GD_n_cluster(g); c++)
248 rec_attach_bb(GD_clust(g)[c], bbsym, lpsym, lwsym, lhsym, yOff);
249 agxbfree(&buf);
250}
251
252double attach_attrs_and_arrows(graph_t *g, bool *sp, bool *ep) {
253 node_t *n;
254 edge_t *e;
255 pointf ptf;
256 int dim3 = (GD_odim(g) >= 3);
257 Agsym_t* bbsym = NULL;
258 Agsym_t* lpsym = NULL;
259 Agsym_t* lwsym = NULL;
260 Agsym_t* lhsym = NULL;
261
262 gv_fixLocale (1);
263 bool e_arrows = false; // graph has edges with end arrows
264 bool s_arrows = false; // graph has edges with start arrows
265 const offsets_t offsets = setYInvert(g);
266 agxbuf xb = {0};
267 safe_dcl(g, AGNODE, "pos", "");
268 safe_dcl(g, AGNODE, "rects", "");
269 N_width = safe_dcl(g, AGNODE, "width", "");
270 N_height = safe_dcl(g, AGNODE, "height", "");
271 safe_dcl(g, AGEDGE, "pos", "");
272 if (GD_has_labels(g) & NODE_XLABEL)
273 safe_dcl(g, AGNODE, "xlp", "");
274 if (GD_has_labels(g) & EDGE_LABEL)
275 safe_dcl(g, AGEDGE, "lp", "");
276 if (GD_has_labels(g) & EDGE_XLABEL)
277 safe_dcl(g, AGEDGE, "xlp", "");
278 if (GD_has_labels(g) & HEAD_LABEL)
279 safe_dcl(g, AGEDGE, "head_lp", "");
280 if (GD_has_labels(g) & TAIL_LABEL)
281 safe_dcl(g, AGEDGE, "tail_lp", "");
282 if (GD_has_labels(g) & GRAPH_LABEL) {
283 lpsym = safe_dcl(g, AGRAPH, "lp", "");
284 lwsym = safe_dcl(g, AGRAPH, "lwidth", "");
285 lhsym = safe_dcl(g, AGRAPH, "lheight", "");
286 }
287 bbsym = safe_dcl(g, AGRAPH, "bb", "");
288 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
289 if (dim3) {
290 int k;
291
292 agxbprint(&xb, "%.5g,%.5g,%.5g", ND_coord(n).x,
293 yDir(ND_coord(n).y, offsets.Y),
294 POINTS_PER_INCH * ND_pos(n)[2]);
295 for (k = 3; k < GD_odim(g); k++) {
296 agxbprint(&xb, ",%.5g", POINTS_PER_INCH*(ND_pos(n)[k]));
297 }
298 agset(n, "pos", agxbuse(&xb));
299 } else {
300 agxbprint(&xb, "%.5g,%.5g", ND_coord(n).x, yDir(ND_coord(n).y, offsets.Y));
301 agset(n, "pos", agxbuse(&xb));
302 }
303 agxbprint(&xb, "%.5g", PS2INCH(ND_ht(n)));
304 agxset(n, N_height, agxbuse(&xb));
305 agxbprint(&xb, "%.5g", PS2INCH(ND_lw(n) + ND_rw(n)));
306 agxset(n, N_width, agxbuse(&xb));
307 if (ND_xlabel(n) && ND_xlabel(n)->set) {
308 ptf = ND_xlabel(n)->pos;
309 agxbprint(&xb, "%.5g,%.5g", ptf.x, yDir(ptf.y, offsets.Y));
310 agset(n, "xlp", agxbuse(&xb));
311 }
312 if (strcmp(ND_shape(n)->name, "record") == 0) {
313 set_record_rects(n, ND_shape_info(n), &xb, offsets.Y);
314 agxbpop(&xb); /* get rid of last space */
315 agset(n, "rects", agxbuse(&xb));
316 } else {
318 if (N_vertices && isPolygon(n)) {
319 poly = ND_shape_info(n);
320 size_t sides = poly->sides;
321 if (sides < 3) {
322 char *p = agget(n, "samplepoints");
323 if (p)
324 sides = strtoul(p, NULL, 0);
325 else
326 sides = 8;
327 if (sides < 3)
328 sides = 8;
329 }
330 for (size_t i = 0; i < sides; i++) {
331 if (i > 0)
332 agxbputc(&xb, ' ');
333 if (poly->sides >= 3)
334 agxbprint(&xb, "%.5g %.5g",
335 PS2INCH(poly->vertices[i].x),
336 YFDIR(offsets, PS2INCH(poly->vertices[i].y)));
337 else
338 agxbprint(&xb, "%.5g %.5g",
339 ND_width(n) / 2.0 * cos((double)i / (double)sides * M_PI * 2.0),
340 YFDIR(offsets,
341 ND_height(n) / 2.0 * sin((double)i / (double)sides * M_PI * 2.0)));
342 }
343 agxset(n, N_vertices, agxbuse(&xb));
344 }
345 }
346 if (State >= GVSPLINES) {
347 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
348 if (ED_edge_type(e) == IGNORED)
349 continue;
350 if (ED_spl(e) == NULL)
351 continue; /* reported in postproc */
352 for (size_t i = 0; i < ED_spl(e)->size; i++) {
353 if (i > 0)
354 agxbputc(&xb, ';');
355 if (ED_spl(e)->list[i].sflag) {
356 s_arrows = true;
357 agxbprint(&xb, "s,%.5g,%.5g ",
358 ED_spl(e)->list[i].sp.x,
359 yDir(ED_spl(e)->list[i].sp.y, offsets.Y));
360 }
361 if (ED_spl(e)->list[i].eflag) {
362 e_arrows = true;
363 agxbprint(&xb, "e,%.5g,%.5g ",
364 ED_spl(e)->list[i].ep.x,
365 yDir(ED_spl(e)->list[i].ep.y, offsets.Y));
366 }
367 for (size_t j = 0; j < ED_spl(e)->list[i].size; j++) {
368 if (j > 0)
369 agxbputc(&xb, ' ');
370 ptf = ED_spl(e)->list[i].list[j];
371 agxbprint(&xb, "%.5g,%.5g", ptf.x, yDir(ptf.y, offsets.Y));
372 }
373 }
374 agset(e, "pos", agxbuse(&xb));
375 if (ED_label(e)) {
376 ptf = ED_label(e)->pos;
377 agxbprint(&xb, "%.5g,%.5g", ptf.x, yDir(ptf.y, offsets.Y));
378 agset(e, "lp", agxbuse(&xb));
379 }
380 if (ED_xlabel(e) && ED_xlabel(e)->set) {
381 ptf = ED_xlabel(e)->pos;
382 agxbprint(&xb, "%.5g,%.5g", ptf.x, yDir(ptf.y, offsets.Y));
383 agset(e, "xlp", agxbuse(&xb));
384 }
385 if (ED_head_label(e)) {
386 ptf = ED_head_label(e)->pos;
387 agxbprint(&xb, "%.5g,%.5g", ptf.x, yDir(ptf.y, offsets.Y));
388 agset(e, "head_lp", agxbuse(&xb));
389 }
390 if (ED_tail_label(e)) {
391 ptf = ED_tail_label(e)->pos;
392 agxbprint(&xb, "%.5g,%.5g", ptf.x, yDir(ptf.y, offsets.Y));
393 agset(e, "tail_lp", agxbuse(&xb));
394 }
395 }
396 }
397 }
398 rec_attach_bb(g, bbsym, lpsym, lwsym, lhsym, offsets.Y);
399 agxbfree(&xb);
400
401 if (HAS_CLUST_EDGE(g))
403
404 if (sp != NULL) {
405 *sp = s_arrows;
406 }
407 if (ep != NULL) {
408 *ep = e_arrows;
409 }
410 gv_fixLocale (0);
411 return offsets.Y;
412}
413
415{
417}
418
Helpers for dealing with agstrcanon
static char * agstrcanon_buffer(const char *str)
get a buffer suitable for passing into agstrcanon
Definition agstrcanon.h:16
static int agxbpop(agxbuf *xb)
removes last character added, if any
Definition agxbuf.h:111
static void agxbfree(agxbuf *xb)
free any malloced resources
Definition agxbuf.h:78
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:234
static WUR char * agxbuse(agxbuf *xb)
Definition agxbuf.h:307
static int agxbputc(agxbuf *xb, char c)
add character to buffer
Definition agxbuf.h:277
#define M_PI
Definition arith.h:41
void undoClusterEdges(graph_t *g)
Definition utils.c:1026
char * late_nnstring(void *obj, attrsym_t *attr, char *defaultValue)
Definition utils.c:86
attrsym_t * safe_dcl(graph_t *g, int obj_kind, char *name, char *defaultValue)
Definition utils.c:1061
#define HEAD_LABEL
Definition const.h:177
#define EDGE_XLABEL
Definition const.h:181
#define GRAPH_LABEL
Definition const.h:179
#define TAIL_LABEL
Definition const.h:178
#define EDGE_LABEL
Definition const.h:176
#define IGNORED
Definition const.h:30
#define DEFAULT_COLOR
Definition const.h:48
#define DEFAULT_FILL
Definition const.h:69
#define GVSPLINES
Definition const.h:173
#define NODE_XLABEL
Definition const.h:180
void gv_fixLocale(int set)
Definition emit.c:3848
#define PS2INCH(a_points)
Definition geom.h:64
#define POINTS_PER_INCH
Definition geom.h:58
Agsym_t * N_width
Definition globals.h:74
int State
Definition globals.h:63
Agsym_t * E_style
Definition globals.h:84
Agsym_t * N_style
Definition globals.h:76
Agsym_t * E_color
Definition globals.h:82
Agsym_t * N_label
Definition globals.h:76
Agsym_t * N_fillcolor
Definition globals.h:74
Agsym_t * N_vertices
Definition globals.h:79
bool Y_invert
invert y in dot & plain output
Definition globals.h:67
Agsym_t * N_color
Definition globals.h:74
Agsym_t * N_height
Definition globals.h:74
void free(void *)
require define api prefix
Definition gmlparse.y:17
node NULL
Definition grammar.y:181
int agset(void *obj, char *name, const char *value)
Definition attr.c:489
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:536
char * agget(void *obj, char *name)
Definition attr.c:462
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:472
#define ED_xlabel(e)
Definition types.h:590
#define ED_head_label(e)
Definition types.h:587
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:26
#define ED_spl(e)
Definition types.h:595
#define agtail(e)
Definition cgraph.h:988
#define ED_edge_type(e)
Definition types.h:582
#define ED_tail_label(e)
Definition types.h:596
#define aghead(e)
Definition cgraph.h:989
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:41
#define ED_label(e)
Definition types.h:589
#define GD_has_labels(g)
Definition types.h:368
#define GD_clust(g)
Definition types.h:360
#define GD_bb(g)
Definition types.h:354
#define GD_n_cluster(g)
Definition types.h:389
#define GD_label(g)
Definition types.h:374
#define GD_odim(g)
Definition types.h:391
#define ND_ht(n)
Definition types.h:500
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:48
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:41
#define ND_label(n)
Definition types.h:502
#define ND_rw(n)
Definition types.h:525
#define ND_height(n)
Definition types.h:498
#define ND_width(n)
Definition types.h:536
#define ND_lw(n)
Definition types.h:506
#define ND_xlabel(n)
Definition types.h:503
#define ND_shape_info(n)
Definition types.h:529
#define ND_pos(n)
Definition types.h:520
#define ND_coord(n)
Definition types.h:490
#define ND_shape(n)
Definition types.h:528
Agraph_t * agraphof(void *obj)
Definition obj.c:185
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:143
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
@ AGRAPH
Definition cgraph.h:207
char * agstrcanon(char *, char *)
Definition write.c:219
int agstrfree(Agraph_t *, const char *, bool is_html)
Definition refstr.c:415
char * agstrdup(Agraph_t *, const char *)
returns a pointer to a reference-counted copy of the argument string, creating one if necessary
Definition refstr.c:399
void attach_attrs(graph_t *g)
Definition output.c:414
Graphviz context library.
textitem scanner parser str
Definition htmlparse.y:224
#define IS_CLUST_NODE(n)
Definition macros.h:23
#define HAS_CLUST_EDGE(g)
Definition macros.h:24
static void agputs(int(*putstr)(void *chan, const char *str), const char *s, void *fp)
Definition output.c:37
static void printpoint(int(*putstr)(void *chan, const char *str), void *f, pointf p, double yOff)
Definition output.c:74
static void printdouble(int(*putstr)(void *chan, const char *str), void *f, char *prefix, double v)
Definition output.c:64
static void writenodeandport(int(*putstr)(void *chan, const char *str), FILE *f, node_t *node, char *portname)
Definition output.c:108
static void rec_attach_bb(graph_t *g, Agsym_t *bbsym, Agsym_t *lpsym, Agsym_t *lwsym, Agsym_t *lhsym, double yOff)
Definition output.c:227
void write_plain(GVJ_t *job, graph_t *g, void *f, bool extend)
Definition output.c:127
static double YFDIR(offsets_t offsets, double y)
Definition output.c:29
double attach_attrs_and_arrows(graph_t *g, bool *sp, bool *ep)
Definition output.c:252
double yDir(double y, double Y_off)
Definition output.c:33
static void agputc(int(*putstr)(void *chan, const char *str), char c, void *fp)
Definition output.c:42
static char * canon(graph_t *g, char *s, char *buffer)
Definition output.c:101
static void printint(int(*putstr)(void *chan, const char *str), void *f, char *prefix, size_t i)
Definition output.c:54
static void printstring(int(*putstr)(void *chan, const char *str), void *f, char *prefix, char *s)
Definition output.c:48
static void set_record_rects(node_t *n, field_t *f, agxbuf *xb, double yOff)
Definition output.c:213
static offsets_t setYInvert(graph_t *g)
Definition output.c:86
#define PRISIZE_T
Definition prisize_t.h:25
bool isPolygon(node_t *)
Definition shapes.c:1926
Agdisc_t disc
Definition cgraph.h:411
Agiodisc_t * io
Definition cgraph.h:338
int(* putstr)(void *chan, const char *str)
Definition cgraph.h:328
graph or subgraph
Definition cgraph.h:424
Agclos_t * clos
shared resources
Definition cgraph.h:434
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:651
double zoom
Definition gvcjob.h:318
Definition types.h:89
size_t size
Definition types.h:91
pointf * list
Definition types.h:90
pointf UR
Definition geom.h:41
pointf LL
Definition geom.h:41
int n_flds
Definition types.h:238
boxf b
Definition types.h:237
struct field_t ** fld
Definition types.h:240
state for offset calculations
Definition output.c:24
double YF
Y in inches
Definition output.c:26
double Y
ymin + ymax
Definition output.c:25
double x
Definition geom.h:29
double y
Definition geom.h:29
struct poly_s poly
Definition grammar.c:89