aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/troff/t10.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/troff/t10.c')
-rw-r--r--src/cmd/troff/t10.c512
1 files changed, 512 insertions, 0 deletions
diff --git a/src/cmd/troff/t10.c b/src/cmd/troff/t10.c
new file mode 100644
index 00000000..3e8026d1
--- /dev/null
+++ b/src/cmd/troff/t10.c
@@ -0,0 +1,512 @@
+#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)
+ strcpy(devname, p);
+ 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;
+
+ sprintf(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] = 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;
+ int z, dx, dy, dx2, dy2, n;
+ Tchar i;
+ int outsize; /* size of object being printed */
+
+ 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 */
+}