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