tt10.c - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tt10.c (9439B)
       ---
            1 #include "tdef.h"
            2 #include "fns.h"
            3 #include "ext.h"
            4 
            5 /*
            6  * troff10.c
            7  *
            8  * typesetter interface
            9  */
           10 
           11 int        vpos         = 0;        /* absolute vertical position on page */
           12 int        hpos         = 0;        /* ditto horizontal */
           13 
           14 extern Font fonts[MAXFONTS+1];
           15 
           16 int        Inch;
           17 int        Hor;
           18 int        Vert;
           19 int        Unitwidth;
           20 int        nfonts;
           21 
           22 
           23 
           24 void t_ptinit(void)
           25 {
           26         int i;
           27         char buf[100], *p;
           28 
           29         hmot = t_hmot;
           30         makem = t_makem;
           31         setabs = t_setabs;
           32         setch = t_setch;
           33         sethl = t_sethl;
           34         setht = t_setht;
           35         setslant = t_setslant;
           36         vmot = t_vmot;
           37         xlss = t_xlss;
           38         findft = t_findft;
           39         width = t_width;
           40         mchbits = t_mchbits;
           41         ptlead = t_ptlead;
           42         ptout = t_ptout;
           43         ptpause = t_ptpause;
           44         setfont = t_setfont;
           45         setps = t_setps;
           46         setwd = t_setwd;
           47 
           48         /* open table for device, */
           49         /* read in resolution, size info, font info, etc., set params */
           50         if ((p = getenv("TYPESETTER")) != 0)
           51                 strcpy(devname, p);
           52         if (termtab[0] == 0)
           53                 strcpy(termtab, DWBfontdir);
           54         if (fontdir[0] == 0)
           55                 strcpy(fontdir, DWBfontdir);
           56         if (devname[0] == 0)
           57                 strcpy(devname, TDEVNAME);
           58         hyf = 1;
           59         lg = 1;
           60 
           61         sprintf(buf, "/dev%s/DESC", devname);
           62         strcat(termtab, buf);
           63         if (getdesc(termtab) < 0) {
           64                 ERROR "can't open DESC file %s", termtab WARN;
           65                 done3(1);
           66         }
           67         if (!ascii) {
           68                 OUT "x T %s\n", devname PUT;
           69                 OUT "x res %d %d %d\n", Inch, Hor, Vert PUT;
           70                 OUT "x init\n" PUT;
           71         }
           72         for (i = 1; i <= nfonts; i++)
           73                 setfp(i, fontlab[i], (char *) 0, 0);
           74         sps = EM/3;        /* space size */
           75         ics = EM;        /* insertion character space */
           76         for (i = 0; i < (NTAB - 1) && DTAB * (i + 1) < TABMASK; i++)
           77                 tabtab[i] = DTAB * (i + 1);
           78         tabtab[NTAB-1] = 0;
           79         pl = 11 * INCH;                        /* paper length */
           80         po = PO;                /* page offset */
           81         spacesz = SS;
           82         lss = lss1 = VS;
           83         ll = ll1 = lt = lt1 = LL;
           84         t_specnames();        /* install names like "hyphen", etc. */
           85 }
           86 
           87 void t_specnames(void)
           88 {
           89         int        i;
           90 
           91         for (i = 0; spnames[i].n; i++)
           92                 *spnames[i].n = chadd(spnames[i].v, Troffchar, Install);
           93 }
           94 
           95 void t_ptout(Tchar i)
           96 {
           97         int dv;
           98         Tchar *k;
           99         int temp, a, b;
          100         int diff;
          101 
          102         if (cbits(i) != '\n') {
          103                 if (olinep >= oline + olnsize) {
          104                         diff = olinep - oline;
          105                         olnsize += OLNSIZE;
          106                         if ((oline = (Tchar *)realloc((char *)oline, olnsize * sizeof(Tchar))) != NULL) {
          107                                 if (diff && olinep)
          108                                         olinep = oline + diff;
          109                         } else {
          110                                 ERROR "Output line overflow." WARN;
          111                                 done(2);
          112                         }
          113                 }
          114                 *olinep++ = i;
          115                 return;
          116         }
          117         if (olinep == oline) {
          118                 lead += lss;
          119                 return;
          120         }
          121 
          122         hpos = po;        /* ??? */
          123         esc = 0;        /* ??? */
          124         ptesc();        /* the problem is to get back to the left end of the line */
          125         dv = 0;
          126         for (k = oline; k < olinep; k++) {
          127                 if (ismot(*k) && isvmot(*k)) {
          128                         temp = absmot(*k);
          129                         if (isnmot(*k))
          130                                 temp = -temp;
          131                         dv += temp;
          132                 }
          133         }
          134         if (dv) {
          135                 vflag++;
          136                 *olinep++ = makem(-dv);
          137                 vflag = 0;
          138         }
          139 
          140         b = dip->blss + lss;
          141         lead += dip->blss + lss;
          142         dip->blss = 0;
          143         for (k = oline; k < olinep; )
          144                 k += ptout0(k);        /* now passing a pointer! */
          145         olinep = oline;
          146         lead += dip->alss;
          147         a = dip->alss;
          148         dip->alss = 0;
          149         /*
          150         OUT "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos PUT;
          151 */
          152         OUT "n%d %d\n", b, a PUT;        /* be nice to chuck */
          153 }
          154 
          155 int ptout0(Tchar *pi)
          156 {
          157         int j, k, w;
          158         int z, dx, dy, dx2, dy2, n;
          159         Tchar i;
          160         int outsize;        /* size of object being printed */
          161 
          162         w = 0;
          163         outsize = 1;        /* default */
          164         i = *pi;
          165         k = cbits(i);
          166         if (ismot(i)) {
          167                 j = absmot(i);
          168                 if (isnmot(i))
          169                         j = -j;
          170                 if (isvmot(i))
          171                         lead += j;
          172                 else
          173                         esc += j;
          174                 return(outsize);
          175         }
          176         if (k == CHARHT) {
          177                 xpts = fbits(i);        /* sneaky, font bits as size bits */
          178                 if (xpts != mpts)
          179                         ptps();
          180                 OUT "x H %ld\n", sbits(i) PUT;
          181                 return(outsize);
          182         }
          183         if (k == SLANT) {
          184                 OUT "x S %ld\n", sfbits(i)-180 PUT;
          185                 return(outsize);
          186         }
          187         if (k == WORDSP) {
          188                 oput('w');
          189                 return(outsize);
          190         }
          191         if (sfbits(i) == oldbits) {
          192                 xfont = pfont;
          193                 xpts = ppts;
          194         } else
          195                 xbits(i, 2);
          196         if (k == XON) {
          197                 extern int xon;
          198                 ptflush();        /* guarantee that everything is out */
          199                 if (esc)
          200                         ptesc();
          201                 if (xfont != mfont)
          202                         ptfont();
          203                 if (xpts != mpts)
          204                         ptps();
          205                 if (lead)
          206                         ptlead();
          207                 OUT "x X " PUT;
          208                 xon++;
          209                 for (j = 1; cbits(pi[j]) != XOFF; j++)
          210                         outascii(pi[j]);
          211                 oput('\n');
          212                 xon--;
          213                 return j+1;
          214         }
          215         if (k < 040 && k != DRAWFCN)
          216                 return(outsize);
          217         j = z = 0;
          218         if (k != DRAWFCN) {
          219                 if (widcache[k].fontpts == (xfont<<8) + xpts  && !setwdf) {
          220                         w = widcache[k].width;
          221                         bd = 0;
          222                         cs = 0;
          223                 } else
          224                         w = getcw(k);
          225                 if (cs) {
          226                         if (bd)
          227                                 w += (bd - 1) * HOR;
          228                         j = (cs - w) / 2;
          229                         w = cs - j;
          230                         if (bd)
          231                                 w -= (bd - 1) * HOR;
          232                 }
          233                 if (iszbit(i)) {
          234                         if (cs)
          235                                 w = -j;
          236                         else
          237                                 w = 0;
          238                         z = 1;
          239                 }
          240         }
          241         esc += j;
          242         if (xfont != mfont)
          243                 ptfont();
          244         if (xpts != mpts)
          245                 ptps();
          246         if (lead)
          247                 ptlead();
          248         /* put out the real character here */
          249         if (k == DRAWFCN) {
          250                 if (esc)
          251                         ptesc();
          252                 w = 0;
          253                 dx = absmot(pi[3]);
          254                 if (isnmot(pi[3]))
          255                         dx = -dx;
          256                 dy = absmot(pi[4]);
          257                 if (isnmot(pi[4]))
          258                         dy = -dy;
          259                 switch (cbits(pi[1])) {
          260                 case DRAWCIRCLE:        /* circle */
          261                         OUT "D%c %d\n", DRAWCIRCLE, dx PUT;        /* dx is diameter */
          262                         hpos += dx;
          263                         break;
          264                 case DRAWELLIPSE:
          265                         OUT "D%c %d %d\n", DRAWELLIPSE, dx, dy PUT;
          266                         hpos += dx;
          267                         break;
          268                 case DRAWBUILD:
          269                         k = cbits(pi[2]);
          270                         OUT "D%c %d ", DRAWBUILD, dx PUT;
          271                         if (k < ALPHABET)
          272                                 OUT "%c\n", k PUT;
          273                         else
          274                                 ptchname(k);
          275                         hpos += dx;
          276                         break;
          277                 case DRAWLINE:        /* line */
          278                         k = cbits(pi[2]);
          279                         OUT "D%c %d %d ", DRAWLINE, dx, dy PUT;
          280                         if (k < ALPHABET)
          281                                 OUT "%c\n", k PUT;
          282                         else
          283                                 ptchname(k);
          284                         hpos += dx;
          285                         vpos += dy;
          286                         break;
          287                 case DRAWARC:        /* arc */
          288                         dx2 = absmot(pi[5]);
          289                         if (isnmot(pi[5]))
          290                                 dx2 = -dx2;
          291                         dy2 = absmot(pi[6]);
          292                         if (isnmot(pi[6]))
          293                                 dy2 = -dy2;
          294                         OUT "D%c %d %d %d %d\n", DRAWARC,
          295                                 dx, dy, dx2, dy2 PUT;
          296                         hpos += dx + dx2;
          297                         vpos += dy + dy2;
          298                         break;
          299 
          300                 case 's':        /* using 's' internally to avoid .tr ~ */
          301                         pi[1] = '~';
          302                 case DRAWSPLINE:        /* spline */
          303                 default:        /* something else; copy it like spline */
          304                         OUT "D%c %d %d", (char)cbits(pi[1]), dx, dy PUT;
          305                         hpos += dx;
          306                         vpos += dy;
          307                         if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) {
          308                                 /* it was somehow defective */
          309                                 OUT "\n" PUT;
          310                                 break;
          311                         }
          312                         for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {
          313                                 dx = absmot(pi[n]);
          314                                 if (isnmot(pi[n]))
          315                                         dx = -dx;
          316                                 dy = absmot(pi[n+1]);
          317                                 if (isnmot(pi[n+1]))
          318                                         dy = -dy;
          319                                 OUT " %d %d", dx, dy PUT;
          320                                 hpos += dx;
          321                                 vpos += dy;
          322                         }
          323                         OUT "\n" PUT;
          324                         break;
          325                 }
          326                 for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
          327                         ;
          328                 outsize = n + 1;
          329         } else if (k < ALPHABET) {
          330                 /* try to go faster and compress output */
          331                 /* by printing nnc for small positive motion followed by c */
          332                 /* kludgery; have to make sure set all the vars too */
          333                 if (esc > 0 && esc < 100) {
          334                         oput(esc / 10 + '0');
          335                         oput(esc % 10 + '0');
          336                         oput(k);
          337                         hpos += esc;
          338                         esc = 0;
          339                 } else {
          340                         if (esc)
          341                                 ptesc();
          342                         oput('c');
          343                         oput(k);
          344                         oput('\n');
          345                 }
          346         } else {
          347                 if (esc)
          348                         ptesc();
          349                 ptchname(k);
          350         }
          351         if (bd) {
          352                 bd -= HOR;
          353                 if (esc += bd)
          354                         ptesc();
          355                 if (k < ALPHABET)
          356                         OUT "c%c\n", k PUT;
          357                 else
          358                         ptchname(k);
          359                 if (z)
          360                         esc -= bd;
          361         }
          362         esc += w;
          363         return(outsize);
          364 }
          365 
          366 void ptchname(int k)
          367 {
          368         char *chn = chname(k);
          369 
          370         switch (chn[0]) {
          371         case MBchar:
          372                 OUT "c%s\n", chn+1 PUT;        /* \n not needed? */
          373                 break;
          374         case Number:
          375                 OUT "N%s\n", chn+1 PUT;
          376                 break;
          377         case Troffchar:
          378                 OUT "C%s\n", chn+1 PUT;
          379                 break;
          380         default:
          381                 ERROR "illegal char type %s", chn WARN;
          382                 break;
          383         }
          384 }
          385 
          386 void ptflush(void)        /* get us to a clean output state */
          387 {
          388         if (TROFF) {
          389                 /* ptesc(); but always H, no h */
          390                 hpos += esc;
          391                 OUT "\nH%d\n", hpos PUT;
          392                 esc = 0;
          393                 ptps();
          394                 ptfont();
          395                 ptlead();
          396         }
          397 }
          398 
          399 void ptps(void)
          400 {
          401         int i, j, k;
          402 
          403         i = xpts;
          404         for (j = 0; i > (k = pstab[j]); j++)
          405                 if (!k) {
          406                         k = pstab[--j];
          407                         break;
          408                 }
          409         if (!ascii)
          410                 OUT "s%d\n", k PUT;        /* really should put out string rep of size */
          411         mpts = i;
          412 }
          413 
          414 void ptfont(void)
          415 {
          416         mfont = xfont;
          417         if (ascii)
          418                 return;
          419         if (xfont > nfonts) {
          420                 ptfpcmd(0, fonts[xfont].longname, 0);        /* Put the desired font in the
          421                                          * fontcache of the filter */
          422                 OUT "f0\n" PUT;        /* make sure that it gets noticed */
          423         } else
          424                 OUT "f%d\n", xfont PUT;
          425 }
          426 
          427 void ptfpcmd(int f, char *s, char *longname)
          428 {
          429         if (f > nfonts)                /* a bit risky? */
          430                 f = 0;
          431         if (longname) {
          432                 OUT "x font %d %s %s\n", f, s, longname PUT;
          433         } else {
          434                 OUT "x font %d %s\n", f, s PUT;
          435         }
          436 /*        OUT "f%d\n", xfont PUT;        /* need this for buggy version of adobe transcript */
          437                                 /* which apparently believes that x font means */
          438                                 /* to set the font, not just the position. */
          439 }
          440 
          441 void t_ptlead(void)
          442 {
          443         vpos += lead;
          444         if (!ascii)
          445                 OUT "V%d\n", vpos PUT;
          446         lead = 0;
          447 }
          448 
          449 void ptesc(void)
          450 {
          451         hpos += esc;
          452         if (!ascii)
          453                 if (esc > 0) {
          454                         oput('h');
          455                         if (esc>=10 && esc<100) {
          456                                 oput(esc/10 + '0');
          457                                 oput(esc%10 + '0');
          458                         } else
          459                                 OUT "%d", esc PUT;
          460                 } else
          461                         OUT "H%d\n", hpos PUT;
          462         esc = 0;
          463 }
          464 
          465 void ptpage(int n)        /* called at end of each output page, we hope */
          466 {
          467         int i;
          468 
          469         if (NROFF)
          470                 return;
          471         ptlead();
          472         vpos = 0;
          473         if (ascii)
          474                 return;
          475         OUT "p%d\n", n PUT;        /* new page */
          476         for (i = 0; i <= nfonts; i++)
          477                 if (fontlab[i]) {
          478                         if (fonts[i].truename)
          479                                 OUT "x font %d %s %s\n", i, fonts[i].longname, fonts[i].truename PUT;
          480                         else
          481                                 OUT "x font %d %s\n", i, fonts[i].longname PUT;
          482                 }
          483         ptps();
          484         ptfont();
          485 }
          486 
          487 void pttrailer(void)
          488 {
          489         if (TROFF)
          490                 OUT "x trailer\n" PUT;
          491 }
          492 
          493 void ptstop(void)
          494 {
          495         if (TROFF)
          496                 OUT "x stop\n" PUT;
          497 }
          498 
          499 void t_ptpause(void)
          500 {
          501         if (ascii)
          502                 return;
          503         ptlead();
          504         vpos = 0;
          505         pttrailer();
          506         ptlead();
          507         OUT "x pause\n" PUT;
          508         flusho();
          509         mpts = mfont = 0;
          510         ptesc();
          511         esc = po;
          512         hpos = vpos = 0;        /* probably in wrong place */
          513 }