123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- /*
- n10.c
- Device interfaces
- */
- #include "tdef.h"
- #include "ext.h"
- #include "fns.h"
- #include <ctype.h>
- Term t; /* terminal characteristics */
- int dtab;
- int plotmode;
- int esct;
- enum { Notype = 0, Type = 1 };
- static char *parse(char *s, int typeit) /* convert \0, etc to nroff driving table format */
- { /* typeit => add a type id to the front for later use */
- static char buf[100], *t, *obuf;
- int quote = 0;
- wchar_t wc;
- obuf = typeit == Type ? buf : buf+1;
- #ifdef UNICODE
- if (mbtowc(&wc, s, strlen(s)) > 1) { /* it's multibyte, */
- buf[0] = MBchar;
- strcpy(buf+1, s);
- return obuf;
- } /* so just hand it back */
- #endif /*UNICODE*/
- buf[0] = Troffchar;
- t = buf + 1;
- if (*s == '"') {
- s++;
- quote = 1;
- }
- for (;;) {
- if (quote && *s == '"') {
- s++;
- break;
- }
- if (!quote && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\0'))
- break;
- if (*s != '\\')
- *t++ = *s++;
- else {
- s++; /* skip \\ */
- if (isdigit(s[0]) && isdigit(s[1]) && isdigit(s[2])) {
- *t++ = (s[0]-'0')<<6 | (s[1]-'0')<<3 | s[2]-'0';
- s += 2;
- } else if (isdigit(s[0])) {
- *t++ = *s - '0';
- } else if (*s == 'b') {
- *t++ = '\b';
- } else if (*s == 'n') {
- *t++ = '\n';
- } else if (*s == 'r') {
- *t++ = '\r';
- } else if (*s == 't') {
- *t++ = '\t';
- } else {
- *t++ = *s;
- }
- s++;
- }
- }
- *t = '\0';
- return obuf;
- }
- static int getnrfont(FILE *fp) /* read the nroff description file */
- {
- FILE *fin;
- Chwid chtemp[NCHARS];
- static Chwid chinit;
- int i, nw, n, wid, code, type;
- char buf[100], ch[100], s1[100], s2[100], cmd[300];
- wchar_t wc;
- chinit.wid = 1;
- chinit.str = "";
- for (i = 0; i < ALPHABET; i++) {
- chtemp[i] = chinit; /* zero out to begin with */
- chtemp[i].num = chtemp[i].code = i; /* every alphabetic character is itself */
- chtemp[i].wid = 1; /* default ascii widths */
- }
- skipline(fp);
- nw = ALPHABET;
- while (fgets(buf, sizeof buf, fp) != NULL) {
- sscanf(buf, "%s %s %[^\n]", ch, s1, s2);
- if (!eq(s1, "\"")) { /* genuine new character */
- sscanf(s1, "%d", &wid);
- } /* else it's a synonym for prev character, */
- /* so leave previous values intact */
- /* decide what kind of alphabet it might come from */
- if (strlen(ch) == 1) { /* it's ascii */
- n = ch[0]; /* origin includes non-graphics */
- chtemp[n].num = ch[0];
- } else if (ch[0] == '\\' && ch[1] == '0') {
- n = strtol(ch+1, 0, 0); /* \0octal or \0xhex */
- chtemp[n].num = n;
- #ifdef UNICODE
- } else if (mbtowc(&wc, ch, strlen(ch)) > 1) {
- chtemp[nw].num = chadd(ch, MBchar, Install);
- n = nw;
- nw++;
- #endif /*UNICODE*/
- } else {
- if (strcmp(ch, "---") == 0) { /* no name */
- sprintf(ch, "%d", code);
- type = Number;
- } else
- type = Troffchar;
- /* BUG in here somewhere when same character occurs twice in table */
- chtemp[nw].num = chadd(ch, type, Install);
- n = nw;
- nw++;
- }
- chtemp[n].wid = wid;
- chtemp[n].str = strdupl(parse(s2, Type));
- }
- t.tfont.nchars = nw;
- t.tfont.wp = (Chwid *) malloc(nw * sizeof(Chwid));
- if (t.tfont.wp == NULL)
- return -1;
- for (i = 0; i < nw; i++)
- t.tfont.wp[i] = chtemp[i];
- return 1;
- }
- void n_ptinit(void)
- {
- int i;
- char *p, *cp;
- char opt[50], cmd[100];
- FILE *fp;
- hmot = n_hmot;
- makem = n_makem;
- setabs = n_setabs;
- setch = n_setch;
- sethl = n_sethl;
- setht = n_setht;
- setslant = n_setslant;
- vmot = n_vmot;
- xlss = n_xlss;
- findft = n_findft;
- width = n_width;
- mchbits = n_mchbits;
- ptlead = n_ptlead;
- ptout = n_ptout;
- ptpause = n_ptpause;
- setfont = n_setfont;
- setps = n_setps;
- setwd = n_setwd;
- if ((p = getenv("NROFFTERM")) != 0)
- strcpy(devname, p);
- if (termtab[0] == 0)
- strcpy(termtab,DWBntermdir);
- if (fontdir[0] == 0)
- strcpy(fontdir, "");
- if (devname[0] == 0)
- strcpy(devname, NDEVNAME);
- pl = 11*INCH;
- po = PO;
- hyf = 0;
- ascii = 1;
- lg = 0;
- fontlab[1] = 'R';
- fontlab[2] = 'I';
- fontlab[3] = 'B';
- fontlab[4] = PAIR('B','I');
- fontlab[5] = 'D';
- bdtab[3] = 3;
- bdtab[4] = 3;
- /* hyphalg = 0; /* for testing */
- strcat(termtab, devname);
- if ((fp = fopen(termtab, "r")) == NULL) {
- ERROR "cannot open %s", termtab WARN;
- exit(-1);
- }
- /* this loop isn't robust about input format errors. */
- /* it assumes name, name-value pairs..., charset */
- /* god help us if we get out of sync. */
- fscanf(fp, "%s", cmd); /* should be device name... */
- if (!is(devname) && trace)
- ERROR "wrong terminal name: saw %s, wanted %s", cmd, devname WARN;
- for (;;) {
- fscanf(fp, "%s", cmd);
- if (is("charset"))
- break;
- fscanf(fp, " %[^\n]", opt);
- if (is("bset")) t.bset = atoi(opt);
- else if (is("breset")) t.breset = atoi(opt);
- else if (is("Hor")) t.Hor = atoi(opt);
- else if (is("Vert")) t.Vert = atoi(opt);
- else if (is("Newline")) t.Newline = atoi(opt);
- else if (is("Char")) t.Char = atoi(opt);
- else if (is("Em")) t.Em = atoi(opt);
- else if (is("Halfline")) t.Halfline = atoi(opt);
- else if (is("Adj")) t.Adj = atoi(opt);
- else if (is("twinit")) t.twinit = strdupl(parse(opt, Notype));
- else if (is("twrest")) t.twrest = strdupl(parse(opt, Notype));
- else if (is("twnl")) t.twnl = strdupl(parse(opt, Notype));
- else if (is("hlr")) t.hlr = strdupl(parse(opt, Notype));
- else if (is("hlf")) t.hlf = strdupl(parse(opt, Notype));
- else if (is("flr")) t.flr = strdupl(parse(opt, Notype));
- else if (is("bdon")) t.bdon = strdupl(parse(opt, Notype));
- else if (is("bdoff")) t.bdoff = strdupl(parse(opt, Notype));
- else if (is("iton")) t.iton = strdupl(parse(opt, Notype));
- else if (is("itoff")) t.itoff = strdupl(parse(opt, Notype));
- else if (is("ploton")) t.ploton = strdupl(parse(opt, Notype));
- else if (is("plotoff")) t.plotoff = strdupl(parse(opt, Notype));
- else if (is("up")) t.up = strdupl(parse(opt, Notype));
- else if (is("down")) t.down = strdupl(parse(opt, Notype));
- else if (is("right")) t.right = strdupl(parse(opt, Notype));
- else if (is("left")) t.left = strdupl(parse(opt, Notype));
- else
- ERROR "bad tab.%s file, %s %s", devname, cmd, opt WARN;
- }
- getnrfont(fp);
- fclose(fp);
- sps = EM;
- ics = EM * 2;
- dtab = 8 * t.Em;
- for (i = 0; i < 16; i++)
- tabtab[i] = dtab * (i + 1);
- pl = 11 * INCH;
- po = PO;
- spacesz = SS;
- lss = lss1 = VS;
- ll = ll1 = lt = lt1 = LL;
- smnt = nfonts = 5; /* R I B BI S */
- n_specnames(); /* install names like "hyphen", etc. */
- if (eqflg)
- t.Adj = t.Hor;
- }
- void n_specnames(void)
- {
- int i;
- for (i = 0; spnames[i].n; i++)
- *spnames[i].n = chadd(spnames[i].v, Troffchar, Install);
- if (c_isalnum == 0)
- c_isalnum = NROFFCHARS;
- }
- void twdone(void)
- {
- if (!TROFF && t.twrest) {
- obufp = obuf;
- oputs(t.twrest);
- flusho();
- if (pipeflg) {
- pclose(ptid);
- }
- restore_tty();
- }
- }
- void n_ptout(Tchar i)
- {
- *olinep++ = i;
- if (olinep >= &oline[LNSIZE])
- olinep--;
- if (cbits(i) != '\n')
- return;
- olinep--;
- lead += dip->blss + lss - t.Newline;
- dip->blss = 0;
- esct = esc = 0;
- if (olinep > oline) {
- move();
- ptout1();
- oputs(t.twnl);
- } else {
- lead += t.Newline;
- move();
- }
- lead += dip->alss;
- dip->alss = 0;
- olinep = oline;
- }
- void ptout1(void)
- {
- int k;
- char *codep;
- int w, j, phyw;
- Tchar *q, i;
- static int oxfont = FT; /* start off in roman */
- for (q = oline; q < olinep; q++) {
- i = *q;
- if (ismot(i)) {
- j = absmot(i);
- if (isnmot(i))
- j = -j;
- if (isvmot(i))
- lead += j;
- else
- esc += j;
- continue;
- }
- if ((k = cbits(i)) <= ' ') {
- switch (k) {
- case ' ': /*space*/
- esc += t.Char;
- break;
- case '\033':
- case '\007':
- case '\016':
- case '\017':
- oput(k);
- break;
- }
- continue;
- }
- phyw = w = t.Char * t.tfont.wp[k].wid;
- if (iszbit(i))
- w = 0;
- if (esc || lead)
- move();
- esct += w;
- xfont = fbits(i);
- if (xfont != oxfont) {
- switch (oxfont) {
- case ULFONT: oputs(t.itoff); break;
- case BDFONT: oputs(t.bdoff); break;
- case BIFONT: oputs(t.itoff); oputs(t.bdoff); break;
- }
- switch (xfont) {
- case ULFONT:
- if (*t.iton & 0377) oputs(t.iton); break;
- case BDFONT:
- if (*t.bdon & 0377) oputs(t.bdon); break;
- case BIFONT:
- if (*t.bdon & 0377) oputs(t.bdon);
- if (*t.iton & 0377) oputs(t.iton);
- break;
- }
- oxfont = xfont;
- }
- if ((xfont == ulfont || xfont == BIFONT) && !(*t.iton & 0377)) {
- for (j = w / t.Char; j > 0; j--)
- oput('_');
- for (j = w / t.Char; j > 0; j--)
- oput('\b');
- }
- if (!(*t.bdon & 0377) && ((j = bdtab[xfont]) || xfont == BDFONT || xfont == BIFONT))
- j++;
- else
- j = 1; /* number of overstrikes for bold */
- if (k < ALPHABET) { /* ordinary ascii */
- oput(k);
- while (--j > 0) {
- oput('\b');
- oput(k);
- }
- } else if (k >= t.tfont.nchars) { /* BUG -- not really understood */
- /* fprintf(stderr, "big char %d, name %s\n", k, chname(k)); /* */
- oputs(chname(k)+1); /* BUG: should separate Troffchar and MBchar... */
- } else if (t.tfont.wp[k].str == 0) {
- /* fprintf(stderr, "nostr char %d, name %s\n", k, chname(k)); /* */
- oputs(chname(k)+1); /* BUG: should separate Troffchar and MBchar... */
- } else if (t.tfont.wp[k].str[0] == MBchar) { /* parse() puts this on */
- /* fprintf(stderr, "MBstr char %d, name %s\n", k, chname(k)); /* */
- oputs(t.tfont.wp[k].str+1);
- } else {
- int oj = j;
- /* fprintf(stderr, "str char %d, name %s\n", k, chname(k)); /* */
- codep = t.tfont.wp[k].str+1; /* Troffchar by default */
- while (*codep != 0) {
- if (*codep & 0200) {
- codep = plot(codep);
- oput(' ');
- } else {
- if (*codep == '%') /* escape */
- codep++;
- oput(*codep);
- if (*codep == '\033')
- oput(*++codep);
- else if (*codep != '\b')
- for (j = oj; --j > 0; ) {
- oput('\b');
- oput(*codep);
- }
- codep++;
- }
- }
- }
- if (!w)
- for (j = phyw / t.Char; j > 0; j--)
- oput('\b');
- }
- }
- char *plot(char *x)
- {
- int i;
- char *j, *k;
- oputs(t.ploton);
- k = x;
- if ((*k & 0377) == 0200)
- k++;
- for (; *k; k++) {
- if (*k == '%') { /* quote char within plot mode */
- oput(*++k);
- } else if (*k & 0200) {
- if (*k & 0100) {
- if (*k & 040)
- j = t.up;
- else
- j = t.down;
- } else {
- if (*k & 040)
- j = t.left;
- else
- j = t.right;
- }
- if ((i = *k & 037) == 0) { /* 2nd 0200 turns it off */
- ++k;
- break;
- }
- while (i--)
- oputs(j);
- } else
- oput(*k);
- }
- oputs(t.plotoff);
- return(k);
- }
- void move(void)
- {
- int k;
- char *i, *j;
- char *p, *q;
- int iesct, dt;
- iesct = esct;
- if (esct += esc)
- i = "\0";
- else
- i = "\n\0";
- j = t.hlf;
- p = t.right;
- q = t.down;
- if (lead) {
- if (lead < 0) {
- lead = -lead;
- i = t.flr;
- /* if(!esct)i = t.flr; else i = "\0";*/
- j = t.hlr;
- q = t.up;
- }
- if (*i & 0377) {
- k = lead / t.Newline;
- lead = lead % t.Newline;
- while (k--)
- oputs(i);
- }
- if (*j & 0377) {
- k = lead / t.Halfline;
- lead = lead % t.Halfline;
- while (k--)
- oputs(j);
- } else { /* no half-line forward, not at line begining */
- k = lead / t.Newline;
- lead = lead % t.Newline;
- if (k > 0)
- esc = esct;
- i = "\n";
- while (k--)
- oputs(i);
- }
- }
- if (esc) {
- if (esc < 0) {
- esc = -esc;
- j = "\b";
- p = t.left;
- } else {
- j = " ";
- if (hflg)
- while ((dt = dtab - (iesct % dtab)) <= esc) {
- if (dt % t.Em)
- break;
- oput(TAB);
- esc -= dt;
- iesct += dt;
- }
- }
- k = esc / t.Em;
- esc = esc % t.Em;
- while (k--)
- oputs(j);
- }
- if ((*t.ploton & 0377) && (esc || lead)) {
- oputs(t.ploton);
- esc /= t.Hor;
- lead /= t.Vert;
- while (esc--)
- oputs(p);
- while (lead--)
- oputs(q);
- oputs(t.plotoff);
- }
- esc = lead = 0;
- }
- void n_ptlead(void)
- {
- move();
- }
- void n_ptpause(void )
- {
- char junk;
- flusho();
- read(2, &junk, 1);
- }
|