always complain if file can't be lstat'ed
[unix-history] / usr / src / local / ditroff / ditroff.old.okeeffe / troff / t6.c
CommitLineData
121f5003
DS
1#include "tdef.h"
2extern
3#include "d.h"
4extern
5#include "v.h"
6#include "dev.h"
7/*
8troff6.c
9
10width functions, sizes and fonts
11*/
12
13#include <sgtty.h>
14#include "ext.h"
15int trflg;
16/* fitab[f][c] is 0 if c is not on font f
17 /* if it's non-zero, c is in fontab[f] at position
18 /* fitab[f][c].
19 */
20int fontlab[NFONT+1];
21short *pstab;
22int cstab[NFONT+1], ccstab[NFONT+1];
23int bdtab[NFONT+1];
24int sbold = 0;
25
26width(j)
27tchar j;
28{
29 register i, k;
30
31 k = 0;
32 i = cbits(j);
33 if (ismot(j)) {
34 if (isvmot(j))
35 goto rtn;
36 k = absmot(j);
37 if (isnmot(j))
38 k = -k;
39 goto rtn;
40 }
41 if (i == '\b') {
42 k = -widthp;
43 goto rtn;
44 }
45 if (i == PRESC)
46 i = eschar;
47 else if (i == ohc || iscontrol(i))
48 goto rtn;
49 if (sfbits(j) == oldbits) {
50 xfont = pfont;
51 xpts = ppts;
52 } else
53 xbits(j);
54 if (iszbit(j))
55 goto rtn;
56 if (!trflg)
57 i = trtab[i];
58 if ((i -= 32) < 0)
59 goto rtn;
60 k = getcw(i);
61 if (bd)
62 k += (bd - 1) * HOR;
63 if (cs)
64 k = cs;
65 widthp = k;
66rtn:
67 xbitf = trflg = 0;
68 return(k);
69}
70
71
72getcw(i)
73register int i;
74{
75 register int k;
76 register char *p;
77 int x, j;
78
79 bd = 0;
80 if (i == 0) { /* a blank */
81 k = (fontab[xfont][0] * spacesz + 6) / 12;
82 /* this nonsense because .ss cmd uses 1/36 em as its units */
83 /* and default is 12 */
84 goto g1;
85 }
86 if ((j = fitab[xfont][i] & BMASK) == 0) { /* it's not on current font */
87 /* search through search list of xfont
88 /* to see what font it ought to be on.
89 /* for now, searches S, then remaining fonts in wraparound order.
90 */
91 if (smnt) {
92 int ii, jj;
93 for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) {
94 j = fitab[ii][i] & BMASK;
95 if (j != 0) {
96 p = fontab[ii];
97 k = *(p + j);
98 if (xfont == sbold)
99 bd = bdtab[ii];
100 if (setwdf)
101 v.ct |= kerntab[ii][j];
102 goto g1;
103 }
104 }
105 }
106 code = 0;
107 k = fontab[xfont][0]; /* leave a space-size space */
108 goto g1;
109 }
110 p = fontab[xfont];
111 if (setwdf)
112 v.ct |= kerntab[xfont][j];
113 k = *(p + j);
114g1:
115 if (!bd)
116 bd = bdtab[xfont];
117 if (cs = cstab[xfont]) {
118 if (ccs = ccstab[xfont])
119 x = ccs;
120 else
121 x = xpts;
122 cs = (cs * EMPTS(x)) / 36;
123 }
124 return(((k&BMASK) * xpts + (Unitwidth / 2)) / Unitwidth);
125 /* Unitwidth is Units/Point, where
126 /* Units is the fundamental digitization
127 /* of the character set widths, and
128 /* Point is the number of goobies in a point
129 /* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6
130 /* In effect, it's the size at which the widths
131 /* translate directly into units.
132 */
133}
134
135
136xbits(i)
137tchar i;
138{
139 register j, k;
140
141 xfont = fbits(i);
142 k = sbits(i);
143 if (k) {
144 xpts = pstab[--k];
145 oldbits = sfbits(i);
146 pfont = xfont;
147 ppts = xpts;
148 goto rtn;
149 }
150 switch (xbitf) {
151 case 0:
152 xfont = font;
153 xpts = pts;
154 break;
155 case 1:
156 xfont = pfont;
157 xpts = ppts;
158 break;
159 case 2:
160 xfont = mfont;
161 xpts = mpts;
162 }
163rtn:
164 xbitf = 0;
165}
166
167
168tchar setch()
169{
170 register j;
171 char temp[10];
172 register char *s;
173 extern char *chname;
174 extern short *chtab;
175 extern int nchtab;
176
177 s = temp;
178 if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
179 return(0);
180 *s = '\0';
181 for (j = 0; j < nchtab; j++)
182 if (strcmp(&chname[chtab[j]], temp) == 0)
183 return(j + 128 | chbits);
184 return(0);
185}
186
187
188tchar absch() /* absolute character number */
189{
190 fprintf(stderr, "troff: no \\C yet\n");
191 return(0);
192}
193
194
195findft(i)
196register int i;
197{
198 register k;
199
200 if ((k = i - '0') >= 0 && k <= nfonts && k < smnt)
201 return(k);
202 for (k = 0; fontlab[k] != i; k++)
203 if (k > nfonts)
204 return(-1);
205 return(k);
206}
207
208
209caseps()
210{
211 register i;
212
213 if (skip())
214 i = apts1;
215 else {
216 noscale++;
217 i = inumb(&apts); /* this is a disaster for fractional point sizes */
218 noscale = 0;
219 if (nonumb)
220 return;
221 }
222 casps1(i);
223}
224
225
226casps1(i)
227register int i;
228{
229 if (i <= 0)
230 return;
231 apts1 = apts;
232 apts = i;
233 pts1 = pts;
234 pts = findps(i);
235 mchbits();
236}
237
238
239findps(i)
240register int i;
241{
242 register j, k;
243
244 for (j = 0; i > (k = pstab[j]); j++)
245 if (!k) {
246 k = pstab[--j];
247 break;
248 }
249 return(k);
250}
251
252
253mchbits()
254{
255 register i, j, k;
256
257 i = pts;
258 for (j = 0; i > (k = pstab[j]); j++)
259 if (!k) {
260 k = pstab[--j];
261 break;
262 }
263 chbits = 0;
264 setsbits(chbits, ++j);
265 setfbits(chbits, font);
266 sps = width(' ' | chbits);
267}
268
269
270setps()
271{
272 register i, j;
273
274 if (((i = cbits(getch())) == '+' || i == '-') && (j = cbits(ch = getch()) - '0') >= 0 && j <= 9) {
275 if (i == '-')
276 j = -j;
277 ch = 0;
278 casps1(apts + j);
279 return;
280 }
281 if ((i -= '0') == 0) {
282 casps1(apts1);
283 return;
284 }
285 if (i > 0 && i <= 9) {
286 /* removed if (i <= 3 && */
287 /* didn't work!!!! */
288 if (i <= 3 && (j = cbits(ch = getch()) - '0') >= 0 && j <= 9) {
289 i = 10 * i + j;
290 ch = 0;
291 }
292 casps1(i);
293 }
294}
295
296
297tchar setht() /* set character height from \H'...' */
298{
299 int n;
300 tchar c;
301
302 getch();
303 n = inumb(&apts);
304 getch();
305 if (n == 0 || nonumb)
306 n = apts; /* does this work? */
307 c = CHARHT;
308 c |= ZBIT;
309 setsbits(c, n);
310 return(c);
311}
312
313tchar setslant() /* set slant from \S'...' */
314{
315 int n;
316 tchar c;
317
318 getch();
319 n = 0;
320 n = inumb(&n);
321 getch();
322 if (nonumb)
323 n = 0;
324 c = SLANT;
325 c |= ZBIT;
326 setsfbits(c, n+180);
327 return(c);
328}
329
330
331caseft()
332{
333 skip();
334 setfont(1);
335}
336
337
338setfont(a)
339int a;
340{
341 register i, j;
342
343 if (a)
344 i = getrq();
345 else
346 i = getsn();
347 if (!i || i == 'P') {
348 j = font1;
349 goto s0;
350 }
351 if (i == 'S' || i == '0')
352 return;
353 if ((j = findft(i)) == -1)
354 if ((j = setfp(0, i, 0)) == -1) /* try to put it in position 0 */
355 return;
356s0:
357 font1 = font;
358 font = j;
359 mchbits();
360}
361
362
363setwd()
364{
365 register base, wid;
366 tchar i;
367 int delim, em, k;
368 int savlevel, savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
369 tchar *savpinchar, *p, *q, tempinchar[LNSIZE]; /* XXX */
370
371 base = v.st = v.sb = wid = v.ct = 0;
372 if (ismot(i = getch()))
373 return;
374 delim = cbits(i);
375 savhp = v.hp;
376 savpinchar = pinchar; /* XXX */
377 for (p=inchar, q=tempinchar; p < pinchar; ) /* XXX */
378 *q++ = *p++; /* XXX */
379 pinchar = inchar; /* XXX */
380 savlevel = level;
381 v.hp = level = 0;
382 savapts = apts;
383 savapts1 = apts1;
384 savfont = font;
385 savfont1 = font1;
386 savpts = pts;
387 savpts1 = pts1;
388 setwdf++;
389 while (cbits(i = getch()) != delim && !nlflg) {
390 wid += width(i);
391 if (!ismot(i)) {
392 em = POINT * xpts;
393 } else if (isvmot(i)) {
394 k = absmot(i);
395 if (isnmot(i))
396 k = -k;
397 base -= k;
398 em = 0;
399 } else
400 continue;
401 if (base < v.sb)
402 v.sb = base;
403 if ((k = base + em) > v.st)
404 v.st = k;
405 }
406 nform = 0;
407 setn1(wid);
408 v.hp = savhp;
409 pinchar = savpinchar; /* XXX */
410 for (p=inchar, q=tempinchar; p < pinchar; ) /* XXX */
411 *p++ = *q++; /* XXX */
412 level = savlevel;
413 apts = savapts;
414 apts1 = savapts1;
415 font = savfont;
416 font1 = savfont1;
417 pts = savpts;
418 pts1 = savpts1;
419 mchbits();
420 setwdf = 0;
421}
422
423
424tchar vmot()
425{
426 dfact = lss;
427 vflag++;
428 return(mot());
429}
430
431
432tchar hmot()
433{
434 dfact = EM;
435 return(mot());
436}
437
438
439tchar mot()
440{
441 register short j, n;
442 tchar i;
443
444 j = HOR;
445 getch(); /*eat delim*/
446 if (n = atoi()) {
447 if (vflag)
448 j = VERT;
449 i = makem(quant(n, j));
450 } else
451 i = 0;
452 getch();
453 vflag = 0;
454 dfact = 1;
455 return(i);
456}
457
458
459tchar sethl(k)
460int k;
461{
462 register j;
463 tchar i;
464
465 j = EM / 2;
466 if (k == 'u')
467 j = -j;
468 else if (k == 'r')
469 j = -2 * j;
470 vflag++;
471 i = makem(j);
472 vflag = 0;
473 return(i);
474}
475
476
477tchar makem(i)
478int i;
479{
480 tchar j;
481
482 if ((j = i) < 0)
483 j = -j;
484 j |= MOT;
485 if (i < 0)
486 j |= NMOT;
487 if (vflag)
488 j |= VMOT;
489 return(j);
490}
491
492
493tchar getlg(i)
494tchar i;
495{
496 tchar j, k;
497 register int lf;
498
499 if ((lf = fontbase[fbits(i)]->ligfont) == 0) /* the font has no ligatures */
500 return(i);
501 j = getch0();
502 if (cbits(j) == 'i' && (lf & LFI))
503 j = LIG_FI;
504 else if (cbits(j) == 'l' && (lf & LFL))
505 j = LIG_FL;
506 else if (cbits(j) == 'f' && (lf & LFF)) {
507 if ((lf & (LFFI|LFFL)) && lg != 2) {
508 k = getch0();
509 if (cbits(k)=='i' && (lf&LFFI))
510 j = LIG_FFI;
511 else if (cbits(k)=='l' && (lf&LFFL))
512 j = LIG_FFL;
513 else {
514 ch0 = k;
515 j = LIG_FF;
516 }
517 } else
518 j = LIG_FF;
519 } else {
520 ch0 = j;
521 j = i;
522 }
523 return(i & SFMASK | j);
524}
525
526
527caselg()
528{
529
530 lg = 1;
531 if (skip())
532 return;
533 lg = atoi();
534}
535
536
537casefp()
538{
539 register i, j;
540 register char *p;
541 char dir[50];
542
543 skip();
544 if ((i = cbits(getch()) - '0') <= 0 || i > nfonts)
545 fprintf(stderr, "troff: fp: bad font position %d\n", i);
546 else if (skip() || !(j = getrq()))
547 fprintf(stderr, "troff: fp: no font name\n");
548 else {
549 skip();
550 setfp(i, j, 0);
551 }
552}
553
554setfp(pos, f, d) /* mount font f at position pos[0...nfonts] */
555int pos, f;
556char *d;
557{
558 register i, j, k;
559 int n;
560 char longname[NS], shortname[10], *p;
561 extern int nchtab;
562
563 shortname[0] = f & BMASK;
564 shortname[1] = f >> BYTE;
565 shortname[2] = '\0';
566 if (d == 0) /* normal case */
567 sprintf(longname, "%s/dev%s/%s.out", fontfile, devname, shortname);
568 else /* 3rd argument is a directory for the font */
569 sprintf(longname, "%s/%s.out", fontfile, shortname);
570 if ((k = open(longname, 0)) < 0) {
571 fprintf(stderr, "troff: Can't open %s\n", longname);
572 return(-1);
573 }
574 n = fontbase[pos]->nwfont & BMASK;
575 read(k, fontbase[pos], 3*n + nchtab + 128 - 32 + sizeof(struct font));
576 kerntab[pos] = (char *) fontab[pos] + (fontbase[pos]->nwfont & BMASK);
577 /* have to reset the fitab pointer because the width may be different */
578 fitab[pos] = (char *) fontab[pos] + 3 * (fontbase[pos]->nwfont & BMASK);
579 if ((fontbase[pos]->nwfont & BMASK) > n) {
580 fprintf(stderr, "troff: Font %s too big for position %d\n", shortname, pos);
581 return(-1);
582 }
583 fontbase[pos]->nwfont = n; /* so can load a larger one again later */
584 close(k);
585 if (pos == smnt) {
586 smnt = 0;
587 sbold = 0;
588 }
589 if ((fontlab[pos] = f) == 'S')
590 smnt = pos;
591 bdtab[pos] = cstab[pos] = ccstab[pos] = 0;
592 /* if there is a directory, no place to store its name. */
593 /* if position isn't zero, no place to store its value. */
594 /* only time a FONTPOS is pushed back is if it's a */
595 /* standard font on position 0 (i.e., mounted implicitly. */
596 /* there's a bug here: if there are several input lines */
597 /* that look like .ft XX in short successtion, the output */
598 /* will all be in the last one because the "x font ..." */
599 /* comes out too soon. pushing back FONTPOS doesn't work */
600 /* with .ft commands because input is flushed after .xx cmds */
601 ptfpcmd(pos, shortname, d);
602 if (d == 0 && pos == 0)
603 ch = (tchar) FONTPOS | (tchar) f << 16;
604 return(pos);
605}
606
607
608casecs()
609{
610 register i, j;
611
612 noscale++;
613 skip();
614 if (!(i = getrq()) || (i = findft(i)) < 0)
615 goto rtn;
616 skip();
617 cstab[i] = atoi();
618 skip();
619 j = atoi();
620 if (nonumb)
621 ccstab[i] = 0;
622 else
623 ccstab[i] = findps(j);
624rtn:
625 noscale = 0;
626}
627
628
629casebd()
630{
631 register i, j, k;
632
633 k = 0;
634bd0:
635 if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
636 if (k)
637 goto bd1;
638 else
639 return;
640 }
641 if (j == smnt) {
642 k = smnt;
643 goto bd0;
644 }
645 if (k) {
646 sbold = j;
647 j = k;
648 }
649bd1:
650 skip();
651 noscale++;
652 bdtab[j] = atoi();
653 noscale = 0;
654}
655
656
657casevs()
658{
659 register i;
660
661 skip();
662 vflag++;
663 dfact = INCH; /* default scaling is points! */
664 dfactd = 72;
665 res = VERT;
666 i = inumb(&lss);
667 if (nonumb)
668 i = lss1;
669 /* if(i < VERT)i = VERT; */
670 if (i < VERT)
671 i = 0;
672 lss1 = lss;
673 lss = i;
674}
675
676
677casess()
678{
679 register i;
680
681 noscale++;
682 skip();
683 if (i = atoi()) {
684 spacesz = i & 0177;
685 sps = width(' ' | chbits);
686 }
687 noscale = 0;
688}
689
690
691tchar xlss()
692{
693 /* stores \x'...' into
694 /* two successive tchars.
695 /* the first contains HX, the second the value,
696 /* encoded as a vertical motion.
697 /* decoding is done in n2.c by pchar().
698 */
699 int i;
700 tchar c;
701
702 getch();
703 dfact = lss;
704 i = quant(atoi(), VERT);
705 dfact = 1;
706 getch();
707 if (i >= 0)
708 ch0 = MOT | VMOT | i;
709 else
710 ch0 = MOT | VMOT | NMOT | -i;
711 c = HX;
712 dummy();
713 return(c);
714}