Blame


1 020c8058 2005-01-04 devnull #include <u.h>
2 020c8058 2005-01-04 devnull #include <libc.h>
3 020c8058 2005-01-04 devnull #include <draw.h>
4 020c8058 2005-01-04 devnull #include <cursor.h>
5 020c8058 2005-01-04 devnull #include <event.h>
6 020c8058 2005-01-04 devnull #include <bio.h>
7 020c8058 2005-01-04 devnull #include "proof.h"
8 020c8058 2005-01-04 devnull
9 020c8058 2005-01-04 devnull int res;
10 020c8058 2005-01-04 devnull int hpos;
11 020c8058 2005-01-04 devnull int vpos;
12 020c8058 2005-01-04 devnull int DIV = 11;
13 020c8058 2005-01-04 devnull
14 020c8058 2005-01-04 devnull Point offset;
15 020c8058 2005-01-04 devnull Point xyoffset = { 0,0 };
16 020c8058 2005-01-04 devnull
17 020c8058 2005-01-04 devnull Rectangle view[MAXVIEW];
18 020c8058 2005-01-04 devnull Rectangle bound[MAXVIEW]; /* extreme points */
19 020c8058 2005-01-04 devnull int nview = 1;
20 020c8058 2005-01-04 devnull
21 020c8058 2005-01-04 devnull int lastp; /* last page number we were on */
22 020c8058 2005-01-04 devnull
23 020c8058 2005-01-04 devnull #define NPAGENUMS 200
24 020c8058 2005-01-04 devnull struct pagenum {
25 020c8058 2005-01-04 devnull int num;
26 020c8058 2005-01-04 devnull long adr;
27 020c8058 2005-01-04 devnull } pagenums[NPAGENUMS];
28 020c8058 2005-01-04 devnull int npagenums;
29 020c8058 2005-01-04 devnull
30 020c8058 2005-01-04 devnull int curfont, cursize;
31 020c8058 2005-01-04 devnull
32 020c8058 2005-01-04 devnull char *getcmdstr(void);
33 020c8058 2005-01-04 devnull
34 020c8058 2005-01-04 devnull static void initpage(void);
35 020c8058 2005-01-04 devnull static void view_setup(int);
36 020c8058 2005-01-04 devnull static Point scale(Point);
37 020c8058 2005-01-04 devnull static void clearview(Rectangle);
38 020c8058 2005-01-04 devnull static int addpage(int);
39 020c8058 2005-01-04 devnull static void spline(Image *, int, Point *);
40 020c8058 2005-01-04 devnull static int skipto(int, int);
41 020c8058 2005-01-04 devnull static void wiggly(int);
42 020c8058 2005-01-04 devnull static void devcntrl(void);
43 020c8058 2005-01-04 devnull static void eatline(void);
44 020c8058 2005-01-04 devnull static int getn(void);
45 020c8058 2005-01-04 devnull static int botpage(int);
46 020c8058 2005-01-04 devnull static void getstr(char *);
47 020c8058 2005-01-04 devnull /*
48 020c8058 2005-01-04 devnull static void getutf(char *);
49 020c8058 2005-01-04 devnull */
50 020c8058 2005-01-04 devnull
51 020c8058 2005-01-04 devnull #define Do screen->r.min
52 020c8058 2005-01-04 devnull #define Dc screen->r.max
53 020c8058 2005-01-04 devnull
54 020c8058 2005-01-04 devnull /* declarations and definitions of font stuff are in font.c and main.c */
55 020c8058 2005-01-04 devnull
56 020c8058 2005-01-04 devnull static void
57 020c8058 2005-01-04 devnull initpage(void)
58 020c8058 2005-01-04 devnull {
59 020c8058 2005-01-04 devnull int i;
60 020c8058 2005-01-04 devnull
61 020c8058 2005-01-04 devnull view_setup(nview);
62 020c8058 2005-01-04 devnull for (i = 0; i < nview-1; i++)
63 020c8058 2005-01-04 devnull draw(screen, view[i], screen, nil, view[i+1].min);
64 020c8058 2005-01-04 devnull clearview(view[nview-1]);
65 020c8058 2005-01-04 devnull offset = view[nview-1].min;
66 020c8058 2005-01-04 devnull vpos = 0;
67 020c8058 2005-01-04 devnull }
68 020c8058 2005-01-04 devnull
69 020c8058 2005-01-04 devnull static void
70 020c8058 2005-01-04 devnull view_setup(int n)
71 020c8058 2005-01-04 devnull {
72 020c8058 2005-01-04 devnull int i, j, v, dx, dy, r, c;
73 020c8058 2005-01-04 devnull
74 020c8058 2005-01-04 devnull switch (n) {
75 020c8058 2005-01-04 devnull case 1: r = 1; c = 1; break;
76 020c8058 2005-01-04 devnull case 2: r = 1; c = 2; break;
77 020c8058 2005-01-04 devnull case 3: r = 1; c = 3; break;
78 020c8058 2005-01-04 devnull case 4: r = 2; c = 2; break;
79 020c8058 2005-01-04 devnull case 5: case 6: r = 2; c = 3; break;
80 020c8058 2005-01-04 devnull case 7: case 8: case 9: r = 3; c = 3; break;
81 020c8058 2005-01-04 devnull default: r = (n+2)/3; c = 3; break; /* finking out */
82 020c8058 2005-01-04 devnull }
83 020c8058 2005-01-04 devnull dx = (Dc.x - Do.x) / c;
84 020c8058 2005-01-04 devnull dy = (Dc.y - Do.y) / r;
85 020c8058 2005-01-04 devnull v = 0;
86 020c8058 2005-01-04 devnull for (i = 0; i < r && v < n; i++)
87 020c8058 2005-01-04 devnull for (j = 0; j < c && v < n; j++) {
88 020c8058 2005-01-04 devnull view[v] = screen->r;
89 020c8058 2005-01-04 devnull view[v].min.x = Do.x + j * dx;
90 020c8058 2005-01-04 devnull view[v].max.x = Do.x + (j+1) * dx;
91 020c8058 2005-01-04 devnull view[v].min.y = Do.y + i * dy;
92 020c8058 2005-01-04 devnull view[v].max.y = Do.y + (i+1) * dy;
93 020c8058 2005-01-04 devnull v++;
94 020c8058 2005-01-04 devnull }
95 020c8058 2005-01-04 devnull }
96 020c8058 2005-01-04 devnull
97 020c8058 2005-01-04 devnull static void
98 020c8058 2005-01-04 devnull clearview(Rectangle r)
99 020c8058 2005-01-04 devnull {
100 020c8058 2005-01-04 devnull draw(screen, r, display->white, nil, r.min);
101 020c8058 2005-01-04 devnull }
102 020c8058 2005-01-04 devnull
103 020c8058 2005-01-04 devnull int resized;
104 020c8058 2005-01-04 devnull void eresized(int new)
105 020c8058 2005-01-04 devnull {
106 020c8058 2005-01-04 devnull /* this is called if we are resized */
107 020c8058 2005-01-04 devnull if(new && getwindow(display, Refnone) < 0)
108 020c8058 2005-01-04 devnull drawerror(display, "can't reattach to window");
109 020c8058 2005-01-04 devnull initpage();
110 020c8058 2005-01-04 devnull resized = 1;
111 020c8058 2005-01-04 devnull }
112 020c8058 2005-01-04 devnull
113 020c8058 2005-01-04 devnull static Point
114 020c8058 2005-01-04 devnull scale(Point p)
115 020c8058 2005-01-04 devnull {
116 020c8058 2005-01-04 devnull p.x /= DIV;
117 020c8058 2005-01-04 devnull p.y /= DIV;
118 020c8058 2005-01-04 devnull return addpt(xyoffset, addpt(offset,p));
119 020c8058 2005-01-04 devnull }
120 020c8058 2005-01-04 devnull
121 020c8058 2005-01-04 devnull static int
122 020c8058 2005-01-04 devnull addpage(int n)
123 020c8058 2005-01-04 devnull {
124 020c8058 2005-01-04 devnull int i;
125 020c8058 2005-01-04 devnull
126 020c8058 2005-01-04 devnull for (i = 0; i < npagenums; i++)
127 020c8058 2005-01-04 devnull if (n == pagenums[i].num)
128 020c8058 2005-01-04 devnull return i;
129 020c8058 2005-01-04 devnull if (npagenums < NPAGENUMS-1) {
130 020c8058 2005-01-04 devnull pagenums[npagenums].num = n;
131 020c8058 2005-01-04 devnull pagenums[npagenums].adr = offsetc();
132 020c8058 2005-01-04 devnull npagenums++;
133 020c8058 2005-01-04 devnull }
134 020c8058 2005-01-04 devnull return npagenums;
135 020c8058 2005-01-04 devnull }
136 020c8058 2005-01-04 devnull
137 020c8058 2005-01-04 devnull void
138 020c8058 2005-01-04 devnull readpage(void)
139 020c8058 2005-01-04 devnull {
140 020c8058 2005-01-04 devnull int c, i, a, alpha, phi;
141 020c8058 2005-01-04 devnull static int first = 0;
142 020c8058 2005-01-04 devnull int m, n, gonow = 1;
143 020c8058 2005-01-04 devnull Rune r[32], t;
144 020c8058 2005-01-04 devnull Point p,q,qq;
145 020c8058 2005-01-04 devnull
146 020c8058 2005-01-04 devnull offset = screen->clipr.min;
147 020c8058 2005-01-04 devnull esetcursor(&deadmouse);
148 020c8058 2005-01-04 devnull while (gonow)
149 020c8058 2005-01-04 devnull {
150 020c8058 2005-01-04 devnull c = getc();
151 020c8058 2005-01-04 devnull switch (c)
152 020c8058 2005-01-04 devnull {
153 020c8058 2005-01-04 devnull case -1:
154 020c8058 2005-01-04 devnull esetcursor(0);
155 020c8058 2005-01-04 devnull if (botpage(lastp+1)) {
156 020c8058 2005-01-04 devnull initpage();
157 020c8058 2005-01-04 devnull break;
158 020c8058 2005-01-04 devnull }
159 020c8058 2005-01-04 devnull exits(0);
160 020c8058 2005-01-04 devnull case 'p': /* new page */
161 020c8058 2005-01-04 devnull lastp = getn();
162 020c8058 2005-01-04 devnull addpage(lastp);
163 020c8058 2005-01-04 devnull if (first++ > 0) {
164 020c8058 2005-01-04 devnull esetcursor(0);
165 020c8058 2005-01-04 devnull botpage(lastp);
166 020c8058 2005-01-04 devnull esetcursor(&deadmouse);
167 020c8058 2005-01-04 devnull }
168 020c8058 2005-01-04 devnull initpage();
169 020c8058 2005-01-04 devnull break;
170 020c8058 2005-01-04 devnull case '\n': /* when input is text */
171 020c8058 2005-01-04 devnull case ' ':
172 020c8058 2005-01-04 devnull case 0: /* occasional noise creeps in */
173 020c8058 2005-01-04 devnull break;
174 020c8058 2005-01-04 devnull case '0': case '1': case '2': case '3': case '4':
175 020c8058 2005-01-04 devnull case '5': case '6': case '7': case '8': case '9':
176 020c8058 2005-01-04 devnull /* two motion digits plus a character */
177 020c8058 2005-01-04 devnull hpos += (c-'0')*10 + getc()-'0';
178 020c8058 2005-01-04 devnull
179 020c8058 2005-01-04 devnull /* FALLS THROUGH */
180 020c8058 2005-01-04 devnull case 'c': /* single ascii character */
181 020c8058 2005-01-04 devnull r[0] = getrune();
182 020c8058 2005-01-04 devnull r[1] = 0;
183 020c8058 2005-01-04 devnull dochar(r);
184 020c8058 2005-01-04 devnull break;
185 020c8058 2005-01-04 devnull
186 020c8058 2005-01-04 devnull case 'C':
187 020c8058 2005-01-04 devnull for(i=0; ; i++){
188 020c8058 2005-01-04 devnull t = getrune();
189 020c8058 2005-01-04 devnull if(isspace(t))
190 020c8058 2005-01-04 devnull break;
191 020c8058 2005-01-04 devnull r[i] = t;
192 020c8058 2005-01-04 devnull }
193 020c8058 2005-01-04 devnull r[i] = 0;
194 020c8058 2005-01-04 devnull dochar(r);
195 020c8058 2005-01-04 devnull break;
196 020c8058 2005-01-04 devnull
197 020c8058 2005-01-04 devnull case 'N':
198 020c8058 2005-01-04 devnull r[0] = getn();
199 020c8058 2005-01-04 devnull r[1] = 0;
200 020c8058 2005-01-04 devnull dochar(r);
201 020c8058 2005-01-04 devnull break;
202 020c8058 2005-01-04 devnull
203 020c8058 2005-01-04 devnull case 'D': /* draw function */
204 020c8058 2005-01-04 devnull switch (getc())
205 020c8058 2005-01-04 devnull {
206 020c8058 2005-01-04 devnull case 'l': /* draw a line */
207 020c8058 2005-01-04 devnull n = getn();
208 020c8058 2005-01-04 devnull m = getn();
209 020c8058 2005-01-04 devnull p = Pt(hpos,vpos);
210 020c8058 2005-01-04 devnull q = addpt(p, Pt(n,m));
211 020c8058 2005-01-04 devnull hpos += n;
212 020c8058 2005-01-04 devnull vpos += m;
213 020c8058 2005-01-04 devnull line(screen, scale(p), scale(q), 0, 0, 0, display->black, ZP);
214 020c8058 2005-01-04 devnull break;
215 020c8058 2005-01-04 devnull case 'c': /* circle */
216 020c8058 2005-01-04 devnull /*nop*/
217 020c8058 2005-01-04 devnull m = getn()/2;
218 020c8058 2005-01-04 devnull p = Pt(hpos+m,vpos);
219 020c8058 2005-01-04 devnull hpos += 2*m;
220 020c8058 2005-01-04 devnull ellipse(screen, scale(p), m/DIV, m/DIV, 0, display->black, ZP);
221 020c8058 2005-01-04 devnull /* p=currentpt; p.x+=dmap(m/2);circle bp,p,a,ONES,Mode*/
222 020c8058 2005-01-04 devnull break;
223 020c8058 2005-01-04 devnull case 'e': /* ellipse */
224 020c8058 2005-01-04 devnull /*nop*/
225 020c8058 2005-01-04 devnull m = getn()/2;
226 020c8058 2005-01-04 devnull n = getn()/2;
227 020c8058 2005-01-04 devnull p = Pt(hpos+m,vpos);
228 020c8058 2005-01-04 devnull hpos += 2*m;
229 020c8058 2005-01-04 devnull ellipse(screen, scale(p), m/DIV, n/DIV, 0, display->black, ZP);
230 020c8058 2005-01-04 devnull break;
231 020c8058 2005-01-04 devnull case 'a': /* arc */
232 020c8058 2005-01-04 devnull p = scale(Pt(hpos,vpos));
233 020c8058 2005-01-04 devnull n = getn();
234 020c8058 2005-01-04 devnull m = getn();
235 020c8058 2005-01-04 devnull hpos += n;
236 020c8058 2005-01-04 devnull vpos += m;
237 020c8058 2005-01-04 devnull q = scale(Pt(hpos,vpos));
238 020c8058 2005-01-04 devnull n = getn();
239 020c8058 2005-01-04 devnull m = getn();
240 020c8058 2005-01-04 devnull hpos += n;
241 020c8058 2005-01-04 devnull vpos += m;
242 020c8058 2005-01-04 devnull qq = scale(Pt(hpos,vpos));
243 020c8058 2005-01-04 devnull /*
244 020c8058 2005-01-04 devnull * tricky: convert from 3-point clockwise to
245 020c8058 2005-01-04 devnull * center, angle1, delta-angle counterclockwise.
246 020c8058 2005-01-04 devnull */
247 020c8058 2005-01-04 devnull a = hypot(qq.x-q.x, qq.y-q.y);
248 020c8058 2005-01-04 devnull phi = atan2(q.y-p.y, p.x-q.x)*180./PI;
249 020c8058 2005-01-04 devnull alpha = atan2(q.y-qq.y, qq.x-q.x)*180./PI - phi;
250 020c8058 2005-01-04 devnull if(alpha < 0)
251 020c8058 2005-01-04 devnull alpha += 360;
252 020c8058 2005-01-04 devnull arc(screen, q, a, a, 0, display->black, ZP, phi, alpha);
253 020c8058 2005-01-04 devnull break;
254 020c8058 2005-01-04 devnull case '~': /* wiggly line */
255 020c8058 2005-01-04 devnull wiggly(0);
256 020c8058 2005-01-04 devnull break;
257 020c8058 2005-01-04 devnull default:
258 020c8058 2005-01-04 devnull break;
259 020c8058 2005-01-04 devnull }
260 020c8058 2005-01-04 devnull eatline();
261 020c8058 2005-01-04 devnull break;
262 020c8058 2005-01-04 devnull case 's':
263 020c8058 2005-01-04 devnull n = getn(); /* ignore fractional sizes */
264 020c8058 2005-01-04 devnull if (cursize == n)
265 020c8058 2005-01-04 devnull break;
266 020c8058 2005-01-04 devnull cursize = n;
267 020c8058 2005-01-04 devnull if (cursize >= NFONT)
268 020c8058 2005-01-04 devnull cursize = NFONT-1;
269 020c8058 2005-01-04 devnull break;
270 020c8058 2005-01-04 devnull case 'f':
271 020c8058 2005-01-04 devnull curfont = getn();
272 020c8058 2005-01-04 devnull break;
273 020c8058 2005-01-04 devnull case 'H': /* absolute horizontal motion */
274 020c8058 2005-01-04 devnull hpos = getn();
275 020c8058 2005-01-04 devnull break;
276 020c8058 2005-01-04 devnull case 'h': /* relative horizontal motion */
277 020c8058 2005-01-04 devnull hpos += getn();
278 020c8058 2005-01-04 devnull break;
279 020c8058 2005-01-04 devnull case 'w': /* word space */
280 020c8058 2005-01-04 devnull break;
281 020c8058 2005-01-04 devnull case 'V':
282 020c8058 2005-01-04 devnull vpos = getn();
283 020c8058 2005-01-04 devnull break;
284 020c8058 2005-01-04 devnull case 'v':
285 020c8058 2005-01-04 devnull vpos += getn();
286 020c8058 2005-01-04 devnull break;
287 020c8058 2005-01-04 devnull case '#': /* comment */
288 020c8058 2005-01-04 devnull case 'n': /* end of line */
289 020c8058 2005-01-04 devnull eatline();
290 020c8058 2005-01-04 devnull break;
291 020c8058 2005-01-04 devnull case 'x': /* device control */
292 020c8058 2005-01-04 devnull devcntrl();
293 020c8058 2005-01-04 devnull break;
294 020c8058 2005-01-04 devnull default:
295 020c8058 2005-01-04 devnull fprint(2, "unknown input character %o %c at offset %lud\n", c, c, offsetc());
296 020c8058 2005-01-04 devnull exits("bad char");
297 020c8058 2005-01-04 devnull }
298 020c8058 2005-01-04 devnull }
299 020c8058 2005-01-04 devnull esetcursor(0);
300 020c8058 2005-01-04 devnull }
301 020c8058 2005-01-04 devnull
302 020c8058 2005-01-04 devnull static void
303 020c8058 2005-01-04 devnull spline(Image *b, int n, Point *pp)
304 020c8058 2005-01-04 devnull {
305 020c8058 2005-01-04 devnull long w, t1, t2, t3, fac=1000;
306 020c8058 2005-01-04 devnull int i, j, steps=10;
307 020c8058 2005-01-04 devnull Point p, q;
308 020c8058 2005-01-04 devnull
309 020c8058 2005-01-04 devnull for (i = n; i > 0; i--)
310 020c8058 2005-01-04 devnull pp[i] = pp[i-1];
311 020c8058 2005-01-04 devnull pp[n+1] = pp[n];
312 020c8058 2005-01-04 devnull n += 2;
313 020c8058 2005-01-04 devnull p = pp[0];
314 020c8058 2005-01-04 devnull for(i = 0; i < n-2; i++)
315 020c8058 2005-01-04 devnull {
316 020c8058 2005-01-04 devnull for(j = 0; j < steps; j++)
317 020c8058 2005-01-04 devnull {
318 020c8058 2005-01-04 devnull w = fac * j / steps;
319 020c8058 2005-01-04 devnull t1 = w * w / (2 * fac);
320 020c8058 2005-01-04 devnull w = w - fac/2;
321 020c8058 2005-01-04 devnull t2 = 3*fac/4 - w * w / fac;
322 020c8058 2005-01-04 devnull w = w - fac/2;
323 020c8058 2005-01-04 devnull t3 = w * w / (2*fac);
324 020c8058 2005-01-04 devnull q.x = (t1*pp[i+2].x + t2*pp[i+1].x +
325 020c8058 2005-01-04 devnull t3*pp[i].x + fac/2) / fac;
326 020c8058 2005-01-04 devnull q.y = (t1*pp[i+2].y + t2*pp[i+1].y +
327 020c8058 2005-01-04 devnull t3*pp[i].y + fac/2) / fac;
328 020c8058 2005-01-04 devnull line(b, p, q, 0, 0, 0, display->black, ZP);
329 020c8058 2005-01-04 devnull p = q;
330 020c8058 2005-01-04 devnull }
331 020c8058 2005-01-04 devnull }
332 020c8058 2005-01-04 devnull }
333 020c8058 2005-01-04 devnull
334 020c8058 2005-01-04 devnull /* Have to parse skipped pages, to find out what fonts are loaded. */
335 020c8058 2005-01-04 devnull static int
336 020c8058 2005-01-04 devnull skipto(int gotop, int curp)
337 020c8058 2005-01-04 devnull {
338 020c8058 2005-01-04 devnull char *p;
339 020c8058 2005-01-04 devnull int i;
340 020c8058 2005-01-04 devnull
341 020c8058 2005-01-04 devnull if (gotop == curp)
342 020c8058 2005-01-04 devnull return 1;
343 020c8058 2005-01-04 devnull for (i = 0; i < npagenums; i++)
344 020c8058 2005-01-04 devnull if (pagenums[i].num == gotop) {
345 020c8058 2005-01-04 devnull if (seekc(pagenums[i].adr) == Beof) {
346 020c8058 2005-01-04 devnull fprint(2, "can't rewind input\n");
347 020c8058 2005-01-04 devnull return 0;
348 020c8058 2005-01-04 devnull }
349 020c8058 2005-01-04 devnull return 1;
350 020c8058 2005-01-04 devnull }
351 020c8058 2005-01-04 devnull if (gotop <= curp) {
352 020c8058 2005-01-04 devnull restart:
353 020c8058 2005-01-04 devnull if (seekc(0) == Beof) {
354 020c8058 2005-01-04 devnull fprint(2, "can't rewind input\n");
355 020c8058 2005-01-04 devnull return 0;
356 020c8058 2005-01-04 devnull }
357 020c8058 2005-01-04 devnull }
358 020c8058 2005-01-04 devnull for(;;){
359 020c8058 2005-01-04 devnull p = rdlinec();
360 020c8058 2005-01-04 devnull if (p == 0) {
361 020c8058 2005-01-04 devnull if(gotop>curp){
362 020c8058 2005-01-04 devnull gotop = curp;
363 020c8058 2005-01-04 devnull goto restart;
364 020c8058 2005-01-04 devnull }
365 020c8058 2005-01-04 devnull return 0;
366 020c8058 2005-01-04 devnull } else if (*p == 'p') {
367 020c8058 2005-01-04 devnull lastp = curp = atoi(p+1);
368 020c8058 2005-01-04 devnull addpage(lastp); /* maybe 1 too high */
369 020c8058 2005-01-04 devnull if (curp>=gotop)
370 020c8058 2005-01-04 devnull return 1;
371 020c8058 2005-01-04 devnull }
372 020c8058 2005-01-04 devnull }
373 020c8058 2005-01-04 devnull }
374 020c8058 2005-01-04 devnull
375 020c8058 2005-01-04 devnull static void
376 020c8058 2005-01-04 devnull wiggly(int skip)
377 020c8058 2005-01-04 devnull {
378 020c8058 2005-01-04 devnull Point p[300];
379 020c8058 2005-01-04 devnull int c,i,n;
380 020c8058 2005-01-04 devnull for (n = 1; (c = getc()) != '\n' && c>=0; n++) {
381 020c8058 2005-01-04 devnull ungetc();
382 020c8058 2005-01-04 devnull p[n].x = getn();
383 020c8058 2005-01-04 devnull p[n].y = getn();
384 020c8058 2005-01-04 devnull }
385 020c8058 2005-01-04 devnull p[0] = Pt(hpos, vpos);
386 020c8058 2005-01-04 devnull for (i = 1; i < n; i++)
387 020c8058 2005-01-04 devnull p[i] = addpt(p[i],p[i-1]);
388 020c8058 2005-01-04 devnull hpos = p[n-1].x;
389 020c8058 2005-01-04 devnull vpos = p[n-1].y;
390 020c8058 2005-01-04 devnull for (i = 0; i < n; i++)
391 020c8058 2005-01-04 devnull p[i] = scale(p[i]);
392 020c8058 2005-01-04 devnull if (!skip)
393 020c8058 2005-01-04 devnull spline(screen,n,p);
394 020c8058 2005-01-04 devnull }
395 020c8058 2005-01-04 devnull
396 020c8058 2005-01-04 devnull static void
397 020c8058 2005-01-04 devnull devcntrl(void) /* interpret device control functions */
398 020c8058 2005-01-04 devnull {
399 020c8058 2005-01-04 devnull char str[80];
400 020c8058 2005-01-04 devnull int n;
401 020c8058 2005-01-04 devnull
402 020c8058 2005-01-04 devnull getstr(str);
403 020c8058 2005-01-04 devnull switch (str[0]) { /* crude for now */
404 020c8058 2005-01-04 devnull case 'i': /* initialize */
405 020c8058 2005-01-04 devnull break;
406 020c8058 2005-01-04 devnull case 'T': /* device name */
407 020c8058 2005-01-04 devnull getstr(devname);
408 020c8058 2005-01-04 devnull break;
409 020c8058 2005-01-04 devnull case 't': /* trailer */
410 020c8058 2005-01-04 devnull break;
411 020c8058 2005-01-04 devnull case 'p': /* pause -- can restart */
412 020c8058 2005-01-04 devnull break;
413 020c8058 2005-01-04 devnull case 's': /* stop */
414 020c8058 2005-01-04 devnull break;
415 020c8058 2005-01-04 devnull case 'r': /* resolution assumed when prepared */
416 020c8058 2005-01-04 devnull res=getn();
417 020c8058 2005-01-04 devnull DIV = floor(.5 + res/(100.0*mag));
418 020c8058 2005-01-04 devnull if (DIV < 1)
419 020c8058 2005-01-04 devnull DIV = 1;
420 020c8058 2005-01-04 devnull mag = res/(100.0*DIV); /* adjust mag according to DIV coarseness */
421 020c8058 2005-01-04 devnull break;
422 020c8058 2005-01-04 devnull case 'f': /* font used */
423 020c8058 2005-01-04 devnull n = getn();
424 020c8058 2005-01-04 devnull getstr(str);
425 020c8058 2005-01-04 devnull loadfontname(n, str);
426 020c8058 2005-01-04 devnull break;
427 020c8058 2005-01-04 devnull /* these don't belong here... */
428 020c8058 2005-01-04 devnull case 'H': /* char height */
429 020c8058 2005-01-04 devnull break;
430 020c8058 2005-01-04 devnull case 'S': /* slant */
431 020c8058 2005-01-04 devnull break;
432 020c8058 2005-01-04 devnull case 'X':
433 020c8058 2005-01-04 devnull break;
434 020c8058 2005-01-04 devnull }
435 020c8058 2005-01-04 devnull eatline();
436 020c8058 2005-01-04 devnull }
437 020c8058 2005-01-04 devnull
438 020c8058 2005-01-04 devnull int
439 020c8058 2005-01-04 devnull isspace(int c)
440 020c8058 2005-01-04 devnull {
441 020c8058 2005-01-04 devnull return c==' ' || c=='\t' || c=='\n';
442 020c8058 2005-01-04 devnull }
443 020c8058 2005-01-04 devnull
444 020c8058 2005-01-04 devnull static void
445 020c8058 2005-01-04 devnull getstr(char *is)
446 020c8058 2005-01-04 devnull {
447 020c8058 2005-01-04 devnull uchar *s = (uchar *) is;
448 020c8058 2005-01-04 devnull
449 020c8058 2005-01-04 devnull for (*s = getc(); isspace(*s); *s = getc())
450 020c8058 2005-01-04 devnull ;
451 020c8058 2005-01-04 devnull for (; !isspace(*s); *++s = getc())
452 020c8058 2005-01-04 devnull ;
453 020c8058 2005-01-04 devnull ungetc();
454 020c8058 2005-01-04 devnull *s = 0;
455 020c8058 2005-01-04 devnull }
456 020c8058 2005-01-04 devnull
457 020c8058 2005-01-04 devnull #if 0
458 020c8058 2005-01-04 devnull static void
459 020c8058 2005-01-04 devnull getutf(char *s) /* get next utf char, as bytes */
460 020c8058 2005-01-04 devnull {
461 020c8058 2005-01-04 devnull int c, i;
462 020c8058 2005-01-04 devnull
463 020c8058 2005-01-04 devnull for (i=0;;) {
464 020c8058 2005-01-04 devnull c = getc();
465 020c8058 2005-01-04 devnull if (c < 0)
466 020c8058 2005-01-04 devnull return;
467 020c8058 2005-01-04 devnull s[i++] = c;
468 020c8058 2005-01-04 devnull
469 020c8058 2005-01-04 devnull if (fullrune(s, i)) {
470 020c8058 2005-01-04 devnull s[i] = 0;
471 020c8058 2005-01-04 devnull return;
472 020c8058 2005-01-04 devnull }
473 020c8058 2005-01-04 devnull }
474 020c8058 2005-01-04 devnull }
475 020c8058 2005-01-04 devnull #endif
476 020c8058 2005-01-04 devnull
477 020c8058 2005-01-04 devnull static void
478 020c8058 2005-01-04 devnull eatline(void)
479 020c8058 2005-01-04 devnull {
480 020c8058 2005-01-04 devnull int c;
481 020c8058 2005-01-04 devnull
482 020c8058 2005-01-04 devnull while ((c=getc()) != '\n' && c >= 0)
483 020c8058 2005-01-04 devnull ;
484 020c8058 2005-01-04 devnull }
485 020c8058 2005-01-04 devnull
486 020c8058 2005-01-04 devnull static int
487 020c8058 2005-01-04 devnull getn(void)
488 020c8058 2005-01-04 devnull {
489 020c8058 2005-01-04 devnull int n, c, sign;
490 020c8058 2005-01-04 devnull
491 020c8058 2005-01-04 devnull while (c = getc())
492 020c8058 2005-01-04 devnull if (!isspace(c))
493 020c8058 2005-01-04 devnull break;
494 020c8058 2005-01-04 devnull if(c == '-'){
495 020c8058 2005-01-04 devnull sign = -1;
496 020c8058 2005-01-04 devnull c = getc();
497 020c8058 2005-01-04 devnull }else
498 020c8058 2005-01-04 devnull sign = 1;
499 020c8058 2005-01-04 devnull for (n = 0; '0'<=c && c<='9'; c = getc())
500 020c8058 2005-01-04 devnull n = n*10 + c - '0';
501 020c8058 2005-01-04 devnull while (c == ' ')
502 020c8058 2005-01-04 devnull c = getc();
503 020c8058 2005-01-04 devnull ungetc();
504 020c8058 2005-01-04 devnull return(n*sign);
505 020c8058 2005-01-04 devnull }
506 020c8058 2005-01-04 devnull
507 020c8058 2005-01-04 devnull static int
508 020c8058 2005-01-04 devnull botpage(int np) /* called at bottom of page np-1 == top of page np */
509 020c8058 2005-01-04 devnull {
510 020c8058 2005-01-04 devnull char *p;
511 020c8058 2005-01-04 devnull int n;
512 020c8058 2005-01-04 devnull
513 020c8058 2005-01-04 devnull while (p = getcmdstr()) {
514 020c8058 2005-01-04 devnull if (*p == '\0')
515 020c8058 2005-01-04 devnull return 0;
516 020c8058 2005-01-04 devnull if (*p == 'q')
517 020c8058 2005-01-04 devnull exits(p);
518 020c8058 2005-01-04 devnull if (*p == 'c') /* nop */
519 020c8058 2005-01-04 devnull continue;
520 020c8058 2005-01-04 devnull if (*p == 'm') {
521 020c8058 2005-01-04 devnull mag = atof(p+1);
522 020c8058 2005-01-04 devnull if (mag <= .1 || mag >= 10)
523 020c8058 2005-01-04 devnull mag = DEFMAG;
524 020c8058 2005-01-04 devnull allfree(); /* zap fonts */
525 020c8058 2005-01-04 devnull DIV = floor(.5 + res/(100.0*mag));
526 020c8058 2005-01-04 devnull if (DIV < 1)
527 020c8058 2005-01-04 devnull DIV = 1;
528 020c8058 2005-01-04 devnull mag = res/(100.0*DIV);
529 020c8058 2005-01-04 devnull return skipto(np-1, np); /* reprint the page */
530 020c8058 2005-01-04 devnull }
531 020c8058 2005-01-04 devnull if (*p == 'x') {
532 020c8058 2005-01-04 devnull xyoffset.x += atoi(p+1)*100;
533 020c8058 2005-01-04 devnull skipto(np-1, np);
534 020c8058 2005-01-04 devnull return 1;
535 020c8058 2005-01-04 devnull }
536 020c8058 2005-01-04 devnull if (*p == 'y') {
537 020c8058 2005-01-04 devnull xyoffset.y += atoi(p+1)*100;
538 020c8058 2005-01-04 devnull skipto(np-1, np);
539 020c8058 2005-01-04 devnull return 1;
540 020c8058 2005-01-04 devnull }
541 020c8058 2005-01-04 devnull if (*p == '/') { /* divide into n pieces */
542 020c8058 2005-01-04 devnull nview = atoi(p+1);
543 020c8058 2005-01-04 devnull if (nview < 1)
544 020c8058 2005-01-04 devnull nview = 1;
545 020c8058 2005-01-04 devnull else if (nview > MAXVIEW)
546 020c8058 2005-01-04 devnull nview = MAXVIEW;
547 020c8058 2005-01-04 devnull return skipto(np-1, np);
548 020c8058 2005-01-04 devnull }
549 020c8058 2005-01-04 devnull if (*p == 'p') {
550 020c8058 2005-01-04 devnull if (p[1] == '\0'){ /* bare 'p' */
551 020c8058 2005-01-04 devnull if(skipto(np-1, np))
552 020c8058 2005-01-04 devnull return 1;
553 020c8058 2005-01-04 devnull continue;
554 020c8058 2005-01-04 devnull }
555 020c8058 2005-01-04 devnull p++;
556 020c8058 2005-01-04 devnull }
557 020c8058 2005-01-04 devnull if ('0'<=*p && *p<='9') {
558 020c8058 2005-01-04 devnull n = atoi(p);
559 020c8058 2005-01-04 devnull if(skipto(n, np))
560 020c8058 2005-01-04 devnull return 1;
561 020c8058 2005-01-04 devnull continue;
562 020c8058 2005-01-04 devnull }
563 020c8058 2005-01-04 devnull if (*p == '-' || *p == '+') {
564 020c8058 2005-01-04 devnull n = atoi(p);
565 020c8058 2005-01-04 devnull if (n == 0)
566 020c8058 2005-01-04 devnull n = *p == '-' ? -1 : 1;
567 020c8058 2005-01-04 devnull if(skipto(np - 1 + n, np))
568 020c8058 2005-01-04 devnull return 1;
569 020c8058 2005-01-04 devnull continue;
570 020c8058 2005-01-04 devnull }
571 020c8058 2005-01-04 devnull if (*p == 'd') {
572 020c8058 2005-01-04 devnull dbg = 1 - dbg;
573 020c8058 2005-01-04 devnull continue;
574 020c8058 2005-01-04 devnull }
575 020c8058 2005-01-04 devnull
576 020c8058 2005-01-04 devnull fprint(2, "illegal; try q, 17, +2, -1, p, m.7, /2, x1, y-.5 or return\n");
577 020c8058 2005-01-04 devnull }
578 020c8058 2005-01-04 devnull return 0;
579 020c8058 2005-01-04 devnull }