7 #define abs(n) (n >= 0 ? n : -(n))
8 #define max(x,y) ((x)>(y) ? (x) : (y))
10 char *textshift
= "\\v'.2m'"; /* move text this far down */
12 /* scaling stuff defined by s command as X0,Y0 to X1,Y1 */
13 /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */
14 /* default output is 6x6 inches */
20 double hpos
= 0; /* current horizontal position in output coordinate system */
21 double vpos
= 0; /* current vertical position; 0 is top of page */
23 double htrue
= 0; /* where we really are */
26 double X0
, Y0
; /* left bottom of input */
27 double X1
, Y1
; /* right top of input */
29 double hmax
; /* right end of output */
30 double vmax
; /* top of output (down is positive) */
34 extern double xmin
, ymin
, xmax
, ymax
;
36 double xconv(double), yconv(double), xsc(double), ysc(double);
37 void space(double, double, double, double);
38 void hgoto(double), vgoto(double), hmot(double), vmot(double);
39 void move(double, double), movehv(double, double);
40 void cont(double, double);
42 void openpl(char *s
) /* initialize device; s is residue of .PS invocation line */
44 double maxw
, maxh
, ratio
= 1;
45 double odeltx
= deltx
, odelty
= delty
;
48 maxw
= getfval("maxpswid");
49 maxh
= getfval("maxpsht");
50 if (deltx
> maxw
) { /* shrink horizontal */
55 if (delty
> maxh
) { /* shrink vertical */
61 fprintf(stderr
, "pic: %g X %g picture shrunk to", odeltx
, odelty
);
62 fprintf(stderr
, " %g X %g\n", deltx
, delty
);
64 space(xmin
, ymin
, xmax
, ymax
);
65 printf("... %g %g %g %g\n", xmin
, ymin
, xmax
, ymax
);
66 printf("... %.3fi %.3fi %.3fi %.3fi\n",
67 xconv(xmin
), yconv(ymin
), xconv(xmax
), yconv(ymax
));
68 printf(".nr 00 \\n(.u\n");
70 printf(".PS %.3fi %.3fi %s", yconv(ymin
), xconv(xmax
), s
);
71 /* assumes \n comes as part of s */
74 void space(double x0
, double y0
, double x1
, double y1
) /* set limits of page */
80 xscale
= deltx
== 0.0 ? 1.0 : deltx
/ (X1
-X0
);
81 yscale
= delty
== 0.0 ? 1.0 : delty
/ (Y1
-Y0
);
84 double xconv(double x
) /* convert x from external to internal form */
86 return (x
-X0
) * xscale
;
89 double xsc(double x
) /* convert x from external to internal form, scaling only */
95 double yconv(double y
) /* convert y from external to internal form */
97 return (Y1
-y
) * yscale
;
100 double ysc(double y
) /* convert y from external to internal form, scaling only */
105 void closepl(char *PEline
) /* clean up after finished */
107 movehv(0.0, 0.0); /* get back to where we started */
108 if (strchr(PEline
, 'F') == NULL
) {
109 printf(".sp 1+%.3fi\n", yconv(ymin
));
111 printf("%s\n", PEline
);
112 printf(".if \\n(00 .fi\n");
115 void move(double x
, double y
) /* go to position x, y in external coords */
121 void movehv(double h
, double v
) /* go to internal position h, v */
127 void hmot(double n
) /* generate n units of horizontal motion */
132 void vmot(double n
) /* generate n units of vertical motion */
147 double fabs(double x
)
149 return x
< 0 ? -x
: x
;
152 void hvflush(void) /* get to proper point for output */
154 if (fabs(hpos
-htrue
) >= 0.0005) {
155 printf("\\h'%.3fi'", hpos
- htrue
);
158 if (fabs(vpos
-vtrue
) >= 0.0005) {
159 printf("\\v'%.3fi'", vpos
- vtrue
);
164 void flyback(void) /* return to upper left corner (entry point) */
170 void printlf(int n
, char *f
)
173 printf(".lf %d %s\n", n
, f
);
175 printf(".lf %d\n", n
);
178 void troff(char *s
) /* output troff right here */
183 void label(char *s
, int t
, int nh
) /* text s of type t nh half-lines up */
191 dprintf("label: %s %o %d\n", s
, t
, nh
);
192 printf("%s", textshift
); /* shift down and left */
198 printf("\\v'%du*\\n(.vu/2u'", -nh
);
199 /* just in case the text contains a quote: */
209 } else if (t
& RJUST
) {
211 printf("\\h\\(ts-\\w\\(ts%s\\(tsu\\(ts%s", s
, s
);
213 printf("\\h'-\\w'%s'u'%s", s
, s
);
214 } else { /* CENTER */
216 printf("\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts%s", s
, s
);
218 printf("\\h'-\\w'%s'u/2u'%s", s
, s
);
224 void line(double x0
, double y0
, double x1
, double y1
) /* draw line from x0,y0 to x1,y1 */
230 void arrow(double x0
, double y0
, double x1
, double y1
, double w
, double h
,
231 double ang
, int nhead
) /* draw arrow (without shaft) */
233 double alpha
, rot
, drot
, hyp
;
237 rot
= atan2(w
/ 2, h
);
238 hyp
= sqrt(w
/2 * w
/2 + h
* h
);
239 alpha
= atan2(y1
-y0
, x1
-x0
) + ang
;
242 dprintf("rot=%g, hyp=%g, alpha=%g\n", rot
, hyp
, alpha
);
243 for (i
= nhead
-1; i
>= 0; i
--) {
244 drot
= 2 * rot
/ (double) (nhead
-1) * (double) i
;
245 dx
= hyp
* cos(alpha
+ PI
- rot
+ drot
);
246 dy
= hyp
* sin(alpha
+ PI
- rot
+ drot
);
247 dprintf("dx,dy = %g,%g\n", dx
, dy
);
248 line(x1
+dx
, y1
+dy
, x1
, y1
);
254 void fillstart(double v
) /* this works only for postscript, obviously. */
255 { /* uses drechsler's dpost conventions... */
257 printf("\\X'BeginObject %g setgray'\n", v
);
262 void fillend(int vis
, int fill
)
265 printf("\\X'EndObject gsave eofill grestore %g setgray %s'\n",
266 !vis
? lastgray
: 0.0,
267 vis
? "stroke" : "");
268 /* for dashed: [50] 0 setdash just before stroke. */
273 void box(double x0
, double y0
, double x1
, double y1
)
282 void cont(double x
, double y
) /* continue line from here to x,y */
292 printf("\\D'l%.3fi %.3fi'\n", dh
, dv
);
293 flyback(); /* expensive */
298 void circle(double x
, double y
, double r
)
302 printf("\\D'c%.3fi'\n", xsc(2 * r
));
306 void spline(double x
, double y
, double n
, ofloat
*p
, int dashed
, double ddval
)
316 for (i
= 0; i
< 2 * n
; i
+= 2) {
317 dx
= xsc(xerr
+= p
[i
]);
319 dy
= ysc(yerr
+= p
[i
+1]);
321 printf(" %.3fi %.3fi", dx
, -dy
); /* WATCH SIGN */
327 void ellipse(double x
, double y
, double r1
, double r2
)
335 printf("\\D'e%.3fi %.3fi'\n", 2 * ir1
, 2 * abs(ir2
));
339 void arc(double x
, double y
, double x0
, double y0
, double x1
, double y1
) /* draw arc with center x,y */
344 printf("\\D'a%.3fi %.3fi %.3fi %.3fi'\n",
345 xsc(x
-x0
), -ysc(y
-y0
), xsc(x1
-x
), -ysc(y1
-y
)); /* WATCH SIGNS */
351 /* what character to draw here depends on what's available. */
352 /* on the 202, l. is good but small. */
353 /* in general, use a smaller, shifted period and hope */
355 printf("\\&\\f1\\h'-.1m'\\v'.03m'\\s-3.\\s+3\\fP\n");