Graphviz  2.41.20171026.1811
picgen.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 
15 #include "render.h"
16 
17 #define PIC_COORDS_PER_LINE (16) /* to avoid stdio BUF overflow */
18 
19 static box BB;
20 static int BezierSubdivision = 10;
21 static int Rot;
22 static int onetime = TRUE;
23 static double Scale;
24 static double Fontscale;
25 
26 /* static char **U_lib,*User,*Vers; */
27 static const char *EscComment = ".\\\" "; /* troff comment */
28 
29 typedef struct grcontext_t {
30  char *color, *font;
31  double size;
32 } grcontext_t;
33 
34 #define STACKSIZE 8
35 static grcontext_t S[STACKSIZE];
36 static int SP = 0;
37 
38 static char picgen_msghdr[] = "dot picgen: ";
39 static void unsupported(char *s)
40 {
41  agerr(AGWARN, "%s%s unsupported\n", picgen_msghdr, s);
42 }
43 static void warn(char *s)
44 {
45  agerr(AGWARN, "%s%s\n", picgen_msghdr, s);
46 }
47 
48 /* There are a couple of ways to generate output:
49  1. generate for whatever size is given by the bounding box
50  - the drawing at its "natural" size might not fit on a physical page
51  ~ dot size specification can be used to scale the drawing
52  ~ and it's not difficult for user to scale the pic output to fit (multiply 4 (3 distinct) numbers on 3 lines by a scale factor)
53  - some troff implementations may clip large graphs
54  ~ handle by scaling to manageable size
55  - give explicit width and height as parameters to .PS
56  - pic scale variable is reset to 1.0
57  - fonts are printed as size specified by caller, modified by user scaling
58  2. scale to fit on a physical page
59  - requires an assumption of page size (GNU pic assumes 8.5x11.0 inches)
60  ~ any assumption is bound to be wrong more often than right
61  - requires separate scaling of font point sizes since pic's scale variable doesn't affect text
62  ~ possible, as above
63  - likewise for line thickness
64  - GNU pic does this (except for fonts) if .PS is used without explicit width or height; DWB pic does not
65  ~ pic variants likely to cause trouble
66  The first approach is used here.
67 */
68 
69 static pointf cvt2ptf(point p)
70 {
71  pointf r;
72 
73  r.x = PS2INCH(p.x);
74  r.y = PS2INCH(p.y);
75  return r;
76 }
77 
78 
79 /* troff font mapping */
80 typedef struct {
81  char trname[3], *psname;
82 } fontinfo;
83 
84 static fontinfo fonttab[] = {
85  {"AB", "AvantGarde-Demi"},
86  {"AI", "AvantGarde-BookOblique"},
87  {"AR", "AvantGarde-Book"},
88  {"AX", "AvantGarde-DemiOblique"},
89  {"B ", "Times-Bold"},
90  {"BI", "Times-BoldItalic"},
91  {"CB", "Courier-Bold"},
92  {"CO", "Courier"},
93  {"CX", "Courier-BoldOblique"},
94  {"H ", "Helvetica"},
95  {"HB", "Helvetica-Bold"},
96  {"HI", "Helvetica-Oblique"},
97  {"HX", "Helvetica-BoldOblique"},
98  {"Hb", "Helvetica-Narrow-Bold"},
99  {"Hi", "Helvetica-Narrow-Oblique"},
100  {"Hr", "Helvetica-Narrow"},
101  {"Hx", "Helvetica-Narrow-BoldOblique"},
102  {"I ", "Times-Italic"},
103  {"KB", "Bookman-Demi"},
104  {"KI", "Bookman-LightItalic"},
105  {"KR", "Bookman-Light"},
106  {"KX", "Bookman-DemiItalic"},
107  {"NB", "NewCenturySchlbk-Bold"},
108  {"NI", "NewCenturySchlbk-Italic"},
109  {"NR", "NewCenturySchlbk-Roman"},
110  {"NX", "NewCenturySchlbk-BoldItalic"},
111  {"PA", "Palatino-Roman"},
112  {"PB", "Palatino-Bold"},
113  {"PI", "Palatino-Italic"},
114  {"PX", "Palatino-BoldItalic"},
115  {"R ", "Times-Roman"},
116  {"S ", "Symbol"},
117  {"ZD", "ZapfDingbats"},
118  {"\000\000", (char *) 0}
119 };
120 
121 static char *picfontname(char *psname)
122 {
123  char *rv;
124  fontinfo *p;
125 
126  for (p = fonttab; p->psname; p++)
127  if (streq(p->psname, psname))
128  break;
129  if (p->psname)
130  rv = p->trname;
131  else {
132  agerr(AGERR, "%s%s is not a troff font\n", picgen_msghdr, psname);
133  /* try base font names, e.g. Helvetica-Outline-Oblique -> Helvetica-Outline -> Helvetica */
134  if ((rv = strrchr(psname, '-'))) {
135  *rv = '\0'; /* psname is not specified as const ... */
136  rv = picfontname(psname);
137  } else
138  rv = "R";
139  }
140  return rv;
141 }
142 
143 static char *pic_fcoord(char *buf, pointf pf)
144 {
145  sprintf(buf, "(%.5f,%.5f)", Scale * pf.x, Scale * pf.y);
146  return buf;
147 }
148 
149 static char *pic_coord(char *buf, point p)
150 {
151  return pic_fcoord(buf, cvt2ptf(p));
152 }
153 
154 static void pic_reset(void)
155 {
156  onetime = TRUE;
157 }
158 
159 static void pic_begin_job(FILE * ofp, graph_t * g, const char **lib, char *info[], point pages)
160 {
161  /* U_lib = lib; */
162  if (onetime && (pages.x * pages.y > 1)) {
163  unsupported("pagination");
164  onetime = FALSE;
165  }
166  fprintf(Output_file, "%s Creator: %s version %s (%s)\n",
167  EscComment, info[0], info[1], info[2]);
168  fprintf(Output_file, "%s Title: %s\n", EscComment, agnameof(g));
169 }
170 
171 static void pic_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb)
172 {
173  BB = bb;
174 
175  fprintf(Output_file,
176  "%s save point size and font\n.nr .S \\n(.s\n.nr DF \\n(.f\n",
177  EscComment);
178 }
179 
180 static void pic_end_graph(void)
181 {
182  fprintf(Output_file,
183  "%s restore point size and font\n.ps \\n(.S\n.ft \\n(DF\n",
184  EscComment);
185 }
186 
187 static void pic_begin_page(graph_t * g, point page, double scale, int rot,
188  point offset)
189 {
190  double height, width;
191 
192  if (onetime && rot && (rot != 90)) {
193  unsupported("rotation");
194  onetime = FALSE;
195  }
196  Rot = rot;
197  height = PS2INCH((double) (BB.UR.y) - (double) (BB.LL.y));
198  width = PS2INCH((double) (BB.UR.x) - (double) (BB.LL.x));
199  Scale = scale;
200  if (Rot == 90) {
201  double temp = width;
202  width = height;
203  height = temp;
204  }
205  fprintf(Output_file, ".PS %.5f %.5f\n", width, height);
206  EscComment = "#"; /* pic comment */
207  fprintf(Output_file,
208  "%s to change drawing size, multiply the width and height on the .PS line above and the number on the two lines below (rounded to the nearest integer) by a scale factor\n",
209  EscComment);
210  if (width > 0.0) {
211  Fontscale = log10(width);
212  Fontscale += 3.0 - (int) Fontscale; /* between 3.0 and 4.0 */
213  } else
214  Fontscale = 3.0;
215  Fontscale = pow(10.0, Fontscale); /* a power of 10 times width, between 1000 and 10000 */
216  fprintf(Output_file, ".nr SF %.0f\nscalethickness = %.0f\n", Fontscale,
217  Fontscale);
218  fprintf(Output_file,
219  "%s don't change anything below this line in this drawing\n",
220  EscComment);
221  fprintf(Output_file,
222  "%s non-fatal run-time pic version determination, version 2\n",
223  EscComment);
224  fprintf(Output_file,
225  "boxrad=2.0 %s will be reset to 0.0 by gpic only\n",
226  EscComment);
227  fprintf(Output_file, "scale=1.0 %s required for comparisons\n",
228  EscComment);
229  fprintf(Output_file,
230  "%s boxrad is now 0.0 in gpic, else it remains 2.0\n",
231  EscComment);
232  fprintf(Output_file,
233  "%s dashwid is 0.1 in 10th Edition, 0.05 in DWB 2 and in gpic\n",
234  EscComment);
235  fprintf(Output_file,
236  "%s fillval is 0.3 in 10th Edition (fill 0 means black), 0.5 in gpic (fill 0 means white), undefined in DWB 2\n",
237  EscComment);
238  fprintf(Output_file,
239  "%s fill has no meaning in DWB 2, gpic can use fill or filled, 10th Edition uses fill only\n",
240  EscComment);
241  fprintf(Output_file,
242  "%s DWB 2 doesn't use fill and doesn't define fillval\n",
243  EscComment);
244  fprintf(Output_file,
245  "%s reset works in gpic and 10th edition, but isn't defined in DWB 2\n",
246  EscComment);
247  fprintf(Output_file, "%s DWB 2 compatibility definitions\n",
248  EscComment);
249  fprintf(Output_file,
250  "if boxrad > 1.0 && dashwid < 0.075 then X\n\tfillval = 1;\n\tdefine fill Y Y;\n\tdefine solid Y Y;\n\tdefine reset Y scale=1.0 Y;\nX\n");
251  fprintf(Output_file, "reset %s set to known state\n", EscComment);
252  fprintf(Output_file, "%s GNU pic vs. 10th Edition d\\(e'tente\n",
253  EscComment);
254  fprintf(Output_file,
255  "if fillval > 0.4 then X\n\tdefine setfillval Y fillval = 1 - Y;\n\tdefine bold Y thickness 2 Y;\n");
256  fprintf(Output_file,
257  "\t%s if you use gpic and it barfs on encountering \"solid\",\n",
258  EscComment);
259  fprintf(Output_file,
260  "\t%s\tinstall a more recent version of gpic or switch to DWB or 10th Edition pic;\n",
261  EscComment);
262  fprintf(Output_file,
263  "\t%s\tsorry, the groff folks changed gpic; send any complaint to them;\n",
264  EscComment);
265  fprintf(Output_file,
266  "X else Z\n\tdefine setfillval Y fillval = Y;\n\tdefine bold Y Y;\n\tdefine filled Y fill Y;\nZ\n");
267  fprintf(Output_file,
268  "%s arrowhead has no meaning in DWB 2, arrowhead = 7 makes filled arrowheads in gpic and in 10th Edition\n",
269  EscComment);
270  fprintf(Output_file,
271  "%s arrowhead is undefined in DWB 2, initially 1 in gpic, 2 in 10th Edition\n",
272  EscComment);
273  fprintf(Output_file, "arrowhead = 7 %s not used by graphviz\n",
274  EscComment);
275  fprintf(Output_file,
276  "%s GNU pic supports a boxrad variable to draw boxes with rounded corners; DWB and 10th Ed. do not\n",
277  EscComment);
278  fprintf(Output_file, "boxrad = 0 %s no rounded corners in graphviz\n",
279  EscComment);
280  fprintf(Output_file,
281  "%s GNU pic supports a linethick variable to set line thickness; DWB and 10th Ed. do not\n",
282  EscComment);
283  fprintf(Output_file, "linethick = 0; oldlinethick = linethick\n");
284  fprintf(Output_file,
285  "%s .PS w/o args causes GNU pic to scale drawing to fit 8.5x11 paper; DWB does not\n",
286  EscComment);
287  fprintf(Output_file,
288  "%s maxpsht and maxpswid have no meaning in DWB 2.0, set page boundaries in gpic and in 10th Edition\n",
289  EscComment);
290  fprintf(Output_file,
291  "%s maxpsht and maxpswid are predefined to 11.0 and 8.5 in gpic\n",
292  EscComment);
293  fprintf(Output_file, "maxpsht = %f\nmaxpswid = %f\n", height, width);
294  fprintf(Output_file, "Dot: [\n");
295  fprintf(Output_file,
296  "define attrs0 %% %%; define unfilled %% %%; define rounded %% %%; define diagonals %% %%\n");
297 }
298 
299 static void pic_end_page(void)
300 {
301  fprintf(Output_file, "]\n.PE\n");
302  EscComment = ".\\\" "; /* troff comment */
303  assert(SP == 0);
304 }
305 
306 static void pic_begin_node(node_t * n)
307 {
308  fprintf(Output_file, "%s\t%s\n", EscComment, agnameof(n));
309 }
310 
311 static void pic_begin_edge(edge_t * e)
312 {
313  fprintf(Output_file, "%s\t%s -> %s\n", EscComment,
314  agnameof(agtail(e)), agnameof(aghead(e)));
315 }
316 
317 static void pic_begin_context(void)
318 {
319  fprintf(Output_file, "{\n");
320  if (SP == STACKSIZE - 1)
321  warn("stk ovfl");
322  else {
323  SP++;
324  S[SP] = S[SP - 1];
325  fprintf(Output_file, "define attrs%d %% %%\n", SP); /* ensure plain (no attributes) style at start of context */
326  }
327 }
328 
329 static void pic_end_context(void)
330 {
331  if (SP == 0)
332  warn("stk undfl");
333  else {
334  SP--;
335  fprintf(Output_file, "}\n"); /* end context group */
336  /* restore correct font and size for context */
337  if (S[SP + 1].font
338  && (!(S[SP].font) || strcmp(S[SP + 1].font, S[SP].font)))
339  fprintf(Output_file, ".ft %s\n", picfontname(S[SP].font));
340  if (S[SP + 1].size != S[SP].size) {
341  int sz;
342 
343  if ((sz = (int) (S[SP].size * Scale)) < 1)
344  sz = 1;
345  fprintf(Output_file, ".ps %d*\\n(SFu/%.0fu\n", sz, Fontscale);
346  }
347  fprintf(Output_file, "linethick = oldlinethick\n");
348  }
349 }
350 
351 static void pic_set_font(char *name, double size)
352 {
353  if (name && (!(S[SP].font) || strcmp(S[SP].font, name))) {
354  S[SP].font = name;
355  fprintf(Output_file, ".ft %s\n", picfontname(name));
356  }
357  if (size != S[SP].size) {
358  int sz;
359 
360  S[SP].size = size;
361  if ((sz = (int) (size * Scale)) < 1)
362  sz = 1;
363  fprintf(Output_file, ".ps %d*\\n(SFu/%.0fu\n", sz, Fontscale);
364  }
365 }
366 
367 static char *pic_string(char *s)
368 {
369  static char *buf = NULL;
370  static int bufsize = 0;
371  int pos = 0;
372  char *p;
373 
374  if (!buf) {
375  bufsize = 64;
376  buf = N_GNEW(bufsize, char);
377  }
378 
379  p = buf;
380  while (*s) {
381  if (pos > (bufsize - 8)) {
382  bufsize *= 2;
383  buf = grealloc(buf, bufsize);
384  p = buf + pos;
385  }
386  if (*s == '\015') { /* GACK, PTUI! Fire up the teletype, boys;
387  somebody's sending an old-fashioned mechanical
388  "carriage return" control character. */
389  s++;
390  continue;
391  }
392  if (*s == '\\') {
393  strcpy(p, "\\(rs"); /* e.g. man 5 groff_char from mkssoftware.com */
394  p += 4;
395  pos += 4;
396  s++;
397  continue;
398  }
399  *p++ = *s++;
400  pos++;
401  }
402  *p = '\0';
403  return buf;
404 }
405 
406 static void pic_textpara(point p, textpara_t * para)
407 {
408  pointf pf;
409  short flag = 0;
410  double fontsz = S[SP].size;
411 
412  switch (para->just) {
413  case 'l':
414  p.x = p.x;
415  break;
416  case 'r':
417  p.x = p.x - para->width;
418  break;
419  default:
420  case 'n':
421  p.x = p.x - para->width / 2;
422  break;
423  }
424  pf = cvt2ptf(p);
425  /* Why on earth would we do this. But it works. SCN 2/26/2002 */
426  /* adjust text baseline for quirks of the renderer */
427  pf.y += fontsz / (3.0 * POINTS_PER_INCH);
428  pf.x += para->width / (2.0 * POINTS_PER_INCH);
429  if (!(S[SP].size)) { /* size was never set in this or hierarchically higher context */
430  pic_set_font(S[SP].font, fontsz); /* primarily to output font and/or size directives */
431  for (flag = SP; ((S[flag].size = fontsz), flag); flag--) /* set size in contexts */
432  ; /* flag is zero again at loop termination */
433  }
434  if (fontsz != S[SP].size) { /* size already set in context,
435  but different from request; start new context */
436  flag = 1;
437  pic_begin_context();
438  pic_set_font(S[SP - 1].font, fontsz);
439  }
440  fprintf(Output_file, "\"%s\" at (%.5f,%.5f);\n",
441  pic_string(para->str), Scale * pf.x, Scale * pf.y);
442  if (flag)
443  pic_end_context();
444 }
445 
446 static void pic_set_color(char *name)
447 {
448  gvcolor_t color;
449 
450  S[SP].color = name;
451  colorxlate(name, &color, HSVA_DOUBLE);
452  /* just v used to set grayscale value */
453  fprintf(Output_file, "setfillval %f\n", color.u.HSVA[2]);
454 }
455 
456 static void pic_set_style(char **s)
457 {
458  const char *line, *p;
459  char skip = 0;
460  char buf[BUFSIZ];
461 
462  buf[0] = '\0';
463  fprintf(Output_file, "define attrs%d %%", SP);
464  while ((p = line = *s++)) {
465  while (*p)
466  p++;
467  p++;
468  while (*p) {
469  if (!strcmp(line, "setlinewidth")) { /* a hack to handle the user-defined (PS) style spec in proc3d.dot */
470  long n = atol(p);
471 
472  sprintf(buf,
473  "oldlinethick = linethick;linethick = %ld * scalethickness / %.0f\n",
474  n, Fontscale / Scale);
475  skip = 1;
476  } else
477  fprintf(Output_file, " %s", p);
478  while (*p)
479  p++;
480  p++;
481  }
482  if (!skip)
483  fprintf(Output_file, " %s", line);
484  skip = 0;
485  }
486  fprintf(Output_file, " %%\n");
487  fprintf(Output_file, "%s", buf);
488 }
489 
490 static void pic_ellipse(point p, int rx, int ry, int filled)
491 {
492  pointf pf;
493 
494  pf = cvt2ptf(p);
495  fprintf(Output_file,
496  "ellipse attrs%d %swid %.5f ht %.5f at (%.5f,%.5f);\n", SP,
497  filled ? "fill " : "", Scale * PS2INCH(2 * rx),
498  Scale * PS2INCH(2 * ry), Scale * pf.x, Scale * pf.y);
499 }
500 
501 static void point_list_out(point * A, int n, int close)
502 {
503  int j;
504  char buf[SMALLBUF];
505 
506  for (j = 0; j < n; j++)
507  fprintf(Output_file, "P%d: %s\n", j, pic_coord(buf, A[j]));
508  for (j = 0; j + 1 < n; j++)
509  fprintf(Output_file, "move to P%d; line attrs%d to P%d\n", j, SP,
510  j + 1);
511  if (close)
512  fprintf(Output_file, "move to P%d; line attrs%d to P0\n", n - 1,
513  SP);
514 }
515 
516 static void pic_polygon(point * A, int n, int filled)
517 {
518  /* test for special case: rectangle oriented with page */
519  if ((n == 4) && (((A[0].x == A[1].x) && (A[0].y == A[3].y)
520  && (A[1].y == A[2].y) && (A[2].x == A[3].x))
521  || ((A[0].y == A[1].y) && (A[0].x == A[3].x)
522  && (A[1].x == A[2].x) && (A[2].y == A[3].y))
523  )) {
524  pointf pf1, pf2;
525 
526  pf1 = cvt2ptf(A[0]); /* opposite */
527  pf2 = cvt2ptf(A[2]); /* corners */
528  if (filled) {
529  gvcolor_t color;
530 
531  colorxlate(S[SP].color, &color, HSVA_DOUBLE);
532  fprintf(Output_file, "setfillval %f\n", color.u.HSVA[2]);
533  }
534  fprintf(Output_file, "box attrs%d %swid %.5f ht %.5f at (%.5f,%.5f);\n", SP, filled ? "fill " : "", Scale * fabs(pf1.x - pf2.x), Scale * fabs(pf1.y - pf2.y), /* width, height */
535  Scale * (pf1.x + pf2.x) / 2.0, Scale * (pf1.y + pf2.y) / 2.0); /* center coordinates */
536  return;
537  }
538  if (onetime && filled) {
539  unsupported("shape fill");
540  onetime = FALSE;
541  }
542  point_list_out(A, n, TRUE);
543 }
544 
545 static void pic_polyline(point * A, int n)
546 {
547  point_list_out(A, n, FALSE);
548 }
549 
550 static void pic_usershape(usershape_t *us, boxf b, point *A, int n, boolean filled)
551 {
552 /* FIXME */
553  /* it's not at all clear what xxx_user_shape is supposed to do; in most xxxgen.c files it emits a message */
554  /* this defines the shape as a macro and then invokes the macro */
555  fprintf(Output_file, "define %s {\n", us->name);
556  fprintf(Output_file, "}\n%s\n", us->name);
557 }
558 
559 static void pic_bezier(point * A, int n, int arrow_at_start,
560  int arrow_at_end, int filled)
561 {
562  pointf V[4], p;
563  int i, j, m, step;
564  char buf[SMALLBUF];
565 
566  if (arrow_at_start || arrow_at_end)
567  warn("not supposed to be making arrows here!");
568  V[3] = cvt2ptf(A[0]); /* initial cond */
569  for (i = m = 0; i + 3 < n; i += 3) {
570  V[0] = V[3];
571  for (j = 1; j <= 3; j++)
572  V[j] = cvt2ptf(A[i + j]);
573  p = Bezier(V, 3, 0.0, NULL, NULL);
574  if (!i)
575  fprintf(Output_file, "P0: %s\n", pic_fcoord(buf, p));
576  for (step = 1; step <= BezierSubdivision; step++) {
577  p = Bezier(V, 3, (double) step / BezierSubdivision, NULL,
578  NULL);
579  ++m;
580  fprintf(Output_file, "P%d: %s\n", m, pic_fcoord(buf, p));
581  }
582  }
583  for (i = 0; i + 2 <= m; i += 2) /* DWB 2 pic suffers from severe roundoff errors if too many steps are plotted at once */
584  fprintf(Output_file, "move to P%d; line attrs%d to P%d then to P%d\n", i, SP, i + 1, i + 2); /* use line, as splines can't be dotted or dashed */
585 }
586 
587 static void pic_comment(char *str)
588 {
589  fprintf(Output_file, "'\\\" %s\n", str);
590 }
591 
592 codegen_t PIC_CodeGen = {
593  pic_reset,
594  pic_begin_job, 0, /* pic_end_job */
595  pic_begin_graph, pic_end_graph,
596  pic_begin_page, pic_end_page,
597  0, /* pic_begin_layer */ 0, /* pic_end_layer */
598  0, /* pic_begin_cluster */ 0, /* pic_end_cluster */
599  0, /* pic_begin_nodes */ 0, /* pic_end_nodes */
600  0, /* pic_begin_edges */ 0, /* pic_end_edges */
601  pic_begin_node, 0, /* pic_end_node */
602  pic_begin_edge, 0, /* pic_end_edge */
603  pic_begin_context, pic_end_context,
604  0, /* pic_begin_anchor */ 0, /* pic_end_anchor */
605  pic_set_font, pic_textpara,
606  pic_set_color, pic_set_color, pic_set_style,
607  pic_ellipse, pic_polygon,
608  pic_bezier, pic_polyline,
609  0, /* bezier_has_arrows */
610  pic_comment,
611  pic_usershape
612 };
codegen_t PIC_CodeGen
Definition: picgen.c:592
Definition: cgraph.h:388
union color_s::@10 u
void * grealloc(void *ptr, size_t size)
Definition: memory.c:54
char * color
Definition: mpgen.c:36
#define SMALLBUF
Definition: const.h:17
char * font
Definition: mpgen.c:36
char * psname
Definition: picgen.c:81
#define assert(x)
Definition: cghdr.h:47
Definition: geom.h:28
Definition: color.h:34
int agerr(agerrlevel_t level, const char *fmt,...)
Definition: agerror.c:141
point UR
Definition: geom.h:33
int x
Definition: geom.h:26
#define POINTS_PER_INCH
Definition: geom.h:62
Definition: cgraph.h:388
#define PS2INCH(a_points)
Definition: geom.h:69
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
Definition: edge.c:525
int
Definition: grammar.c:1264
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
Definition: edge.c:533
char trname[3]
Definition: picgen.c:81
double y
Definition: geom.h:28
Definition: gvcint.h:70
CGRAPH_API char * agnameof(void *)
Definition: id.c:143
point LL
Definition: geom.h:33
Definition: grammar.c:79
int colorxlate(char *str, gvcolor_t *color, color_type_t target_type)
Definition: colxlate.c:254
double HSVA[4]
Definition: color.h:37
pointf Bezier(pointf *V, int degree, double t, pointf *Left, pointf *Right)
Definition: utils.c:221
#define NULL
Definition: logic.h:39
Definition: geom.h:26
double x
Definition: geom.h:28
#define streq(s, t)
Definition: cghdr.h:52
GVC_t * gvc
Definition: htmlparse.c:87
#define STACKSIZE
Definition: picgen.c:34
double size
Definition: mpgen.c:37
void(* pf)(char *, void *)
Definition: xdot.c:501
struct grcontext_t grcontext_t
agxbuf * str
Definition: htmlparse.c:85
int y
Definition: geom.h:26
const char * name
Definition: usershape.h:53
Definition: geom.h:35
#define N_GNEW(n, t)
Definition: agxbuf.c:20
#define FALSE
Definition: cgraph.h:35
Definition: geom.h:33
#define TRUE
Definition: cgraph.h:38