Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include "tdef.h"
#include "fns.h"
#include "ext.h"

/*
 * troff10.c
 * 
 * typesetter interface
 */

int     vpos     = 0;   /* absolute vertical position on page */
int     hpos     = 0;   /* ditto horizontal */

extern Font fonts[MAXFONTS+1];

int     Inch;
int     Hor;
int     Vert;
int     Unitwidth;
int     nfonts;



void t_ptinit(void)
{
        int i;
        char buf[100], *p;

        hmot = t_hmot;
        makem = t_makem;
        setabs = t_setabs;
        setch = t_setch;
        sethl = t_sethl;
        setht = t_setht;
        setslant = t_setslant;
        vmot = t_vmot;
        xlss = t_xlss;
        findft = t_findft;
        width = t_width;
        mchbits = t_mchbits;
        ptlead = t_ptlead;
        ptout = t_ptout;
        ptpause = t_ptpause;
        setfont = t_setfont;
        setps = t_setps;
        setwd = t_setwd;

        /* open table for device, */
        /* read in resolution, size info, font info, etc., set params */
        if ((p = getenv("TYPESETTER")) != 0){
                strncpy(devname, p, sizeof devname);
                devname[sizeof devname-1] = 0;
        }
        if (termtab[0] == 0)
                strcpy(termtab, DWBfontdir);
        if (fontdir[0] == 0)
                strcpy(fontdir, DWBfontdir);
        if (devname[0] == 0)
                strcpy(devname, TDEVNAME);
        hyf = 1;
        lg = 1;

        snprintf(buf, sizeof buf, "/dev%s/DESC", devname);
        strcat(termtab, buf);
        if (getdesc(termtab) < 0) {
                ERROR "can't open DESC file %s", termtab WARN;
                done3(1);
        }
        if (!ascii) {
                OUT "x T %s\n", devname PUT;
                OUT "x res %d %d %d\n", Inch, Hor, Vert PUT;
                OUT "x init\n" PUT;
        }
        for (i = 1; i <= nfonts; i++)
                setfp(i, fontlab[i], (char *) 0, 0);
        sps = EM/3;     /* space size */
        ics = EM;       /* insertion character space */
        for (i = 0; i < (NTAB - 1) && DTAB * (i + 1) < TABMASK; i++)
                tabtab[i] = DTAB * (i + 1);
        tabtab[NTAB-1] = 0;
        pl = 11 * INCH;                 /* paper length */
        po = PO;                /* page offset */
        spacesz = SS;
        lss = lss1 = VS;
        ll = ll1 = lt = lt1 = LL;
        t_specnames();  /* install names like "hyphen", etc. */
}

void t_specnames(void)
{
        int     i;

        for (i = 0; spnames[i].n; i++)
                *spnames[i].n = chadd(spnames[i].v, Troffchar, Install);
}

void t_ptout(Tchar i)
{
        int dv;
        Tchar *k;
        int temp, a, b;
        int diff;

        if (cbits(i) != '\n') {
                if (olinep >= oline + olnsize) {
                        diff = olinep - oline;
                        olnsize += OLNSIZE;
                        if ((oline = (Tchar *)realloc((char *)oline, olnsize * sizeof(Tchar))) != NULL) {
                                if (diff && olinep)
                                        olinep = oline + diff;
                        } else {
                                ERROR "Output line overflow." WARN;
                                done(2);
                        }
                }
                *olinep++ = i;
                return;
        }
        if (olinep == oline) {
                lead += lss;
                return;
        }

        hpos = po;      /* ??? */
        esc = 0;        /* ??? */
        ptesc();        /* the problem is to get back to the left end of the line */
        dv = 0;
        for (k = oline; k < olinep; k++) {
                if (ismot(*k) && isvmot(*k)) {
                        temp = absmot(*k);
                        if (isnmot(*k))
                                temp = -temp;
                        dv += temp;
                }
        }
        if (dv) {
                vflag++;
                *olinep++ = makem(-dv);
                vflag = 0;
        }

        b = dip->blss + lss;
        lead += dip->blss + lss;
        dip->blss = 0;
        for (k = oline; k < olinep; )
                k += ptout0(k); /* now passing a pointer! */
        olinep = oline;
        lead += dip->alss;
        a = dip->alss;
        dip->alss = 0;
        /*
        OUT "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos PUT;
*/
        OUT "n%d %d\n", b, a PUT;       /* be nice to chuck */
}

