home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 Chris Lewis
- All Rights Reserved
-
- See the LICENSE file for a full description of restrictions under which
- this software is provided.
-
- Function: ditroff frontend.
- */
-
- #include "defs.h"
-
- #ifndef lint
- static char SCCSid[] =
- "@(#)dit.c: 91/03/26 Copyright 91/03/26 00:13:12 Chris Lewis";
- #endif
-
- extern struct cattab tabN[], tabS[], *extidx;
- extern struct troff2befont *extchar;
-
- /* Translation of single character characters to cattab
- entries and, hence, emittable strings via the backends.
- */
- struct cattab **dittab;
-
- /* \(xx characters */
- struct cattab **spctab, **ts;
-
- struct cattab *ditsearch(str)
- char *str; {
- /* should do binary search */
- register int l, mid, h, k;
- l = 0;
- h = extcount - 1;
- #ifdef NEVER
- for (ts = spctab; *ts; ts++)
- if (strcmp((*ts)->ch_name, str) == 0)
- return(*ts);
- #endif
- while(l <= h) {
- mid = (l + h) >> 1;
- k = strcmp(str, spctab[mid]->ch_name);
- if (k == 0)
- return(spctab[mid]);
- else if (k < 0)
- h = mid - 1;
- else
- l = mid + 1;
- }
- return((struct cattab *) NULL);
- }
-
- catcmp(a, b)
- struct cattab **a, **b; {
- return(strcmp((*a)->ch_name, (*b)->ch_name));
- }
-
- addtab(table)
- struct cattab *table; {
- register struct cattab *p;
- extern char *realloc();
-
- for (p = table; p->ch_name != NOC; p++) {
- DBP((D_CAT, "Addtab: %s\n", p->ch_name));
- if (p->ch_desc != NOC && p->ch_catidx != NTC)
- if (strlen(p->ch_name) == 1)
- dittab[p->ch_name[0]] = p;
- else {
- DBP((D_CAT, "AddtabS: %s %d\n", p->ch_name, extcount));
- if (extcount > 0 && !(extcount%EXTCHUNK)) {
- spctab = (struct cattab **) realloc(spctab,
- sizeof(struct cattab *) * (extcount + EXTCHUNK + 1));
- clrarray(&spctab[extcount], sizeof(struct cattab *) *
- (EXTCHUNK+1));
- }
- spctab[extcount++] = p;
- }
- }
- }
-
- fixtab() {
- register int i;
- extern char *malloc();
-
- dittab = (struct cattab **) mustmalloc(sizeof(struct cattab *) * 256,
- "dittab");
-
- spctab = (struct cattab **) mustmalloc(sizeof(struct cattab *) *
- (EXTCHUNK+1), "spctab");
-
- extcount = 0;
-
- addtab(tabN);
- addtab(tabS);
- addtab(extidx);
-
- /* Magic */
- dittab['-'] = &tabN[31];
- dittab['_'] = &tabS[31];
-
- DBP((D_CAT, "End addtab: %d characters\n", extcount));
-
- spctab[extcount] = NULL;
-
- DBP((D_CAT, "After NULL\n"));
-
- if (debug&D_CAT) {
-
- for (ts = spctab; *ts; ts++)
- DBP((D_CAT, "%s -> %08x (%d)\n", (*ts)->ch_name, *ts,
- (*ts)->ch_catidx));
-
- }
-
- qsort(spctab, extcount, sizeof (struct cattab *), catcmp);
-
- DBP((D_CAT, "After qsort\n"));
-
- #ifdef DEBUG
- if (debug&D_CAT) {
-
- for (ts = spctab; *ts; ts++)
- DBP((D_CAT, "%s -> %08x (%d)\n", (*ts)->ch_name, *ts,
- (*ts)->ch_catidx));
-
- for (i = 0; i < 256; i++)
- if (dittab[i])
- DBP((D_CAT, "%d:%02x:%c: %d/%d\n", i, i, i, dittab[i]->ch_set,
- dittab[i]->ch_catidx));
- }
- #endif
- }
-
- #ifdef DIT
- int indtres;
-
- int points, font, ch, i;
- int xpos, ypos;
-
- dit() {
- register int cmd, nc, i, j;
- register struct cattab *p;
- register struct cattab *last = (struct cattab *) NULL;
- char special[512];
- fixtab();
- DBP((D_CAT, "Finished fixtab\n"));
- while(1) {
- switch(cmd = skipwhite()) {
- case EOF:
- goto finish;
- case 's':
- points = getnum();
- DBP((D_CAT, "Pointsize %d\n", points));
- break;
- case 'f':
- font = getnum();
- if (font < 0 || font >= INTFONTS) {
- fprintf(stderr,
- "%s: font number %d too high - make INTFONTS bigger\n",
- progname, font);
- font = 1;
- } else if (font == 0)
- /* font 0 stuff - because I map font n to n-1 internally */
- font = INTFONTS - 1;
- else
- font--;
- DBP((D_CAT, "Font %d\n", font));
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- xpos += (cmd - '0') * 10 + (getchar() - '0');
- /*fallthru*/
- case 'c':
- p = dittab[ch = (getchar()&0xff)];
- if (!p) {
- char seq[2];
-
- if (ch == ' ')
- break;
- fprintf(stderr,
- "%s: don't know this character: 0x%02x(%c)\n",
- progname, ch, ch);
- seq[0] = ch;
- seq[1] = '\0';
- ditemit(xpos, ypos, font, points, 0, seq);
- break;
- }
- if (p->ch_wididx == NTC) /* extended character */
- ditemit(xpos, ypos,
- p->ch_set == N ? -font-1: -symidx-1,
- points, p->ch_catidx,
- extchars[p->ch_catidx].t2b_charseq);
- else
- ditemit(xpos, ypos,
- p->ch_set == N ? font: symidx,
- points, p->ch_catidx, (char *) NULL);
- break;
-
- case 'u': /* groff kern this sequence command */
- j = getnum();
- /* kern ignored for the moment - have to read the width
- table */
- /* fallthru */
- case 't': /* groff sequence */
- { char ubuf[100];
- /* should really read the width tables and
- do each character individually, but for the
- moment, this should work reasonably well */
- #ifdef OPT
- canonflush();
- #endif
- while((ch = getchar()) != EOF && isspace(ch));
- if (ch == EOF)
- break;
- ubuf[i++] = ch;
- while((ch = getchar()) != EOF && !isspace(ch))
- ubuf[i++] = ch;
- p = dittab[ubuf[0]&0xff];
- if (!p)
- ditemit(xpos, ypos, font, points, 0, ubuf);
- else if (p->ch_wididx == NTC)
- ditemit(xpos, ypos,
- p->ch_set == N ? -font-1: -symidx-1,
- points, 0, ubuf);
- else
- ditemit(xpos, ypos, p->ch_set == N ? font: symidx,
- points, 0, ubuf);
- }
- case 'C':
- i = 0;
- while((ch = getchar()) != EOF && !isspace(ch))
- special[i++] = ch;
- special[i] = '\0';
- if (last && strcmp(last->ch_name, special) == 0)
- p = last;
- else {
- p = ditsearch(special);
- last = p;
- }
- if (!p) {
- fprintf(stderr,
- "%s: don't know this character: %s\n", progname,
- special);
- } else {
- if (p->ch_wididx == NTC) /* extended character */
- ditemit(xpos, ypos,
- p->ch_set == N ? -font-1 : -symidx-1,
- points, p->ch_catidx,
- extchars[p->ch_catidx].t2b_charseq);
- else
- ditemit(xpos, ypos,
- p->ch_set == N ? font : symidx,
- points, p->ch_catidx, (char *) NULL);
- DBP((D_CAT, "Special %s\n", special));
- }
- break;
- case 'x':
- {
- char cmd[20], a1[20], a2[20], a3[20];
- int cnt;
- i = 0;
- #ifdef OPT
- canonflush();
- #endif
- /* synchronize special X & Y to current position
- (ie: so psfig will work */
- specXPos = (int) ((long) xpos * TROFFRESOLUTION / indtres);
- specYPos = (int) ((long) ypos * TROFFRESOLUTION / indtres);
-
- while((ch = getchar()) != EOF && isspace(ch));
- special[i++] = ch;
- while((ch = getchar()) != EOF && ch != '\n')
- special[i++] = ch;
- special[i] = '\0';
- DBP((D_CAT, "Command %s\n", special));
- i = sscanf(special, "%s %s %s %s", cmd, a1, a2, a3);
- if (i <= 0) {
- fprintf(stderr, "%s: bad x command: %s\n",
- progname, special);
- exit(1);
- }
- switch(cmd[0]) {
- case 'p':
- case 'H':
- case 'S':
- break;
- case 'f': /* font load */
- if (i != 3) {
- fprintf(stderr, "%s: bad font command: %s\n",
- progname, special);
- exit(1);
- }
- sprintf(special, "F%s%s", a1, a2);
- DBP((D_CAT, "FONT %s %s\n", a1, a2));
- dospecial(special);
- break;
- case 'r': /* specify resolution */
- if (i != 4) {
- fprintf(stderr, "%s: bad res command: %s\n",
- progname, special);
- exit(1);
- }
- indtres = atoi(a1);
- if (indtres <= 0) {
- if (i != 4) {
- fprintf(stderr,
- "%s: ridiculous res value: %s\n",
- progname, special);
- exit(1);
- }
- }
- DBP((D_CAT, "RES %d\n", indtres));
- break;
- case 'i':
- DBP((D_CAT, "INIT\n"));
- if (be->beprolog)
- (*be->beprolog)();
- resetState();
- break;
- case 't':
- DBP((D_CAT, "TRAILER\n"));
- break;
- case 's':
- DBP((D_CAT, "STOP\n"));
- return;
- case 'T':
- if (i != 2) {
- fprintf(stderr, "%s: bad x T command: %s\n",
- progname, special);
- exit(1);
- }
- device = mustmalloc(strlen(a1) + 1, "device");
- strcpy(device, a1);
- DBP((D_CAT, "TYPE %s\n", a1));
- break;
- case 'X':
- switch(a1[0]) {
- case 'f':
- a1[0] = 'I';
- break;
- case 'p':
- a1[0] = 'P';
- break;
- }
- dospecial(a1);
- break;
-
- default:
- fprintf(stderr, "%s: unknown special: %s\n",
- progname, special);
- }
- }
- break;
- case 'H':
- xpos = getnum();
- DBP((D_CAT, "Hor: %d\n", xpos));
- break;
- case 'h':
- xpos += getnum();
- DBP((D_CAT, "Hor (inc): %d\n", xpos));
- break;
- case 'V':
- #ifdef OPT
- canonflush();
- #endif
- ypos = getnum();
- DBP((D_CAT, "Ver: %d\n", ypos));
- break;
- case 'v':
- #ifdef OPT
- canonflush();
- #endif
- ypos += getnum();
- DBP((D_CAT, "Ver (inc): %d\n", ypos));
- break;
- break;
- case 'p':
- ch = getnum();
- DBP((D_CAT, "Page %d\n", ch));
- if (be->bepage)
- (*be->bepage)();
- break;
- case 'n': /* end of line */
- ch = getnum();
- ch = skipwhite();
- ungetc(ch, stdin);
- ch = getnum();
- break;
- case 'i': /* stipple? BERK */
- ch = getnum();
- break;
- case 'P': /* split end? BERK */
- break;
- case 'w':
- #ifdef OPT
- canonflush();
- #endif
- break;
- case '#':
- case 'D':
- case '!':
- #ifdef OPT
- canonflush();
- #endif
- i = 1;
- special[0] = cmd;
- while((ch = getchar()) != EOF && isspace(ch));
- special[i++] = ch;
- while((ch = getchar()) != EOF && ch != '\n')
- special[i++] = ch;
- special[i] = '\0';
- DBP((D_CAT, "#/D/! %s\n", special));
-
- switch(cmd) {
- case '#':
- break;
- case '!':
- special[0] = 'P';
- dospecial(xpos * TROFFRESOLUTION / indtres,
- ypos * TROFFRESOLUTION / indtres,
- special);
- break;
- case 'D': {
- short values[100];
- int opcode, ct, newx, newy;
-
- if (!(opcode = drawparse(&ct, values, &special[1])))
- break;
- if (!strchr("lcCeEa~tfpP", opcode)) {
- fprintf(stderr, "%s: unknown draw code %s\n",
- progname, special);
- break;
- }
- newx = xpos;
- newy = ypos;
- if (opcode == 'e' || opcode == 'E')
- newx += values[0];
- else if (opcode != 't' && opcode != 'f') {
- for (i = 0; i < ct/2; i++) {
- newx += values[i*2];
- newy += values[i*2+1];
- }
- if (i*2 < ct)
- newx += values[i*2];
- }
- if (opcode != 't' && opcode != 'f')
- for (i = 0; i < ct; i++)
- values[i] = values[i] * TROFFRESOLUTION /
- indtres;
-
- DBP((D_CAT, "Draw: xpos,ypos,opcode,ct,special = %d,%d,%d,%d,%s\n",
- xpos, ypos, opcode, ct, special));
-
- if (be->bedraw)
- (be->bedraw)(xpos * TROFFRESOLUTION / indtres,
- ypos * TROFFRESOLUTION / indtres,
- opcode, ct, values, special);
- xpos = newx;
- ypos = newy;
- }
- }
- break;
- }
- }
- finish: ;
- }
-
- skipwhite() {
- int c;
- while((c = getchar()) != EOF && isspace(c));
- return(c);
- }
-
- getnum() {
- register int ret = 0;
- int c;
- while((c = getchar()) != EOF && isdigit(c))
- ret = ret * 10 + (c - '0');
- ungetc(c, stdin);
- DBP((D_CAT, "Getnum: %d\n", ret));
- return(ret);
- }
-
- ditemit(x, y, font, points, troffChar, sequence)
- int x, y;
- int font, points, troffChar;
- register char *sequence; {
- DBP((D_CAT, "x,y: %d/%d -> ", x, y));
- x = (int) ((long) x * TROFFRESOLUTION / indtres);
- y = (int) ((long) y * TROFFRESOLUTION / indtres);
- DBP((D_CAT, "%d/%d (font,points,ch = %d,%d,%d)\n", x, y, font, points,
- troffChar));
- #ifdef OPT
- if (sequence) {
- canonflush();
- if (be->beputchar)
- (*be->beputchar)(x, y, font, points, troffChar, sequence);
- } else
- canoninsert(x, y, font, points, troffChar);
- #else
- if (be->beputchar)
- (*be->beputchar)(x, y, font, points, troffChar, sequence);
- #endif
- }
- #endif
-