t6.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       t6.c (15468B)
       ---
            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         int j;
          221         char temp[50];
          222         char *s;
          223 
          224         j = 0;
          225         s = temp;
          226         if (c == '(') {        /* \(xx */
          227                 if ((*s++ = getach()) == 0 || (*s++ = getach()) == 0)
          228                         return(0);
          229         } else {        /* \C'...' */
          230                 c = getach();
          231                 while ((*s = getach()) != c && *s != 0 && s < temp + sizeof(temp) - 1)
          232                         s++;
          233         }
          234         *s = '\0';
          235 #ifdef UNICODE
          236         return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
          237 #else
          238         if (NROFF) {
          239                 j = chadd(temp, Troffchar, Lookup);
          240                 if ( j == -1)
          241                         return 0;
          242                 else
          243                         return j | chbits;
          244         } else
          245                 return chadd(temp, Troffchar, Install) | chbits; /* add name even if haven't seen it */
          246                 
          247 #endif /*UNICODE*/
          248 }
          249 
          250 Tchar t_setabs(void)                /* set absolute char from \N'...' */
          251 {
          252         int n;
          253         char temp[10];
          254 
          255         getch();        /* delim */
          256         n = 0;
          257         n = inumb(&n);
          258         getch();        /* delim */
          259         if (nonumb)
          260                 return 0;
          261         sprintf(temp, "%d", n);        /* convert into "#n" */
          262         n = chadd(temp, Number, Install);
          263         return n | chbits;
          264 }
          265 
          266 
          267 /*
          268  * fontlab[] is a cache that contains font information
          269  * for each font.
          270  * fontlab[] contains the 1- or 2-character name of the
          271  * font current associated with that font.
          272  * fonts 1..nfonts correspond to the mounted fonts;
          273  * the last of these are the special fonts.
          274  * If we don't use the (named) font in one of the
          275  * standard positions, we install the name in the next
          276  * free slot of fontlab[] and font[].
          277  * Whenever we need info about the font, we
          278  * read in the data into the next free slot with getfont.
          279  * The ptfont() (t10.c) routine will tell
          280  * the device filter to put the font always at position
          281  * zero if xfont > nfonts, so no need to change these filters.
          282  * Yes, this is a bit kludgy.
          283  *
          284  * This gives the new specs of findft:
          285  *         find the font name i, where i also can be a number.
          286  *         Installs the font(name) i when not present
          287  *         returns -1 on error
          288  */
          289 
          290 int
          291 t_findft(int i)
          292 {
          293         int k;
          294         Uchar *p;
          295 
          296         p = unpair(i);
          297 
          298         if (isdigit(p[0])) {                /* first look for numbers */
          299                 k = p[0] - '0';
          300                 if (p[1] > 0 && isdigit(p[1]))
          301                         k = 10 * k + p[1] - '0';
          302                 if (k > 0 && k <= nfonts && k < smnt)
          303                         return(k);        /* mounted font:  .ft 3 */
          304                 if (fontlab[k] && k <= MAXFONTS) {        /* translate */
          305                         return(k);                        /*number to a name */
          306                 } else {
          307                         fprintf(stderr, "troff: no font at position %d\n", k);
          308                         return(-1);        /* wild number */
          309                 }
          310         }
          311 
          312         /*
          313          * Now we look for font names
          314          */
          315         for (k = 1; fontlab[k] != i; k++) {
          316                 if (k > MAXFONTS)
          317                         return(-1);        /* running out of fontlab space */
          318                 if (fontlab[k] == 0) {        /* passed all existing names */
          319                         if (setfp(k, i, (char *) 0, 1) == -1)
          320                                 return(-1);
          321                         else {
          322                                 fontlab[k] = i;        /* install the name */
          323                                 return(k);
          324                         }
          325                 }
          326         }
          327         return(k);                        /* was one of the existing names */
          328 }
          329 
          330 
          331 void caseps(void)
          332 {
          333         int i;
          334 
          335         if (TROFF) {
          336                 if(skip())
          337                         i = apts1;
          338                 else {
          339                         noscale++;
          340                         i = inumb(&apts);        /* this is a disaster for fractional point sizes */
          341                         noscale = 0;
          342                         if(nonumb)
          343                                 i = apts1;
          344                 }
          345                 casps1(i);
          346         }
          347 }
          348 
          349 
          350 void casps1(int i)
          351 {
          352 
          353 /*
          354  * in olden times, it used to ignore changes to 0 or negative.
          355  * this is meant to allow the requested size to be anything,
          356  * in particular so eqn can generate lots of \s-3's and still
          357  * get back by matching \s+3's.
          358 
          359         if (i <= 0)
          360                 return;
          361 */
          362         apts1 = apts;
          363         apts = i;
          364         pts1 = pts;
          365         pts = findps(i);
          366         mchbits();
          367 }
          368 
          369 int
          370 findps(int i)
          371 {
          372         int j, k;
          373 
          374         for (j=k=0 ; pstab[j] != 0 ; j++)
          375                 if (abs(pstab[j]-i) < abs(pstab[k]-i))
          376                         k = j;
          377 
          378         return(pstab[k]);
          379 }
          380 
          381 
          382 void t_mchbits(void)
          383 {
          384         int i, j, k;
          385 
          386         i = pts;
          387         for (j = 0; i > (k = pstab[j]); j++)
          388                 if (!k) {
          389                         j--;
          390                         break;
          391                 }
          392         chbits = 0;
          393         setsbits(chbits, ++j);
          394         setfbits(chbits, font);
          395         sps = width(' ' | chbits);
          396         zapwcache(1);
          397 }
          398 
          399 void t_setps(void)
          400 {
          401         int i, j;
          402 
          403         j = 0;
          404         i = cbits(getch());
          405         if (isdigit(i)) {                /* \sd or \sdd */
          406                 i -= '0';
          407                 if (i == 0)                /* \s0 */
          408                         j = apts1;
          409                 else if (i <= 3 && (ch=getch()) && isdigit(j = cbits(ch))) {        /* \sdd */
          410                         j = 10 * i + j - '0';
          411                         ch = 0;
          412                 } else                /* \sd */
          413                         j = i;
          414         } else if (i == '(') {                /* \s(dd */
          415                 j = cbits(getch()) - '0';
          416                 j = 10 * j + cbits(getch()) - '0';
          417                 if (j == 0)                /* \s(00 */
          418                         j = apts1;
          419         } else if (i == '+' || i == '-') {        /* \s+, \s- */
          420                 j = cbits(getch());
          421                 if (isdigit(j)) {                /* \s+d, \s-d */
          422                         j -= '0';
          423                 } else if (j == '(') {                /* \s+(dd, \s-(dd */
          424                         j = cbits(getch()) - '0';
          425                         j = 10 * j + cbits(getch()) - '0';
          426                 }
          427                 if (i == '-')
          428                         j = -j;
          429                 j += apts;
          430         }
          431         casps1(j);
          432 }
          433 
          434 
          435 Tchar t_setht(void)                /* set character height from \H'...' */
          436 {
          437         int n;
          438         Tchar c;
          439 
          440         getch();
          441         n = inumb(&apts);
          442         getch();
          443         if (n == 0 || nonumb)
          444                 n = apts;        /* does this work? */
          445         c = CHARHT;
          446         c |= ZBIT;
          447         setsbits(c, n);
          448         setfbits(c, pts);        /* sneaky, CHARHT font bits are size bits */
          449         return(c);
          450 }
          451 
          452 Tchar t_setslant(void)                /* set slant from \S'...' */
          453 {
          454         int n;
          455         Tchar c;
          456 
          457         getch();
          458         n = 0;
          459         n = inumb(&n);
          460         getch();
          461         if (nonumb)
          462                 n = 0;
          463         c = SLANT;
          464         c |= ZBIT;
          465         setsfbits(c, n+180);
          466         return(c);
          467 }
          468 
          469 
          470 void caseft(void)
          471 {
          472         if (!TROFF) {
          473                 n_caseft();
          474                 return;
          475         }
          476         skip();
          477         setfont(1);
          478 }
          479 
          480 
          481 void t_setfont(int a)
          482 {
          483         int i, j;
          484 
          485         if (a)
          486                 i = getrq();
          487         else 
          488                 i = getsn();
          489         if (!i || i == 'P') {
          490                 j = font1;
          491                 goto s0;
          492         }
          493         if (/* i == 'S' || */ i == '0')        /* an experiment -- why can't we change to it? */
          494                 return;
          495         if ((j = findft(i)) == -1)
          496                 if ((j = setfp(0, i, (char*) 0, 1)) == -1)        /* try to put it in position 0 */
          497                         return;
          498 s0:
          499         font1 = font;
          500         font = j;
          501         mchbits();
          502 }
          503 
          504 
          505 void t_setwd(void)
          506 {
          507         int base, wid;
          508         Tchar i;
          509         int delim, emsz, k;
          510         int savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1;
          511 
          512         base = numtabp[ST].val = numtabp[SB].val = wid = numtabp[CT].val = 0;
          513         if (ismot(i = getch()))
          514                 return;
          515         delim = cbits(i);
          516         savhp = numtabp[HP].val;
          517         numtabp[HP].val = 0;
          518         savapts = apts;
          519         savapts1 = apts1;
          520         savfont = font;
          521         savfont1 = font1;
          522         savpts = pts;
          523         savpts1 = pts1;
          524         setwdf++;
          525         while (cbits(i = getch()) != delim && !nlflg) {
          526                 k = width(i);
          527                 wid += k;
          528                 numtabp[HP].val += k;
          529                 if (!ismot(i)) {
          530                         emsz = (INCH/72) * xpts;
          531                 } else if (isvmot(i)) {
          532                         k = absmot(i);
          533                         if (isnmot(i))
          534                                 k = -k;
          535                         base -= k;
          536                         emsz = 0;
          537                 } else 
          538                         continue;
          539                 if (base < numtabp[SB].val)
          540                         numtabp[SB].val = base;
          541                 if ((k = base + emsz) > numtabp[ST].val)
          542                         numtabp[ST].val = k;
          543         }
          544         setn1(wid, 0, (Tchar) 0);
          545         numtabp[HP].val = savhp;
          546         apts = savapts;
          547         apts1 = savapts1;
          548         font = savfont;
          549         font1 = savfont1;
          550         pts = savpts;
          551         pts1 = savpts1;
          552         mchbits();
          553         setwdf = 0;
          554 }
          555 
          556 
          557 Tchar t_vmot(void)
          558 {
          559         dfact = lss;
          560         vflag++;
          561         return t_mot();
          562 }
          563 
          564 
          565 Tchar t_hmot(void)
          566 {
          567         dfact = EM;
          568         return t_mot();
          569 }
          570 
          571 
          572 Tchar t_mot(void)
          573 {
          574         int j, n;
          575         Tchar i;
          576 
          577         j = HOR;
          578         getch(); /*eat delim*/
          579         if (n = atoi0()) {
          580                 if (vflag)
          581                         j = VERT;
          582                 i = makem(quant(n, j));
          583         } else
          584                 i = 0;
          585         getch();
          586         vflag = 0;
          587         dfact = 1;
          588         return(i);
          589 }
          590 
          591 
          592 Tchar t_sethl(int k)
          593 {
          594         int j;
          595         Tchar i;
          596 
          597         j = EM / 2;
          598         if (k == 'u')
          599                 j = -j;
          600         else if (k == 'r')
          601                 j = -2 * j;
          602         vflag++;
          603         i = makem(j);
          604         vflag = 0;
          605         return(i);
          606 }
          607 
          608 
          609 Tchar t_makem(int i)
          610 {
          611         Tchar j;
          612 
          613         if (i >= 0)
          614                 j = i;
          615         else
          616                 j = -i;
          617         if (Hor > 1 && !vflag)
          618                 j = (j + Hor/2)/Hor * Hor;
          619         j |= MOT;
          620         if (i < 0)
          621                 j |= NMOT;
          622         if (vflag)
          623                 j |= VMOT;
          624         return(j);
          625 }
          626 
          627 
          628 Tchar getlg(Tchar i)
          629 {
          630         Tchar j, k;
          631         int lf;
          632 
          633         if (!TROFF)
          634                 return i;
          635         if ((lf = fonts[fbits(i)].ligfont) == 0) /* font lacks ligatures */
          636                 return(i);
          637         j = getch0();
          638         if (cbits(j) == 'i' && (lf & LFI))
          639                 j = LIG_FI;
          640         else if (cbits(j) == 'l' && (lf & LFL))
          641                 j = LIG_FL;
          642         else if (cbits(j) == 'f' && (lf & LFF)) {
          643                 if ((lf & (LFFI|LFFL)) && lg != 2) {
          644                         k = getch0();
          645                         if (cbits(k)=='i' && (lf&LFFI))
          646                                 j = LIG_FFI;
          647                         else if (cbits(k)=='l' && (lf&LFFL))
          648                                 j = LIG_FFL;
          649                         else {
          650                                 *pbp++ = k;
          651                                 j = LIG_FF;
          652                         }
          653                 } else 
          654                         j = LIG_FF;
          655         } else {
          656                 *pbp++ = j;
          657                 j = i;
          658         }
          659         return(i & SFMASK | j);
          660 }
          661 
          662 
          663 void caselg(void)
          664 {
          665 
          666         if(TROFF) {
          667                 skip();
          668                 lg = atoi0();
          669                 if (nonumb)
          670                         lg = 1;
          671         }
          672 }
          673 
          674 void casefp(void)
          675 {
          676         int i, j;
          677 
          678         if (!TROFF) {
          679                 n_casefp();
          680                 return;
          681         }
          682         skip();
          683         i = cbits(getch());
          684         if (isdigit(i)) {
          685                 i -= '0';
          686                 j = cbits(getch());
          687                 if (isdigit(j))
          688                         i = 10 * i + j - '0';
          689         }
          690         if (i <= 0 || i > nfonts)
          691                 ERROR "fp: bad font position %d", i WARN;
          692         else if (skip() || !(j = getrq()))
          693                 ERROR "fp: no font name" WARN; 
          694         else if (skip() || !getname())
          695                 setfp(i, j, (char*) 0, 1);
          696         else                /* 3rd argument = filename */
          697                 setfp(i, j, nextf, 1);
          698 }
          699 
          700 char *strdupl(const char *s)        /* make a copy of s */
          701 {
          702         char *t;
          703 
          704         t = (char *) malloc(strlen(s) + 1);
          705         if (t == NULL)
          706                 ERROR "out of space in strdupl(%s)", s FATAL;
          707         strcpy(t, s);
          708         return t;
          709 }
          710 
          711 int
          712 setfp(int pos, int f, char *truename, int print)        /* mount font f at position pos[0...nfonts] */
          713 {
          714         char pathname[NS], shortname[NS], *sl;
          715 
          716         sl = (char*)0;
          717         zapwcache(0);
          718         if (truename)
          719                 strcpy(shortname, truename);
          720         else
          721                 strcpy(shortname, (char *) unpair(f));
          722         if (truename && strrchr(truename, '/')) {        /* .fp 1 R dir/file: use verbatim */
          723                 sprintf(pathname, "%s", truename);
          724                 if (fonts[pos].truename)
          725                         free(fonts[pos].truename);
          726                 fonts[pos].truename = strdupl(truename);
          727         } else if (truename) {                        /* synonym: .fp 1 R Avant */
          728                 sprintf(pathname, "%s/dev%s/%s", fontdir, devname, truename);
          729                 truename = 0;        /* so doesn't get repeated by ptfpcmd */
          730         } else                                        /* vanilla: .fp 5 XX */
          731                 sprintf(pathname, "%s/dev%s/%s", fontdir, devname, shortname);
          732         if (truename == 0 && fonts[pos].truename != 0) {
          733                 free(fonts[pos].truename);
          734                 fonts[pos].truename = 0;
          735         }
          736         if (getfont(pathname, pos) < 0) {
          737                 ERROR "Can't open font file %s", pathname WARN;
          738                 return -1;
          739         }
          740         if (print && !ascii) {
          741                 ptfpcmd(pos, fonts[pos].longname, truename);
          742                 ptfont();
          743         }
          744         if (pos == smnt) {
          745                 smnt = 0; 
          746                 sbold = 0; 
          747         }
          748         fontlab[pos] = f;
          749         if (smnt == 0 && fonts[pos].specfont)
          750                 smnt = pos;
          751         bdtab[pos] = cstab[pos] = ccstab[pos] = 0;
          752         return pos;
          753 }
          754 
          755 /*
          756  * .cs request; don't check legality of optional arguments
          757  */
          758 void casecs(void)
          759 {
          760         int i, j;
          761 
          762         if (TROFF) {
          763                 int savtr = trace;
          764 
          765                 trace = 0;
          766                 noscale++;
          767                 skip();
          768                 if (!(i = getrq()) || (i = findft(i)) < 0)
          769                         goto rtn;
          770                 skip();
          771                 cstab[i] = atoi0();
          772                 skip();
          773                 j = atoi0();
          774                 if(nonumb)
          775                         ccstab[i] = 0;
          776                 else
          777                         ccstab[i] = findps(j);
          778         rtn:
          779                 zapwcache(0);
          780                 noscale = 0;
          781                 trace = savtr;
          782         }
          783 }
          784 
          785 
          786 void casebd(void)
          787 {
          788         int i, j, k;
          789 
          790         j=0;
          791         if (!TROFF) {
          792                 n_casebd();
          793                 return;
          794         }
          795         zapwcache(0);
          796         k = 0;
          797 bd0:
          798         if (skip() || !(i = getrq()) || (j = findft(i)) == -1) {
          799                 if (k)
          800                         goto bd1;
          801                 else 
          802                         return;
          803         }
          804         if (j == smnt) {
          805                 k = smnt;
          806                 goto bd0;
          807         }
          808         if (k) {
          809                 sbold = j;
          810                 j = k;
          811         }
          812 bd1:
          813         skip();
          814         noscale++;
          815         bdtab[j] = atoi0();
          816         noscale = 0;
          817 }
          818 
          819 
          820 void casevs(void)
          821 {
          822         int i;
          823 
          824         if (!TROFF) {
          825                 n_casevs();
          826                 return;
          827         }
          828         skip();
          829         vflag++;
          830         dfact = INCH; /* default scaling is points! */
          831         dfactd = 72;
          832         res = VERT;
          833         i = inumb(&lss);
          834         if (nonumb)
          835                 i = lss1;
          836         if (i < VERT) 
          837                 i = VERT;
          838         lss1 = lss;
          839         lss = i;
          840 }
          841 
          842 
          843 void casess(void)
          844 {
          845         int i;
          846 
          847         if(TROFF) {
          848                 noscale++;
          849                 skip();
          850                 if(i = atoi0()) {
          851                         spacesz = i & 0177;
          852                         zapwcache(0);
          853                         sps = width(' ' | chbits);
          854                 }
          855                 noscale = 0;
          856         }
          857 }
          858 
          859 
          860 Tchar t_xlss(void)
          861 {
          862         /* stores \x'...' into two successive Tchars.
          863         /* the first contains HX, the second the value,
          864         /* encoded as a vertical motion.
          865         /* decoding is done in n2.c by pchar().
          866         */
          867         int i;
          868 
          869         getch();
          870         dfact = lss;
          871         i = quant(atoi0(), VERT);
          872         dfact = 1;
          873         getch();
          874         if (i >= 0)
          875                 *pbp++ = MOT | VMOT | i;
          876         else
          877                 *pbp++ = MOT | VMOT | NMOT | -i;
          878         return(HX);
          879 }
          880 
          881 Uchar *unpair(int i)
          882 {
          883         static Uchar name[3];
          884 
          885         name[0] = i & SHORTMASK;
          886         name[1] = (i >> SHORT) & SHORTMASK;
          887         name[2] = 0;
          888         return name;
          889 }