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