|
|
1.1 root 1: /*
2: * drive 8400 typesetter
3: * This will probably run it faster if you
4: * modify setfont and put1 to actually send out
5: * a font change command when needed, instead of
6: * after every special character.
7:
8: * realistically, this code has never been tested,
9: * so take it with a grain of salt
10:
11: */
12:
13: /*
14: output language from troff:
15: all numbers are character strings
16:
17: sn size in points
18: fn font as number from 1-n
19: cx ascii character x
20: Cxyz funny char xyz. terminated by white space
21: Hn go to absolute horizontal position n
22: Vn go to absolute vertical position n (down is positive)
23: hn go n units horizontally (relative)
24: vn ditto vertically
25: nnc move right nn, then print c (exactly 2 digits!)
26: (this wart is an optimization that shrinks output file size
27: about 35% and run-time about 15% while preserving ascii-ness)
28: Dt ...\n draw operation 't':
29: Dl x y line from here by x,y
30: Dc d circle of diameter d with left side here
31: De x y ellipse of axes x,y with left side here
32: Da x y r arc counter-clockwise by x,y of radius r
33: D~ x y x y ... wiggly line by x,y then x,y ...
34: nb a end of line (information only -- no action needed)
35: w paddable word space -- no action needed
36: b = space before line, a = after
37: p new page begins -- set v to 0
38: #...\n comment
39: x ...\n device control functions:
40: x i init
41: x T s name of device is s
42: x r n h v resolution is n/inch
43: h = min horizontal motion, v = min vert
44: x p pause (can restart)
45: x s stop -- done for ever
46: x t generate trailer
47: x f n s font position n contains font s
48: x H n set character height to n
49: x S n set slant to N
50:
51: Subcommands like "i" are often spelled out like "init".
52: */
53:
54: #include <stdio.h>
55: #include <ctype.h>
56: #include <signal.h>
57:
58: #include "dev.h"
59: #define NFONT 10
60:
61: int output = 0; /* do we do output at all? */
62: int nolist = 0; /* output page list if > 0 */
63: int olist[20]; /* pairs of page numbers */
64: int spage = 9999; /* stop every spage pages */
65: int scount = 0;
66:
67: struct dev dev;
68: struct Font *fontbase[NFONT+1];
69: short *pstab;
70: int nsizes;
71: int nfonts;
72: int smnt; /* index of first special font */
73: int nchtab;
74: char *chname;
75: short *chtab;
76: char *fitab[NFONT+1];
77: char *widthtab[NFONT+1]; /* widtab would be a better name */
78: char *codetab[NFONT+1]; /* device codes */
79:
80: #define FATAL 1
81: #define BMASK 0377
82: int dbg = 0;
83: int windowht = 250; /* resettable logical height of d202 faceplate */
84: int res; /* input assumed computed according to this resolution */
85:
86: char *typesetter = "/dev/8400";
87: FILE *tf = NULL; /* output file */
88: char *fontdir = "/usr/lib/font";
89: extern char devname[];
90:
91: #define hmot(n) hpos += n
92: #define hgoto(n) hpos = n
93: #define vmot(n) vgoto(vpos + n)
94:
95: int size = -1; /* this is invalid */
96: int font = -1; /* current font */
97: int hpos; /* horizontal position where we are supposed to be next (left = 0) */
98: int oldh; /* previous H position */
99: int vpos; /* current vertical position (down positive) */
100: int oldv; /* current pos in 1/4 point units */
101: int horig; /* h origin of current block; hpos rel to this */
102: int vorig;
103: int DX = 2; /* step size in x for drawing */
104: int DY = 2; /* step size in y for drawing */
105: int drawdot = '.'; /* draw with this character */
106: int drawsize = 1; /* shrink by this factor when drawing */
107:
108: main(argc, argv)
109: char *argv[];
110: {
111: FILE *fp;
112: int i;
113: int busyflag = 0;
114: int waitflag = 0;
115: int done();
116:
117: while (argc > 1 && argv[1][0] == '-') {
118: switch (argv[1][1]) {
119: case 'f':
120: case 'F':
121: fontdir = argv[2];
122: argv++;
123: argc--;
124: break;
125: case 't':
126: tf = stdout;
127: break;
128: case 'o':
129: outlist(&argv[1][2]);
130: break;
131: case 'd':
132: dbg = atoi(&argv[1][2]);
133: if (dbg == 0) dbg = 1;
134: tf = stdout;
135: break;
136: case 'b':
137: busyflag = 1;
138: break;
139: case 'w':
140: waitflag = 1;
141: break;
142: case 's':
143: spage = atoi(&argv[1][2]);
144: if (spage <= 0)
145: spage = 9999;
146: break;
147: case 'i':
148: windowht = atoi(&argv[1][2]);
149: break;
150: }
151: argc--;
152: argv++;
153: }
154: tryagain:
155: if (tf != stdout)
156: tf = fopen(typesetter, "w");
157: if (busyflag) {
158: printf(tf==NULL? "Busy.\n": "Available.\n");
159: exit(0);
160: }
161: if (tf == NULL) {
162: if (waitflag == 0) {
163: error(!FATAL, "can't open typesetter\n");
164: exit(1);
165: } else {
166: sleep(60);
167: goto tryagain;
168: }
169: }
170:
171: if (signal(SIGINT, done) == SIG_IGN) {
172: signal(SIGINT, SIG_IGN);
173: signal(SIGQUIT, SIG_IGN);
174: signal(SIGHUP, SIG_IGN);
175: } else {
176: signal(SIGQUIT, done);
177: signal(SIGHUP, done);
178: }
179: signal(SIGTERM, done);
180:
181: if (argc <= 1)
182: conv(stdin);
183: else
184: while (--argc > 0) {
185: if (strcmp(*++argv, "-") == 0)
186: fp = stdin;
187: else if ((fp = fopen(*argv, "r")) == NULL)
188: error(FATAL, "can't open %s", *argv);
189: conv(fp);
190: fclose(fp);
191: }
192: account();
193: done();
194: }
195:
196: outlist(s) /* process list of page numbers to be printed */
197: char *s;
198: {
199: int n1, n2, i;
200:
201: nolist = 0;
202: while (*s) {
203: n1 = 0;
204: if (isdigit(*s))
205: do
206: n1 = 10 * n1 + *s++ - '0';
207: while (isdigit(*s));
208: else
209: n1 = -9999;
210: n2 = n1;
211: if (*s == '-') {
212: s++;
213: n2 = 0;
214: if (isdigit(*s))
215: do
216: n2 = 10 * n2 + *s++ - '0';
217: while (isdigit(*s));
218: else
219: n2 = 9999;
220: }
221: olist[nolist++] = n1;
222: olist[nolist++] = n2;
223: if (*s != '\0')
224: s++;
225: }
226: olist[nolist] = 0;
227: if (dbg)
228: for (i=0; i<nolist; i += 2)
229: printf("%3d %3d\n", olist[i], olist[i+1]);
230: }
231:
232: conv(fp)
233: register FILE *fp;
234: {
235: register int c, k;
236: int m, n, i, n1, m1;
237: char str[100], buf[300];
238:
239: while ((c = getc(fp)) != EOF) {
240: switch (c) {
241: case '\n': /* when input is text */
242: case ' ':
243: case 0: /* occasional noise creeps in */
244: break;
245: case '{': /* push down current environment */
246: t_push();
247: break;
248: case '}':
249: t_pop();
250: break;
251: case '0': case '1': case '2': case '3': case '4':
252: case '5': case '6': case '7': case '8': case '9':
253: /* two motion digits plus a character */
254: hmot((c-'0')*10 + getc(fp)-'0');
255: put1(getc(fp));
256: break;
257: case 'c': /* single ascii character */
258: put1(getc(fp));
259: break;
260: case 'C':
261: fscanf(fp, "%s", str);
262: put1s(str);
263: break;
264: case 't': /* straight text */
265: fgets(buf, sizeof(buf), fp);
266: t_text(buf);
267: break;
268: case 'D': /* draw function */
269: fgets(buf, sizeof(buf), fp);
270: switch (buf[0]) {
271: case 'l': /* draw a line */
272: sscanf(buf+1, "%d %d", &n, &m);
273: drawline(n, m, ".");
274: break;
275: case 'c': /* circle */
276: sscanf(buf+1, "%d", &n);
277: drawcirc(n);
278: break;
279: case 'e': /* ellipse */
280: sscanf(buf+1, "%d %d", &m, &n);
281: drawellip(m, n);
282: break;
283: case 'a': /* arc */
284: sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
285: drawarc(n, m, n1, m1);
286: break;
287: case '~': /* wiggly line */
288: drawwig(buf+1);
289: break;
290: default:
291: error(FATAL, "unknown drawing function %s\n", buf);
292: break;
293: }
294: break;
295: case 's':
296: fscanf(fp, "%d", &n); /* ignore fractional sizes */
297: setsize(t_size(n));
298: break;
299: case 'f':
300: fscanf(fp, "%s", str);
301: setfont(t_font(str));
302: break;
303: case 'H': /* absolute horizontal motion */
304: /* fscanf(fp, "%d", &n); */
305: while ((c = getc(fp)) == ' ')
306: ;
307: k = 0;
308: do {
309: k = 10 * k + c - '0';
310: } while (isdigit(c = getc(fp)));
311: ungetc(c, fp);
312: hgoto(k);
313: break;
314: case 'h': /* relative horizontal motion */
315: /* fscanf(fp, "%d", &n); */
316: while ((c = getc(fp)) == ' ')
317: ;
318: k = 0;
319: do {
320: k = 10 * k + c - '0';
321: } while (isdigit(c = getc(fp)));
322: ungetc(c, fp);
323: hmot(k);
324: break;
325: case 'w': /* word space */
326: break;
327: case 'V':
328: fscanf(fp, "%d", &n);
329: vgoto(n);
330: break;
331: case 'v':
332: fscanf(fp, "%d", &n);
333: vmot(n);
334: break;
335: case 'p': /* new page */
336: fscanf(fp, "%d", &n);
337: t_page(n);
338: break;
339: case 'n': /* end of line */
340: while (getc(fp) != '\n')
341: ;
342: t_newline();
343: break;
344: case '#': /* comment */
345: while (getc(fp) != '\n')
346: ;
347: break;
348: case 'x': /* device control */
349: devcntrl(fp);
350: break;
351: default:
352: error(!FATAL, "unknown input character %o %c\n", c, c);
353: done();
354: }
355: }
356: }
357:
358: devcntrl(fp) /* interpret device control functions */
359: FILE *fp;
360: {
361: char str[20], str1[50], buf[50];
362: int c, n;
363:
364: fscanf(fp, "%s", str);
365: switch (str[0]) { /* crude for now */
366: case 'i': /* initialize */
367: fileinit();
368: t_init(0);
369: break;
370: case 'T': /* device name */
371: fscanf(fp, "%s", devname);
372: break;
373: case 't': /* trailer */
374: t_trailer();
375: break;
376: case 'p': /* pause -- can restart */
377: t_reset('p');
378: break;
379: case 's': /* stop */
380: t_reset('s');
381: break;
382: case 'r': /* resolution assumed when prepared */
383: fscanf(fp, "%d", &res);
384: break;
385: case 'f': /* font used */
386: fscanf(fp, "%d %s", &n, str);
387: fgets(buf, sizeof buf, fp); /* in case there's a filename */
388: ungetc('\n', fp); /* fgets goes too far */
389: str1[0] = 0; /* in case there's nothing to come in */
390: sscanf(buf, "%s", str1);
391: loadfont(n, str, str1);
392: break;
393: /* these don't belong here... */
394: case 'H': /* char height */
395: fscanf(fp, "%d", &n);
396: t_charht(n);
397: break;
398: case 'S': /* slant */
399: fscanf(fp, "%d", &n);
400: t_slant(n);
401: break;
402: }
403: while ((c = getc(fp)) != '\n') /* skip rest of input line */
404: if (c == EOF)
405: break;
406: }
407:
408: fileinit() /* read in font and code files, etc. */
409: {
410: int i, fin, nw;
411: char *malloc(), *filebase, *p;
412: char temp[60];
413:
414: /* open table for device,
415: /* read in resolution, size info, font info, etc.
416: /* and set params
417: */
418: sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname);
419: if ((fin = open(temp, 0)) < 0)
420: error(FATAL, "can't open tables for %s\n", temp);
421: read(fin, &dev, sizeof(struct dev));
422: nfonts = dev.nfonts;
423: nsizes = dev.nsizes;
424: nchtab = dev.nchtab;
425: filebase = malloc(dev.filesize); /* enough room for whole file */
426: read(fin, filebase, dev.filesize); /* all at once */
427: pstab = (short *) filebase;
428: chtab = pstab + nsizes + 1;
429: chname = (char *) (chtab + dev.nchtab);
430: p = chname + dev.lchname;
431: for (i = 1; i <= nfonts; i++) {
432: fontbase[i] = (struct Font *) p;
433: nw = *p & BMASK; /* 1st thing is width count */
434: if (smnt == 0 && fontbase[i]->specfont == 1)
435: smnt = i; /* first special font */
436: p += sizeof(struct Font); /* that's what's on the beginning */
437: widthtab[i] = p;
438: codetab[i] = p + 2 * nw;
439: fitab[i] = p + 3 * nw;
440: p += 3 * nw + dev.nchtab + 128 - 32;
441: t_fp(i, fontbase[i]->namefont, fontbase[i]->intname);
442: if(dbg > 1) fontprint(i);
443: }
444: fontbase[0] = (struct Font *) malloc(3*255 + dev.nchtab + (128-32) + sizeof (struct Font));
445: widthtab[0] = (char *) fontbase[0] + sizeof (struct Font);
446: fontbase[0]->nwfont = 255;
447: close(fin);
448: }
449:
450: fontprint(i) /* debugging print of font i (0,...) */
451: {
452: int j, k, n;
453: char *p;
454:
455: printf("font %d:\n", i);
456: p = (char *) fontbase[i];
457: n = fontbase[i]->nwfont & BMASK;
458: printf("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",
459: p, n, fontbase[i]->specfont, fontbase[i]->namefont, widthtab[i], fitab[i]);
460: printf("widths:\n");
461: for (j=0; j <= n; j++) {
462: printf(" %2d", widthtab[i][j] & BMASK);
463: if (j % 20 == 19) printf("\n");
464: }
465: printf("\ncodetab:\n");
466: for (j=0; j <= n; j++) {
467: printf(" %2d", codetab[i][j] & BMASK);
468: if (j % 20 == 19) printf("\n");
469: }
470: printf("\nfitab:\n");
471: for (j=0; j <= dev.nchtab + 128-32; j++) {
472: printf(" %2d", fitab[i][j] & BMASK);
473: if (j % 20 == 19) printf("\n");
474: }
475: printf("\n");
476: }
477:
478: loadfont(n, s, s1) /* load font info for font s on position n (0...) */
479: int n;
480: char *s, *s1;
481: {
482: char temp[60];
483: int fin, nw, norig;
484:
485: if (n < 0 || n > NFONT)
486: error(FATAL, "illegal fp command %d %s", n, s);
487: if (strcmp(s, fontbase[n]->namefont) == 0)
488: return;
489: if (s1 == NULL || s1[0] == '\0')
490: sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, s);
491: else
492: sprintf(temp, "%s/%s.out", s1, s);
493: if ((fin = open(temp, 0)) < 0)
494: error(FATAL, "can't open font table %s", temp);
495: norig = fontbase[n]->nwfont & BMASK;
496: read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct Font));
497: if ((fontbase[n]->nwfont & BMASK) > norig)
498: error(FATAL, "Font %s too big for position %d\n", s, n);
499: close(fin);
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: fontbase[n]->nwfont = norig; /* so can later use full original size */
506: if (dbg > 1) fontprint(n);
507: }
508:
509: done()
510: {
511: if (tf == NULL)
512: exit(1);
513: t_reset('s');
514: exit(0);
515: }
516:
517: error(f, s, a1, a2, a3, a4, a5, a6, a7) {
518: fprintf(stderr, "d8400: ");
519: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
520: fprintf(stderr, "\n");
521: if (f)
522: done();
523: }
524:
525:
526: /*
527: Here beginneth all the stuff that really depends
528: on the 8400 (we hope).
529: */
530:
531:
532: char devname[20] = "8400";
533:
534: #define START_TAKE 0x80
535: #define END_TAKE 0x81
536: #define INIT_REV 0x85
537: #define POINT_SIZE 0x87
538: #define SET_SIZE 0x88 /* means horizontal width indep of ht */
539: #define VERT_FWD 0x89
540: #define VERT_REV 0x8a
541: #define HOR_POS 0x8b
542: #define SLANT_MODE 0x8f
543: #define SEL_FACE 0x96 /* select font, probably */
544: #define FONT_NUMBER 0x99
545: #define HOR_RIGHT 0x9b
546: #define HOR_LEFT 0x9c
547:
548: #define RES 1728 /* 8400 is ??? goobies per inch vertically */
549: /* but 972 horizontally! */
550: /* can get 486 vertically by using electronic baseline jump */
551: #define TRAILER (14 * res)
552: #define LMARGIN 0 /* left margin offset */
553: #define HMAX (48 * (res/6)) /* maximum horizontal size = 48 picas */
554: #define VMAX (15 * res) /* 15 inch page */
555:
556: int lastc, lastw; /* last character and width (maybe not used) */
557:
558: long paper; /* paper used */
559:
560: t_init(reinit) /* initialize device */
561: int reinit;
562: {
563: int i;
564:
565: hpos = vpos = oldv = oldh = 0;
566: /* the above are not true until the code below happens*/
567: setsize(t_size(10)); /* start somewhere */
568: setfont(1);
569:
570: for (i = 0; i < 10; i++) /* reset sequence */
571: putc(0, tf);
572: putcmd(START_TAKE, 0); /* resets device */
573: putcmd(INIT_REV, 0); /* sets up for reverse vertical */
574:
575: for (i = 0; i < nchtab; i++)
576: if (strcmp(&chname[chtab[i]], "l.") == 0)
577: break;
578: if (i < nchtab) {
579: drawdot = i + 128;
580: drawsize = 1;
581: } else {
582: drawdot = '.';
583: drawsize = 2; /* half size */
584: }
585: }
586:
587: #define MAXSTATE 5
588:
589: struct state {
590: int ssize;
591: int sfont;
592: int shpos;
593: int svpos;
594: int shorig;
595: int svorig;
596: };
597: struct state state[MAXSTATE];
598: struct state *statep = state;
599:
600: t_push() /* begin a new block */
601: {
602: hflush();
603: statep->ssize = size;
604: statep->sfont = font;
605: statep->shorig = horig;
606: statep->svorig = vorig;
607: statep->shpos = hpos;
608: statep->svpos = vpos;
609: horig = hpos;
610: vorig = vpos;
611: hpos = vpos = 0;
612: if (statep++ >= state+MAXSTATE)
613: error(FATAL, "{ nested too deep");
614: hpos = vpos = 0;
615: }
616:
617: t_pop() /* pop to previous state */
618: {
619: if (--statep < state)
620: error(FATAL, "extra }");
621: size = statep->ssize;
622: font = statep->sfont;
623: hpos = statep->shpos;
624: vpos = statep->svpos;
625: horig = statep->shorig;
626: vorig = statep->svorig;
627: }
628:
629: t_page(n) /* do whatever new page functions */
630: {
631: int i;
632:
633: if (output) {
634: if (tf != stdout)
635: paper += vpos;
636: if (++scount >= spage) {
637: t_reset('p');
638: scount = 0;
639: }
640: }
641: vpos = 0;
642: oldv = 0;
643: output = 1;
644: if (nolist == 0)
645: return; /* no -o specified */
646: output = 0;
647: for (i = 0; i < nolist; i += 2)
648: if (n >= olist[i] && n <= olist[i+1]) {
649: output = 1;
650: break;
651: }
652: }
653:
654: t_newline() /* do whatever for the end of a line */
655: {
656: hpos = 0; /* because we're now back at the left margin */
657: }
658:
659: t_size(n) /* convert integer to internal size number*/
660: int n;
661: {
662: int i;
663:
664: if (n <= pstab[0])
665: return(1);
666: else if (n >= pstab[nsizes-1])
667: return(nsizes);
668: for (i = 0; n > pstab[i]; i++)
669: ;
670: return(i+1);
671: }
672:
673: t_charht(n) /* set character height to n */
674: int n;
675: {
676: setsize(n); /* first set the size */
677: putcmd(SET_SIZE, pstab[size-1]); /* then restore horizontal */
678: }
679:
680: t_slant(n) /* set slant to n */
681: int n;
682: {
683: putcmd(SLANT_MODE, n);
684: }
685:
686: t_font(s) /* convert string to internal font number */
687: char *s;
688: {
689: int n;
690:
691: n = atoi(s);
692: if (n < 0 || n > nfonts)
693: n = 1;
694: return(n);
695: }
696:
697: t_text(s) /* print string s as text */
698: char *s;
699: {
700: int c, w;
701: char str[100];
702:
703: if (!output)
704: return;
705: while (c = *s++) {
706: if (c == '\\') {
707: switch (c = *s++) {
708: case '\\':
709: case 'e':
710: put1('\\');
711: break;
712: case '(':
713: str[0] = *s++;
714: str[1] = *s++;
715: str[2] = '\0';
716: put1s(str);
717: break;
718: }
719: } else {
720: put1(c);
721: }
722: hmot(lastw);
723: if (dbg) printf("width = %d\n", lastw);
724: }
725: }
726:
727: t_reset(c)
728: {
729: int n;
730:
731: if (output)
732: paper += vpos;
733: output = 1; /* by God */
734: fflush(tf);
735: }
736:
737: char *tracct = "/usr/adm/tracct";
738:
739: account() /* record paper use */
740: {
741: FILE *f = NULL;
742: char *name, *getlogin();
743:
744: if (tf == stdout)
745: return;
746: f = fopen(tracct, "a");
747: if(f != NULL) {
748: name = getlogin();
749: if (name == NULL)
750: name = "???";
751: fprintf(f, "%4d %s\n", (int)(paper/res + 20+6)/12, name);
752: }
753: }
754:
755: t_trailer()
756: {
757: return;
758: vpos = oldv = 0;
759: vgoto(TRAILER);
760: vpos = oldv = 0;
761: }
762:
763: hflush() /* actual horizontal output occurs here */
764: {
765: register int dh;
766: int htrue;
767:
768: if (!output)
769: return;
770: htrue = hpos + horig;
771: dh = htrue - oldh;
772: if (dh > 0) {
773: if (dbg)
774: printf(" h> %d\n", dh & BMASK);
775: else
776: putcmd(HOR_RIGHT, dh);
777: } else if (dh < 0) {
778: if (dbg)
779: printf(" h<- %d\n", dh);
780: else
781: putcmd(HOR_LEFT, dh);
782: }
783: oldh = htrue + horig;
784: }
785:
786: vgoto(n)
787: {
788: int dv, vtrue;
789:
790: if (!output)
791: return;
792: if (dbg) printf(" vgoto %d to %d\n", vpos, n);
793: vtrue = vpos + vorig;
794: dv = n - vtrue;
795: if (dv > 0) {
796: if (dbg)
797: printf(" v down %d\n", dv);
798: else
799: putcmd(VERT_FWD, dv);
800: } else if (dv < 0) {
801: if (dbg)
802: printf("v up %d\n", dv);
803: else
804: putcmd(VERT_REV, dv);
805: }
806: vpos = n;
807: }
808:
809:
810: put1s(s) /* s is a funny char name */
811: char *s;
812: {
813: int i;
814:
815: if (!output)
816: return;
817: if (dbg) printf("%s ", s);
818: for (i = 0; i < nchtab; i++)
819: if (strcmp(&chname[chtab[i]], s) == 0)
820: break;
821: if (i < nchtab)
822: put1(i + 128);
823: }
824:
825: put1(c) /* output char c */
826: int c;
827: {
828: char *pw;
829: register char *p;
830: register int i, k;
831: int j, ofont, code, w;
832:
833: if (!output)
834: return;
835: c -= 32;
836: if (c <= 0) {
837: if (dbg) printf("non-exist 0%o\n", c+32);
838: lastw = widthtab[font][0] * pstab[size-1] / dev.unitwidth;
839: return;
840: }
841: k = ofont = font;
842: i = fitab[font][c] & BMASK;
843: if (i != 0) { /* it's on this font */
844: p = codetab[font];
845: pw = widthtab[font];
846: } else if (smnt > 0) { /* on special (we hope) */
847: for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1))
848: if ((i = fitab[k][c] & BMASK) != 0) {
849: p = codetab[k];
850: pw = widthtab[k];
851: setfont(k);
852: break;
853: }
854: }
855: if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) {
856: if (dbg) printf("not found 0%o\n", c+32);
857: return;
858: }
859: hflush();
860: if (dbg) {
861: if (isprint(c+32))
862: printf("%c %d\n", c+32, code);
863: else
864: printf("%03o %d\n", c+32, code);
865: } else
866: putc(code, tf);
867: /* SHOULD INTEGRATE THIS WITH HORIZONTAL MOTION */
868:
869: if (font != ofont)
870: setfont(ofont);
871: lastw = pw[i] & 077;
872: lastw = (lastw * pstab[size-1] + dev.unitwidth/2) / dev.unitwidth;
873: }
874:
875: setsize(n) /* set point size to n (internal) */
876: int n;
877: {
878:
879: if (!output)
880: return;
881: if (n == size)
882: return; /* already there */
883: /* for now, only cope with integer sizes */
884: putcmd(POINT_SIZE, pstab[n-1]);
885: size = n;
886: }
887:
888: /* font position info: */
889:
890: struct {
891: char *name;
892: int number;
893: } fontname[NFONT+1];
894:
895: t_fp(n, s, si) /* font position n now contains font s, intname si */
896: int n;
897: char *s, *si;
898: {
899: fontname[n].name = s;
900: fontname[n].number = atoi(si);
901: }
902:
903: setfont(n) /* set font to n */
904: int n;
905: {
906: if (!output)
907: return;
908: if (n < 0 || n > NFONT)
909: error(FATAL, "illegal font %d\n", n);
910: putcmd(FONT_NUMBER, fontname[n].number);
911: font = n;
912: }
913:
914: putcmd(n1, n2)
915: {
916: putc(n1, tf);
917: putc(((n2>>8) & 0177) | 0200, tf); /* always turn on */
918: putc(n2 & 0377, tf);
919: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.