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