17 #define PIC_COORDS_PER_LINE (16)
20 static int BezierSubdivision = 10;
22 static int onetime =
TRUE;
24 static double Fontscale;
27 static const char *EscComment =
".\\\" ";
38 static char picgen_msghdr[] =
"dot picgen: ";
39 static void unsupported(
char *
s)
41 agerr(
AGWARN,
"%s%s unsupported\n", picgen_msghdr, s);
43 static void warn(
char *
s)
81 char trname[3], *psname;
85 {
"AB",
"AvantGarde-Demi"},
86 {
"AI",
"AvantGarde-BookOblique"},
87 {
"AR",
"AvantGarde-Book"},
88 {
"AX",
"AvantGarde-DemiOblique"},
90 {
"BI",
"Times-BoldItalic"},
91 {
"CB",
"Courier-Bold"},
93 {
"CX",
"Courier-BoldOblique"},
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"},
117 {
"ZD",
"ZapfDingbats"},
118 {
"\000\000", (
char *) 0}
121 static char *picfontname(
char *psname)
126 for (p = fonttab; p->
psname; p++)
132 agerr(
AGERR,
"%s%s is not a troff font\n", picgen_msghdr, psname);
134 if ((rv = strrchr(psname,
'-'))) {
136 rv = picfontname(psname);
143 static char *pic_fcoord(
char *buf,
pointf pf)
145 sprintf(buf,
"(%.5f,%.5f)", Scale * pf.
x, Scale * pf.
y);
149 static char *pic_coord(
char *buf,
point p)
151 return pic_fcoord(buf, cvt2ptf(p));
154 static void pic_reset(
void)
159 static void pic_begin_job(FILE * ofp,
graph_t * g,
const char **lib,
char *
info[],
point pages)
162 if (onetime && (pages.
x * pages.
y > 1)) {
163 unsupported(
"pagination");
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));
176 "%s save point size and font\n.nr .S \\n(.s\n.nr DF \\n(.f\n",
180 static void pic_end_graph(
void)
183 "%s restore point size and font\n.ps \\n(.S\n.ft \\n(DF\n",
187 static void pic_begin_page(
graph_t * g,
point page,
double scale,
int rot,
190 double height, width;
192 if (onetime && rot && (rot != 90)) {
193 unsupported(
"rotation");
205 fprintf(Output_file,
".PS %.5f %.5f\n", width, height);
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",
211 Fontscale = log10(width);
212 Fontscale += 3.0 - (
int) Fontscale;
215 Fontscale = pow(10.0, Fontscale);
216 fprintf(Output_file,
".nr SF %.0f\nscalethickness = %.0f\n", Fontscale,
219 "%s don't change anything below this line in this drawing\n",
222 "%s non-fatal run-time pic version determination, version 2\n",
225 "boxrad=2.0 %s will be reset to 0.0 by gpic only\n",
227 fprintf(Output_file,
"scale=1.0 %s required for comparisons\n",
230 "%s boxrad is now 0.0 in gpic, else it remains 2.0\n",
233 "%s dashwid is 0.1 in 10th Edition, 0.05 in DWB 2 and in gpic\n",
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",
239 "%s fill has no meaning in DWB 2, gpic can use fill or filled, 10th Edition uses fill only\n",
242 "%s DWB 2 doesn't use fill and doesn't define fillval\n",
245 "%s reset works in gpic and 10th edition, but isn't defined in DWB 2\n",
247 fprintf(Output_file,
"%s DWB 2 compatibility definitions\n",
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",
255 "if fillval > 0.4 then X\n\tdefine setfillval Y fillval = 1 - Y;\n\tdefine bold Y thickness 2 Y;\n");
257 "\t%s if you use gpic and it barfs on encountering \"solid\",\n",
260 "\t%s\tinstall a more recent version of gpic or switch to DWB or 10th Edition pic;\n",
263 "\t%s\tsorry, the groff folks changed gpic; send any complaint to them;\n",
266 "X else Z\n\tdefine setfillval Y fillval = Y;\n\tdefine bold Y Y;\n\tdefine filled Y fill Y;\nZ\n");
268 "%s arrowhead has no meaning in DWB 2, arrowhead = 7 makes filled arrowheads in gpic and in 10th Edition\n",
271 "%s arrowhead is undefined in DWB 2, initially 1 in gpic, 2 in 10th Edition\n",
273 fprintf(Output_file,
"arrowhead = 7 %s not used by graphviz\n",
276 "%s GNU pic supports a boxrad variable to draw boxes with rounded corners; DWB and 10th Ed. do not\n",
278 fprintf(Output_file,
"boxrad = 0 %s no rounded corners in graphviz\n",
281 "%s GNU pic supports a linethick variable to set line thickness; DWB and 10th Ed. do not\n",
283 fprintf(Output_file,
"linethick = 0; oldlinethick = linethick\n");
285 "%s .PS w/o args causes GNU pic to scale drawing to fit 8.5x11 paper; DWB does not\n",
288 "%s maxpsht and maxpswid have no meaning in DWB 2.0, set page boundaries in gpic and in 10th Edition\n",
291 "%s maxpsht and maxpswid are predefined to 11.0 and 8.5 in gpic\n",
293 fprintf(Output_file,
"maxpsht = %f\nmaxpswid = %f\n", height, width);
294 fprintf(Output_file,
"Dot: [\n");
296 "define attrs0 %% %%; define unfilled %% %%; define rounded %% %%; define diagonals %% %%\n");
299 static void pic_end_page(
void)
301 fprintf(Output_file,
"]\n.PE\n");
302 EscComment =
".\\\" ";
306 static void pic_begin_node(
node_t * n)
308 fprintf(Output_file,
"%s\t%s\n", EscComment,
agnameof(n));
311 static void pic_begin_edge(
edge_t * e)
313 fprintf(Output_file,
"%s\t%s -> %s\n", EscComment,
317 static void pic_begin_context(
void)
319 fprintf(Output_file,
"{\n");
325 fprintf(Output_file,
"define attrs%d %% %%\n", SP);
329 static void pic_end_context(
void)
335 fprintf(Output_file,
"}\n");
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) {
343 if ((sz = (
int) (S[SP].size * Scale)) < 1)
345 fprintf(Output_file,
".ps %d*\\n(SFu/%.0fu\n", sz, Fontscale);
347 fprintf(Output_file,
"linethick = oldlinethick\n");
351 static void pic_set_font(
char *name,
double size)
353 if (name && (!(S[SP].font) || strcmp(S[SP].font, name))) {
355 fprintf(Output_file,
".ft %s\n", picfontname(name));
357 if (size != S[SP].size) {
361 if ((sz = (
int) (size * Scale)) < 1)
363 fprintf(Output_file,
".ps %d*\\n(SFu/%.0fu\n", sz, Fontscale);
367 static char *pic_string(
char *
s)
369 static char *buf =
NULL;
370 static int bufsize = 0;
376 buf =
N_GNEW(bufsize,
char);
381 if (pos > (bufsize - 8)) {
406 static void pic_textpara(
point p, textpara_t * para)
410 double fontsz = S[SP].
size;
412 switch (para->just) {
417 p.
x = p.
x - para->width;
421 p.
x = p.
x - para->width / 2;
430 pic_set_font(S[SP].font, fontsz);
431 for (flag = SP; ((S[flag].
size = fontsz), flag); flag--)
434 if (fontsz != S[SP].size) {
438 pic_set_font(S[SP - 1].font, fontsz);
440 fprintf(Output_file,
"\"%s\" at (%.5f,%.5f);\n",
441 pic_string(para->str), Scale * pf.
x, Scale * pf.
y);
446 static void pic_set_color(
char *name)
453 fprintf(Output_file,
"setfillval %f\n", color.
u.
HSVA[2]);
456 static void pic_set_style(
char **s)
458 const char *line, *p;
463 fprintf(Output_file,
"define attrs%d %%", SP);
464 while ((p = line = *s++)) {
469 if (!strcmp(line,
"setlinewidth")) {
473 "oldlinethick = linethick;linethick = %ld * scalethickness / %.0f\n",
474 n, Fontscale / Scale);
477 fprintf(Output_file,
" %s", p);
483 fprintf(Output_file,
" %s", line);
486 fprintf(Output_file,
" %%\n");
487 fprintf(Output_file,
"%s", buf);
490 static void pic_ellipse(
point p,
int rx,
int ry,
int filled)
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);
501 static void point_list_out(
point * A,
int n,
int close)
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,
512 fprintf(Output_file,
"move to P%d; line attrs%d to P0\n", n - 1,
516 static void pic_polygon(
point * A,
int n,
int filled)
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))
532 fprintf(Output_file,
"setfillval %f\n", color.
u.
HSVA[2]);
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),
535 Scale * (pf1.
x + pf2.
x) / 2.0, Scale * (pf1.
y + pf2.
y) / 2.0);
538 if (onetime && filled) {
539 unsupported(
"shape fill");
542 point_list_out(A, n,
TRUE);
545 static void pic_polyline(
point * A,
int n)
547 point_list_out(A, n,
FALSE);
555 fprintf(Output_file,
"define %s {\n", us->
name);
556 fprintf(Output_file,
"}\n%s\n", us->
name);
559 static void pic_bezier(
point * A,
int n,
int arrow_at_start,
560 int arrow_at_end,
int filled)
566 if (arrow_at_start || arrow_at_end)
567 warn(
"not supposed to be making arrows here!");
568 V[3] = cvt2ptf(A[0]);
569 for (i = m = 0; i + 3 < n; i += 3) {
571 for (j = 1; j <= 3; j++)
572 V[j] = cvt2ptf(A[i + j]);
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,
580 fprintf(Output_file,
"P%d: %s\n", m, pic_fcoord(buf, p));
583 for (i = 0; i + 2 <= m; i += 2)
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);
587 static void pic_comment(
char *
str)
589 fprintf(Output_file,
"'\\\" %s\n", str);
595 pic_begin_graph, pic_end_graph,
596 pic_begin_page, pic_end_page,
603 pic_begin_context, pic_end_context,
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,
void * grealloc(void *ptr, size_t size)
int agerr(agerrlevel_t level, const char *fmt,...)
#define PS2INCH(a_points)
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
CGRAPH_API char * agnameof(void *)
int colorxlate(char *str, gvcolor_t *color, color_type_t target_type)
pointf Bezier(pointf *V, int degree, double t, pointf *Left, pointf *Right)
void(* pf)(char *, void *)
struct grcontext_t grcontext_t