1 #ifndef lint
2 static char *sccsid = "@(#)dhar.c 1.4 CWI 1.4 03/23/88";
3 #endif
4 /*
5 * Drive the Harris 7500 tyepsetter
6 * 75XX
7 * Other machines of that harris serie will probably run as well with this
8 *
9 * Author: jaap akkerhuis, Oc 1982, Mathematisch Cetrum.
10 *
11 */
12 /*
13 output language from troff:
14 all numbers are character strings
15
16 sn size in points
17 fn font as number from 1-n
18 cx ascii character x
19 Cxyz funny char xyz. terminated by white space
20 Hn go to absolute horizontal position n
21 Vn go to absolute vertical position n (down is positive)
22 hn go n units horizontally (relative)
23 vn ditto vertically
24 nnc move right nn, then print c (exactly 2 digits!)
25 (this wart is an optimization that shrinks output file size
26 about 35% and run-time about 15% while preserving ascii-ness)
27 Dt ...\n draw operation 't':
28 Dl x y line from here by x,y
29 Dc d circle of diameter d with left side here
30 De x y ellipse of axes x,y with left side here
31 Da x y r arc counter-clockwise by x,y of radius r
32 D~ x y x y ... wiggly line by x,y then x,y ...
33 w paddable words space -- no action needed
34 nb a end of line (information only -- no action needed)
35 b = space before line, a = after
36 p new page begins -- set v to 0
37 tstring print string as plain text
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 * MC:jna
55 * The output language signs { and } are not described
56 *
57 */
58
59 #include <stdio.h>
60 #include <ctype.h>
61 #include <signal.h>
62
63 #include "../dev.h"
64 #define NFONT 10
65
66 int output = 0; /* do we do output at all? */
67 int nolist = 0; /* output page list if > 0 */
68 int olist[20]; /* pairs of page numbers */
69 int spage = 9999; /* stop every spage pages */
70 int scount = 0;
71
72 struct dev dev;
73 struct Font *fontbase[NFONT+1];
74 short *pstab;
75 int nsizes;
76 int nfonts;
77 int smnt; /* index of first special font */
78 int nchtab;
79 char *chname;
80 short *chtab;
81 char *fitab[NFONT+1];
82 char *widthtab[NFONT+1]; /* widtab would be a better name */
83 char *codetab[NFONT+1]; /* device codes */
84 #if pdp
85 #define tosh(a,b) (a)[2*(b)] & BMASK | ((a)[2*(b) + 1] & BMASK) << BYTE
86 typedef char f_code;
87 f_code *fonttab[2*(NFONT+1)]; /*MC:jna optional fontcodes */
88 #endif pdp
89 #if tahoe || sun
90 #define tosh(a,b) (a)[2*(b) + 1] & BMASK | ((a)[2*(b)] & BMASK) << BYTE
91 typedef char f_code;
92 f_code *fonttab[2*(NFONT+1)]; /*MC:jna optional fontcodes */
93 #endif tahoe || sun
94 #if vax
95 #define tosh(a,b) (a)[b]
96 typedef short f_code;
97 f_code *fonttab[NFONT+1]; /*MC:jna optional fontcodes */
98 #endif vax
99
100 #define FATAL 1
101 #define BMASK 0377
102 #define BYTE 8
103 int dbg = 0;
104 int eflag;
105 int cflag;
106 int res; /* input assumed computed according to this resolution */
107 int tf = 0; /* output file will be har.in or standout */
108 char *fontdir = "/usr/local/lib/ditroff/font";
109 extern char devname[];
110
111 #define abs(n) ((n) >= 0 ? (n) : -(n))
112
113 int font = 1; /* current font */
114 int hpos; /* horizontal position where we are supposed to be next (left = 0) */
115 int lastw; /* width of last printed char, (for t_text()) */
116 int vpos; /* current vertical position (down positive) */
117 int horig; /* h origin of current block; hpos rel to this */
118 int vorig;
119 int htrue = 0;
120 int vtrue = 0;
121 int DX = 4; /* step size in x for drawing */
122 int DY = 4; /* step size in y for drawing */
123 int drawdot = '.'; /* draw with this character */
124 int drawsize = 1; /* shrink by this factor when drawing */
125 /* drawsize will be set in t_init as well! */
126
main(argc,argv)127 main(argc, argv)
128 char *argv[];
129 {
130 FILE *fp;
131 int i;
132 int done();
133 while (argc > 1 && argv[1][0] == '-') {
134 switch (argv[1][1]) {
135 case 'f':
136 case 'F':
137 fontdir = argv[2];
138 argv++;
139 argc--;
140 break;
141 case 't':
142 tf = 1; /* stdout */
143 break;
144 case 'o':
145 outlist(&argv[1][2]);
146 break;
147 case 'd':
148 dbg = atoi(&argv[1][2]);
149 if (dbg == 0) dbg = 1;
150 break;
151 case 's':
152 spage = atoi(&argv[1][2]);
153 if (spage <= 0)
154 spage = 9999;
155 break;
156 case 'e':
157 eflag++;
158 break;
159 case 'c':
160 cflag++;
161 break;
162 }
163 argc--;
164 argv++;
165 }
166 /*
167 * Stop every 4 pages to prevent the
168 * Harris to Cut the paper every 6 feet,
169 * wat will likely to be in the middle of
170 * a page. Every for page is proved to be
171 * reasonable.
172 */
173 if (spage == 0 || 9999)
174 spage = 4;
175
176 if (signal(SIGINT, done) == SIG_IGN) {
177 signal(SIGINT, SIG_IGN);
178 signal(SIGQUIT, SIG_IGN);
179 signal(SIGHUP, SIG_IGN);
180 } else {
181 signal(SIGQUIT, done);
182 signal(SIGHUP, done);
183 }
184 signal(SIGTERM, done);
185 if (argc <= 1)
186 conv(stdin);
187 else
188 while (--argc > 0) {
189 if (strcmp(*++argv, "-") == 0)
190 fp = stdin;
191 else if ((fp = fopen(*argv, "r")) == NULL)
192 error(FATAL, "can't open %s", *argv);
193 conv(fp);
194 fclose(fp);
195 }
196 account();
197 done();
198 }
199
outlist(s)200 outlist(s) /* process list of page numbers to be printed */
201 char *s;
202 {
203 int n1, n2, i;
204
205 nolist = 0;
206 while (*s) {
207 n1 = 0;
208 if (isdigit(*s))
209 do
210 n1 = 10 * n1 + *s++ - '0';
211 while (isdigit(*s));
212 else
213 n1 = -9999;
214 n2 = n1;
215 if (*s == '-') {
216 s++;
217 n2 = 0;
218 if (isdigit(*s))
219 do
220 n2 = 10 * n2 + *s++ - '0';
221 while (isdigit(*s));
222 else
223 n2 = 9999;
224 }
225 olist[nolist++] = n1;
226 olist[nolist++] = n2;
227 if (*s != '\0')
228 s++;
229 }
230 olist[nolist] = 0;
231 if (dbg)
232 for (i=0; i<nolist; i += 2)
233 printf("%3d %3d\n", olist[i], olist[i+1]);
234 }
235
conv(fp)236 conv(fp)
237 register FILE *fp;
238 {
239 register int c, k;
240 int m, n, i, n1, m1;
241 char str[100], buf[300];
242
243 while ((c = getc(fp)) != EOF) {
244 switch (c) {
245 case '\n': /* when input is text */
246 case ' ':
247 case 0: /* occasional noise creeps in */
248 break;
249 case '{': /* push down current environment */
250 t_push();
251 break;
252 case '}':
253 t_pop();
254 break;
255 case '0': case '1': case '2': case '3': case '4':
256 case '5': case '6': case '7': case '8': case '9':
257 /* two motion digits plus a character */
258 hmot((c-'0')*10 + getc(fp)-'0');
259 put1(getc(fp));
260 break;
261 case 'c': /* single ascii character */
262 put1(getc(fp));
263 break;
264 case 'C':
265 fscanf(fp, "%s", str);
266 put1s(str);
267 break;
268 case 't': /* straight text */
269 fgets(buf, sizeof(buf), fp);
270 t_text(buf);
271 break;
272 case 'D': /* draw function */
273 fgets(buf, sizeof(buf), fp);
274 switch (buf[0]) {
275 case 'l': /* draw a line */
276 sscanf(buf+1, "%d %d", &n, &m);
277 drawline(n, m, ".");
278 break;
279 case 'c': /* circle */
280 sscanf(buf+1, "%d", &n);
281 drawcirc(n);
282 break;
283 case 'e': /* ellipse */
284 sscanf(buf+1, "%d %d", &m, &n);
285 drawellip(m, n);
286 break;
287 case 'a': /* arc */
288 sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
289 drawarc(n, m, n1, m1);
290 break;
291 case '~': /* wiggly line */
292 drawwig(buf+1);
293 break;
294 default:
295 error(FATAL, "unknown drawing function %s\n", buf);
296 break;
297 }
298 break;
299 case 's':
300 fscanf(fp, "%d", &n); /* ignore fractional sizes */
301 setsize(t_size(n));
302 break;
303 case 'f':
304 fscanf(fp, "%s", str);
305 setfont(t_font(str));
306 break;
307 case 'H': /* absolute horizontal motion */
308 /* fscanf(fp, "%d", &n); */
309 while ((c = getc(fp)) == ' ')
310 ;
311 k = 0;
312 do {
313 k = 10 * k + c - '0';
314 } while (isdigit(c = getc(fp)));
315 ungetc(c, fp);
316 hgoto(k);
317 break;
318 case 'h': /* relative horizontal motion */
319 /* fscanf(fp, "%d", &n); */
320 while ((c = getc(fp)) == ' ')
321 ;
322 k = 0;
323 do {
324 k = 10 * k + c - '0';
325 } while (isdigit(c = getc(fp)));
326 ungetc(c, fp);
327 hmot(k);
328 break;
329 case 'w': /* word space */
330 break;
331 case 'V':
332 fscanf(fp, "%d", &n);
333 vgoto(n);
334 break;
335 case 'v':
336 fscanf(fp, "%d", &n);
337 vmot(n);
338 break;
339 case 'p': /* new page */
340 fscanf(fp, "%d", &n);
341 t_page(n);
342 break;
343 case 'n': /* end of line */
344 while (getc(fp) != '\n')
345 ;
346 t_newline();
347 break;
348 case '#': /* comment */
349 while (getc(fp) != '\n')
350 ;
351 break;
352 case 'x': /* device control */
353 devcntrl(fp);
354 break;
355 default:
356 error(!FATAL, "unknown input character %o %c\n", c, c);
357 done();
358 }
359 }
360 }
361
devcntrl(fp)362 devcntrl(fp) /* interpret device control functions */
363 FILE *fp;
364 {
365 char str[20], str1[50], buf[50];
366 int c, n;
367
368 fscanf(fp, "%s", str);
369 switch (str[0]) { /* crude for now */
370 case 'i': /* initialize */
371 fileinit();
372 t_init(0);
373 break;
374 case 'T': /* device name */
375 fscanf(fp, "%s", devname);
376 break;
377 case 't': /* trailer */
378 t_trailer();
379 break;
380 case 'p': /* pause -- can restart */
381 t_reset('p');
382 break;
383 case 's': /* stop */
384 t_reset('s');
385 break;
386 case 'r': /* resolution assumed when prepared */
387 fscanf(fp, "%d", &res);
388 break;
389 case 'f': /* font used */
390 fscanf(fp, "%d %s", &n, str);
391 fgets(buf, sizeof buf, fp); /* in case there's a filename */
392 ungetc('\n', fp); /* fgets goes too far */
393 str1[0] = 0; /* in case there's nothing to come in */
394 sscanf(buf, "%s", str1);
395 loadfont(n, str, str1);
396 break;
397 /* these don't belong here... */
398 case 'H': /* char height */
399 fscanf(fp, "%d", &n);
400 t_charht(t_size(n));
401 break;
402 case 'S': /* slant */
403 fscanf(fp, "%d", &n);
404 t_slant(n);
405 break;
406 }
407 while ((c = getc(fp)) != '\n') /* skip rest of input line */
408 if (c == EOF)
409 break;
410 }
411
fileinit()412 fileinit() /* read in font and code files, etc. */
413 {
414 int i, fin, nw;
415 char *malloc(), *filebase, *p;
416 char temp[60];
417
418 /* open table for device,
419 /* read in resolution, size info, font info, etc.
420 /* and set params
421 */
422 sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname);
423 if ((fin = open(temp, 0)) < 0)
424 error(FATAL, "can't open tables for %s\n", temp);
425 read(fin, &dev, sizeof(struct dev));
426 nfonts = dev.nfonts;
427 nsizes = dev.nsizes;
428 nchtab = dev.nchtab;
429 filebase = malloc(dev.filesize); /* enough room for whole file */
430 read(fin, filebase, dev.filesize); /* all at once */
431 pstab = (short *) filebase;
432 chtab = pstab + nsizes + 1;
433 chname = (char *) (chtab + dev.nchtab);
434 p = chname + dev.lchname;
435 for (i = 1; i <= nfonts; i++) {
436 fontbase[i] = (struct Font *) p;
437 nw = *p & BMASK; /* 1st thing is width count */
438 if (smnt == 0 && fontbase[i]->specfont == 1)
439 smnt = i; /* first special font */
440 p += sizeof(struct Font); /* that's what's on the beginning */
441 widthtab[i] = p;
442 codetab[i] = p + 2 * nw;
443 fitab[i] = p + 3 * nw;
444 p += 3 * nw + dev.nchtab + 128 - 32;
445 if(fontbase[i]->fonttab == 1) { /*MC:jna There is a fonttable */
446 fonttab[i] = (f_code *)p; /*MC:jna get it */
447 p += nw * sizeof( short ); /* and skip it */
448 }
449 t_fp(i, fontbase[i]->namefont, fontbase[i]->intname);
450 if(dbg > 2) fontprint(i);
451 }
452 /*MC:jna
453 *
454 * Make space for the font cache for NCH characters
455 * also reserve space for fonttable, if any is to come
456 *
457 */
458 fontbase[0] = (struct Font *) malloc(3*255 + dev.nchtab + (128-32) + sizeof (struct Font) + 255 * sizeof( short));
459 widthtab[0] = (char *) fontbase[0] + sizeof (struct Font);
460 fontbase[0]->nwfont = 255;
461 fontbase[0]->fonttab = 2; /* there is room for a fonttable! */
462 close(fin);
463 }
464
fontprint(i)465 fontprint(i) /* debugging print of font i (0,...) */
466 {
467 int j, k, n;
468 char *p;
469
470 printf("font %d:\n", i);
471 p = (char *) fontbase[i];
472 n = fontbase[i]->nwfont & BMASK;
473 printf("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",
474 p, n, fontbase[i]->specfont, fontbase[i]->namefont, widthtab[i], fitab[i]);
475 if( fontbase[i]->fonttab == 1)
476 printf("base fonttab=0%o\n", fonttab[i]);
477 printf("widths:\n");
478 for (j=0; j <= n; j++) {
479 printf(" %2d", widthtab[i][j] & BMASK);
480 if (j % 20 == 19) printf("\n");
481 }
482 printf("\ncodetab:\n");
483 for (j=0; j <= n; j++) {
484 printf(" %2d", codetab[i][j] & BMASK);
485 if (j % 20 == 19) printf("\n");
486 }
487 printf("\nfitab:\n");
488 for (j=0; j <= dev.nchtab + 128-32; j++) {
489 printf(" %2d", fitab[i][j] & BMASK);
490 if (j % 20 == 19) printf("\n");
491 }
492 if(fontbase[i]->fonttab == 1) {
493 printf("\nfonttab:\n");
494 for (j=0; j <= n; j++) {
495 printf(" %d", fonttab[i][j] );
496 if (j % 20 == 19) printf("\n");
497 }
498 }
499 printf("\n");
500 }
501
loadfont(n,s,s1)502 loadfont(n, s, s1) /* load font info for font s on position n (0...) */
503 int n;
504 char *s, *s1;
505 {
506 char temp[60];
507 int fin, nw, norig, forig;
508 char *p;
509
510 if (n < 0 || n > NFONT)
511 error(FATAL, "illegal fp command %d %s", n, s);
512 if (strcmp(s, fontbase[n]->namefont) == 0)
513 return;
514 if (s1 == NULL || s1[0] == '\0')
515 sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, s);
516 else
517 sprintf(temp, "%s/%s.out", s1, s);
518 if ((fin = open(temp, 0)) < 0)
519 error(FATAL, "can't open font table %s", temp);
520 norig = fontbase[n]->nwfont & BMASK;
521 forig = fontbase[n]->fonttab;
522 if(dbg > 3)
523 printf("nworig, %d, fonttaborig %d\n", norig, forig);
524 /*
525 *MC:jna norig is the original amount of chars in
526 * the (premounted) font)
527 *
528 * first geuss there is no fonttab
529 */
530 read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct Font));
531 if ((fontbase[n]->nwfont & BMASK) > norig || (forig == 0 && fontbase[n]->fonttab == 1))
532 error(FATAL, "Font %s too big for position %d\n", s, n);
533 /*
534 *MC:jna This means it is wise to make the default mounted
535 * fonts larger then any other mounttable fonts.
536 * And because of the kludge with the fonttable,
537 * Make sure that they all contain fonttables!
538 * It will make your life easier.
539 */
540 nw = fontbase[n]->nwfont & BMASK;
541 if(dbg > 3)
542 printf("nw %d\n", nw);
543 if(fontbase[n]->fonttab == 1) {
544 lseek(fin, 0L, 0);
545 read(fin, fontbase[n], 3*norig + nchtab+128-32 + nw*sizeof(short) + sizeof(struct Font));
546 /*
547 * There turned out to be a fonttab, so we have to read it in
548 *MC:jna a bit stupid, but the laziest way (for me)
549 */
550 }
551 close(fin);
552 widthtab[n] = (char *) fontbase[n] + sizeof(struct Font);
553 codetab[n] = (char *) widthtab[n] + 2 * nw;
554 fitab[n] = (char *) widthtab[n] + 3 * nw;
555 if(fontbase[n]->fonttab == 1)
556 fonttab[n] = (f_code *) (widthtab[n] + 3*nw + nchtab+128-32);
557 t_fp(n, fontbase[n]->namefont, fontbase[n]->intname);
558 fontbase[n]->nwfont = norig; /* so can later use full original size */
559 if(fontbase[n]->fonttab == 0 && forig != 0)
560 fontbase[n]->fonttab = 2;
561 /* so we signal that there is place
562 * for a fonttab! */
563
564 if (dbg > 2) fontprint(n);
565 }
566
done()567 done()
568 {
569 t_reset('s');
570 exit(0);
571 }
572
573 extern int ex();
574
575 /*VARARGS*/
error(f,s,a1,a2,a3,a4,a5,a6,a7)576 error(f, s, a1, a2, a3, a4, a5, a6, a7)
577 int f;
578 {
579 fprintf(stderr, "dhar: ");
580 fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
581 fprintf(stderr, "\n");
582 fflush(stderr);
583 if (f) {
584 ex();
585 exit(1);
586 }
587 }
588
589 /******************************************************************************
590 ******************************************************************************
591 *
592 * Here begins the stuff that really depends on the harris
593 *
594 * For the time being, no use is made of the ruling functions of the Harris
595 *
596 ******************************************************************************
597 ******************************************************************************
598 */
599
600 /*
601 * The basic idea is to delay the output as long as possible
602 * until you really have to.
603 * Until that time we just keep a machine status.
604 *
605 */
606
607 #include "hcodes.h"
608
609 char devname[20] = "har";
610 int fcut;
611 int nocutting;
612 unsigned short papuse;
613 char harcode;
614
t_init(reinit)615 t_init(reinit) /* initialize device */
616 int reinit;
617 {
618 register int i;
619 extern int size;
620
621 hpos = vpos = 0;
622
623 if( strcmp( devname, "har") != NULL )
624 error(FATAL, "This input is not for the harris");
625
626 if (!tf)
627 if ( ( tf = creat("@har.in", 0664)) < 0)
628 error(FATAL, "Cannot create outputfile");
629
630 /* if there is a drawing character, use it */
631 for ( i = 0; i < nchtab; i++)
632 if (strcmp(&chname[chtab[i]], "l.") == 0)
633 break;
634 if ( i < nchtab) {
635 drawdot = i + 128;
636 drawsize = 1;
637 } else {
638 drawdot = '.';
639 drawsize = 3; /* 1/3 size */
640 }
641
642 output = 1;
643
644 oput(VMV); oput(0); oput(0);
645 /* See Harris Manual appendix D */
646 oput(HPO);oput(0);oput(0);
647
648 /* some initial size */
649 size = 10;
650 putsize();
651 putfont(999);
652 oput(STA);oput(0);oput(0360);
653
654 if( eflag ) {
655 operator("Translating");
656 oput(EST); /* enable slave Translator */
657 fprintf(stderr,"Slave code translator enabled\n");
658 } else
659 operator("dhar started");
660
661 oput(OB0); /* reset oblique */
662 oput(NAD); /* No automatic displacement */
663 output = 0;
664 }
665
666 /*
667 * The reason of struct state is never explained by bwk
668 * but it looks like an stack of environments being pushed and popped
669 *
670 */
671
672 #define MAXSTATE 5
673
674 struct state {
675 int ssize;
676 int sfont;
677 int shpos;
678 int svpos;
679 int shorig;
680 int svorig;
681 };
682 struct state state[MAXSTATE];
683 struct state *statep = state;
684
t_push()685 t_push() /* begin a new block */
686 {
687 extern size;
688
689 error(!FATAL, "Different environment entered!");
690 hflush();
691 statep->ssize = size;
692 statep->sfont = font;
693 statep->shorig = horig;
694 statep->svorig = vorig;
695 statep->shpos = hpos;
696 statep->svpos = vpos;
697 horig = hpos;
698 vorig = vpos;
699 hpos = vpos = 0;
700 if (statep++ >= state+MAXSTATE)
701 error(FATAL, "{ nested too deep");
702 hpos = vpos = 0;
703 }
704
t_pop()705 t_pop() /* pop to previous state */
706 {
707 extern size;
708 if (--statep < state)
709 error(FATAL, "extra }");
710 size = statep->ssize;
711 font = statep->sfont;
712 hpos = statep->shpos;
713 vpos = statep->svpos;
714 horig = statep->shorig;
715 vorig = statep->svorig;
716 }
717
718 int pageno = 0;
719
t_page(n)720 t_page(n) /* do whatever new page functions */
721 {
722 int i;
723
724 if (output) {
725 papuse++;
726 /*
727 * accounting in pages, for the time being.
728 * New harprot should do the real accounting
729 */
730 if (++scount >= spage) {
731 t_reset('p');
732 scount = 0;
733 }
734 }
735 vpos = 0;
736 output = 1;
737 ++pageno;
738 if (nolist == 0)
739 return; /* no -o specified */
740 output = 0;
741 for (i = 0; i < nolist; i += 2)
742 if (n >= olist[i] && n <= olist[i+1]) {
743 output = 1;
744 break;
745 }
746 }
747
t_newline()748 t_newline() /* do whatever for the end of a line */
749 {
750 hpos = 0; /* because we're now back at the left margin */
751 }
752
753 /*
754 * A PSZ command on the Harris will change the horizontal & vertical size
755 * A HPZ command will change just the Horizontal size.
756 *
757 * so size will contain horizontal size, and versize the vertical
758 */
759 int size; /* current sizenumber (a legal index in pstab) */
760 int horsize; /* current horizontal size */
761 int versize; /* current vertcal size */
762 int vsizeflag; /* if set, versize differs from size */
763
t_size(n)764 t_size(n) /* convert integer to internal size number*/
765 int n;
766 {
767 int i;
768
769 if (n <= pstab[0])
770 return(1);
771 else if (n >= pstab[nsizes-1])
772 return(nsizes);
773 for (i = 0; n > pstab[i]; i++)
774 ;
775 return(i+1);
776 }
777
t_charht(n)778 t_charht(n) /* set character height to n */
779 int n;
780 {
781 versize = pstab[n-1];
782 if( versize != horsize )
783 vsizeflag = 1;
784 putsize();
785 }
786
787 int sltab[] = { 0, 9, 12, 15, -1}; /* possible slanting factors */
788 int slctab[] = { OB0, OB1, OB2, OB3 }; /* slanting codes */
789 int slant; /* current general slanting factor (of slant cmd) */
790 int fslant; /* slanting factor of current font */
791
792 /*
793 * current font has to be slanted, the slant will be set to fslant.
794 * if the has been a slant command, the slant will be set to "slant",
795 * overiding the fslant.
796 * if slant is reset to 0, and there fslant != 0, slant will be set to "fslant"
797 *
798 * fslant will be manupulated by setfont (slanting can be an attribute
799 * to a (Harris-)font.
800 *
801 * There are to many slants in this comment
802 */
803
t_slant(n)804 t_slant(n) /* do slant cmd */
805 int n;
806 { slant = n;
807 setslant(n);
808 }
809
setslant(n)810 setslant(n) /* set slant to n */
811 int n;
812 { int j;
813 static int aslant; /* the actual slanting factor */
814
815 if( n == aslant)
816 return;
817 if( n == 0 && fslant) { /* back to slant of font */
818 setslant( fslant );
819 return;
820 }
821 for (j = 0; n > ( aslant = sltab[j]); j++)
822 if ( aslant == -1) {
823 aslant = sltab[--j];
824 break;
825 }
826 hflush();
827 oput( slctab[j] );
828 if (dbg)
829 printf("slant to %d\n", aslant);
830 }
831
slantfont(n)832 slantfont(n) /* set fontslant */
833 int n;
834 {
835 fslant = n;
836 if(slant)
837 return; /* slant of slanting command
838 * overrides fslant */
839 setslant( fslant); /* set slanting */
840 }
841
t_font(s)842 t_font(s) /* convert string to internal font number */
843 char *s;
844 {
845 int n;
846
847 n = atoi(s);
848 if (n < 0 || n > nfonts)
849 n = 1;
850 return(n);
851 }
852
t_text(s)853 t_text(s) /* print string s as text, the real \! implemantation */
854 char *s;
855 {
856 int c, w;
857 char str[100];
858
859 error(!FATAL, "t_text not well implented (yet)!");
860 if (!output)
861 return;
862 while (c = *s++) {
863 if (c == '\\') {
864 switch (c = *s++) {
865 case '\\':
866 case 'e':
867 put1('\\');
868 break;
869 case '(':
870 str[0] = *s++;
871 str[1] = *s++;
872 str[2] = '\0';
873 put1s(str);
874 break;
875 }
876 } else {
877 put1(c);
878 }
879 hmot(lastw);
880 if (dbg) printf("width = %d\n", lastw);
881 }
882 }
883
t_reset(c)884 t_reset(c)
885 {
886 int n;
887
888 if (output)
889 /*
890 papuse++
891 */
892 ;
893 switch(c) {
894 case 'p':
895 cut(); /*
896 * interpret pauses as comment for cutting
897 * the paper
898 */
899 if(dbg)
900 printf("reset p\n");
901 break;
902 case 's':
903 cut();
904 nocutting++;
905 if(dbg)
906 printf("reset s\n");
907 ex();
908 break;
909 default:
910 error(!FATAL, "Unknown reset function");
911 break;
912 }
913 }
914
cut()915 cut()
916 {
917 if (cflag || nocutting)
918 return;
919 hflush();
920 oput(CUT);
921 hpos = 0;
922 fcut = 1;
923 if (dbg)
924 printf("Cut\n");
925 }
926
account()927 account() /* record paper use */
928 {
929 /* Don somewhere els */
930 }
931
t_trailer()932 t_trailer()
933 {
934 }
935
hflush()936 hflush() /* do the actual motion */
937 {
938 if (!output)
939 return;
940 hor_move( hpos - htrue );
941 }
942
hor_move(amount)943 hor_move( amount )
944 int amount;
945 { int high, low;
946
947 #if vax || tahoe
948 if ( abs(amount) > 0177777)
949 error(FATAL, "Impossible escape");
950 #endif
951 if ( amount == 0 && harcode == 0)
952 return; /* really nothing to do */
953 if(dbg > 1)
954 printf("h_move %d\n", amount);
955 low = amount & BMASK;
956 high = ( amount >> BYTE) & BMASK;
957 /*
958 * if there is a code wating for output,
959 * send that one to be output, plus the movement,
960 * else send the MAB
961 * and the movement
962 */
963 oput( harcode ? harcode : MAB);
964 harcode = 0;
965 oput(high);
966 oput(low);
967 htrue = hpos;
968 }
969
970
hmot(n)971 hmot(n)
972 {
973 hpos += n;
974 }
975
hgoto(n)976 hgoto(n)
977 {
978 hpos = n;
979 }
980
vgoto(n)981 vgoto(n)
982 {
983 vmot(n - vpos);
984 }
985
vmot(n)986 vmot(n) /* generate n units of vertical motion */
987 int n;
988 {
989 if (!output)
990 return;
991 if (n != 0) {
992 ver_move( n );
993 vpos += n;
994 }
995 }
996
ver_move(amount)997 ver_move( amount )
998 int amount;
999 { int high, low;
1000
1001 #if vax || tahoe
1002 if ( abs(amount) > 0177777)
1003 error(FATAL, "Impossible leading");
1004 #endif
1005 if(dbg > 1)
1006 printf("v_move %d\n", amount);
1007 low = amount & BMASK;
1008 high = ( amount >> BYTE) & BMASK;
1009 hflush();
1010 oput(VMV);
1011 oput(high);
1012 oput(low);
1013 }
1014
put1s(s)1015 put1s(s) /* s is a funny char name */
1016 char *s;
1017 {
1018 int i;
1019
1020 if (!output)
1021 return;
1022 /*
1023 if(strcmp("ul", s) == 0) {
1024 set_ul();
1025 return;
1026 }
1027 if(strcmp("ru", s) == 0) {
1028 set_ru();
1029 return;
1030 }
1031 */
1032 for (i = 0; i < nchtab; i++)
1033 if (strcmp(&chname[chtab[i]], s) == 0)
1034 break;
1035 /*
1036 printf("i+128: %d,s: %s, chname: %s\n", i+128, s, &chname[chtab[i]]);
1037 */
1038 if (i < nchtab)
1039 put1(i + 128);
1040 else
1041 if(dbg)
1042 printf("Special char %s doesn't exist\n", s);
1043 }
1044
1045 /*
1046 * The Harris doesn'nt have a proper underrule or rule
1047 *
1048 * Try to generate one with the RULE command.
1049 *
1050 */
1051
1052 #define UL_DOWN 7 /* 7 half decipoints at pointsize 10 */
1053
set_ul()1054 set_ul()
1055 { int move;
1056 int tmp;
1057
1058 hflush();
1059 move = UL_DOWN * versize;
1060 ver_move( move);
1061 tmp = get_width("ul") / 2;
1062 /*
1063 * we assume that dev.unitwidth is 10, so getwidth
1064 * will return the value in half decipoints!
1065 */
1066 set_line(tmp);
1067 ver_move( -move);
1068 }
1069
1070 #define RU_DOWN 1 /* 2 half decipoints at pointsize 10 */
1071
set_ru()1072 set_ru()
1073 {
1074 int tmp, move;
1075
1076 hflush();
1077 move = RU_DOWN * versize;
1078 ver_move( move);
1079 tmp = get_width("ul") / 2;
1080 set_line(tmp);
1081 ver_move( -move);
1082 }
1083
1084 #define HEIGHT 6 /* thickness (decipoints) at pointsize 10 */
1085 #define MIN_VAL 2 /* Minimum value for rule height & length */
1086 #define MAX_H 720 /* Maximum for height */
1087 #define MAX_L 8160 /* Maximum length of the SMC 68 Pica machine */
1088
1089 /*
1090 * set line of length decipoints.
1091 */
1092
set_line(length)1093 set_line( length )
1094 int length;
1095 {
1096 int height;
1097 char one, two, three, four;
1098
1099 /*
1100 printf("Line %d decipoints\n", i);
1101 */
1102
1103 height = (HEIGHT * versize + dev.unitwidth/2) / dev.unitwidth;
1104 if ( height < MIN_VAL)
1105 height = MIN_VAL;
1106 if (height > MAX_H)
1107 height = MAX_H;
1108 if (length > MAX_L)
1109 length = MAX_L;
1110 if (dbg)
1111 printf("Line: length %d height %d\n", length, height);
1112
1113 one = ( height >> BYTE ) | RUL;
1114 two = height & BMASK;
1115 three = length >> BYTE;
1116 four = length & BMASK;
1117 oput(one); oput(two); oput(three); oput(four);
1118 }
1119
1120 /*
1121 * get the width of a char, to be used only by set_ul() and set-ru()
1122 */
1123
1124 int
get_width(s)1125 get_width( s )
1126 char *s;
1127 {
1128 int c;
1129 int width;
1130 int j, i, k, ofont;
1131 char *pw;
1132
1133 for (c = 0; c < nchtab; c++)
1134 if (strcmp(&chname[chtab[c]], s) == 0)
1135 break;
1136 if (c < nchtab)
1137 c += 128-32;
1138 if (c <= 0 || c >= nchtab + 128-32) {
1139 if (dbg) printf("non-exist 0%o\n", c+32);
1140 return;
1141 }
1142 k = ofont = font;
1143 i = fitab[font][c] & BMASK;
1144 if (i != 0) { /* it's on this font */
1145 pw = widthtab[font];
1146 } else if (smnt > 0) { /* on special (we hope) */
1147 for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1))
1148 /*
1149 * Look for the character, start at the special font
1150 * and search further in a wrap around manner
1151 */
1152 if ((i = fitab[k][c] & BMASK) != 0) {
1153 pw = widthtab[k];
1154 setfont(k);
1155 break;
1156 }
1157 }
1158 if (i == 0 || (width = pw[i] & BMASK) == 0 || k > nfonts) {
1159 /* device drivers do width & 077, not really necessary */
1160 if (dbg) {
1161 printf("Width not found \\(%s\n", s);
1162 }
1163 return;
1164 }
1165 width = (width * horsize + dev.unitwidth/2) / dev.unitwidth;
1166 if (font != ofont)
1167 setfont(ofont);
1168 return( width);
1169 }
1170
1171 /* font position info: */
1172
1173 struct {
1174 char *name;
1175 int number;
1176 } fontname[NFONT+1];
1177
put1(c)1178 put1(c) /* output char c */
1179 int c;
1180 {
1181 char *pw;
1182 register char *p;
1183 register int i, k;
1184 int j, ofont, code;
1185 short f;
1186
1187 if (!output)
1188 return;
1189 c -= 32;
1190 if (c <= 0) {
1191 if (dbg) printf("non-exist 0%o\n", c+32);
1192 lastw = widthtab[font][0] * pstab[size-1] /dev.unitwidth;
1193 return;
1194 }
1195 k = ofont = font;
1196 i = fitab[font][c] & BMASK;
1197 if (i != 0) { /* it's on this font */
1198 p = codetab[font];
1199 pw = widthtab[font];
1200 } else if (smnt > 0) { /* on special (we hope) */
1201 for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1))
1202 /*
1203 * Look for the character, start at the special font
1204 * and search further in a wrap around manner
1205 */
1206 if ((i = fitab[k][c] & BMASK) != 0) {
1207 p = codetab[k];
1208 pw = widthtab[k];
1209 setfont(k);
1210 break;
1211 }
1212 }
1213 if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) {
1214 if (dbg) {
1215 if (isprint(c+32) && isascii(c+32))
1216 printf("not found %c\n", c+32);
1217 else
1218 printf("not found \\(%s\n", &chname[chtab[c -128+32]]);
1219 }
1220 return;
1221 }
1222 if (fontbase[k]->fonttab == 1)
1223 f = tosh( fonttab[k], i);
1224 else
1225 f = fontname[k].number;
1226 hflush();
1227 if (dbg) {
1228 if (isprint(c+32) && isascii(c+32)) { /* My God! */
1229 printf("%c %d %d\n", c+32, code, f);
1230 }
1231 else
1232 printf("\\(%s %d %d\n", &chname[chtab[c -128+32]], code, f);
1233 }
1234 if(code == 0 || code > 0200) {
1235 error(FATAL,"Illegal code 0%o found for char %03o\n", code, c+32);
1236 }
1237 putcode(code, f); /* character is < 254 */
1238 if (font != ofont) /* char on special font, reset */
1239 setfont(ofont);
1240 lastw = pw[i] & BMASK;
1241 /*HIRO*/
1242 if( dbg)
1243 fprintf(stderr,"lastw %d pw[i] %d\n", lastw,pw[i]);
1244 lastw = (lastw * pstab[size-1] + dev.unitwidth/2) / dev.unitwidth;
1245 }
1246
putcode(code,f)1247 putcode(code, f)
1248 char code; short f;
1249 {
1250 static short phfont;
1251
1252 #if vax || tahoe
1253 if ( f > 0177777)
1254 error(FATAL, "Impossible font selected");
1255 #endif
1256
1257 if( harcode) { /* if character pending */
1258 hflush(); /* update position and flush pending char */
1259 }
1260 if ( f != phfont ) {
1261 if(dbg > 1)
1262 printf("font to %d\n", f);
1263 putfont(f);
1264 }
1265 harcode = code;
1266 phfont = f;
1267 }
1268
putfont(f)1269 putfont(f)
1270 int f;
1271 { int high, low;
1272
1273 low = f & BMASK;
1274 high = (f >> BYTE ) & BMASK;
1275 oput(FNT);
1276 oput(high);
1277 oput(low);
1278 }
1279
setsize(n)1280 setsize(n) /* set point size to a true pointsize */
1281 int n;
1282 {
1283
1284 if (!output)
1285 return;
1286 horsize = pstab[n-1];
1287 vsizeflag = 0;
1288 size = n;
1289 putsize();
1290 }
1291
1292 /*
1293 * Do the actual sizechange(s).
1294 */
1295
putsize()1296 putsize()
1297 {
1298 if(!vsizeflag) {
1299 flushchar();
1300 sizecmd( PSZ, horsize);
1301 }
1302 else {
1303 flushchar();
1304 sizecmd( PSZ, versize);
1305 sizecmd( HPZ, horsize);
1306 }
1307 }
1308
sizecmd(cmd,n)1309 sizecmd( cmd, n)
1310 int cmd, n;
1311 {
1312 int i, low, high;
1313
1314 i = 10 * n;
1315 if(dbg)
1316 printf("size to %d\n", n);
1317 if( i > 01777)
1318 error(FATAL, "Impossible pointsize requested");
1319 low = i & BMASK;
1320 high = (i >> BYTE) & BMASK;
1321 if( high > 03 )
1322 error(FATAL, "system error in point size cmd");
1323 oput( cmd | high);
1324 oput(low);
1325 }
1326
t_fp(n,s,si)1327 t_fp(n, s, si) /* font position n now contains font s, intname si */
1328 int n;
1329 char *s, *si;
1330 {
1331 fontname[n].name = s;
1332 fontname[n].number = atoi(si);
1333 }
1334
setfont(n)1335 setfont(n) /* set font to n (internal)*/
1336 int n;
1337 {
1338 if (!output)
1339 return;
1340 if (n < 0 || n > NFONT)
1341 error(FATAL, "illegal font %d\n", n);
1342 font = n;
1343 slantfont(fontbase[n]->slant & BMASK);
1344 }
1345
1346 /*
1347 putint(n)
1348 {
1349 if (dbg) {
1350 printf("%02d\n", n);
1351 return;
1352 }
1353 putc(n>>8, tf);
1354 putc(n, tf);
1355 }
1356 */
1357