15 Point xyoffset = { 0,0 };
17 Rectangle view[MAXVIEW];
18 Rectangle bound[MAXVIEW]; /* extreme points */
21 int lastp; /* last page number we were on */
27 } pagenums[NPAGENUMS];
32 char *getcmdstr(void);
34 static void initpage(void);
35 static void view_setup(int);
36 static Point scale(Point);
37 static void clearview(Rectangle);
38 static int addpage(int);
39 static void spline(Image *, int, Point *);
40 static int skipto(int, int);
41 static void wiggly(int);
42 static void devcntrl(void);
43 static void eatline(void);
44 static int getn(void);
45 static int botpage(int);
46 static void getstr(char *);
48 static void getutf(char *);
51 #define Do screen->r.min
52 #define Dc screen->r.max
54 /* declarations and definitions of font stuff are in font.c and main.c */
62 for (i = 0; i < nview-1; i++)
63 draw(screen, view[i], screen, nil, view[i+1].min);
64 clearview(view[nview-1]);
65 offset = view[nview-1].min;
72 int i, j, v, dx, dy, r, c;
75 case 1: r = 1; c = 1; break;
76 case 2: r = 1; c = 2; break;
77 case 3: r = 1; c = 3; break;
78 case 4: r = 2; c = 2; break;
79 case 5: case 6: r = 2; c = 3; break;
80 case 7: case 8: case 9: r = 3; c = 3; break;
81 default: r = (n+2)/3; c = 3; break; /* finking out */
83 dx = (Dc.x - Do.x) / c;
84 dy = (Dc.y - Do.y) / r;
86 for (i = 0; i < r && v < n; i++)
87 for (j = 0; j < c && v < n; j++) {
89 view[v].min.x = Do.x + j * dx;
90 view[v].max.x = Do.x + (j+1) * dx;
91 view[v].min.y = Do.y + i * dy;
92 view[v].max.y = Do.y + (i+1) * dy;
98 clearview(Rectangle r)
100 draw(screen, r, display->white, nil, r.min);
104 void eresized(int new)
106 /* this is called if we are resized */
107 if(new && getwindow(display, Refnone) < 0)
108 drawerror(display, "can't reattach to window");
118 return addpt(xyoffset, addpt(offset,p));
126 for (i = 0; i < npagenums; i++)
127 if (n == pagenums[i].num)
129 if (npagenums < NPAGENUMS-1) {
130 pagenums[npagenums].num = n;
131 pagenums[npagenums].adr = offsetc();
140 int c, i, a, alpha, phi;
141 static int first = 0;
146 offset = screen->clipr.min;
147 esetcursor(&deadmouse);
155 if (botpage(lastp+1)) {
160 case 'p': /* new page */
166 esetcursor(&deadmouse);
170 case '\n': /* when input is text */
172 case 0: /* occasional noise creeps in */
174 case '0': case '1': case '2': case '3': case '4':
175 case '5': case '6': case '7': case '8': case '9':
176 /* two motion digits plus a character */
177 hpos += (c-'0')*10 + getc()-'0';
180 case 'c': /* single ascii character */
203 case 'D': /* draw function */
206 case 'l': /* draw a line */
210 q = addpt(p, Pt(n,m));
213 line(screen, scale(p), scale(q), 0, 0, 0, display->black, ZP);
215 case 'c': /* circle */
220 ellipse(screen, scale(p), m/DIV, m/DIV, 0, display->black, ZP);
221 /* p=currentpt; p.x+=dmap(m/2);circle bp,p,a,ONES,Mode*/
223 case 'e': /* ellipse */
229 ellipse(screen, scale(p), m/DIV, n/DIV, 0, display->black, ZP);
232 p = scale(Pt(hpos,vpos));
237 q = scale(Pt(hpos,vpos));
242 qq = scale(Pt(hpos,vpos));
244 * tricky: convert from 3-point clockwise to
245 * center, angle1, delta-angle counterclockwise.
247 a = hypot(qq.x-q.x, qq.y-q.y);
248 phi = atan2(q.y-p.y, p.x-q.x)*180./PI;
249 alpha = atan2(q.y-qq.y, qq.x-q.x)*180./PI - phi;
252 arc(screen, q, a, a, 0, display->black, ZP, phi, alpha);
254 case '~': /* wiggly line */
263 n = getn(); /* ignore fractional sizes */
267 if (cursize >= NFONT)
273 case 'H': /* absolute horizontal motion */
276 case 'h': /* relative horizontal motion */
279 case 'w': /* word space */
287 case '#': /* comment */
288 case 'n': /* end of line */
291 case 'x': /* device control */
295 fprint(2, "unknown input character %o %c at offset %lud\n", c, c, offsetc());
303 spline(Image *b, int n, Point *pp)
305 long w, t1, t2, t3, fac=1000;
309 for (i = n; i > 0; i--)
314 for(i = 0; i < n-2; i++)
316 for(j = 0; j < steps; j++)
319 t1 = w * w / (2 * fac);
321 t2 = 3*fac/4 - w * w / fac;
323 t3 = w * w / (2*fac);
324 q.x = (t1*pp[i+2].x + t2*pp[i+1].x +
325 t3*pp[i].x + fac/2) / fac;
326 q.y = (t1*pp[i+2].y + t2*pp[i+1].y +
327 t3*pp[i].y + fac/2) / fac;
328 line(b, p, q, 0, 0, 0, display->black, ZP);
334 /* Have to parse skipped pages, to find out what fonts are loaded. */
336 skipto(int gotop, int curp)
343 for (i = 0; i < npagenums; i++)
344 if (pagenums[i].num == gotop) {
345 if (seekc(pagenums[i].adr) == Beof) {
346 fprint(2, "can't rewind input\n");
353 if (seekc(0) == Beof) {
354 fprint(2, "can't rewind input\n");
366 } else if (*p == 'p') {
367 lastp = curp = atoi(p+1);
368 addpage(lastp); /* maybe 1 too high */
380 for (n = 1; (c = getc()) != '\n' && c>=0; n++) {
385 p[0] = Pt(hpos, vpos);
386 for (i = 1; i < n; i++)
387 p[i] = addpt(p[i],p[i-1]);
390 for (i = 0; i < n; i++)
397 devcntrl(void) /* interpret device control functions */
403 switch (str[0]) { /* crude for now */
404 case 'i': /* initialize */
406 case 'T': /* device name */
409 case 't': /* trailer */
411 case 'p': /* pause -- can restart */
415 case 'r': /* resolution assumed when prepared */
417 DIV = floor(.5 + res/(100.0*mag));
420 mag = res/(100.0*DIV); /* adjust mag according to DIV coarseness */
422 case 'f': /* font used */
425 loadfontname(n, str);
427 /* these don't belong here... */
428 case 'H': /* char height */
430 case 'S': /* slant */
441 return c==' ' || c=='\t' || c=='\n';
447 uchar *s = (uchar *) is;
449 for (*s = getc(); isspace(*s); *s = getc())
451 for (; !isspace(*s); *++s = getc())
459 getutf(char *s) /* get next utf char, as bytes */
469 if (fullrune(s, i)) {
482 while ((c=getc()) != '\n' && c >= 0)
499 for (n = 0; '0'<=c && c<='9'; c = getc())
508 botpage(int np) /* called at bottom of page np-1 == top of page np */
513 while (p = getcmdstr()) {
518 if (*p == 'c') /* nop */
522 if (mag <= .1 || mag >= 10)
524 allfree(); /* zap fonts */
525 DIV = floor(.5 + res/(100.0*mag));
528 mag = res/(100.0*DIV);
529 return skipto(np-1, np); /* reprint the page */
532 xyoffset.x += atoi(p+1)*100;
537 xyoffset.y += atoi(p+1)*100;
541 if (*p == '/') { /* divide into n pieces */
545 else if (nview > MAXVIEW)
547 return skipto(np-1, np);
550 if (p[1] == '\0'){ /* bare 'p' */
557 if ('0'<=*p && *p<='9') {
563 if (*p == '-' || *p == '+') {
566 n = *p == '-' ? -1 : 1;
567 if(skipto(np - 1 + n, np))
576 fprint(2, "illegal; try q, 17, +2, -1, p, m.7, /2, x1, y-.5 or return\n");