1 #ifndef lint
2 static char sccsid[] = "@(#)t6.c	2.2 (CWI) 87/07/10";
3 #endif lint
4 /*
5  * t6.c
6  *
7  * width functions, sizes and fonts
8  */
9 
10 #include "tdef.h"
11 #include "dev.h"
12 #include <sgtty.h>
13 #include <ctype.h>
14 #include "ext.h"
15 
16 /* fitab[f][c] is 0 if c is not on font f
17 	/* if it's non-zero, c is in fontab[f] at position
18 	/* fitab[f][c].
19 	*/
20 extern	struct Font *fontbase[NFONT+1];
21 extern	char *codetab[NFONT+1];
22 extern int nchtab;
23 
24 int	fontlab[MAXFONTS+1];
25 short	*pstab;
26 int	cstab[MAXFONTS+1];
27 int	ccstab[MAXFONTS+1];
28 int	bdtab[MAXFONTS+1];
29 int	sbold = 0;
30 
width(j)31 width(j)
32 register tchar j;
33 {
34 	register i, k;
35 
36 	if (j & (ZBIT|MOT)) {
37 		if (iszbit(j))
38 			return(0);
39 		if (isvmot(j))
40 			return(0);
41 		k = absmot(j);
42 		if (isnmot(j))
43 			k = -k;
44 		return(k);
45 	}
46 	i = cbits(j);
47 	if (i < ' ') {
48 		if (i == '\b')
49 			return(-widthp);
50 		if (i == PRESC)
51 			i = eschar;
52 		else if (iscontrol(i))
53 			return(0);
54 	}
55 	if (i==ohc)
56 		return(0);
57 	i = trtab[i];
58 	if (i < 32)
59 		return(0);
60 	if (sfbits(j) == oldbits) {
61 		xfont = pfont;
62 		xpts = ppts;
63 	} else
64 		xbits(j, 0);
65 	if (widcache[i-32].fontpts == (xfont<<8) + xpts && !setwdf)
66 		k = widcache[i-32].width;
67 	else {
68 		k = getcw(i-32);
69 		if (bd)
70 			k += (bd - 1) * HOR;
71 		if (cs)
72 			k = cs;
73 	}
74 	widthp = k;
75 	return(k);
76 }
77 
78 /*
79  * clear width cache-- s means just space
80  */
zapwcache(s)81 zapwcache(s)
82 {
83 	register i;
84 
85 	if (s) {
86 		widcache[0].fontpts = 0;
87 		return;
88 	}
89 	for (i=0; i<NWIDCACHE; i++)
90 		widcache[i].fontpts = 0;
91 }
92 
getcw(i)93 getcw(i)
94 register int	i;
95 {
96 	register int	k;
97 	register char	*p;
98 	register int	x, j;
99 	int nocache = 0;
100 	int	savxfont = 0, savsbold = 0, savulfont = 0;
101 
102 	/*
103 	 * Here comes first part of bug fix
104 	 */
105 
106 	if( xfont > nfonts) {		/* font is not mounted */
107 		savxfont = xfont;
108 		if( xfont == sbold) {
109 			savsbold = sbold;
110 			sbold = 0;
111 		}
112 		if( xfont == ulfont) {
113 			savulfont = ulfont;
114 			ulfont = 0;
115 		}
116 		xfont = 0;
117 		setfp(0, fontlab[savxfont], 0);
118 		bdtab[0] = bdtab[savxfont];	/* Save */
119 		cstab[0] = cstab[savxfont];	/*  as  */
120 		ccstab[0] = ccstab[savxfont];	/* well */
121 	}
122 	/* End */
123 
124 
125 	bd = 0;
126 	if (i >= nchtab + 128-32) {
127 		j = abscw(i + 32 - (nchtab+128));
128 		goto g0;
129 	}
130 	if (i == 0) {	/* a blank */
131 		k = (fontab[xfont][0] * spacesz + 6) / 12;
132 		/* this nonsense because .ss cmd uses 1/36 em as its units */
133 		/* and default is 12 */
134 		goto g1;
135 	}
136 	if ((j = fitab[xfont][i] & BYTEMASK) == 0) {	/* it's not on current font */
137 		/* search through search list of xfont
138 		/* to see what font it ought to be on.
139 		/* searches S, then remaining fonts in wraparound order.
140 		*/
141 		nocache = 1;
142 		if (smnt) {
143 			int ii, jj;
144 			for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) {
145 				j = fitab[ii][i] & BYTEMASK;
146 				if (j != 0) {
147 					p = fontab[ii];
148 					k = *(p + j);
149 					if (xfont == sbold)
150 						bd = bdtab[ii];
151 					if (setwdf)
152 						numtab[CT].val |= kerntab[ii][j];
153 					goto g1;
154 				}
155 			}
156 		}
157 		k = fontab[xfont][0];	/* leave a space-size space */
158 		goto g1;
159 	}
160  g0:
161 	p = fontab[xfont];
162 	if (setwdf)
163 		numtab[CT].val |= kerntab[xfont][j];
164 	k = *(p + j);
165  g1:
166 	if (!bd)
167 		bd = bdtab[xfont];
168 	if (cs = cstab[xfont]) {
169 		nocache = 1;
170 		if (ccs = ccstab[xfont])
171 			x = ccs;
172 		else
173 			x = xpts;
174 		cs = (cs * EMPTS(x)) / 36;
175 	}
176 	k = ((k&BYTEMASK) * xpts + (Unitwidth / 2)) / Unitwidth;
177 	/*
178 	 * undo the fontswap
179 	 */
180 	if(savxfont) {
181 		xfont = savxfont;
182 		if(savsbold)
183 			sbold = savsbold;
184 		if(savulfont)
185 			ulfont = savulfont;
186 		/*
187 		 * H'm, I guess we should not put
188 		 * this width in the cache
189 		 */
190 		nocache = 1;
191 	}
192 	if (nocache|bd)
193 		widcache[i].fontpts = 0;
194 	else {
195 		widcache[i].fontpts = (xfont<<8) + xpts;
196 		widcache[i].width = k;
197 	}
198 	return(k);
199 	/* Unitwidth is Units/Point, where
200 	/* Units is the fundamental digitization
201 	/* of the character set widths, and
202 	/* Point is the number of goobies in a point
203 	/* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6
204 	/* In effect, it's the size at which the widths
205 	/* translate directly into units.
206 	*/
207 }
208 
abscw(n)209 abscw(n)	/* return index of abs char n in fontab[], etc. */
210 {	register int i, ncf;
211 
212 	ncf = fontbase[xfont]->nwfont & BYTEMASK;
213 	for (i = 0; i < ncf; i++)
214 		if (codetab[xfont][i] == n)
215 			return i;
216 	return 0;
217 }
218 
xbits(i,bitf)219 xbits(i, bitf)
220 register tchar i;
221 {
222 	register k;
223 
224 	xfont = fbits(i);
225 	k = sbits(i);
226 	if (k) {
227 		xpts = pstab[--k];
228 		oldbits = sfbits(i);
229 		pfont = xfont;
230 		ppts = xpts;
231 		return;
232 	}
233 	switch (bitf) {
234 	case 0:
235 		xfont = font;
236 		xpts = pts;
237 		break;
238 	case 1:
239 		xfont = pfont;
240 		xpts = ppts;
241 		break;
242 	case 2:
243 		xfont = mfont;
244 		xpts = mpts;
245 	}
246 }
247 
248 
setch()249 tchar setch()
250 {
251 	register j;
252 	char	temp[10];
253 	register char	*s;
254 	extern char	*chname;
255 	extern short	*chtab;
256 	extern int	nchtab;
257 
258 	s = temp;
259 	if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
260 		return(0);
261 	*s = '\0';
262 	for (j = 0; j < nchtab; j++)
263 		if (strcmp(&chname[chtab[j]], temp) == 0)
264 			return(j + 128 | chbits);
265 	return(0);
266 }
267 
setabs()268 tchar setabs()		/* set absolute char from \C'...' */
269 {
270 	int i, n, nf;
271 	extern int	nchtab;
272 
273 	getch();
274 	n = 0;
275 	n = inumb(&n);
276 	getch();
277 	if (nonumb)
278 		return 0;
279 	return n + nchtab + 128;
280 }
281 /*
282  * I (jaap) expand fontlab to the maximum of fonts troff can
283  * handle. The maximum number i, due to the two chars
284  * fontname limit, is 99.
285  * If we don't use the (named) font in one of the
286  * standard position, we install the name in the next
287  * free slot. Whenever we need info about the font, we
288  * read in the data at position zero, and secretly use
289  * the data (actually only necessary for the width
290  * and ligature info). The ptfont() (t10.c) routine will tell
291  * the device filter to put the font always at position
292  * zero if xfont > physfonts, so no need to change these filters.
293  * Yes, this is a bit kludgy.
294  *
295  * This gives the new specs of findft:
296  *
297  * find the font name i, where i also can be a number.
298  *
299  * Installs the font(name) i when not present
300  *
301  * returns -1 on error
302  */
303 
findft(i)304 findft(i)
305 register int	i;
306 {
307 	register k;
308 	register char *p;
309 	extern char * unpair();
310 
311 	p = unpair(i);
312 
313 	/* first look for numbers */
314 	if( isdigit(p[0]) && (p[1] == 0 || isdigit(p[1]))) {
315 		k = p[0] - '0';
316 		if( p[1] > 0 && isdigit(p[1]))
317 			k = 10 * k + ( p[1] - '0');
318 
319 		/*
320 		fprintf(ptid, "x xxx it's a number: %d\n", k);
321 		*/
322 		if( k > 0 && k <= nfonts && fontbase[k]->specfont == 0 ) {
323 			/*
324 			fprintf(ptid, "x xxx it's a mounted font\n");
325 			*/
326 			return(k);	/* mounted font */
327 		}
328 		if( fontlab[k] && k <= MAXFONTS) {	/* translate */
329 			/*
330 			fprintf(ptid, "x xxx font exists\n");
331 			*/
332 			return(k);			/*number to a name */
333 		}
334 		else {
335 			fprintf(stderr, "troff: no font at position %d\n", k);
336 			return(-1);	/* wild number */
337 		}
338 	}
339 
340 	/*
341 	 * Now we look for font names
342 	 */
343 	for (k = 1; fontlab[k] != i; k++) {
344 		if (k > MAXFONTS +1)	/* the +1 is for the ``font cache'' */
345 			return(-1);	/* running out of fontlab space */
346 		if ( !fontlab[k] ) {	/* passed all existing names */
347 			if (k <= NFONT) {
348 				if(setfp(k, i, 0) < 0)
349 					return(-1);
350 				nfonts = k;
351 			} else
352 				if(setfp(0, i, 0) < 0)
353 					return(-1);
354 			/*
355 			fprintf(ptid, "x xxx installed %s on %d\n", name ,k);
356 			*/
357 				/* now install the name */
358 			fontlab[k] = i;
359 				/*
360 				 * and remember accociated with
361 				 * this font, ligature info etc.
362 				*/
363 			return(k);
364 		}
365 	}
366 	return(k);			/* was one of the existing names */
367 }
368 
369 
caseps()370 caseps()
371 {
372 	register i;
373 
374 	if (skip())
375 		i = apts1;
376 	else {
377 		noscale++;
378 		i = inumb(&apts);	/* this is a disaster for fractional point sizes */
379 		noscale = 0;
380 		if (nonumb)
381 			return;
382 	}
383 	casps1(i);
384 }
385 
386 
casps1(i)387 casps1(i)
388 register int	i;
389 {
390 
391 /*
392  * in olden times, it used to ignore changes to 0 or negative.
393  * this is meant to allow the requested size to be anything,
394  * in particular so eqn can generate lots of \s-3's and still
395  * get back by matching \s+3's.
396 
397 	if (i <= 0)
398 		return;
399 */
400 	apts1 = apts;
401 	apts = i;
402 	pts1 = pts;
403 	pts = findps(i);
404 	mchbits();
405 }
406 
407 
findps(i)408 findps(i)
409 register int	i;
410 {
411 	register j, k;
412 
413 	for (j=k=0 ; pstab[j] != 0 ; j++)
414 		if (abs(pstab[j]-i) < abs(pstab[k]-i))
415 			k = j;
416 
417 	return(pstab[k]);
418 }
419 
420 
mchbits()421 mchbits()
422 {
423 	register i, j, k;
424 
425 	i = pts;
426 	for (j = 0; i > (k = pstab[j]); j++)
427 		if (!k) {
428 			k = pstab[--j];
429 			break;
430 		}
431 	chbits = 0;
432 	setsbits(chbits, ++j);
433 	setfbits(chbits, font);
434 	sps = width(' ' | chbits);
435 	zapwcache(1);
436 }
437 
setps()438 setps()
439 {
440 	register int i, j;
441 
442 	i = cbits(getch());
443 	if (isdigit(i)) {		/* \sd or \sdd */
444 		i -= '0';
445 		if (i == 0)		/* \s0 */
446 			j = apts1;
447 		else if (i <= 3 && isdigit(j = cbits(ch=getch()))) {	/* \sdd */
448 			j = 10 * i + j - '0';
449 			ch = 0;
450 		} else		/* \sd */
451 			j = i;
452 	} else if (i == '(') {		/* \s(dd */
453 		j = cbits(getch()) - '0';
454 		j = 10 * j + cbits(getch()) - '0';
455 		if (j == 0)		/* \s(00 */
456 			j = apts1;
457 	} else if (i == '+' || i == '-') {	/* \s+, \s- */
458 		j = cbits(getch());
459 		if (isdigit(j)) {		/* \s+d, \s-d */
460 			j -= '0';
461 		} else if (j == '(') {		/* \s+(dd, \s-(dd */
462 			j = cbits(getch()) - '0';
463 			j = 10 * j + cbits(getch()) - '0';
464 		}
465 		if (i == '-')
466 			j = -j;
467 		j += apts;
468 	}
469 	casps1(j);
470 }
471 
472 
setht()473 tchar setht()		/* set character height from \H'...' */
474 {
475 	int n;
476 	tchar c;
477 
478 	getch();
479 	n = inumb(&apts);
480 	getch();
481 	if (n == 0 || nonumb)
482 		n = apts;	/* does this work? */
483 	c = CHARHT;
484 	c |= ZBIT;
485 	setsbits(c, n);
486 	return(c);
487 }
488 
setslant()489 tchar setslant()		/* set slant from \S'...' */
490 {
491 	int n;
492 	tchar c;
493 
494 	getch();
495 	n = 0;
496 	n = inumb(&n);
497 	getch();
498 	if (nonumb)
499 		n = 0;
500 	c = SLANT;
501 	c |= ZBIT;
502 	setsfbits(c, n+180);
503 	return(c);
504 }
505 
506 
casest()507 casest()
508 {
509 	register i, j;
510 	register char last;
511 
512 	skip();
513 	i = getrq();
514 	if (!i || i == 'P') {
515 	    stip = stip1;
516 	    return;
517 	}
518 	if (i == '0')
519 	    goto sterr;
520 
521 	last = cbits(i) >> BYTE;
522 	if ((j = (i & BYTEMASK) - '0') >= 0 && j <= 9) {/* digit - see if two */
523 	    if (last)
524 		if ((last -= '0') < 0 || last > 9)
525 		    goto sterr;
526 	    if (j > nstips)
527 		goto sterr;
528 	} else {					/* stipple name */
529 	    for (j = 0; stiplab[j] != i; j++)
530 		if (j > nstips)
531 		    goto sterr;
532 	}
533 	stip1 = stip;
534 	stip = j;
535 	return;
536 sterr:
537 	fprintf(stderr, "troff: Can't find stipple %c%c\n", i & BYTEMASK, last);
538 }
539 
540 
caseft()541 caseft()
542 {
543 	skip();
544 	setfont(1);
545 }
546 
547 
setfont(a)548 setfont(a)
549 int	a;
550 {
551 	register i, j;
552 
553 	if (a)
554 		i = getrq();
555 	else
556 		i = getsn();
557 	if (!i || i == 'P') {
558 		j = font1;
559 		goto s0;
560 	}
561 	if (i == 'S' || i == '0')
562 		return;
563 	if ((j = findft(i)) == -1)
564 #ifdef notdef
565 		/* findft does the setfp if possible */
566 		if ((j = setfp(0, i, 0)) == -1)	/* try to put it in position 0 */
567 #endif
568 			return;
569 s0:
570 	font1 = font;
571 	font = j;
572 	mchbits();
573 }
574 
575 
setwd()576 setwd()
577 {
578 	register base, wid;
579 	register tchar i;
580 	int	delim, emsz, k;
581 	int	savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
582 
583 	base = numtab[ST].val = numtab[ST].val = wid = numtab[CT].val = 0;
584 	if (ismot(i = getch()))
585 		return;
586 	delim = cbits(i);
587 	savhp = numtab[HP].val;
588 	numtab[HP].val = 0;
589 	savapts = apts;
590 	savapts1 = apts1;
591 	savfont = font;
592 	savfont1 = font1;
593 	savpts = pts;
594 	savpts1 = pts1;
595 	setwdf++;
596 	while (cbits(i = getch()) != delim && !nlflg) {
597 		k = width(i);
598 		wid += k;
599 		numtab[HP].val += k;
600 		if (!ismot(i)) {
601 			emsz = POINT * xpts;
602 		} else if (isvmot(i)) {
603 			k = absmot(i);
604 			if (isnmot(i))
605 				k = -k;
606 			base -= k;
607 			emsz = 0;
608 		} else
609 			continue;
610 		if (base < numtab[SB].val)
611 			numtab[SB].val = base;
612 		if ((k = base + emsz) > numtab[ST].val)
613 			numtab[ST].val = k;
614 	}
615 	setn1(wid, 0, (tchar) 0);
616 	numtab[HP].val = savhp;
617 	apts = savapts;
618 	apts1 = savapts1;
619 	font = savfont;
620 	font1 = savfont1;
621 	pts = savpts;
622 	pts1 = savpts1;
623 	mchbits();
624 	setwdf = 0;
625 }
626 
627 
vmot()628 tchar vmot()
629 {
630 	dfact = lss;
631 	vflag++;
632 	return(mot());
633 }
634 
635 
hmot()636 tchar hmot()
637 {
638 	dfact = EM;
639 	return(mot());
640 }
641 
642 
mot()643 tchar mot()
644 {
645 	register int j, n;
646 	register tchar i;
647 
648 	j = HOR;
649 	getch(); /*eat delim*/
650 	if (n = atoi()) {
651 		if (vflag)
652 			j = VERT;
653 		i = makem(quant(n, j));
654 	} else
655 		i = 0;
656 	getch();
657 	vflag = 0;
658 	dfact = 1;
659 	return(i);
660 }
661 
662 
sethl(k)663 tchar sethl(k)
664 int	k;
665 {
666 	register j;
667 	tchar i;
668 
669 	j = EM / 2;
670 	if (k == 'u')
671 		j = -j;
672 	else if (k == 'r')
673 		j = -2 * j;
674 	vflag++;
675 	i = makem(j);
676 	vflag = 0;
677 	return(i);
678 }
679 
680 
makem(i)681 tchar makem(i)
682 register int	i;
683 {
684 	register tchar j;
685 
686 	if ((j = i) < 0)
687 		j = -j;
688 	j |= MOT;
689 	if (i < 0)
690 		j |= NMOT;
691 	if (vflag)
692 		j |= VMOT;
693 	return(j);
694 }
695 
696 
getlg(i)697 tchar getlg(i)
698 tchar i;
699 {
700 	tchar j, k;
701 	register int lf;
702 
703 		/* remember to map the font */
704 	if ((lf = fontbase[fbits(i) > nfonts ? 0 : fbits(i)]->ligfont) == 0) {
705 		/* font lacks ligatures */
706 		return(i);
707 	}
708 	j = getch0();
709 	if (cbits(j) == 'i' && (lf & LFI))
710 		j = LIG_FI;
711 	else if (cbits(j) == 'l' && (lf & LFL))
712 		j = LIG_FL;
713 	else if (cbits(j) == 'f' && (lf & LFF)) {
714 		if ((lf & (LFFI|LFFL)) && lg != 2) {
715 			k = getch0();
716 			if (cbits(k)=='i' && (lf&LFFI))
717 				j = LIG_FFI;
718 			else if (cbits(k)=='l' && (lf&LFFL))
719 				j = LIG_FFL;
720 			else {
721 				*pbp++ = k;
722 				j = LIG_FF;
723 			}
724 		} else
725 			j = LIG_FF;
726 	} else {
727 		*pbp++ = j;
728 		j = i;
729 	}
730 	return(i & SFMASK | j);
731 }
732 
733 
caselg()734 caselg()
735 {
736 
737 	lg = 1;
738 	if (skip())
739 		return;
740 	lg = atoi();
741 }
742 
743 
casefp()744 casefp()
745 {
746 	register int i, j;
747 	register char *s;
748 
749 	skip();
750 	/* allow .fp for fonts >nfonts, <NFONTS? */
751 	if ((i = cbits(getch()) - '0') <= 0 || i > nfonts)
752 		errprint("fp: bad font position %d", i);
753 	else if (skip() || !(j = getrq()))
754 		errprint("fp: no font name");
755 	else if (skip() || !getname())
756 		setfp(i, j, 0);
757 	else		/* 3rd argument = filename */
758 		setfp(i, j, nextf);
759 }
760 
setfp(pos,f,truename)761 setfp(pos, f, truename)	/* mount font f at position pos[0...NFONTS] */
762 register pos;
763 int f;
764 char *truename;
765 {
766 	register k;
767 	register struct Font *ft;
768 	int n;
769 	char longname[NS], shortname[20];
770 	extern int nchtab;
771 	extern struct dev dev;
772 
773 	if (fontlab[pos] == f)		/* if f already mounted at pos, */
774 		return(pos);		/* don't remount it */
775 	zapwcache(0);
776 	if (truename)
777 		strcpy(shortname, truename);
778 	else {
779 		shortname[0] = f & BYTEMASK;
780 		shortname[1] = f >> BYTE;
781 		shortname[2] = '\0';
782 	}
783 	sprintf(longname, "%s/dev%s/%s.out", fontfile, devname, shortname);
784 	if ((k = open(longname, 0)) < 0) {
785 		errprint("Can't open %s", longname);
786 		return(-1);
787 	}
788 	if ((ft = fontbase[pos]) == 0) {
789 		ft = fontbase[pos] = (struct Font *) malloc(EXTRAFONT);
790 		ft->nwfont = MAXCHARS;
791 		fontab[pos] = (char *)(ft + 1);
792 	}
793 	n = ft->nwfont;
794 	read(k, (char *) ft, 3*n + nchtab + 128 - 32 + sizeof(struct Font));
795 	close(k);
796 
797 	k = ft->nwfont;
798 	kerntab[pos] = (char *) fontab[pos] + k;
799 	codetab[pos] = (char *) fontab[pos] + 2 * k;
800 	/* have to reset the fitab pointer because the width may be different */
801 	fitab[pos] = (char *) fontab[pos] + 3 * k;
802 	ft->nwfont = n;	/* so can load a larger one again later */
803 	if (k > n) {
804 		errprint("Font %s too big for position %d", shortname, pos);
805 		return(-1);
806 	}
807 	if (pos == smnt) {
808 		smnt = 0;
809 		sbold = 0;
810 	}
811 	if ((fontlab[pos] = f) == 'S')
812 		smnt = pos;
813 	bdtab[pos] = cstab[pos] = ccstab[pos] = 0;
814 		/* if there is a directory, no place to store its name. */
815 		/* if position isn't zero, no place to store its value. */
816 		/* only time a FONTPOS is pushed back is if it's a */
817 		/* standard font on position 0 (i.e., mounted implicitly. */
818 		/* there's a bug here:  if there are several input lines */
819 		/* that look like .ft XX in short successtion, the output */
820 		/* will all be in the last one because the "x font ..." */
821 		/* comes out too soon.  pushing back FONTPOS doesn't work */
822 		/* with .ft commands because input is flushed after .xx cmds */
823 
824 		/*
825 		 * Trying to fix this FONTPOS problem: See findft()
826 		 */
827 	if ( pos > 0 && pos <= physfonts)
828 		ptfpcmd(pos, shortname);
829 	return(pos);
830 }
831 
832 
casecs()833 casecs()
834 {
835 	register i, j;
836 
837 	noscale++;
838 	skip();
839 	if (!(i = getrq()) || (i = findft(i)) < 0)
840 		goto rtn;
841 	skip();
842 	cstab[i] = atoi();
843 	skip();
844 	j = atoi();
845 	if (nonumb)
846 		ccstab[i] = 0;
847 	else
848 		ccstab[i] = findps(j);
849 rtn:
850 	zapwcache(0);
851 	noscale = 0;
852 }
853 
854 
casebd()855 casebd()
856 {
857 	register i, j, k;
858 
859 	zapwcache(0);
860 	k = 0;
861 bd0:
862 	if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
863 		if (k)
864 			goto bd1;
865 		else
866 			return;
867 	}
868 	if (j == smnt) {
869 		k = smnt;
870 		goto bd0;
871 	}
872 	if (k) {
873 		sbold = j;
874 		j = k;
875 	}
876 bd1:
877 	skip();
878 	noscale++;
879 	bdtab[j] = atoi();
880 	noscale = 0;
881 }
882 
883 
casevs()884 casevs()
885 {
886 	register i;
887 
888 	skip();
889 	vflag++;
890 	dfact = INCH; /* default scaling is points! */
891 	dfactd = 72;
892 	res = VERT;
893 	i = inumb(&lss);
894 	if (nonumb)
895 		i = lss1;
896 	/*	if(i < VERT)i = VERT; */
897 	if (i < VERT)
898 		i = 0;
899 	lss1 = lss;
900 	lss = i;
901 }
902 
903 
casess()904 casess()
905 {
906 	register i;
907 
908 	noscale++;
909 	skip();
910 	if (i = atoi()) {
911 		spacesz = i & 0177;
912 		zapwcache(0);
913 		sps = width(' ' | chbits);
914 	}
915 	noscale = 0;
916 }
917 
918 
xlss()919 tchar xlss()
920 {
921 	/* stores \x'...' into
922 	/* two successive tchars.
923 	/* the first contains HX, the second the value,
924 	/* encoded as a vertical motion.
925 	/* decoding is done in n2.c by pchar().
926 	*/
927 	int	i;
928 
929 	getch();
930 	dfact = lss;
931 	i = quant(atoi(), VERT);
932 	dfact = 1;
933 	getch();
934 	if (i >= 0)
935 		*pbp++ = MOT | VMOT | i;
936 	else
937 		*pbp++ = MOT | VMOT | NMOT | -i;
938 	return(HX);
939 }
940 
941 char *
unpair(i)942 unpair(i)
943 register int i;
944 {	static char name[3];
945 
946 	name[0] = i & BYTEMASK;
947 	name[1] = i >> BYTE;
948 	name[2] = 0;
949 	return (name);
950 }
951