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