|
|
1.1 root 1: /*
2: * drive jerq terminal.
3: * not many sizes and fonts right now
4: */
5:
6: /*
7: output language from troff:
8: all numbers are character strings
9:
10: sn size in points
11: fn font as number from 1-n
12: cx ascii character x
13: Cxyz funny char xyz. terminated by white space
14: Hn go to absolute horizontal position n
15: Vn go to absolute vertical position n (down is positive)
16: hn go n units horizontally (relative)
17: vn ditto vertically
18: nnc move right nn, then print c (exactly 2 digits!)
19: (this wart is an optimization that shrinks output file size
20: about 35% and run-time about 15% while preserving ascii-ness)
21: Dt ...\n draw operation 't':
22: Dl x y line from here by x,y
23: Dc d circle of diameter d with left side here
24: De x y ellipse of axes x,y with left side here
25: Da x y r arc counter-clockwise by x,y of radius r
26: D~ x y x y ... wiggly line by x,y then x,y ...
27: nb a end of line (information only -- no action needed)
28: b = space before line, a = after
29: p new page begins -- set v to 0
30: #...\n comment
31: x ...\n device control functions:
32: x i init
33: x T s name of device is s
34: x r n h v resolution is n/inch
35: h = min horizontal motion, v = min vert
36: x p pause (can restart)
37: x s stop -- done for ever
38: x t generate trailer
39: x f n s font position n contains font s
40: x H n set character height to n
41: x S n set slant to N
42:
43: Subcommands like "i" are often spelled out like "init".
44: */
45:
46: #include <stdio.h>
47: #include <signal.h>
48: #include <math.h>
49: #include <ctype.h>
50: #include <sgtty.h>
51: #include "dev.h"
52: #define NFONT 10
53:
54: struct sgttyb sttymodes, sttysave, sttychars;
55: int xx, yy;
56: int xoffset = 0; /* shift output right by this amount */
57: int yoffset = 0; /* shift down (!) by this amount */
58: int output = 0; /* do we do output at all? */
59: int nolist = 0; /* output page list if > 0 */
60: int olist[20]; /* pairs of page numbers */
61:
62: int erase = 1;
63: float aspect = 1; /* default aspect ratio */
64: int revmode = 0; /* reverse video if set */
65: int (*sigint)();
66: int (*sigquit)();
67: int jtcalled = 0; /* 1 if managed to call jt */
68:
69: struct dev dev;
70: struct font *fontbase[NFONT+1];
71: short *pstab;
72: int nsizes = 1;
73: int nfonts;
74: int smnt; /* index of first special font */
75: int nchtab;
76: char *chname;
77: short *chtab;
78: char *fitab[NFONT+1];
79: char *widthtab[NFONT+1]; /* widtab would be a better name */
80: char *codetab[NFONT+1]; /* device codes */
81:
82: #define FATAL 1
83: #define BMASK 0377
84: int dbg = 0;
85: int Xflag = 0;
86: long lineno = 0;
87: int res = 972; /* input assumed computed according to this resolution */
88: /* initial value to avoid 0 divide */
89: #define JERQRES 100.0 /* resolution of jerq */
90: FILE *tf = NULL; /* output file pointer */
91: char outfile[20];
92: char *fontdir = "/usr/lib/font";
93: extern char devname[];
94:
95: FILE *fp = stdin; /* input file pointer */
96:
97: main(argc, argv)
98: char *argv[];
99: {
100: char buf[BUFSIZ];
101: int done();
102: char *getenv(), *jerq;
103:
104: jerq = getenv("JERQ");
105: if (jerq == NULL) {
106: error(!FATAL, "JERQ parameter not set\n");
107: exit(1);
108: }
109: sprintf(outfile, "/dev/%s", jerq);
110: while (argc > 1 && argv[1][0] == '-') {
111: switch (argv[1][1]) {
112: case 't':
113: tf = stdout;
114: break;
115: case 'x':
116: xoffset = atoi(&argv[1][2]);
117: break;
118: case 'y':
119: yoffset = atoi(&argv[1][2]);
120: break;
121: case 'a':
122: aspect = atof(&argv[1][2]);
123: break;
124: case 'e':
125: erase = 0;
126: break;
127: case 'o':
128: outlist(&argv[1][2]);
129: break;
130: case 'd':
131: dbg = atoi(&argv[1][2]);
132: if (dbg == 0) dbg = 1;
133: tf = stdout;
134: break;
135: case 'j':
136: outfile[8] = argv[1][2]; /* kludge */
137: break;
138: case 'X': /* use experimental version */
139: Xflag++;
140: break;
141: }
142: argc--;
143: argv++;
144: }
145:
146: if (tf == NULL && (tf = fopen(outfile, "w")) == NULL)
147: error(FATAL, "can't open terminal %s", outfile);
148: if (tf != stdout) {
149: pushmode();
150: jtcalled++;
151: if (Xflag)
152: system("68ld /usr/bwk/troff/devjerq/jt");
153: else
154: system("68ld /usr/jerq/lib/jt");
155: }
156: sigint = signal(SIGINT, done);
157: sigquit = signal(SIGQUIT, SIG_IGN);
158: if (argc <= 1)
159: conv(stdin);
160: else
161: while (--argc > 0) {
162: if (strcmp(*++argv, "-") == 0)
163: fp = stdin;
164: else if ((fp = fopen(*argv, "r")) == NULL)
165: error(FATAL, "can't open %s", *argv);
166: conv(fp);
167: fclose(fp);
168: }
169: done();
170: }
171:
172: pushmode()
173: {
174: ioctl(1, TIOCGETP, &sttymodes);
175: sttysave=sttymodes;
176: sttymodes.sg_flags|=RAW;
177: sttymodes.sg_flags&=~ECHO;
178: ioctl(1, TIOCSETP, &sttymodes);
179: }
180:
181: popmode()
182: {
183: ioctl(1, TIOCSETP, &sttysave);
184: }
185:
186: outlist(s) /* process list of page numbers to be printed */
187: char *s;
188: {
189: int n1, n2, i;
190:
191: nolist = 0;
192: while (*s) {
193: n1 = 0;
194: if (isdigit(*s))
195: do
196: n1 = 10 * n1 + *s++ - '0';
197: while (isdigit(*s));
198: else
199: n1 = -9999;
200: n2 = n1;
201: if (*s == '-') {
202: s++;
203: n2 = 0;
204: if (isdigit(*s))
205: do
206: n2 = 10 * n2 + *s++ - '0';
207: while (isdigit(*s));
208: else
209: n2 = 9999;
210: }
211: olist[nolist++] = n1;
212: olist[nolist++] = n2;
213: if (*s != '\0')
214: s++;
215: }
216: olist[nolist] = 0;
217: if (dbg)
218: for (i=0; i<nolist; i += 2)
219: printf("%3d %3d\n", olist[i], olist[i+1]);
220: }
221:
222: in_olist(n) /* is n in olist? */
223: int n;
224: {
225: int i;
226:
227: if (nolist == 0)
228: return(1); /* everything is included */
229: for (i = 0; i < nolist; i += 2)
230: if (n >= olist[i] && n <= olist[i+1])
231: return(1);
232: return(0);
233: }
234:
235: conv(fp)
236: register FILE *fp;
237: {
238: register int c, k;
239: int m, n, i, n1, m1;
240: char str[100], buf[300];
241:
242: while ((c = getc(fp)) != EOF) {
243: switch (c) {
244: case '\n': /* when input is text */
245: case ' ':
246: case 0: /* occasional noise creeps in */
247: break;
248: case '{': /* push down current environment */
249: t_push();
250: break;
251: case '}':
252: t_pop();
253: break;
254: case '0': case '1': case '2': case '3': case '4':
255: case '5': case '6': case '7': case '8': case '9':
256: /* two motion digits plus a character */
257: hmot((c-'0')*10 + getc(fp)-'0');
258: put1(getc(fp));
259: break;
260: case 'c': /* single ascii character */
261: put1(getc(fp));
262: break;
263: case 'C':
264: fscanf(fp, "%s", str);
265: put1s(str);
266: break;
267: case 't': /* straight text */
268: fgets(buf, sizeof(buf), fp);
269: t_text(buf);
270: break;
271: case 'D': /* draw function */
272: fgets(buf, sizeof(buf), fp);
273: switch (buf[0]) {
274: case 'l': /* draw a line */
275: sscanf(buf+1, "%d %d", &n, &m);
276: drawline(n, m, ".");
277: break;
278: case 'c': /* circle */
279: sscanf(buf+1, "%d", &n);
280: drawcirc(n);
281: break;
282: case 'e': /* ellipse */
283: sscanf(buf+1, "%d %d", &m, &n);
284: drawellip(m, n);
285: break;
286: case 'a': /* arc */
287: sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
288: drawarc(n, m, n1, m1);
289: break;
290: case '~': /* wiggly line */
291: drawwig(buf+1);
292: break;
293: default:
294: error(FATAL, "unknown drawing function %s\n", buf);
295: break;
296: }
297: break;
298: case 's':
299: fscanf(fp, "%d", &n); /* ignore fractional sizes */
300: setsize(t_size(n));
301: break;
302: case 'f':
303: fscanf(fp, "%s", str);
304: setfont(t_font(str));
305: break;
306: case 'H': /* absolute horizontal motion */
307: /* fscanf(fp, "%d", &n); */
308: while ((c = getc(fp)) == ' ')
309: ;
310: k = 0;
311: do {
312: k = 10 * k + c - '0';
313: } while (isdigit(c = getc(fp)));
314: ungetc(c, fp);
315: hgoto(k);
316: break;
317: case 'h': /* relative horizontal motion */
318: /* fscanf(fp, "%d", &n); */
319: while ((c = getc(fp)) == ' ')
320: ;
321: k = 0;
322: do {
323: k = 10 * k + c - '0';
324: } while (isdigit(c = getc(fp)));
325: ungetc(c, fp);
326: hmot(k);
327: break;
328: case 'w': /* word space */
329: break;
330: case 'V':
331: fscanf(fp, "%d", &n);
332: vgoto(n);
333: break;
334: case 'v':
335: fscanf(fp, "%d", &n);
336: vmot(n);
337: break;
338: case 'p': /* new page */
339: fscanf(fp, "%d", &n);
340: t_page(n);
341: break;
342: case 'n': /* end of line */
343: while (getc(fp) != '\n')
344: ;
345: t_newline();
346: break;
347: case '#': /* comment */
348: while (getc(fp) != '\n')
349: ;
350: break;
351: case 'x': /* device control */
352: devcntrl(fp);
353: break;
354: default:
355: error(!FATAL, "unknown input character %o %c\n", c, c);
356: done();
357: }
358: }
359: }
360:
361: devcntrl(fp) /* interpret device control functions */
362: FILE *fp;
363: {
364: char str[20], str1[50], buf[50];
365: int c, n;
366:
367: fscanf(fp, "%s", str);
368: switch (str[0]) { /* crude for now */
369: case 'i': /* initialize */
370: fileinit();
371: t_init(0);
372: break;
373: case 'T': /* device name */
374: fscanf(fp, "%s", devname);
375: break;
376: case 't': /* trailer */
377: t_trailer();
378: break;
379: case 'p': /* pause -- can restart */
380: t_reset('p');
381: break;
382: case 's': /* stop */
383: t_reset('s');
384: break;
385: case 'r': /* resolution assumed when prepared */
386: fscanf(fp, "%d", &res);
387: break;
388: case 'f': /* font used */
389: fscanf(fp, "%d %s", &n, str);
390: fgets(buf, sizeof buf, fp); /* in case there's a filename */
391: ungetc('\n', fp); /* fgets goes too far */
392: str1[0] = 0; /* in case there's nothing to come in */
393: sscanf(buf, "%s", str1);
394: loadfont(n, str, str1);
395: break;
396: /* these don't belong here... */
397: case 'H': /* char height */
398: fscanf(fp, "%d", &n);
399: t_charht(n);
400: break;
401: case 'S': /* slant */
402: fscanf(fp, "%d", &n);
403: t_slant(n);
404: break;
405: }
406: while ((c = getc(fp)) != '\n') /* skip rest of input line */
407: if (c == EOF)
408: break;
409: }
410:
411: fileinit() /* read in font and code files, etc. */
412: {
413: int i, fin, nw;
414: char *malloc(), *filebase, *p;
415: char temp[60];
416:
417: /* open table for device,
418: /* read in resolution, size info, font info, etc.
419: /* and set params
420: */
421: strcpy(devname, "202"); /* this is the only char set we have */
422: /* the resolution, etc., is already in */
423: sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname);
424: if ((fin = open(temp, 0)) < 0)
425: error(FATAL, "can't open tables for %s\n", temp);
426: read(fin, &dev, sizeof(struct dev));
427: nfonts = dev.nfonts;
428: nsizes = dev.nsizes;
429: nchtab = dev.nchtab;
430: filebase = malloc(dev.filesize); /* enough room for whole file */
431: read(fin, filebase, dev.filesize); /* all at once */
432: pstab = (short *) filebase;
433: chtab = pstab + nsizes + 1;
434: chname = (char *) (chtab + dev.nchtab);
435: p = chname + dev.lchname;
436: for (i = 0; i <= nfonts; i++) {
437: fontbase[i] = NULL;
438: widthtab[i] = codetab[i] = fitab[i] = NULL;
439: }
440: close(fin);
441: }
442:
443: fontprint(i) /* debugging print of font i (0,...) */
444: {
445: int j, k, n;
446: char *p;
447:
448: printf("font %d:\n", i);
449: p = (char *) fontbase[i];
450: n = fontbase[i]->nwfont & BMASK;
451: printf("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",
452: p, n, fontbase[i]->specfont, fontbase[i]->namefont, widthtab[i], fitab[i]);
453: printf("widths:\n");
454: for (j=0; j <= n; j++) {
455: printf(" %2d", widthtab[i][j] & BMASK);
456: if (j % 20 == 19) printf("\n");
457: }
458: printf("\ncodetab:\n");
459: for (j=0; j <= n; j++) {
460: printf(" %2d", codetab[i][j] & BMASK);
461: if (j % 20 == 19) printf("\n");
462: }
463: printf("\nfitab:\n");
464: for (j=0; j <= dev.nchtab + 128-32; j++) {
465: printf(" %2d", fitab[i][j] & BMASK);
466: if (j % 20 == 19) printf("\n");
467: }
468: printf("\n");
469: }
470:
471: loadfont(n, s, s1) /* load font info for font s on position n (0...) */
472: int n;
473: char *s, *s1;
474: {
475: char temp[60];
476: int fin, nw, norig;
477:
478: if (n < 0 || n > NFONT)
479: error(FATAL, "illegal fp command %d %s", n, s);
480: if (fontbase[n] != NULL && strcmp(s, fontbase[n]->namefont) == 0)
481: return;
482: if (s1 == NULL || s1[0] == '\0')
483: sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, s);
484: else
485: sprintf(temp, "%s/%s.out", s1, s);
486: if ((fin = open(temp, 0)) < 0) {
487: error(!FATAL, "can't open font table %s", temp);
488: return;
489: }
490: if (fontbase[n] != NULL)
491: free(fontbase[n]);
492: fontbase[n] = (struct font *) malloc(3*255 + dev.nchtab +
493: (128-32) + sizeof(struct font));
494: if (fontbase[n] == NULL)
495: error(FATAL, "Out of space in loadfont %s\n", s);
496: read(fin, fontbase[n], 3*255 + nchtab+128-32 + sizeof(struct font));
497: close(fin);
498: if (smnt == 0 && fontbase[n]->specfont == 1)
499: smnt = n;
500: nw = fontbase[n]->nwfont & BMASK;
501: widthtab[n] = (char *) fontbase[n] + sizeof(struct font);
502: codetab[n] = (char *) widthtab[n] + 2 * nw;
503: fitab[n] = (char *) widthtab[n] + 3 * nw;
504: t_fp(n, fontbase[n]->namefont, fontbase[n]->intname);
505: if (dbg > 1) fontprint(n);
506: }
507:
508: #define MINY 0
509: #define MAXY (1023-10)
510: #define MAXX 800
511:
512: error(f, s, a1, a2, a3, a4, a5, a6, a7) {
513: if (dbg) {
514: fprintf(stderr, "jc: ");
515: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
516: fprintf(stderr, " near line %ld\n", lineno);
517: }
518: if (f)
519: done(2);
520: }
521:
522:
523: /*
524: Here beginneth all the stuff that really depends
525: on the jerq (we hope).
526: */
527:
528:
529: char devname[20] = "jerq";
530:
531: #define oput(c) if (output) xychar(xx, yy, c); else;
532:
533: int stopped = 0;
534: int size = 1;
535: int font = 1; /* current font */
536: int hpos; /* horizontal position where we are supposed to be next (left = 0) */
537: int vpos; /* current vertical position (down positive) */
538:
539: int horig; /* h origin of current block; hpos rel to this */
540: int vorig; /* v origin of current block; vpos rel to this */
541:
542: int DX = 8; /* step size in x for drawing */
543: int DY = 8; /* step size in y for drawing */
544: int drawdot = '.'; /* draw with this character */
545: int drawsize = 1; /* shrink by this factor when drawing */
546:
547: t_init(reinit) /* initialize device */
548: int reinit;
549: {
550: int i;
551:
552: if (! reinit) {
553: fprintf(tf, "i\n");
554: for (i = 0; i < nchtab; i++)
555: if (strcmp(&chname[chtab[i]], "l.") == 0)
556: break;
557: if (i < nchtab) {
558: drawdot = i + 128;
559: drawsize = 1;
560: } else {
561: drawdot = '.';
562: drawsize = 2; /* half size */
563: }
564: }
565: fflush(tf);
566: stopped = 0;
567: if (erase) {
568: fprintf(tf, "e\n");
569: fflush(tf);
570: }
571: hpos = vpos = 0;
572: setsize(t_size(10)); /* start somewhere */
573: sendpt();
574: }
575:
576: #define MAXSTATE 5
577:
578: struct state {
579: int ssize;
580: int sfont;
581: int shpos;
582: int svpos;
583: int shorig;
584: int svorig;
585: };
586: struct state state[MAXSTATE];
587: struct state *statep = state;
588:
589: t_push() /* begin a new block */
590: {
591: hflush();
592: statep->ssize = size;
593: statep->sfont = font;
594: statep->shorig = horig;
595: statep->svorig = vorig;
596: statep->shpos = hpos;
597: statep->svpos = vpos;
598: horig = hpos;
599: vorig = vpos;
600: hpos = vpos = 0;
601: if (statep++ >= state+MAXSTATE)
602: error(FATAL, "{ nested too deep");
603: hpos = vpos = 0;
604: }
605:
606: t_pop() /* pop to previous state */
607: {
608: if (--statep < state)
609: error(FATAL, "extra }");
610: size = statep->ssize;
611: font = statep->sfont;
612: hpos = statep->shpos;
613: vpos = statep->svpos;
614: horig = statep->shorig;
615: vorig = statep->svorig;
616: }
617:
618: int np; /* number of pages seen */
619: int npmax; /* high-water mark of np */
620: int pgnum[100]; /* their actual numbers */
621: long pgadr[100]; /* their seek addresses */
622:
623: t_page(n) /* do whatever new page functions */
624: {
625: long ftell();
626: int c, m, i;
627: char buf[100], *bp;
628:
629: pgnum[np++] = n;
630: pgadr[np] = ftell(fp);
631: if (np > npmax)
632: npmax = np;
633: if (output == 0) {
634: output = in_olist(n);
635: t_init(1);
636: return;
637: }
638: /* have just printed something, and seen p<n> for next one */
639: vgoto(11 * res - 100);
640: sendpt();
641: fflush(tf);
642:
643: next:
644: for (bp = buf; (*bp = readch()); )
645: if (*bp++ == '\n')
646: break;
647: *bp = 0;
648: switch (buf[0]) {
649: case '\004':
650: case '\177':
651: case 0:
652: done();
653: break;
654: case '\n':
655: if (stopped)
656: done();
657: output = in_olist(n);
658: t_init(1);
659: return;
660: case '!':
661: callunix(&buf[1]);
662: fputs("!\n", stderr);
663: break;
664: case 'e':
665: erase = 1 - erase;
666: if (erase) {
667: putc('e', tf);
668: fflush(tf);
669: }
670: break;
671: case 'r':
672: putc('r', tf);
673: fflush(tf);
674: break;
675: case 'a':
676: aspect = atof(&buf[1]);
677: break;
678: case 'x':
679: xoffset = atoi(&buf[1]);
680: break;
681: case 'y':
682: yoffset = atoi(&buf[1]);
683: break;
684: case '-':
685: case 'p':
686: m = atoi(&buf[1]) + 1;
687: if (fp == stdin) {
688: fputs("you can't; it's not a file\n", stderr);
689: break;
690: }
691: if (np - m <= 0) {
692: fputs("too far back\n", stderr);
693: break;
694: }
695: np -= m;
696: fseek(fp, pgadr[np], 0);
697: output = 1;
698: t_init(1);
699: return;
700: case '0': case '1': case '2': case '3': case '4':
701: case '5': case '6': case '7': case '8': case '9':
702: m = atoi(&buf[0]);
703: for (i = 0; i < npmax; i++)
704: if (m == pgnum[i])
705: break;
706: if (i >= npmax || fp == stdin) {
707: fputs("you can't\n", stderr);
708: break;
709: }
710: np = i + 1;
711: fseek(fp, pgadr[np], 0);
712: output = 1;
713: t_init(1);
714: return;
715: case 'o':
716: outlist(&buf[1]);
717: output = 0;
718: t_init(1);
719: return;
720: case 'q':
721: done();
722: break;
723: case '?':
724: fputs("!cmd unix cmd\n", stderr);
725: fputs("p print this page again\n", stderr);
726: fputs("-n go back n pages\n", stderr);
727: fputs("n print page n (previously printed)\n", stderr);
728: fputs("o... set the -o output list to ...\n", stderr);
729: fputs("en n=0 -> don't erase; n=1 -> erase\n", stderr);
730: fputs("an set aspect ratio to n\n", stderr);
731: fputs("xn set x offset to n (+ => right)\n", stderr);
732: fputs("yn set y offset to n (+ => down)\n", stderr);
733: break;
734: default:
735: fputs("?\n", stderr);
736: break;
737: }
738: goto next;
739: }
740:
741: t_newline() /* do whatever for the end of a line */
742: {
743: hpos = 0;
744: }
745:
746: t_size(n) /* convert integer to internal size number*/
747: int n;
748: {
749: int i;
750:
751: if (n <= pstab[0])
752: return(1);
753: else if (n >= pstab[nsizes-1])
754: return(nsizes);
755: for (i = 0; n > pstab[i]; i++)
756: ;
757: return(i+1);
758: }
759:
760: t_charht(n) /* set character height to n */
761: int n;
762: {
763: /* punt for now */
764: }
765:
766: t_slant(n) /* set slant to n */
767: int n;
768: {
769: /* punt for now */
770: }
771:
772: t_font(s) /* convert string to internal font number */
773: char *s;
774: {
775: int n;
776:
777: n = atoi(s);
778: if (n < 1 || n > nfonts)
779: n = 1;
780: return(n);
781: }
782:
783: t_text(s) /* print string s as text */
784: char *s;
785: {
786: int c, w;
787: char str[100];
788:
789: if (!output)
790: return;
791: w = res / 2 * pstab[size-1] / 72;
792: while ((c = *s++) != '\n') {
793: if (c == '\\') {
794: switch (c = *s++) {
795: case '\\':
796: case 'e':
797: put1('\\');
798: break;
799: case '(':
800: str[0] = *s++;
801: str[1] = *s++;
802: str[2] = '\0';
803: put1s(str);
804: break;
805: }
806: } else {
807: put1(c);
808: }
809: hmot(w);
810: }
811: }
812:
813: t_reset(c)
814: {
815: int n;
816:
817: output = 1;
818: fflush(tf);
819: if (c == 's') {
820: stopped = 1;
821: t_page(9999);
822: }
823: }
824:
825: t_trailer()
826: {
827: }
828:
829: hgoto(n)
830: {
831: hpos = n; /* this is where we want to be */
832: /* before printing a character, */
833: /* have to make sure it's true */
834: }
835:
836: hmot(n) /* generate n units of horizontal motion */
837: int n;
838: {
839: hgoto(hpos + n);
840: }
841:
842: hflush() /* actual horizontal output occurs here */
843: {
844: if (output)
845: sendpt();
846: }
847:
848: vgoto(n)
849: {
850: vpos = n;
851: }
852:
853: vmot(n) /* generate n units of vertical motion */
854: int n;
855: {
856: vgoto(vpos + n); /* ignores rounding */
857: }
858:
859: put1s(s) /* s is a funny char name */
860: char *s;
861: {
862: int i;
863:
864: if (!output)
865: return;
866: if (dbg) printf("%s ", s);
867: for (i = 0; i < nchtab; i++)
868: if (strcmp(&chname[chtab[i]], s) == 0)
869: break;
870: if (i < nchtab)
871: put1(i + 128);
872: }
873:
874: put1(c) /* output char c */
875: int c;
876: {
877: char *pw;
878: register char *p;
879: register int i, k;
880: int j, ofont, code, w;
881:
882: if (!output)
883: return;
884: c -= 32;
885: if (c <= 0) {
886: if (dbg) printf("non-exist 0%o\n", c+32);
887: return;
888: }
889: k = ofont = font;
890: i = fitab[font][c] & BMASK;
891: if (i != 0) { /* it's on this font */
892: p = codetab[font];
893: pw = widthtab[font];
894: } else if (smnt > 0) { /* on special (we hope) */
895: for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1))
896: if ((i = fitab[k][c] & BMASK) != 0) {
897: p = codetab[k];
898: pw = widthtab[k];
899: setfont(k);
900: break;
901: }
902: }
903: if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) {
904: if (dbg) printf("not found 0%o\n", c+32);
905: return;
906: }
907: hflush();
908: if (dbg) {
909: if (isprint(c+32))
910: printf("%c %d\n", c+32, code);
911: else
912: printf("%03o %d\n", c+32, code);
913: } else
914: oput(code);
915: if (font != ofont)
916: setfont(ofont);
917: }
918:
919: setsize(n) /* set point size to n (internal) */
920: int n;
921: {
922:
923: if (!output)
924: return;
925: if (n == size)
926: return; /* already there */
927: putc('s', tf);
928: putint(pstab[n-1]);
929: size = n;
930: }
931:
932: /* font position info: */
933:
934: struct {
935: char *name;
936: int number;
937: } fontname[NFONT+1];
938:
939: t_fp(n, s, si) /* font position n now contains font s, intname si */
940: int n;
941: char *s, *si;
942: {
943: fontname[n].name = s;
944: fontname[n].number = atoi(si);
945: }
946:
947: setfont(n) /* set font to n */
948: int n;
949: {
950: if (!output)
951: return;
952: if (n < 0 || n > NFONT)
953: error(FATAL, "illegal font %d\n", n);
954: putc('f', tf);
955: /* putint(fontname[n].number); */
956: putint(n); /* for now */
957: font = n;
958: }
959:
960: done()
961: {
962: output = 1;
963: hgoto(0);
964: vgoto(11 * res - 100); /* bottom of page */
965: sendpt();
966: fflush(tf);
967: if (jtcalled)
968: system("run - /usr/jerq/lib/term");
969: popmode();
970: exit(0);
971: }
972:
973: callunix(line)
974: char line[];
975: {
976: int rc, status, unixpid;
977: if( (unixpid=fork())==0 ) {
978: signal(SIGINT,sigint); signal(SIGQUIT,sigquit);
979: close(0); close(1); dup(2); dup(2);
980: execl("/bin/sh", "-sh", "-c", line, 0);
981: exit(255);
982: }
983: else if(unixpid == -1)
984: return;
985: else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN);
986: while( (rc = wait(&status)) != unixpid && rc != -1 ) ;
987: signal(SIGINT, done); signal(SIGQUIT,sigquit);
988: }
989: }
990: readch(){
991: char c;
992: if (read(2,&c,1)<1 || (c == '\004') || (c == '\177')) c=0;
993: return(c);
994: }
995:
996: scalept(n)
997: {
998: ((float)(n) * JERQRES / res) * aspect + 0.5;
999: }
1000:
1001: sendpt()
1002: {
1003: float fx, fy;
1004:
1005: fx = hpos + horig;
1006: fy = vpos + vorig;
1007: xx = fx * JERQRES / res * aspect + 0.5;
1008: xx += xoffset;
1009: yy = fy * (MAXY-MINY) / (11 * res) + MINY + 0.5;
1010: yy += yoffset;
1011: }
1012:
1013: xychar(x,y,c)
1014: {
1015: static int lasty = 0;
1016: static int lastx = 0;
1017:
1018: if (y != lasty) {
1019: putc('y', tf);
1020: putint(y);
1021: lasty = y;
1022: }
1023: /* optimization? */
1024: if (x-lastx >= 0 && x-lastx <= 255 && c != '0') {
1025: putc('X', tf);
1026: putc(x-lastx, tf);
1027: putc(c, tf);
1028: } else {
1029: putc('x', tf);
1030: putint(x);
1031: if (c) {
1032: putc('c', tf);
1033: putc(c, tf);
1034: }
1035: }
1036: lastx = x;
1037: }
1038:
1039: putint(n)
1040: {
1041: if (dbg) {
1042: printf("%02d\n", n);
1043: return;
1044: }
1045: putc(n>>8, tf);
1046: putc(n, tf);
1047: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.