1*48307Sbostic /*-
2*48307Sbostic * %sccs.include.proprietary.c%
3*48307Sbostic */
4*48307Sbostic
57080Srrh #ifndef lint
6*48307Sbostic static char sccsid[] = "@(#)t6.c 4.4 (Berkeley) 04/18/91";
7*48307Sbostic #endif /* not lint */
87080Srrh
97080Srrh #include "tdef.h"
107080Srrh extern
117080Srrh #include "d.h"
127080Srrh extern
137080Srrh #include "v.h"
1437896Sbostic #include "pathnames.h"
157080Srrh
167080Srrh /*
177080Srrh troff6.c
187080Srrh
197080Srrh width functions, sizes and fonts
207080Srrh */
217080Srrh
227080Srrh extern int inchar[LNSIZE], *pinchar; /* XXX */
237080Srrh extern int eschar;
247080Srrh extern int widthp;
257080Srrh extern int ohc;
267080Srrh extern int xpts;
277080Srrh extern int xfont;
287080Srrh extern int code;
297080Srrh extern int smnt;
307080Srrh extern int setwdf;
317080Srrh extern int cs;
327080Srrh extern int ccs;
337080Srrh extern int spacesz;
347080Srrh extern char trtab[];
357080Srrh extern int xbitf;
367080Srrh extern int mfont;
377080Srrh extern int mpts;
387080Srrh extern int pfont;
397080Srrh extern int ppts;
407080Srrh extern int oldbits;
417080Srrh extern int chbits;
427080Srrh extern int spbits;
437080Srrh extern int nonumb;
447080Srrh extern int noscale;
457080Srrh extern int font;
467080Srrh extern int font1;
477080Srrh extern int pts;
487080Srrh extern int pts1;
497080Srrh extern int apts;
507080Srrh extern int apts1;
517080Srrh extern int sps;
527080Srrh extern int nlflg;
537080Srrh extern int nform;
547080Srrh extern int dfact;
557080Srrh extern int lss;
567080Srrh extern int lss1;
577080Srrh extern int vflag;
587080Srrh extern int ch0;
597080Srrh extern int lg;
6037896Sbostic char *fontfile = _PATH_FONTS;
6111248Sshannon int ffi = 0;
627080Srrh extern int bd;
637080Srrh extern int level;
647080Srrh extern int ch;
657080Srrh extern int res;
667080Srrh extern int ptid;
677080Srrh extern char W1[],W2[],W3[],W4[];
687080Srrh extern int xxx;
697080Srrh int trflg;
707080Srrh char *fontab[] = {W1,W2,W3,W4};
717080Srrh int fontlab[] = {'R','I','B','S',0};
727080Srrh char pstab[] = {6,7,8,9,10,11,12,14,16,18,20,22,24,28,36,0};
737080Srrh char psctab[] = {010,000,001,007,002,003,004,005,0211,006,
747080Srrh 0212,0213,0214,0215,0216,0};
757080Srrh int cstab[4], ccstab[4];
767080Srrh int bdtab[4];
777080Srrh int sbold = 0;
787080Srrh int spsz = 0;
797080Srrh struct fz {
807080Srrh char sign;
817080Srrh char size;
827080Srrh int inc;
837080Srrh } fz[4];
847080Srrh
width(c)857080Srrh width(c)
867080Srrh int c;
877080Srrh {
887080Srrh register i,j,k;
897080Srrh
907080Srrh j = c;
917080Srrh k = 0;
927080Srrh if(j & MOT){
937080Srrh if(j & VMOT)goto rtn;
947080Srrh k = j & ~MOTV;
957080Srrh if(j & NMOT)k = -k;
967080Srrh goto rtn;
977080Srrh }
987080Srrh if((i = (j & CMASK)) == 010){
997080Srrh k = -widthp;
1007080Srrh goto rtn;
1017080Srrh }
1027080Srrh if(i == PRESC)i = eschar;
1037080Srrh if((i == ohc) ||
1047080Srrh (i >= 0370))goto rtn;
1057080Srrh if((j>>BYTE) == oldbits){
1067080Srrh xfont = pfont;
1077080Srrh xpts = ppts;
1087080Srrh }else xbits(j);
1097080Srrh if(j & ZBIT)goto rtn;
1107080Srrh if(!trflg)i = trtab[i] & BMASK;
1117080Srrh if((i -= 32) < 0)goto rtn;
1127080Srrh k = getcw(i);
1137080Srrh if(bd)k += bd - 1;
1147080Srrh if(cs)k = cs;
1157080Srrh widthp = k;
1167080Srrh rtn:
1177080Srrh xbitf = trflg = 0;
1187080Srrh return(k);
1197080Srrh }
getcw(i)1207080Srrh getcw(i)
1217080Srrh int i;
1227080Srrh {
1237080Srrh register j,k;
1247080Srrh register char *p;
1257080Srrh int x;
1267080Srrh extern char codetab[];
1277080Srrh
1287080Srrh bd = 0;
1297080Srrh if((code = codetab[i]) & 0200){
1307080Srrh if(smnt){
1317080Srrh p = fontab[smnt-1];
1327080Srrh if(xfont == (sbold-1))bd = bdtab[smnt-1];
1337080Srrh goto g0;
1347080Srrh }
1357080Srrh code = 0;
1367080Srrh k = 36;
1377080Srrh goto g1;
1387080Srrh }
1397080Srrh p = fontab[xfont];
1407080Srrh g0:
1417080Srrh if(!i)k = spacesz;
1427080Srrh else k = *(p + i) & BMASK;
1437080Srrh if(setwdf)v.ct |= ((k>>6) & 3);
1447080Srrh g1:
1457080Srrh k = (j = (k&077)*(xpts&077))/6;
1467080Srrh if((j%6) >= 3)k++;
1477080Srrh if(cs = cstab[xfont]){
1487080Srrh if(ccs = ccstab[xfont])x = ccs; else x = xpts;
1497080Srrh cs = (j = (cs&077)*(x&077))/6;
1507080Srrh if((j%6) >= 3)cs++;
1517080Srrh }
1527080Srrh if(!bd)bd = bdtab[xfont];
1537080Srrh return(k);
1547080Srrh }
xbits(i)1557080Srrh xbits(i)
1567080Srrh int i;
1577080Srrh {
1587080Srrh register j, k;
1597080Srrh
1607080Srrh /*
1617080Srrh if((j = i >> BYTE) == oldbits){
1627080Srrh xfont = pfont;
1637080Srrh xpts = ppts;
1647080Srrh goto rtn;
1657080Srrh }
1667080Srrh */
1677080Srrh j = i >> BYTE;
1687080Srrh xfont = (j>>1) & 03;
1697080Srrh if(k = (j>>3) & 017){
1707080Srrh xpts = pstab[--k];
1717080Srrh if(psctab[k] < 0)xpts |= DBL;
1727080Srrh oldbits = j;
1737080Srrh pfont = xfont;
1747080Srrh ppts = xpts;
1757080Srrh goto rtn;
1767080Srrh }
1777080Srrh switch(xbitf){
1787080Srrh case 0:
1797080Srrh xfont = font;
1807080Srrh xpts = pts;
1817080Srrh break;
1827080Srrh case 1:
1837080Srrh xfont = pfont;
1847080Srrh xpts = ppts;
1857080Srrh break;
1867080Srrh case 2:
1877080Srrh xfont = mfont;
1887080Srrh xpts = mpts;
1897080Srrh }
1907080Srrh rtn:
1917080Srrh xbitf = 0;
1927080Srrh }
setch()1937080Srrh setch(){
1947080Srrh register i,*j,k;
1957080Srrh extern int chtab[];
1967080Srrh
1977080Srrh if((i = getrq()) == 0)return(0);
1987080Srrh for(j=chtab;*j != i;j++)if(*(j++) == 0)return(0);
1997080Srrh k = *(++j) | chbits;
2007080Srrh /*
2017080Srrh if((i & CMASK) == '*'){
2027080Srrh if(((i = find('R',fontlab)) < 0) &&
2037080Srrh ((i = find('G',fontlab)) < 0))
2047080Srrh return(k);
2057080Srrh else return((k & ~(03<<(BYTE+1))) | (i<<(BYTE+1)));
2067080Srrh }
2077080Srrh */
2087080Srrh return(k);
2097080Srrh }
find(i,j)2107080Srrh find(i,j)
2117080Srrh int i,j[];
2127080Srrh {
2137080Srrh register k;
2147080Srrh
2157080Srrh if(((k = i-'0') >= 1) && (k <= 4) && (k != smnt))return(--k);
2167080Srrh for(k=0; j[k] != i; k++)if(j[k] == 0)return(-1);
2177080Srrh return(k);
2187080Srrh }
casefz()2197080Srrh casefz(){
2207080Srrh register i, j, k;
2217080Srrh int savinc;
2227080Srrh
2237080Srrh k = 0;
2247080Srrh fz0:
2257080Srrh if(skip() || !(i = getrq()) ||
2267080Srrh ((j = find(i,fontlab)) == -1)){
2277080Srrh if(k)goto fz1;
2287080Srrh else return;
2297080Srrh }
2307080Srrh if(j == (smnt-1)){
2317080Srrh k = smnt;
2327080Srrh goto fz0;
2337080Srrh }
2347080Srrh if(k){
2357080Srrh spsz = j + 1;
2367080Srrh j = k -1;
2377080Srrh }
2387080Srrh fz1:
2397080Srrh if((j==font) && fz[j].inc)savinc = fz[j].inc;
2407080Srrh else savinc = 0;
2417080Srrh fz[j].inc = fz[j].sign = fz[j].size = 0;
2427080Srrh if(skip()){
2437080Srrh if(k)spsz = 0;
2447080Srrh goto fz2;
2457080Srrh }
2467080Srrh if(((i=((k=getch()) & CMASK)) == '+') || (i == '-'))fz[j].sign = i;
2477080Srrh else{
2487080Srrh fz[j].sign = 0;
2497080Srrh ch = k;
2507080Srrh }
2517080Srrh noscale++;
2527080Srrh fz[j].size = atoi();
2537080Srrh noscale = 0;
2547080Srrh fz2:
2557080Srrh if(j==font)casps1(apts + savinc);
2567080Srrh else if(j == smnt-1)mchbits();
2577080Srrh }
caseps()2587080Srrh caseps(){
2597080Srrh register i;
2607080Srrh
2617080Srrh if(skip())i = apts1;
2627080Srrh else{
2637080Srrh noscale++;
2647080Srrh i = inumb(&apts);
2657080Srrh noscale = 0;
2667080Srrh if(nonumb)return;
2677080Srrh }
2687080Srrh casps1(i);
2697080Srrh }
casps1(i)2707080Srrh casps1(i)
2717080Srrh int i;
2727080Srrh {
2737080Srrh if(i <= 0)return;
2747080Srrh if(fz[font].size){
2757080Srrh i = getfz(font, i);
2767080Srrh }
2777080Srrh apts1 = apts;
2787080Srrh apts = i;
2797080Srrh pts1 = pts;
2807080Srrh pts = findps(i & 077);
2817080Srrh mchbits();
2827080Srrh }
findps(i)2837080Srrh findps(i)
2847080Srrh int i;
2857080Srrh {
2867080Srrh register j, k;
2877080Srrh
2887080Srrh for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;}
2897080Srrh if(psctab[j] < 0)k |= DBL;
2907080Srrh return(k);
2917080Srrh }
mchbits()2927080Srrh mchbits(){
2937080Srrh register i, j, k;
2947080Srrh
2957080Srrh spbits = 0;
2967080Srrh i = pts & 077;
2977080Srrh for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;}
2987080Srrh chbits = (((++j)<<2) | font) << (BYTE + 1);
2997080Srrh sps = width(' ' | chbits);
3007080Srrh if(font == (spsz-1)){
3017080Srrh i = findps(getfz(smnt-1, apts + fz[font].inc));
3027080Srrh for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;}
3037080Srrh spbits = (((++j)<<2) | font) << (BYTE + 1);
3047080Srrh }
3057080Srrh }
getfz(x,y)3067080Srrh getfz(x,y)
3077080Srrh int x, y;
3087080Srrh {
3097080Srrh register i, j, k;
3107080Srrh
3117080Srrh i = fz[x].size;
3127080Srrh j = fz[x].sign;
3137080Srrh if(i || j){
3147080Srrh if(j == '+')i += y;
3157080Srrh else if(j == '-')i = y - i;
3167080Srrh }
3177080Srrh fz[x].inc = y - i;
3187080Srrh return(i);
3197080Srrh }
setps()3207080Srrh setps(){
3217080Srrh register i,j;
3227080Srrh
3237080Srrh if((((i=getch() & CMASK) == '+') || (i == '-')) &&
3247080Srrh (((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9))){
3257080Srrh if(i == '-')j = -j;
3267080Srrh ch = 0;
3277080Srrh casps1(apts+j);
3287080Srrh return;
3297080Srrh }
3307080Srrh if((i -= '0') == 0){
3317080Srrh casps1(apts1);
3327080Srrh return;
3337080Srrh }
3347080Srrh if((i > 0) && (i <= 9)){
3357080Srrh if((i <= 3) &&
3367080Srrh ((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9)){
3377080Srrh i = 10*i +j;
3387080Srrh ch = 0;
3397080Srrh }
3407080Srrh casps1(i);
3417080Srrh }
3427080Srrh }
caseft()3437080Srrh caseft(){
3447080Srrh skip();
3457080Srrh setfont(1);
3467080Srrh }
setfont(a)3477080Srrh setfont(a)
3487080Srrh int a;
3497080Srrh {
3507080Srrh register i,j;
3517080Srrh
3527080Srrh if(a)i = getrq();
3537080Srrh else i = getsn();
3547080Srrh if(!i || (i == 'P')){
3557080Srrh j = font1;
3567080Srrh goto s0;
3577080Srrh }
3587080Srrh if(i == 'S')return;
3597080Srrh if((j = find(i,fontlab)) == -1)return;
3607080Srrh s0:
3617080Srrh font1 = font;
3627080Srrh font = j;
3637080Srrh i = 0;
3647080Srrh if(fz[font1].size){
3657080Srrh i++;
3667080Srrh casps1(apts + fz[font1].inc);
3677080Srrh }else if(fz[font].size){
3687080Srrh i++;
3697080Srrh casps1(apts);
3707080Srrh }
3717080Srrh if(!i)mchbits();
3727080Srrh }
setwd()3737080Srrh setwd(){
3747080Srrh register i, base, wid;
3757080Srrh int delim, em, k;
3767080Srrh int savlevel, savhp, savapts, savapts1, savfont, savfont1,
3777080Srrh savpts, savpts1;
3787080Srrh int *savpinchar, *p, *q, tempinchar[LNSIZE]; /* XXX */
3797080Srrh
3807080Srrh base = v.st = v.sb = wid = v.ct = 0;
3817080Srrh if((delim = getch() & CMASK) & MOT)return;
3827080Srrh savhp = v.hp;
3837080Srrh savpinchar = pinchar; /* XXX */
3847080Srrh for (p=inchar, q=tempinchar; p < pinchar; ) /* XXX */
3857080Srrh *q++ = *p++; /* XXX */
3867080Srrh pinchar = inchar; /* XXX */
3877080Srrh savlevel = level;
3887080Srrh v.hp = level = 0;
3897080Srrh savapts = apts;
3907080Srrh savapts1 = apts1;
3917080Srrh savfont = font;
3927080Srrh savfont1 = font1;
3937080Srrh savpts = pts;
3947080Srrh savpts1 = pts1;
3957080Srrh setwdf++;
3967080Srrh while((((i = getch()) & CMASK) != delim) && !nlflg){
3977080Srrh wid += width(i);
3987080Srrh if(!(i & MOT)){
3997080Srrh em = (xpts & 077)*6;
4007080Srrh }else if(i & VMOT){
4017080Srrh k = i & ~MOTV;
4027080Srrh if(i & NMOT)k = -k;
4037080Srrh base -= k;
4047080Srrh em = 0;
4057080Srrh }else continue;
4067080Srrh if(base < v.sb)v.sb = base;
4077080Srrh if((k=base + em) > v.st)v.st = k;
4087080Srrh }
4097080Srrh nform = 0;
4107080Srrh setn1(wid);
4117080Srrh v.hp = savhp;
4127080Srrh pinchar = savpinchar; /* XXX */
4137080Srrh for (p=inchar, q=tempinchar; p < pinchar; ) /* XXX */
4147080Srrh *p++ = *q++; /* XXX */
4157080Srrh level = savlevel;
4167080Srrh apts = savapts;
4177080Srrh apts1 = savapts1;
4187080Srrh font = savfont;
4197080Srrh font1 = savfont1;
4207080Srrh pts = savpts;
4217080Srrh pts1 = savpts1;
4227080Srrh mchbits();
4237080Srrh setwdf = 0;
4247080Srrh }
vmot()4257080Srrh vmot(){
4267080Srrh dfact = lss;
4277080Srrh vflag++;
4287080Srrh return(mot());
4297080Srrh }
hmot()4307080Srrh hmot(){
4317080Srrh dfact = 6 * (pts & 077);
4327080Srrh return(mot());
4337080Srrh }
mot()4347080Srrh mot(){
4357080Srrh register i, j;
4367080Srrh
4377080Srrh j = HOR;
4387080Srrh getch(); /*eat delim*/
4397080Srrh if(i = atoi()){
4407080Srrh if(vflag)j = VERT;
4417080Srrh i = makem(quant(i,j));
4427080Srrh }
4437080Srrh getch();
4447080Srrh vflag = 0;
4457080Srrh dfact = 1;
4467080Srrh return(i);
4477080Srrh }
sethl(k)4487080Srrh sethl(k)
4497080Srrh int k;
4507080Srrh {
4517080Srrh register i;
4527080Srrh
4537080Srrh i = 3 * (pts & 077);
4547080Srrh if(k == 'u')i = -i;
4557080Srrh else if(k == 'r')i = -2*i;
4567080Srrh vflag++;
4577080Srrh i = makem(i);
4587080Srrh vflag = 0;
4597080Srrh return(i);
4607080Srrh }
makem(i)4617080Srrh makem(i)
4627080Srrh int i;
4637080Srrh {
4647080Srrh register j;
4657080Srrh
4667080Srrh if((j = i) < 0)j = -j;
4677080Srrh j = (j & ~MOTV) | MOT;
4687080Srrh if(i < 0)j |= NMOT;
4697080Srrh if(vflag)j |= VMOT;
4707080Srrh return(j);
4717080Srrh }
getlg(i)4727080Srrh getlg(i)
4737080Srrh int i;
4747080Srrh {
4757080Srrh register j, k;
4767080Srrh
4777080Srrh switch((j = getch0()) & CMASK){
4787080Srrh case 'f':
4797080Srrh if(lg!=2){switch((k =getch0()) & CMASK){
4807080Srrh case 'i':
4817080Srrh j = 0214;
4827080Srrh break;
4837080Srrh case 'l':
4847080Srrh j = 0215;
4857080Srrh break;
4867080Srrh default:
4877080Srrh ch0 = k;
4887080Srrh j = 0213;
4897080Srrh }
4907080Srrh }else j = 0213;
4917080Srrh break;
4927080Srrh case 'l':
4937080Srrh j = 0212;
4947080Srrh break;
4957080Srrh case 'i':
4967080Srrh j = 0211;
4977080Srrh break;
4987080Srrh default:
4997080Srrh ch0 = j;
5007080Srrh j = i;
5017080Srrh }
5027080Srrh return((i & ~CMASK) | j);
5037080Srrh }
caselg()5047080Srrh caselg(){
5057080Srrh
5067080Srrh lg = 1;
5077080Srrh if(skip())return;
5087080Srrh lg = atoi();
5097080Srrh }
casefp()5107080Srrh casefp(){
5117080Srrh register i, j, k;
5127080Srrh int x;
5137080Srrh
51411248Sshannon if (ffi == 0)
51511248Sshannon while (fontfile[ffi] != 'X')
51611248Sshannon ffi++;
5177080Srrh skip();
5187080Srrh if(((i = (getch() & CMASK) - '0' -1) < 0) || (i >3)){prstr("fp: bad font position\n"); return;}
5197080Srrh if(skip() || !(j = getrq())){prstr("fp: no font name\n"); return;}
5207080Srrh fontfile[ffi] = j & BMASK;
5217080Srrh fontfile[ffi+1] = j>>BYTE;
5227080Srrh if((k = open(fontfile,0)) < 0){
5237080Srrh prstr("Cannot open ");
5247080Srrh c0:
5257080Srrh prstr(fontfile);
5267080Srrh prstr("\n");
5277080Srrh done(-1);
5287080Srrh }
5297080Srrh if(lseek(k,8L * sizeof(int),0) < 0)goto c1;
5307080Srrh if(read(k,fontab[i],256-32) != 256-32){
5317080Srrh c1:
5327080Srrh prstr("Cannot read ");
5337080Srrh goto c0;
5347080Srrh }
5357080Srrh close(k);
5367080Srrh if(i == (smnt-1)){smnt = 0; sbold = 0; spsz = 0;}
5377080Srrh if((fontlab[i] = j) == 'S')smnt = i + 1;
5387080Srrh bdtab[i] = cstab[i] = ccstab[i] = 0;
5397080Srrh fz[i].inc = fz[i].sign = fz[i].size = 0;
5407080Srrh if(ptid != 1){
5417080Srrh prstr("Mount font ");
5427080Srrh prstr(&fontfile[ffi]);
5437080Srrh prstr(" on ");
5447080Srrh x = PAIR((i + '1'),0);
5457080Srrh prstr((char *)&x);
5467080Srrh prstr("\n");
5477080Srrh }
5487080Srrh }
casecs()5497080Srrh casecs(){
5507080Srrh register i, j;
5517080Srrh
5527080Srrh noscale++;
5537080Srrh skip();
5547080Srrh if(!(i=getrq()) ||
5557080Srrh ((i = find(i,fontlab)) < 0))goto rtn;
5567080Srrh skip();
5577080Srrh cstab[i] = atoi();
5587080Srrh skip();
5597080Srrh j = atoi();
5607080Srrh if(!nonumb)ccstab[i] = findps(j);
5617080Srrh rtn:
5627080Srrh noscale = 0;
5637080Srrh }
casebd()5647080Srrh casebd(){
5657080Srrh register i, j, k;
5667080Srrh
5677080Srrh k = 0;
5687080Srrh bd0:
5697080Srrh if(skip() || !(i = getrq()) ||
5707080Srrh ((j = find(i,fontlab)) == -1)){
5717080Srrh if(k)goto bd1;
5727080Srrh else return;
5737080Srrh }
5747080Srrh if(j == (smnt-1)){
5757080Srrh k = smnt;
5767080Srrh goto bd0;
5777080Srrh }
5787080Srrh if(k){
5797080Srrh sbold = j + 1;
5807080Srrh j = k -1;
5817080Srrh }
5827080Srrh bd1:
5837080Srrh skip();
5847080Srrh noscale++;
5857080Srrh bdtab[j] = atoi();
5867080Srrh noscale = 0;
5877080Srrh }
casevs()5887080Srrh casevs(){
5897080Srrh register i;
5907080Srrh
5917080Srrh skip();
5927080Srrh vflag++;
5937080Srrh dfact = 6; /*default scaling is points!*/
5947080Srrh res = VERT;
5957080Srrh i = inumb(&lss);
5967080Srrh if(nonumb)i = lss1;
5977080Srrh if(i < VERT)i = VERT;
5987080Srrh lss1 = lss;
5997080Srrh lss = i;
6007080Srrh }
casess()6017080Srrh casess(){
6027080Srrh register i;
6037080Srrh
6047080Srrh noscale++;
6057080Srrh skip();
6067080Srrh if(i = atoi()){
6077080Srrh spacesz = i& 0177;
6087080Srrh sps = width(' ' | chbits);
6097080Srrh }
6107080Srrh noscale = 0;
6117080Srrh }
xlss()6127080Srrh xlss(){
6137080Srrh register i, j;
6147080Srrh
6157080Srrh getch();
6167080Srrh dfact = lss;
6177080Srrh i = quant(atoi(),VERT);
6187080Srrh dfact = 1;
6197080Srrh getch();
6207080Srrh if((j = i) < 0)j = -j;
6217080Srrh ch0 = ((j & 03700)<<3) | HX;
6227080Srrh if(i < 0)ch0 |= 040000;
6237080Srrh return(((j & 077)<<9) | LX);
6247080Srrh }
625