32 #define BEZIERSUBDIVISION 6
34 #define PIC_COORDS_PER_LINE (16)
38 static int onetime =
TRUE;
39 static double Fontscale;
62 static const char *EscComment =
".\\\" ";
63 static const char picgen_msghdr[] =
"dot pic plugin: ";
65 static void unsupported(
char *
s)
67 agerr(
AGWARN,
"%s%s unsupported\n", picgen_msghdr, s);
72 char trname[3], *psname;
76 {
"AB",
"AvantGarde-Demi"},
77 {
"AI",
"AvantGarde-BookOblique"},
78 {
"AR",
"AvantGarde-Book"},
79 {
"AX",
"AvantGarde-DemiOblique"},
81 {
"BI",
"Times-BoldItalic"},
82 {
"CB",
"Courier-Bold"},
84 {
"CX",
"Courier-BoldOblique"},
86 {
"HB",
"Helvetica-Bold"},
87 {
"HI",
"Helvetica-Oblique"},
88 {
"HX",
"Helvetica-BoldOblique"},
89 {
"Hb",
"Helvetica-Narrow-Bold"},
90 {
"Hi",
"Helvetica-Narrow-Oblique"},
91 {
"Hr",
"Helvetica-Narrow"},
92 {
"Hx",
"Helvetica-Narrow-BoldOblique"},
93 {
"I ",
"Times-Italic"},
94 {
"KB",
"Bookman-Demi"},
95 {
"KI",
"Bookman-LightItalic"},
96 {
"KR",
"Bookman-Light"},
97 {
"KX",
"Bookman-DemiItalic"},
98 {
"NB",
"NewCenturySchlbk-Bold"},
99 {
"NI",
"NewCenturySchlbk-Italic"},
100 {
"NR",
"NewCenturySchlbk-Roman"},
101 {
"NX",
"NewCenturySchlbk-BoldItalic"},
102 {
"PA",
"Palatino-Roman"},
103 {
"PB",
"Palatino-Bold"},
104 {
"PI",
"Palatino-Italic"},
105 {
"PX",
"Palatino-BoldItalic"},
106 {
"R ",
"Times-Roman"},
108 {
"ZD",
"ZapfDingbats"},
109 {
"\000\000", (
char *) 0}
112 static char *picfontname(
char *psname)
117 for (p = fonttab; p->
psname; p++)
118 if (strcmp(p->
psname, psname) == 0)
123 agerr(
AGERR,
"%s%s is not a troff font\n", picgen_msghdr, psname);
125 if ((rv = strrchr(psname,
'-'))) {
127 rv = picfontname(psname);
134 static void picptarray(
GVJ_t *job,
pointf * A,
int n,
int close)
139 for (i = 0; i < n; i++) {
150 static char *pic_string(
char *
s)
152 static char *buf =
NULL;
153 static int bufsize = 0;
160 buf = malloc(bufsize *
sizeof(
char));
165 if (pos > (bufsize - 8)) {
167 buf = realloc(buf, bufsize *
sizeof(
char));
179 sprintf(p,
"%03o", c);
188 static void pic_line_style(
obj_state_t *obj,
int *line_style,
double *style_val)
207 static void pic_comment(
GVJ_t *job,
char *
str)
209 gvprintf(job,
"%s %s\n", EscComment, str);
212 static void pic_begin_graph(
GVJ_t * job)
216 gvprintf(job,
"%s Creator: %s version %s (%s)\n",
220 "%s save point size and font\n.nr .S \\n(.s\n.nr DF \\n(.f\n",
224 static void pic_end_graph(
GVJ_t * job)
227 "%s restore point size and font\n.ps \\n(.S\n.ft \\n(DF\n",
231 static void pic_begin_page(
GVJ_t * job)
234 double height, width;
237 unsupported(
"rotation");
247 gvprintf(job,
".PS %.5f %.5f\n", width, height);
249 "%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",
252 Fontscale = log10(width);
253 Fontscale += 3.0 - (
int) Fontscale;
256 Fontscale = pow(10.0, Fontscale);
257 gvprintf(job,
".nr SF %.0f\nscalethickness = %.0f\n", Fontscale,
260 "%s don't change anything below this line in this drawing\n",
263 "%s non-fatal run-time pic version determination, version 2\n",
266 "boxrad=2.0 %s will be reset to 0.0 by gpic only\n",
268 gvprintf(job,
"scale=1.0 %s required for comparisons\n",
271 "%s boxrad is now 0.0 in gpic, else it remains 2.0\n",
274 "%s dashwid is 0.1 in 10th Edition, 0.05 in DWB 2 and in gpic\n",
277 "%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",
280 "%s fill has no meaning in DWB 2, gpic can use fill or filled, 10th Edition uses fill only\n",
283 "%s DWB 2 doesn't use fill and doesn't define fillval\n",
286 "%s reset works in gpic and 10th edition, but isn't defined in DWB 2\n",
288 gvprintf(job,
"%s DWB 2 compatibility definitions\n",
291 "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");
292 gvprintf(job,
"reset %s set to known state\n", EscComment);
293 gvprintf(job,
"%s GNU pic vs. 10th Edition d\\(e'tente\n",
296 "if fillval > 0.4 then X\n\tdefine setfillval Y fillval = 1 - Y;\n\tdefine bold Y thickness 2 Y;\n");
298 "\t%s if you use gpic and it barfs on encountering \"solid\",\n",
301 "\t%s\tinstall a more recent version of gpic or switch to DWB or 10th Edition pic;\n",
304 "\t%s\tsorry, the groff folks changed gpic; send any complaint to them;\n",
307 "X else Z\n\tdefine setfillval Y fillval = Y;\n\tdefine bold Y Y;\n\tdefine filled Y fill Y;\nZ\n");
309 "%s arrowhead has no meaning in DWB 2, arrowhead = 7 makes filled arrowheads in gpic and in 10th Edition\n",
312 "%s arrowhead is undefined in DWB 2, initially 1 in gpic, 2 in 10th Edition\n",
314 gvprintf(job,
"arrowhead = 7 %s not used by graphviz\n",
317 "%s GNU pic supports a boxrad variable to draw boxes with rounded corners; DWB and 10th Ed. do not\n",
319 gvprintf(job,
"boxrad = 0 %s no rounded corners in graphviz\n",
322 "%s GNU pic supports a linethick variable to set line thickness; DWB and 10th Ed. do not\n",
324 gvprintf(job,
"linethick = 0; oldlinethick = linethick\n");
326 "%s .PS w/o args causes GNU pic to scale drawing to fit 8.5x11 paper; DWB does not\n",
329 "%s maxpsht and maxpswid have no meaning in DWB 2.0, set page boundaries in gpic and in 10th Edition\n",
332 "%s maxpsht and maxpswid are predefined to 11.0 and 8.5 in gpic\n",
334 gvprintf(job,
"maxpsht = %f\nmaxpswid = %f\n", height, width);
337 "define attrs0 %% %%; define unfilled %% %%; define rounded %% %%; define diagonals %% %%\n");
340 static void pic_end_page(
GVJ_t * job)
348 static char *lastname;
352 switch (span->
just) {
367 if (span->
font->
name && (!(lastname) || strcmp(lastname, span->
font->
name))) {
371 if ((sz = (
int)span->
font->
size) < 1)
373 if (sz != lastsize) {
374 gvprintf(job,
".ps %d*\\n(SFu/%.0fu\n", sz, Fontscale);
377 gvprintf(job,
"\"%s\" at (%.5f,%.5f);\n",
378 pic_string(span->
str), p.
x, p.
y);
381 static void pic_ellipse(
GVJ_t * job,
pointf * A,
int filled)
386 "ellipse attrs%d %swid %.5f ht %.5f at (%.5f,%.5f);\n", 1,
387 filled ?
"fill " :
"",
394 static void pic_bezier(
GVJ_t * job,
pointf * A,
int n,
int arrow_at_start,
396 int arrow_at_end,
int filled)
425 1) * 20 *
sizeof(
char));
428 pic_line_style(obj, &line_style, &style_val);
445 size = sprintf(buf,
" %d %d", p.
x, p.
y);
448 for (i = 0; i + 3 < n; i += 3) {
450 for (j = 1; j <= 3; j++) {
458 size = sprintf(buf,
" %d %d", p.
x, p.
y);
477 for (i = 0; i < count; i++) {
478 gvprintf(job,
" %d", i % (count - 1) ? 1 : 0);
483 static void pic_polygon(
GVJ_t * job,
pointf * A,
int n,
int filled)
503 pic_line_style(obj, &line_style, &style_val);
510 picptarray(job, A, n, 1);
513 static void pic_polyline(
GVJ_t * job,
pointf * A,
int n)
533 pic_line_style(obj, &line_style, &style_val);
540 picptarray(job, A, n, 0);
gvrender_engine_t pic_engine
int agerr(agerrlevel_t level, const char *fmt,...)
gvplugin_installed_t gvrender_pic_types[]
#define PS2INCH(a_points)
int gvputs(GVJ_t *job, const char *s)
CGRAPH_API char * agnameof(void *)
#define BEZIERSUBDIVISION
pointf Bezier(pointf *V, int degree, double t, pointf *Left, pointf *Right)
void(* pf)(char *, void *)
gvplugin_installed_t gvdevice_pic_types[]
void gvprintf(GVJ_t *job, const char *format,...)