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