int ptout0(Tchar *pi)
{
        int j, k, w, z, dx, dy, dx2, dy2, n;
        int outsize;    /* size of object being printed */
        Tchar i;

        w = 0;
        outsize = 1;    /* default */
        i = *pi;
        k = cbits(i);
        if (ismot(i)) {
                j = absmot(i);
                if (isnmot(i))
                        j = -j;
                if (isvmot(i))
                        lead += j;
                else 
                        esc += j;
                return(outsize);
        }
        if (k == CHARHT) {
                xpts = fbits(i);        /* sneaky, font bits as size bits */
                if (xpts != mpts)
                        ptps();
                OUT "x H %d\n", sbits(i) PUT;
                return(outsize);
        }
        if (k == SLANT) {
                OUT "x S %d\n", sfbits(i)-180 PUT;
                return(outsize);
        }
        if (k == WORDSP) {
                oput('w');
                return(outsize);
        }
        if (sfbits(i) == oldbits) {
                xfont = pfont;
                xpts = ppts;
        } else 
                xbits(i, 2);
        if (k == XON) {
                extern int xon;
                ptflush();      /* guarantee that everything is out */
                if (esc)
                        ptesc();
                if (xfont != mfont)
                        ptfont();
                if (xpts != mpts)
                        ptps();
                if (lead)
                        ptlead();
                OUT "x X " PUT;
                xon++;
                for (j = 1; cbits(pi[j]) != XOFF; j++)
                        outascii(pi[j]);
                oput('\n');
                xon--;
                return j+1;
        }
        if (k < 040 && k != DRAWFCN)
                return(outsize);
        j = z = 0;
        if (k != DRAWFCN) {
                if (widcache[k].fontpts == (xfont<<8) + xpts  && !setwdf) {
                        w = widcache[k].width;
                        bd = 0;
                        cs = 0;
                } else
                        w = getcw(k);
                if (cs) {
                        if (bd)
                                w += (bd - 1) * HOR;
                        j = (cs - w) / 2;
                        w = cs - j;
                        if (bd)
                                w -= (bd - 1) * HOR;
                }
                if (iszbit(i)) {
                        if (cs)
                                w = -j; 
                        else 
                                w = 0;
                        z = 1;
                }
        }
        esc += j;
        if (xfont != mfont)
                ptfont();
        if (xpts != mpts)
                ptps();
        if (lead)
                ptlead();
        /* put out the real character here */
        if (k == DRAWFCN) {
                if (esc)
                        ptesc();
                w = 0;
                dx = absmot(pi[3]);
                if (isnmot(pi[3]))
                        dx = -dx;
                dy = absmot(pi[4]);
                if (isnmot(pi[4]))
                        dy = -dy;
                switch (cbits(pi[1])) {
                case DRAWCIRCLE:        /* circle */
                        OUT "D%c %d\n", DRAWCIRCLE, dx PUT;     /* dx is diameter */
                        hpos += dx;
                        break;
                case DRAWELLIPSE:
                        OUT "D%c %d %d\n", DRAWELLIPSE, dx, dy PUT;
                        hpos += dx;
                        break;
                case DRAWBUILD:
                        k = cbits(pi[2]);
                        OUT "D%c %d ", DRAWBUILD, dx PUT;
                        if (k < ALPHABET)
                                OUT "%c\n", k PUT;
                        else
                                ptchname(k);
                        hpos += dx;
                        break;
                case DRAWLINE:  /* line */
                        k = cbits(pi[2]);
                        OUT "D%c %d %d ", DRAWLINE, dx, dy PUT;
                        if (k < ALPHABET)
                                OUT "%c\n", k PUT;
                        else
                                ptchname(k);
                        hpos += dx;
                        vpos += dy;
                        break;
                case DRAWARC:   /* arc */
                        dx2 = absmot(pi[5]);
                        if (isnmot(pi[5]))
                                dx2 = -dx2;
                        dy2 = absmot(pi[6]);
                        if (isnmot(pi[6]))
                                dy2 = -dy2;
                        OUT "D%c %d %d %d %d\n", DRAWARC,
                                dx, dy, dx2, dy2 PUT;
                        hpos += dx + dx2;
                        vpos += dy + dy2;
                        break;

                case 's':       /* using 's' internally to avoid .tr ~ */
                        pi[1] = '~';
                case DRAWSPLINE:        /* spline */
                default:        /* something else; copy it like spline */
                        OUT "D%c %d %d", cbits(pi[1]), dx, dy PUT;
                        hpos += dx;
                        vpos += dy;
                        if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) {
                                /* it was somehow defective */
                                OUT "\n" PUT;
                                break;
                        }
                        for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {
                                dx = absmot(pi[n]);
                                if (isnmot(pi[n]))
                                        dx = -dx;
                                dy = absmot(pi[n+1]);
                                if (isnmot(pi[n+1]))
                                        dy = -dy;
                                OUT " %d %d", dx, dy PUT;
                                hpos += dx;
                                vpos += dy;
                        }
                        OUT "\n" PUT;
                        break;
                }
                for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
                        ;
                outsize = n + 1;
        } else if (k < ALPHABET) {
                /* try to go faster and compress output */
                /* by printing nnc for small positive motion followed by c */
                /* kludgery; have to make sure set all the vars too */
                if (esc > 0 && esc < 100) {
                        oput(esc / 10 + '0');
                        oput(esc % 10 + '0');
                        oput(k);
                        hpos += esc;
                        esc = 0;
                } else {
                        if (esc)
                                ptesc();
                        oput('c');
                        oput(k);
                        oput('\n');
                }
        } else {
                if (esc)
                        ptesc();
                ptchname(k);
        }
        if (bd) {
                bd -= HOR;
                if (esc += bd)
                        ptesc();
                if (k < ALPHABET)
                        OUT "c%c\n", k PUT;
                else
                        ptchname(k);
                if (z)
                        esc -= bd;
        }
        esc += w;
        return(outsize);
}

