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