1 /*-
2 * %sccs.include.proprietary.c%
3 */
4
5 #ifndef lint
6 static char sccsid[] = "@(#)svt6.c 4.3 (Berkeley) 04/18/91";
7 #endif /* not lint */
8
9 #include "tdef.h"
10 extern
11 #include "d.h"
12 extern
13 #include "v.h"
14 #include "pathnames.h"
15
16 /*
17 troff6.c
18
19 width functions, sizes and fonts
20 */
21
22 extern int inchar[LNSIZE], *pinchar; /* XXX */
23 extern int eschar;
24 extern int widthp;
25 extern int ohc;
26 extern int xpts;
27 extern int xfont;
28 extern int code;
29 extern int smnt;
30 extern int setwdf;
31 extern int cs;
32 extern int ccs;
33 extern int spacesz;
34 extern char trtab[];
35 extern int xbitf;
36 extern int mfont;
37 extern int mpts;
38 extern int pfont;
39 extern int ppts;
40 extern int oldbits;
41 extern int chbits;
42 extern int spbits;
43 extern int nonumb;
44 extern int noscale;
45 extern int font;
46 extern int font1;
47 extern int pts;
48 extern int pts1;
49 extern int apts;
50 extern int apts1;
51 extern int sps;
52 extern int nlflg;
53 extern int nform;
54 extern int dfact;
55 extern int lss;
56 extern int lss1;
57 extern int vflag;
58 extern int ch0;
59 extern int lg;
60 char fontfile[] = _PATH_FONTS;
61 int ffi = 16;
62 extern int bd;
63 extern int level;
64 extern int ch;
65 extern int res;
66 extern int ptid;
67 extern char W1[],W2[],W3[],W4[];
68 extern int xxx;
69 int trflg;
70 char *fontab[] = {W1,W2,W3,W4};
71 int fontlab[] = {'R','I','B','S',0};
72 char pstab[] = {6,7,8,9,10,11,12,14,16,18,20,22,24,28,36,0};
73 char psctab[] = {010,000,001,007,002,003,004,005,0211,006,
74 0212,0213,0214,0215,0216,0};
75 int cstab[4], ccstab[4];
76 int bdtab[4];
77 int sbold = 0;
78 int spsz = 0;
79 struct fz {
80 char sign;
81 char size;
82 int inc;
83 } fz[4];
84
width(c)85 width(c)
86 int c;
87 {
88 register i,j,k;
89
90 j = c;
91 k = 0;
92 if(j & MOT){
93 if(j & VMOT)goto rtn;
94 k = j & ~MOTV;
95 if(j & NMOT)k = -k;
96 goto rtn;
97 }
98 if((i = (j & CMASK)) == 010){
99 k = -widthp;
100 goto rtn;
101 }
102 if(i == PRESC)i = eschar;
103 if((i == ohc) ||
104 (i >= 0370))goto rtn;
105 if((j>>BYTE) == oldbits){
106 xfont = pfont;
107 xpts = ppts;
108 }else xbits(j);
109 if(j & ZBIT)goto rtn;
110 if(!trflg)i = trtab[i] & BMASK;
111 if((i -= 32) < 0)goto rtn;
112 k = getcw(i);
113 if(bd)k += bd - 1;
114 if(cs)k = cs;
115 widthp = k;
116 rtn:
117 xbitf = trflg = 0;
118 return(k);
119 }
getcw(i)120 getcw(i)
121 int i;
122 {
123 register j,k;
124 register char *p;
125 int x;
126 extern char codetab[];
127
128 bd = 0;
129 if((code = codetab[i]) & 0200){
130 if(smnt){
131 p = fontab[smnt-1];
132 if(xfont == (sbold-1))bd = bdtab[smnt-1];
133 goto g0;
134 }
135 code = 0;
136 k = 36;
137 goto g1;
138 }
139 p = fontab[xfont];
140 g0:
141 if(!i)k = spacesz;
142 else k = *(p + i) & BMASK;
143 if(setwdf)v.ct |= ((k>>6) & 3);
144 g1:
145 k = (j = (k&077)*(xpts&077))/6;
146 if((j%6) >= 3)k++;
147 if(cs = cstab[xfont]){
148 if(ccs = ccstab[xfont])x = ccs; else x = xpts;
149 cs = (j = (cs&077)*(x&077))/6;
150 if((j%6) >= 3)cs++;
151 }
152 if(!bd)bd = bdtab[xfont];
153 return(k);
154 }
xbits(i)155 xbits(i)
156 int i;
157 {
158 register j, k;
159
160 /*
161 if((j = i >> BYTE) == oldbits){
162 xfont = pfont;
163 xpts = ppts;
164 goto rtn;
165 }
166 */
167 j = i >> BYTE;
168 xfont = (j>>1) & 03;
169 if(k = (j>>3) & 017){
170 xpts = pstab[--k];
171 if(psctab[k] < 0)xpts |= DBL;
172 oldbits = j;
173 pfont = xfont;
174 ppts = xpts;
175 goto rtn;
176 }
177 switch(xbitf){
178 case 0:
179 xfont = font;
180 xpts = pts;
181 break;
182 case 1:
183 xfont = pfont;
184 xpts = ppts;
185 break;
186 case 2:
187 xfont = mfont;
188 xpts = mpts;
189 }
190 rtn:
191 xbitf = 0;
192 }
setch()193 setch(){
194 register i,*j,k;
195 extern int chtab[];
196
197 if((i = getrq()) == 0)return(0);
198 for(j=chtab;*j != i;j++)if(*(j++) == 0)return(0);
199 k = *(++j) | chbits;
200 /*
201 if((i & CMASK) == '*'){
202 if(((i = find('R',fontlab)) < 0) &&
203 ((i = find('G',fontlab)) < 0))
204 return(k);
205 else return((k & ~(03<<(BYTE+1))) | (i<<(BYTE+1)));
206 }
207 */
208 return(k);
209 }
find(i,j)210 find(i,j)
211 int i,j[];
212 {
213 register k;
214
215 if(((k = i-'0') >= 1) && (k <= 4) && (k != smnt))return(--k);
216 for(k=0; j[k] != i; k++)if(j[k] == 0)return(-1);
217 return(k);
218 }
casefz()219 casefz(){
220 register i, j, k;
221 int savinc;
222
223 k = 0;
224 fz0:
225 if(skip() || !(i = getrq()) ||
226 ((j = find(i,fontlab)) == -1)){
227 if(k)goto fz1;
228 else return;
229 }
230 if(j == (smnt-1)){
231 k = smnt;
232 goto fz0;
233 }
234 if(k){
235 spsz = j + 1;
236 j = k -1;
237 }
238 fz1:
239 if((j==font) && fz[j].inc)savinc = fz[j].inc;
240 else savinc = 0;
241 fz[j].inc = fz[j].sign = fz[j].size = 0;
242 if(skip()){
243 if(k)spsz = 0;
244 goto fz2;
245 }
246 if(((i=((k=getch()) & CMASK)) == '+') || (i == '-'))fz[j].sign = i;
247 else{
248 fz[j].sign = 0;
249 ch = k;
250 }
251 noscale++;
252 fz[j].size = atoi();
253 noscale = 0;
254 fz2:
255 if(j==font)casps1(apts + savinc);
256 else if(j == smnt-1)mchbits();
257 }
caseps()258 caseps(){
259 register i;
260
261 if(skip())i = apts1;
262 else{
263 noscale++;
264 i = inumb(&apts);
265 noscale = 0;
266 if(nonumb)return;
267 }
268 casps1(i);
269 }
casps1(i)270 casps1(i)
271 int i;
272 {
273 if(i <= 0)return;
274 if(fz[font].size){
275 i = getfz(font, i);
276 }
277 apts1 = apts;
278 apts = i;
279 pts1 = pts;
280 pts = findps(i & 077);
281 mchbits();
282 }
findps(i)283 findps(i)
284 int i;
285 {
286 register j, k;
287
288 for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;}
289 if(psctab[j] < 0)k |= DBL;
290 return(k);
291 }
mchbits()292 mchbits(){
293 register i, j, k;
294
295 spbits = 0;
296 i = pts & 077;
297 for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;}
298 chbits = (((++j)<<2) | font) << (BYTE + 1);
299 sps = width(' ' | chbits);
300 if(font == (spsz-1)){
301 i = findps(getfz(smnt-1, apts + fz[font].inc));
302 for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;}
303 spbits = (((++j)<<2) | font) << (BYTE + 1);
304 }
305 }
getfz(x,y)306 getfz(x,y)
307 int x, y;
308 {
309 register i, j, k;
310
311 i = fz[x].size;
312 j = fz[x].sign;
313 if(i || j){
314 if(j == '+')i += y;
315 else if(j == '-')i = y - i;
316 }
317 fz[x].inc = y - i;
318 return(i);
319 }
setps()320 setps(){
321 register i,j;
322
323 if((((i=getch() & CMASK) == '+') || (i == '-')) &&
324 (((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9))){
325 if(i == '-')j = -j;
326 ch = 0;
327 casps1(apts+j);
328 return;
329 }
330 if((i -= '0') == 0){
331 casps1(apts1);
332 return;
333 }
334 if((i > 0) && (i <= 9)){
335 if((i <= 3) &&
336 ((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9)){
337 i = 10*i +j;
338 ch = 0;
339 }
340 casps1(i);
341 }
342 }
caseft()343 caseft(){
344 skip();
345 setfont(1);
346 }
setfont(a)347 setfont(a)
348 int a;
349 {
350 register i,j;
351
352 if(a)i = getrq();
353 else i = getsn();
354 if(!i || (i == 'P')){
355 j = font1;
356 goto s0;
357 }
358 if(i == 'S')return;
359 if((j = find(i,fontlab)) == -1)return;
360 s0:
361 font1 = font;
362 font = j;
363 i = 0;
364 if(fz[font1].size){
365 i++;
366 casps1(apts + fz[font1].inc);
367 }else if(fz[font].size){
368 i++;
369 casps1(apts);
370 }
371 if(!i)mchbits();
372 }
setwd()373 setwd(){
374 register i, base, wid;
375 int delim, em, k;
376 int savlevel, savhp, savapts, savapts1, savfont, savfont1,
377 savpts, savpts1;
378
379 base = v.st = v.sb = wid = v.ct = 0;
380 if((delim = getch() & CMASK) & MOT)return;
381 savhp = v.hp;
382 savlevel = level;
383 v.hp = level = 0;
384 savapts = apts;
385 savapts1 = apts1;
386 savfont = font;
387 savfont1 = font1;
388 savpts = pts;
389 savpts1 = pts1;
390 setwdf++;
391 while((((i = getch()) & CMASK) != delim) && !nlflg){
392 wid += width(i);
393 if(!(i & MOT)){
394 em = (xpts & 077)*6;
395 }else if(i & VMOT){
396 k = i & ~MOTV;
397 if(i & NMOT)k = -k;
398 base -= k;
399 em = 0;
400 }else continue;
401 if(base < v.sb)v.sb = base;
402 if((k=base + em) > v.st)v.st = k;
403 }
404 nform = 0;
405 setn1(wid);
406 v.hp = savhp;
407 level = savlevel;
408 apts = savapts;
409 apts1 = savapts1;
410 font = savfont;
411 font1 = savfont1;
412 pts = savpts;
413 pts1 = savpts1;
414 mchbits();
415 setwdf = 0;
416 }
vmot()417 vmot(){
418 dfact = lss;
419 vflag++;
420 return(mot());
421 }
hmot()422 hmot(){
423 dfact = 6 * (pts & 077);
424 return(mot());
425 }
mot()426 mot(){
427 register i, j;
428
429 j = HOR;
430 getch(); /*eat delim*/
431 if(i = atoi()){
432 if(vflag)j = VERT;
433 i = makem(quant(i,j));
434 }
435 getch();
436 vflag = 0;
437 dfact = 1;
438 return(i);
439 }
sethl(k)440 sethl(k)
441 int k;
442 {
443 register i;
444
445 i = 3 * (pts & 077);
446 if(k == 'u')i = -i;
447 else if(k == 'r')i = -2*i;
448 vflag++;
449 i = makem(i);
450 vflag = 0;
451 return(i);
452 }
makem(i)453 makem(i)
454 int i;
455 {
456 register j;
457
458 if((j = i) < 0)j = -j;
459 j = (j & ~MOTV) | MOT;
460 if(i < 0)j |= NMOT;
461 if(vflag)j |= VMOT;
462 return(j);
463 }
getlg(i)464 getlg(i)
465 int i;
466 {
467 register j, k;
468
469 switch((j = getch0()) & CMASK){
470 case 'f':
471 if(lg!=2){switch((k =getch0()) & CMASK){
472 case 'i':
473 j = 0214;
474 break;
475 case 'l':
476 j = 0215;
477 break;
478 default:
479 ch0 = k;
480 j = 0213;
481 }
482 }else j = 0213;
483 break;
484 case 'l':
485 j = 0212;
486 break;
487 case 'i':
488 j = 0211;
489 break;
490 default:
491 ch0 = j;
492 j = i;
493 }
494 return((i & ~CMASK) | j);
495 }
caselg()496 caselg(){
497
498 lg = 1;
499 if(skip())return;
500 lg = atoi();
501 }
casefp()502 casefp(){
503 register i, j, k;
504 int x;
505
506 skip();
507 if(((i = (getch() & CMASK) - '0' -1) < 0) || (i >3)){prstr("fp: bad font position\n"); return;}
508 if(skip() || !(j = getrq())){prstr("fp: no font name\n"); return;}
509 fontfile[ffi] = j & BMASK;
510 fontfile[ffi+1] = j>>BYTE;
511 if((k = open(fontfile,0)) < 0){
512 prstr("Cannot open ");
513 c0:
514 prstr(fontfile);
515 prstr("\n");
516 done(-1);
517 }
518 if(lseek(k,8L * sizeof(int),0) < 0)goto c1;
519 if(read(k,fontab[i],256-32) != 256-32){
520 c1:
521 prstr("Cannot read ");
522 goto c0;
523 }
524 close(k);
525 if(i == (smnt-1)){smnt = 0; sbold = 0; spsz = 0;}
526 if((fontlab[i] = j) == 'S')smnt = i + 1;
527 bdtab[i] = cstab[i] = ccstab[i] = 0;
528 fz[i].inc = fz[i].sign = fz[i].size = 0;
529 if(ptid != 1){
530 prstr("Mount font ");
531 prstr(&fontfile[ffi]);
532 prstr(" on ");
533 x = PAIR((i + '1'),0);
534 prstr((char *)&x);
535 prstr("\n");
536 }
537 }
casecs()538 casecs(){
539 register i, j;
540
541 noscale++;
542 skip();
543 if(!(i=getrq()) ||
544 ((i = find(i,fontlab)) < 0))goto rtn;
545 skip();
546 cstab[i] = atoi();
547 skip();
548 j = atoi();
549 if(!nonumb)ccstab[i] = findps(j);
550 rtn:
551 noscale = 0;
552 }
casebd()553 casebd(){
554 register i, j, k;
555
556 k = 0;
557 bd0:
558 if(skip() || !(i = getrq()) ||
559 ((j = find(i,fontlab)) == -1)){
560 if(k)goto bd1;
561 else return;
562 }
563 if(j == (smnt-1)){
564 k = smnt;
565 goto bd0;
566 }
567 if(k){
568 sbold = j + 1;
569 j = k -1;
570 }
571 bd1:
572 skip();
573 noscale++;
574 bdtab[j] = atoi();
575 noscale = 0;
576 }
casevs()577 casevs(){
578 register i;
579
580 skip();
581 vflag++;
582 dfact = 6; /*default scaling is points!*/
583 res = VERT;
584 i = inumb(&lss);
585 if(nonumb)i = lss1;
586 if(i < VERT)i = VERT;
587 lss1 = lss;
588 lss = i;
589 }
casess()590 casess(){
591 register i;
592
593 noscale++;
594 skip();
595 if(i = atoi()){
596 spacesz = i& 0177;
597 sps = width(' ' | chbits);
598 }
599 noscale = 0;
600 }
xlss()601 xlss(){
602 register i, j;
603
604 getch();
605 dfact = lss;
606 i = quant(atoi(),VERT);
607 dfact = 1;
608 getch();
609 if((j = i) < 0)j = -j;
610 ch0 = ((j & 03700)<<3) | HX;
611 if(i < 0)ch0 |= 040000;
612 return(((j & 077)<<9) | LX);
613 }
614