xref: /original-bsd/old/roff/troff/t6.c (revision 7748387a)
1 /*-
2  * %sccs.include.proprietary.c%
3  */
4 
5 #ifndef lint
6 static char sccsid[] = "@(#)t6.c	4.4 (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 = 0;
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 
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
343 caseft(){
344 	skip();
345 	setfont(1);
346 }
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 }
373 setwd(){
374 	register i, base, wid;
375 	int delim, em, k;
376 	int savlevel, savhp, savapts, savapts1, savfont, savfont1,
377 		savpts, savpts1;
378         int *savpinchar, *p, *q, tempinchar[LNSIZE];    /* XXX */
379 
380 	base = v.st = v.sb = wid = v.ct = 0;
381 	if((delim = getch() & CMASK) & MOT)return;
382 	savhp = v.hp;
383         savpinchar = pinchar;   /* XXX */
384         for (p=inchar, q=tempinchar; p < pinchar; )     /* XXX */
385                 *q++ = *p++;    /* XXX */
386         pinchar = inchar;       /* XXX */
387 	savlevel = level;
388 	v.hp = level = 0;
389 	savapts = apts;
390 	savapts1 = apts1;
391 	savfont = font;
392 	savfont1 = font1;
393 	savpts = pts;
394 	savpts1 = pts1;
395 	setwdf++;
396 	while((((i = getch()) & CMASK) != delim) && !nlflg){
397 		wid += width(i);
398 		if(!(i & MOT)){
399 			em = (xpts & 077)*6;
400 		}else if(i & VMOT){
401 			k = i & ~MOTV;
402 			if(i & NMOT)k = -k;
403 			base -= k;
404 			em = 0;
405 		}else continue;
406 		if(base < v.sb)v.sb = base;
407 		if((k=base + em) > v.st)v.st = k;
408 	}
409 	nform = 0;
410 	setn1(wid);
411 	v.hp = savhp;
412         pinchar = savpinchar;   /* XXX */
413         for (p=inchar, q=tempinchar; p < pinchar; )     /* XXX */
414                 *p++ = *q++;    /* XXX */
415 	level = savlevel;
416 	apts = savapts;
417 	apts1 = savapts1;
418 	font = savfont;
419 	font1 = savfont1;
420 	pts = savpts;
421 	pts1 = savpts1;
422 	mchbits();
423 	setwdf = 0;
424 }
425 vmot(){
426 	dfact = lss;
427 	vflag++;
428 	return(mot());
429 }
430 hmot(){
431 	dfact = 6 * (pts & 077);
432 	return(mot());
433 }
434 mot(){
435 	register i, j;
436 
437 	j = HOR;
438 	getch(); /*eat delim*/
439 	if(i = atoi()){
440 		if(vflag)j = VERT;
441 		i = makem(quant(i,j));
442 	}
443 	getch();
444 	vflag = 0;
445 	dfact = 1;
446 	return(i);
447 }
448 sethl(k)
449 int k;
450 {
451 	register i;
452 
453 	i = 3 * (pts & 077);
454 	if(k == 'u')i = -i;
455 	else if(k == 'r')i = -2*i;
456 	vflag++;
457 	i = makem(i);
458 	vflag = 0;
459 	return(i);
460 }
461 makem(i)
462 int i;
463 {
464 	register j;
465 
466 	if((j = i) < 0)j = -j;
467 	j = (j & ~MOTV) | MOT;
468 	if(i < 0)j |= NMOT;
469 	if(vflag)j |= VMOT;
470 	return(j);
471 }
472 getlg(i)
473 int i;
474 {
475 	register j, k;
476 
477 	switch((j = getch0()) & CMASK){
478 		case 'f':
479 			if(lg!=2){switch((k =getch0()) & CMASK){
480 					case 'i':
481 						j = 0214;
482 						break;
483 					case 'l':
484 						j = 0215;
485 						break;
486 					default:
487 						ch0 = k;
488 						j = 0213;
489 				}
490 			}else j = 0213;
491 			break;
492 		case 'l':
493 			j = 0212;
494 			break;
495 		case 'i':
496 			j = 0211;
497 			break;
498 		default:
499 			ch0 = j;
500 			j = i;
501 	}
502 	return((i & ~CMASK) | j);
503 }
504 caselg(){
505 
506 	lg = 1;
507 	if(skip())return;
508 	lg = atoi();
509 }
510 casefp(){
511 	register i, j, k;
512 	int x;
513 
514 	if (ffi == 0)
515 		while (fontfile[ffi] != 'X')
516 			ffi++;
517 	skip();
518 	if(((i = (getch() & CMASK) - '0' -1) < 0) || (i >3)){prstr("fp: bad font position\n"); return;}
519 	if(skip() || !(j = getrq())){prstr("fp: no font name\n"); return;}
520 	fontfile[ffi] = j & BMASK;
521 	fontfile[ffi+1] = j>>BYTE;
522 	if((k = open(fontfile,0)) < 0){
523 		prstr("Cannot open ");
524 	c0:
525 		prstr(fontfile);
526 		prstr("\n");
527 		done(-1);
528 	}
529 	if(lseek(k,8L * sizeof(int),0) < 0)goto c1;
530 	if(read(k,fontab[i],256-32) != 256-32){
531 	c1:
532 		prstr("Cannot read ");
533 		goto c0;
534 	}
535 	close(k);
536 	if(i == (smnt-1)){smnt = 0; sbold = 0; spsz = 0;}
537 	if((fontlab[i] = j) == 'S')smnt = i + 1;
538 	bdtab[i] = cstab[i] = ccstab[i] = 0;
539 	fz[i].inc = fz[i].sign = fz[i].size = 0;
540 	if(ptid != 1){
541 		prstr("Mount font ");
542 		prstr(&fontfile[ffi]);
543 		prstr(" on ");
544 		x = PAIR((i + '1'),0);
545 		prstr((char *)&x);
546 		prstr("\n");
547 	}
548 }
549 casecs(){
550 	register i, j;
551 
552 	noscale++;
553 	skip();
554 	if(!(i=getrq()) ||
555 	  ((i = find(i,fontlab)) < 0))goto rtn;
556 	skip();
557 	cstab[i] = atoi();
558 	skip();
559 	j = atoi();
560 	if(!nonumb)ccstab[i] = findps(j);
561 rtn:
562 	noscale = 0;
563 }
564 casebd(){
565 	register i, j, k;
566 
567 	k = 0;
568 bd0:
569 	if(skip() || !(i = getrq()) ||
570 	  ((j = find(i,fontlab))  == -1)){
571 		if(k)goto bd1;
572 		else return;
573 	}
574 	if(j == (smnt-1)){
575 		k = smnt;
576 		goto bd0;
577 	}
578 	if(k){
579 		sbold = j + 1;
580 		j = k -1;
581 	}
582 bd1:
583 	skip();
584 	noscale++;
585 	bdtab[j] = atoi();
586 	noscale = 0;
587 }
588 casevs(){
589 	register i;
590 
591 	skip();
592 	vflag++;
593 	dfact = 6; /*default scaling is points!*/
594 	res = VERT;
595 	i = inumb(&lss);
596 	if(nonumb)i = lss1;
597 	if(i < VERT)i = VERT;
598 	lss1 = lss;
599 	lss = i;
600 }
601 casess(){
602 	register i;
603 
604 	noscale++;
605 	skip();
606 	if(i = atoi()){
607 		spacesz = i& 0177;
608 		sps = width(' ' | chbits);
609 	}
610 	noscale = 0;
611 }
612 xlss(){
613 	register i, j;
614 
615 	getch();
616 	dfact = lss;
617 	i = quant(atoi(),VERT);
618 	dfact = 1;
619 	getch();
620 	if((j = i) < 0)j = -j;
621 	ch0 = ((j & 03700)<<3) | HX;
622 	if(i < 0)ch0 |= 040000;
623 	return(((j & 077)<<9) | LX);
624 }
625