URI:
       tt6.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tt6.c (15492B)
       ---
            1 /*
            2  * t6.c
            3  *
            4  * width functions, sizes and fonts
            5  */
            6 
            7 #include "tdef.h"
            8 #include "fns.h"
            9 #include "ext.h"
           10 
           11 int        fontlab[MAXFONTS+1];
           12 int        cstab[MAXFONTS+1];
           13 int        ccstab[MAXFONTS+1];
           14 int        bdtab[MAXFONTS+1];
           15 int        sbold = 0;
           16 
           17 int
           18 t_width(Tchar j)
           19 {
           20         int i, k;
           21 
           22         if (iszbit(j))
           23                 return 0;
           24         if (ismot(j)) {
           25                 if (isvmot(j))
           26                         return(0);
           27                 k = absmot(j);
           28                 if (isnmot(j))
           29                         k = -k;
           30                 return(k);
           31         }
           32         i = cbits(j);
           33         if (i < ' ') {
           34                 if (i == '\b')
           35                         return(-widthp);
           36                 if (i == PRESC)
           37                         i = eschar;
           38                 else if (i == HX)
           39                         return(0);
           40         }
           41         if (i == ohc)
           42                 return(0);
           43         i = trtab[i];
           44         if (i < ' ')
           45                 return(0);
           46         if (sfbits(j) == oldbits) {
           47                 xfont = pfont;
           48                 xpts = ppts;
           49         } else
           50                 xbits(j, 0);
           51         if (i < nchnames + ALPHABET && widcache[i].fontpts == (xfont<<8) + xpts && !setwdf)
           52                 k = widcache[i].width;
           53         else {
           54                 k = getcw(i);
           55                 if (bd)
           56                         k += (bd - 1) * HOR;
           57                 if (cs)
           58                         k = cs;
           59         }
           60         widthp = k;
           61         return(k);
           62 }
           63 
           64 /*
           65  * clear width cache-- s means just space
           66  */
           67 void zapwcache(int s)
           68 {
           69         int i;
           70 
           71         if (s) {
           72                 widcache[' '].fontpts = 0;
           73                 return;
           74         }
           75         for (i=0; i<NWIDCACHE; i++)
           76                 widcache[i].fontpts = 0;
           77 }
           78 
           79 int
           80 onfont(int n, int f)        /* is char n on font f? */
           81 {
           82         int i;
           83         Font *fp = &fonts[f];
           84         Chwid *cp, *ep;
           85         char *np;
           86 
           87         if (n < ALPHABET) {
           88                 if (fp->wp[n].num == n)        /* ascii at front */
           89                         return n;
           90                 else
           91                         return -1;
           92         }
           93         cp = &fp->wp[ALPHABET];
           94         ep = &fp->wp[fp->nchars];
           95         for ( ; cp < ep; cp++)        /* search others */
           96                 if (cp->num == n)
           97                         return cp - &fp->wp[0];
           98         /* maybe it was a \N... */
           99         np = chname(n);
          100         if (*np == Number) {
          101                 i = atoi(np+1);                /* sscanf(np+1, "%d", &i); */
          102                 cp = &fp->wp[0];
          103                 ep = &fp->wp[fp->nchars];
          104                 for ( ; cp < ep; cp++) {        /* search others */
          105                         if (cp->code == i)
          106                                 return cp - &fp->wp[0];
          107                 }
          108                 return -2;        /* a \N that doesn't have an entry */
          109         }
          110         return -1;        /* vanilla not found */
          111 }
          112 
          113 int
          114 getcw(int i)
          115 {
          116         int k, n, x;
          117         Font *fp;
          118         int nocache = 0;
          119         if (i < ' ')
          120                 return 0;
          121         bd = 0;
          122         fp = &fonts[xfont];
          123         if (i == ' ') {        /* a blank */
          124                 k = (fp->spacewidth * spacesz + 6) / 12;
          125                 /* this nonsense because .ss cmd uses 1/36 em as its units */
          126                 /*         and default is 12 */
          127         } else if ((n = onfont(i, xfont)) >= 0) {        /* on this font at n */
          128                 k = fp->wp[n].wid;
          129                 if (setwdf)
          130                         numtabp[CT].val |= fp->wp[n].kern;
          131         } else if (n == -2) {                /* \N with default width */
          132 
          133                 k = fp->defaultwidth;
          134         } else {                        /* not on current font */
          135                 nocache = 1;
          136                 k = fp->defaultwidth;        /* default-size space */
          137                 if (smnt) {
          138                         int ii, jj;
          139                         for (ii=smnt, jj=0; jj < nfonts; jj++, ii=ii % nfonts + 1) {
          140                                 if ((n = onfont(i, ii)) >= 0) {
          141                                         k = fonts[ii].wp[n].wid;
          142                                         if (xfont == sbold)
          143                                                 bd = bdtab[ii];
          144                                         if (setwdf)
          145                                                 numtabp[CT].val |= fonts[ii].wp[n].kern;
          146                                         break;
          147                                 }
          148                         }
          149                 }
          150         }
          151         if (!bd)
          152                 bd = bdtab[xfont];
          153         if (cs = cstab[xfont]) {
          154                 nocache = 1;
          155                 if (ccs = ccstab[xfont])
          156                         x = ccs;
          157                 else
          158                         x = xpts;
          159                 cs = (cs * EMPTS(x)) / 36;
          160         }
          161         /* was (k & BYTEMASK);  since .wid is unsigned, should never happen */
          162         if (k < 0)
          163                 ERROR "can't happen: negative width %d in getcw %d\n", k, i WARN;
          164         k = (k * xpts + (Unitwidth / 2)) / Unitwidth;
          165         if (nocache|bd)
          166                 widcache[i].fontpts = 0;
          167         else {
          168                 widcache[i].fontpts = (xfont<<8) + xpts;
          169                 widcache[i].width = k;
          170         }
          171         return(k);
          172         /* Unitwidth is Units/Point, where
          173         /* Units is the fundamental digitization
          174         /* of the character set widths, and
          175         /* Point is the number of goobies in a point
          176         /* e.g., for cat, Units=36, Point=6, so Unitwidth=36/6=6
          177         /* In effect, it's the size at which the widths
          178         /* translate directly into units.
          179         */
          180 }
          181 
          182 void xbits(Tchar i, int bitf)
          183 {
          184         int k;
          185 
          186         if(TROFF) {
          187                 xfont = fbits(i);
          188                 k = sbits(i);
          189                 if(k) {
          190                         xpts = pstab[k-1];
          191                         oldbits = sfbits(i);
          192                         pfont = xfont;
          193                         ppts = xpts;
          194                         return;
          195                 }
          196                 switch(bitf) {
          197                 case 0:
          198                         xfont = font;
          199                         xpts = pts;
          200                         break;
          201                 case 1:
          202                         xfont = pfont;
          203                         xpts = ppts;
          204                         break;
          205                 case 2:
          206                         xfont = mfont;
          207                         xpts = mpts;
          208                 }
          209         }
          210 }
          211 
          212 
          213 /* these next two functions ought to be the same in troff and nroff, */
          214 /* but the data structures they search are different. */
          215 /* silly historical problem. */
          216 
          217 
          218 Tchar t_setch(int c)
          219 {
          220 #ifndef UNICODE
          221         int j;
          222 #endif
          223         char temp[50];
          224         char *s;
          225 
          226 #ifndef UNICODE
          227         j = 0;
          228 #endif
          229         s = temp;
          230         if (c == '(') {        /* \(xx */
          231                 if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
          232                         return(0);
          233         } else {        /* \C'...' */
          234                 c = getach();
          235                 while ((*s = getach()) != c && *s != 0 && s < temp + sizeof(temp) - 1)
          236                         s++;
          237         }
          238         *s = '\0';
          239 #ifdef UNICODE
          240         return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
          241 #else
          242         if (NROFF) {
          243                 j = chadd(temp, Troffchar, Lookup);
          244                 if ( j == -1)
          245                         return 0;
          246                 else
          247                         return j | chbits;
          248         } else
          249                 return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
          250 
          251 #endif /*UNICODE*/
          252 }
          253 
          254 Tchar t_setabs(void)                /* set absolute char from \N'...' */
          255 {
          256         int n;
          257         char temp[10];
          258 
          259         getch();        /* delim */
          260         n = 0;
          261         n = inumb(&n);
          262         getch();        /* delim */
          263         if (nonumb)
          264                 return 0;
          265         sprintf(temp, "%d", n);        /* convert into "#n" */
          266         n = chadd(temp, Number, Install);
          267         return n | chbits;
          268 }
          269 
          270 
          271 /*
          272  * fontlab[] is a cache that contains font information
          273  * for each font.
          274  * fontlab[] contains the 1- or 2-character name of the
          275  * font current associated with that font.
          276  * fonts 1..nfonts correspond to the mounted fonts;
          277  * the last of these are the special fonts.
          278  * If we don't use the (named) font in one of the
          279  * standard positions, we install the name in the next
          280  * free slot of fontlab[] and font[].
          281  * Whenever we need info about the font, we
          282  * read in the data into the next free slot with getfont.
          283  * The ptfont() (t10.c) routine will tell
          284  * the device filter to put the font always at position
          285  * zero if xfont > nfonts, so no need to change these filters.
          286  * Yes, this is a bit kludgy.
          287  *
          288  * This gives the new specs of findft:
          289  *         find the font name i, where i also can be a number.
          290  *         Installs the font(name) i when not present
          291  *         returns -1 on error
          292  */
          293 
          294 int
          295 t_findft(int i)
          296 {
          297         int k;
          298         Uchar *p;
          299 
          300         p = unpair(i);
          301 
          302         if (isdigit(p[0])) {                /* first look for numbers */
          303                 k = p[0] - '0';
          304                 if (p[1] > 0 && isdigit(p[1]))
          305                         k = 10 * k + p[1] - '0';
          306                 if (k > 0 && k <= nfonts && k < smnt)
          307                         return(k);        /* mounted font:  .ft 3 */
          308                 if (fontlab[k] && k <= MAXFONTS) {        /* translate */
          309                         return(k);                        /*number to a name */
          310                 } else {
          311                         fprintf(stderr, "troff: no font at position %d\n", k);
          312                         return(-1);        /* wild number */
          313                 }
          314         }
          315 
          316         /*
          317          * Now we look for font names
          318          */
          319         for (k = 1; fontlab[k] != i; k++) {
          320                 if (k > MAXFONTS)
          321                         return(-1);        /* running out of fontlab space */
          322                 if (fontlab[k] == 0) {        /* passed all existing names */
          323                         if (setfp(k, i, (char *) 0, 1) == -1)
          324                                 return(-1);
          325                         else {
          326                                 fontlab[k] = i;        /* install the name */
          327                                 return(k);
          328                         }
          329                 }
          330         }
          331         return(k);                        /* was one of the existing names */
          332 }
          333 
          334 
          335 void caseps(void)
          336 {
          337         int i;
          338 
          339         if (TROFF) {
          340                 if(skip())
          341                         i = apts1;
          342                 else {
          343                         noscale++;
          344                         i = inumb(&apts);        /* this is a disaster for fractional point sizes */
          345                         noscale = 0;
          346                         if(nonumb)
          347                                 i = apts1;
          348                 }
          349                 casps1(i);
          350         }
          351 }
          352 
          353 
          354 void casps1(int i)
          355 {
          356 
          357 /*
          358  * in olden times, it used to ignore changes to 0 or negative.
          359  * this is meant to allow the requested size to be anything,
          360  * in particular so eqn can generate lots of \s-3's and still
          361  * get back by matching \s+3's.
          362 
          363         if (i <= 0)
          364                 return;
          365 */
          366         apts1 = apts;
          367         apts = i;
          368         pts1 = pts;
          369         pts = findps(i);
          370         mchbits();
          371 }
          372 
          373 int
          374 findps(int i)
          375 {
          376         int j, k;
          377 
          378         for (j=k=0 ; pstab[j] != 0 ; j++)
          379                 if (abs(pstab[j]-i) < abs(pstab[k]-i))
          380                         k = j;
          381 
          382         return(pstab[k]);
          383 }
          384 
          385 
          386 void t_mchbits(void)
          387 {
          388         int i, j, k;
          389 
          390         i = pts;
          391         for (j = 0; i > (k = pstab[j]); j++)
          392                 if (!k) {
          393                         j--;
          394                         break;
          395                 }
          396         chbits = 0;
          397         setsbits(chbits, ++j);
          398         setfbits(chbits, font);
          399         sps = width(' ' | chbits);
          400         zapwcache(1);
          401 }
          402 
          403 void t_setps(void)
          404 {
          405         int i, j;
          406 
          407         j = 0;
          408         i = cbits(getch());
          409         if (isdigit(i)) {                /* \sd or \sdd */
          410                 i -= '0';
          411                 if (i == 0)                /* \s0 */
          412                         j = apts1;
          413                 else if (i <= 3 && (ch=getch()) && isdigit(j = cbits(ch))) {        /* \sdd */
          414                         j = 10 * i + j - '0';
          415                         ch = 0;
          416                 } else                /* \sd */
          417                         j = i;
          418         } else if (i == '(') {                /* \s(dd */
          419                 j = cbits(getch()) - '0';
          420                 j = 10 * j + cbits(getch()) - '0';
          421                 if (j == 0)                /* \s(00 */
          422                         j = apts1;
          423         } else if (i == '+' || i == '-') {        /* \s+, \s- */
          424                 j = cbits(getch());
          425                 if (isdigit(j)) {                /* \s+d, \s-d */
          426                         j -= '0';
          427                 } else if (j == '(') {                /* \s+(dd, \s-(dd */
          428                         j = cbits(getch()) - '0';
          429                         j = 10 * j + cbits(getch()) - '0';
          430                 }
          431                 if (i == '-')
          432                         j = -j;
          433                 j += apts;
          434         }
          435         casps1(j);
          436 }
          437 
          438 
          439 Tchar t_setht(void)                /* set character height from \H'...' */
          440 {
          441         int n;
          442         Tchar c;
          443 
          444         getch();
          445         n = inumb(&apts);
          446         getch();
          447         if (n == 0 || nonumb)
          448                 n = apts;        /* does this work? */
          449         c = CHARHT;
          450         c |= ZBIT;
          451         setsbits(c, n);
          452         setfbits(c, pts);        /* sneaky, CHARHT font bits are size bits */
          453         return(c);
          454 }
          455 
          456 Tchar t_setslant(void)                /* set slant from \S'...' */
          457 {
          458         int n;
          459         Tchar c;
          460 
          461         getch();
          462         n = 0;
          463         n = inumb(&n);
          464         getch();
          465         if (nonumb)
          466                 n = 0;
          467         c = SLANT;
          468         c |= ZBIT;
          469         setsfbits(c, n+180);
          470         return(c);
          471 }
          472 
          473 
          474 void caseft(void)
          475 {
          476         if (!TROFF) {
          477                 n_caseft();
          478                 return;
          479         }
          480         skip();
          481         setfont(1);
          482 }
          483 
          484 
          485 void t_setfont(int a)
          486 {
          487         int i, j;
          488 
          489         if (a)
          490                 i = getrq();
          491         else
          492                 i = getsn();
          493         if (!i || i == 'P') {
          494                 j = font1;
          495                 goto s0;
          496         }
          497         if (/* i == 'S' || */ i == '0')        /* an experiment -- why can't we change to it? */
          498                 return;
          499         if ((j = findft(i)) == -1)
          500                 if ((j = setfp(0, i, (char*) 0, 1)) == -1)        /* try to put it in position 0 */
          501                         return;
          502 s0:
          503         font1 = font;
          504         font = j;
          505         mchbits();
          506 }
          507 
          508 
          509 void t_setwd(void)
          510 {
          511         int base, wid;
          512         Tchar i;
          513         int delim, emsz, k;
          514         int savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
          515 
          516         base = numtabp[ST].val = numtabp[SB].val = wid = numtabp[CT].val = 0;
          517         if (ismot(i = getch()))
          518                 return;
          519         delim = cbits(i);
          520         savhp = numtabp[HP].val;
          521         numtabp[HP].val = 0;
          522         savapts = apts;
          523         savapts1 = apts1;
          524         savfont = font;
          525         savfont1 = font1;
          526         savpts = pts;
          527         savpts1 = pts1;
          528         setwdf++;
          529         while (cbits(i = getch()) != delim && !nlflg) {
          530                 k = width(i);
          531                 wid += k;
          532                 numtabp[HP].val += k;
          533                 if (!ismot(i)) {
          534                         emsz = (INCH/72) * xpts;
          535                 } else if (isvmot(i)) {
          536                         k = absmot(i);
          537                         if (isnmot(i))
          538                                 k = -k;
          539                         base -= k;
          540                         emsz = 0;
          541                 } else
          542                         continue;
          543                 if (base < numtabp[SB].val)
          544                         numtabp[SB].val = base;
          545                 if ((k = base + emsz) > numtabp[ST].val)
          546                         numtabp[ST].val = k;
          547         }
          548         setn1(wid, 0, (Tchar) 0);
          549         numtabp[HP].val = savhp;
          550         apts = savapts;
          551         apts1 = savapts1;
          552         font = savfont;
          553         font1 = savfont1;
          554         pts = savpts;
          555         pts1 = savpts1;
          556         mchbits();
          557         setwdf = 0;
          558 }
          559 
          560 
          561 Tchar t_vmot(void)
          562 {
          563         dfact = lss;
          564         vflag++;
          565         return t_mot();
          566 }
          567 
          568 
          569 Tchar t_hmot(void)
          570 {
          571         dfact = EM;
          572         return t_mot();
          573 }
          574 
          575 
          576 Tchar t_mot(void)
          577 {
          578         int j, n;
          579         Tchar i;
          580 
          581         j = HOR;
          582         getch(); /*eat delim*/
          583         if (n = atoi0()) {
          584                 if (vflag)
          585                         j = VERT;
          586                 i = makem(quant(n, j));
          587         } else
          588                 i = 0;
          589         getch();
          590         vflag = 0;
          591         dfact = 1;
          592         return(i);
          593 }
          594 
          595 
          596 Tchar t_sethl(int k)
          597 {
          598         int j;
          599         Tchar i;
          600 
          601         j = EM / 2;
          602         if (k == 'u')
          603                 j = -j;
          604         else if (k == 'r')
          605                 j = -2 * j;
          606         vflag++;
          607         i = makem(j);
          608         vflag = 0;
          609         return(i);
          610 }
          611 
          612 
          613 Tchar t_makem(int i)
          614 {
          615         Tchar j;
          616 
          617         if (i >= 0)
          618                 j = i;
          619         else
          620                 j = -i;
          621         if (Hor > 1 && !vflag)
          622                 j = (j + Hor/2)/Hor * Hor;
          623         j |= MOT;
          624         if (i < 0)
          625                 j |= NMOT;
          626         if (vflag)
          627                 j |= VMOT;
          628         return(j);
          629 }
          630 
          631 
          632 Tchar getlg(Tchar i)
          633 {
          634         Tchar j, k;
          635         int lf;
          636 
          637         if (!TROFF)
          638                 return i;
          639         if ((lf = fonts[fbits(i)].ligfont) == 0) /* font lacks ligatures */
          640                 return(i);
          641         j = getch0();
          642         if (cbits(j) == 'i' && (lf & LFI))
          643                 j = LIG_FI;
          644         else if (cbits(j) == 'l' && (lf & LFL))
          645                 j = LIG_FL;
          646         else if (cbits(j) == 'f' && (lf & LFF)) {
          647                 if ((lf & (LFFI|LFFL)) && lg != 2) {
          648                         k = getch0();
          649                         if (cbits(k)=='i' && (lf&LFFI))
          650                                 j = LIG_FFI;
          651                         else if (cbits(k)=='l' && (lf&LFFL))
          652                                 j = LIG_FFL;
          653                         else {
          654                                 *pbp++ = k;
          655                                 j = LIG_FF;
          656                         }
          657                 } else
          658                         j = LIG_FF;
          659         } else {
          660                 *pbp++ = j;
          661                 j = i;
          662         }
          663         return(i & SFMASK | j);
          664 }
          665 
          666 
          667 void caselg(void)
          668 {
          669 
          670         if(TROFF) {
          671                 skip();
          672                 lg = atoi0();
          673                 if (nonumb)
          674                         lg = 1;
          675         }
          676 }
          677 
          678 void casefp(void)
          679 {
          680         int i, j;
          681 
          682         if (!TROFF) {
          683                 n_casefp();
          684                 return;
          685         }
          686         skip();
          687         i = cbits(getch());
          688         if (isdigit(i)) {
          689                 i -= '0';
          690                 j = cbits(getch());
          691                 if (isdigit(j))
          692                         i = 10 * i + j - '0';
          693         }
          694         if (i <= 0 || i > nfonts)
          695                 ERROR "fp: bad font position %d", i WARN;
          696         else if (skip() || !(j = getrq()))
          697                 ERROR "fp: no font name" WARN;
          698         else if (skip() || !getname())
          699                 setfp(i, j, (char*) 0, 1);
          700         else                /* 3rd argument = filename */
          701                 setfp(i, j, nextf, 1);
          702 }
          703 
          704 char *strdupl(const char *s)        /* make a copy of s */
          705 {
          706         char *t;
          707 
          708         t = (char *) malloc(strlen(s) + 1);
          709         if (t == NULL)
          710                 ERROR "out of space in strdupl(%s)", s FATAL;
          711         strcpy(t, s);
          712         return t;
          713 }
          714 
          715 int
          716 setfp(int pos, int f, char *truename, int print)        /* mount font f at position pos[0...nfonts] */
          717 {
          718         char pathname[NS], shortname[NS];
          719 
          720         zapwcache(0);
          721         if (truename)
          722                 strcpy(shortname, truename);
          723         else
          724                 strcpy(shortname, (char *) unpair(f));
          725         if (truename && strrchr(truename, '/')) {        /* .fp 1 R dir/file: use verbatim */
          726                 snprintf(pathname, NS, "%s", truename);
          727                 if (fonts[pos].truename)
          728                         free(fonts[pos].truename);
          729                 fonts[pos].truename = strdupl(truename);
          730         } else if (truename) {                        /* synonym: .fp 1 R Avant */
          731                 snprintf(pathname, NS, "%s/dev%s/%s", fontdir, devname, truename);
          732                 truename = 0;        /* so doesn't get repeated by ptfpcmd */
          733         } else                                        /* vanilla: .fp 5 XX */
          734                 snprintf(pathname, NS, "%s/dev%s/%s", fontdir, devname, shortname);
          735         if (truename == 0 && fonts[pos].truename != 0) {
          736                 free(fonts[pos].truename);
          737                 fonts[pos].truename = 0;
          738         }
          739         if (getfont(pathname, pos) < 0) {
          740                 ERROR "Can't open font file %s", pathname WARN;
          741                 return -1;
          742         }
          743         if (print && !ascii) {
          744                 ptfpcmd(pos, fonts[pos].longname, truename);
          745                 ptfont();
          746         }
          747         if (pos == smnt) {
          748                 smnt = 0;
          749                 sbold = 0;
          750         }
          751         fontlab[pos] = f;
          752         if (smnt == 0 && fonts[pos].specfont)
          753                 smnt = pos;
          754         bdtab[pos] = cstab[pos] = ccstab[pos] = 0;
          755         return pos;
          756 }
          757 
          758 /*
          759  * .cs request; don't check legality of optional arguments
          760  */
          761 void casecs(void)
          762 {
          763         int i, j;
          764 
          765         if (TROFF) {
          766                 int savtr = trace;
          767 
          768                 trace = 0;
          769                 noscale++;
          770                 skip();
          771                 if (!(i = getrq()) || (i = findft(i)) < 0)
          772                         goto rtn;
          773                 skip();
          774                 cstab[i] = atoi0();
          775                 skip();
          776                 j = atoi0();
          777                 if(nonumb)
          778                         ccstab[i] = 0;
          779                 else
          780                         ccstab[i] = findps(j);
          781         rtn:
          782                 zapwcache(0);
          783                 noscale = 0;
          784                 trace = savtr;
          785         }
          786 }
          787 
          788 
          789 void casebd(void)
          790 {
          791         int i, j, k;
          792 
          793         j=0;
          794         if (!TROFF) {
          795                 n_casebd();
          796                 return;
          797         }
          798         zapwcache(0);
          799         k = 0;
          800 bd0:
          801         if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
          802                 if (k)
          803                         goto bd1;
          804                 else
          805                         return;
          806         }
          807         if (j == smnt) {
          808                 k = smnt;
          809                 goto bd0;
          810         }
          811         if (k) {
          812                 sbold = j;
          813                 j = k;
          814         }
          815 bd1:
          816         skip();
          817         noscale++;
          818         bdtab[j] = atoi0();
          819         noscale = 0;
          820 }
          821 
          822 
          823 void casevs(void)
          824 {
          825         int i;
          826 
          827         if (!TROFF) {
          828                 n_casevs();
          829                 return;
          830         }
          831         skip();
          832         vflag++;
          833         dfact = INCH; /* default scaling is points! */
          834         dfactd = 72;
          835         res = VERT;
          836         i = inumb(&lss);
          837         if (nonumb)
          838                 i = lss1;
          839         if (i < VERT)
          840                 i = VERT;
          841         lss1 = lss;
          842         lss = i;
          843 }
          844 
          845 
          846 void casess(void)
          847 {
          848         int i;
          849 
          850         if(TROFF) {
          851                 noscale++;
          852                 skip();
          853                 if(i = atoi0()) {
          854                         spacesz = i & 0177;
          855                         zapwcache(0);
          856                         sps = width(' ' | chbits);
          857                 }
          858                 noscale = 0;
          859         }
          860 }
          861 
          862 
          863 Tchar t_xlss(void)
          864 {
          865         /* stores \x'...' into two successive Tchars.
          866         /* the first contains HX, the second the value,
          867         /* encoded as a vertical motion.
          868         /* decoding is done in n2.c by pchar().
          869         */
          870         int i;
          871 
          872         getch();
          873         dfact = lss;
          874         i = quant(atoi0(), VERT);
          875         dfact = 1;
          876         getch();
          877         if (i >= 0)
          878                 *pbp++ = MOT | VMOT | i;
          879         else
          880                 *pbp++ = MOT | VMOT | NMOT | -i;
          881         return(HX);
          882 }
          883 
          884 Uchar *unpair(int i)
          885 {
          886         static Uchar name[3];
          887 
          888         name[0] = i & SHORTMASK;
          889         name[1] = (i >> SHORT) & SHORTMASK;
          890         name[2] = 0;
          891         return name;
          892 }