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