void ptchname(int k)
{
        char *chn = chname(k);

        switch (chn[0]) {
        case MBchar:
                OUT "c%s\n", chn+1 PUT; /* \n not needed? */
                break;
        case Number:
                OUT "N%s\n", chn+1 PUT;
                break;
        case Troffchar:
                OUT "C%s\n", chn+1 PUT;
                break;
        default:
                ERROR "illegal char type %s", chn WARN;
                break;
        }
}

void ptflush(void)      /* get us to a clean output state */
{
        if (TROFF) {
                /* ptesc(); but always H, no h */
                hpos += esc;
                OUT "\nH%d\n", hpos PUT;
                esc = 0;
                ptps();
                ptfont();
                ptlead();
        }
}

void ptps(void)
{
        int i, j, k;

        i = xpts;
        for (j = 0; i > (k = pstab[j]); j++)
                if (!k) {
                        k = pstab[--j];
                        break;
                }
        if (!ascii)
                OUT "s%d\n", k PUT;     /* really should put out string rep of size */
        mpts = i;
}

void ptfont(void)
{
        mfont = xfont;
        if (ascii)
                return;
        if (xfont > nfonts) {
                ptfpcmd(0, fonts[xfont].longname, 0);   /* Put the desired font in the
                                         * fontcache of the filter */
                OUT "f0\n" PUT; /* make sure that it gets noticed */
        } else
                OUT "f%d\n", xfont PUT;
}

void ptfpcmd(int f, char *s, char *longname)
{
        if (f > nfonts)         /* a bit risky? */
                f = 0;
        if (longname) {
                OUT "x font %d %s %s\n", f, s, longname PUT;
        } else {
                OUT "x font %d %s\n", f, s PUT;
        }
/*      OUT "f%d\n", xfont PUT; /* need this for buggy version of adobe transcript */
                                /* which apparently believes that x font means */
                                /* to set the font, not just the position. */
}

void t_ptlead(void)
{
        vpos += lead;
        if (!ascii)
                OUT "V%d\n", vpos PUT;
        lead = 0;
}

void ptesc(void)
{
        hpos += esc;
        if (!ascii)
                if (esc > 0) {
                        oput('h');
                        if (esc>=10 && esc<100) {
                                oput(esc/10 + '0');
                                oput(esc%10 + '0');
                        } else
                                OUT "%d", esc PUT;
                } else
                        OUT "H%d\n", hpos PUT;
        esc = 0;
}

void ptpage(int n)      /* called at end of each output page, we hope */
{
        int i;

        if (NROFF)
                return;
        ptlead();
        vpos = 0;
        if (ascii)
                return;
        OUT "p%d\n", n PUT;     /* new page */
        for (i = 0; i <= nfonts; i++)
                if (fontlab[i]) {
                        if (fonts[i].truename)
                                OUT "x font %d %s %s\n", i, fonts[i].longname, fonts[i].truename PUT;
                        else
                                OUT "x font %d %s\n", i, fonts[i].longname PUT;
                }
        ptps();
        ptfont();
}

void pttrailer(void)
{
        if (TROFF)
                OUT "x trailer\n" PUT;
}

void ptstop(void)
{
        if (TROFF)
                OUT "x stop\n" PUT;
}

void t_ptpause(void)
{
        if (ascii)
                return;
        ptlead();
        vpos = 0;
        pttrailer();
        ptlead();
        OUT "x pause\n" PUT;
        flusho();
        mpts = mfont = 0;
        ptesc();
        esc = po;
        hpos = vpos = 0;        /* probably in wrong place */
}