home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume24 / psroff3.0 / part04 / dit.c next >
Encoding:
C/C++ Source or Header  |  1991-10-09  |  11.5 KB  |  514 lines

  1. /*
  2.     Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 Chris Lewis
  3.         All Rights Reserved
  4.  
  5.     See the LICENSE file for a full description of restrictions under which
  6.     this software is provided.
  7.  
  8.     Function:        ditroff frontend.
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. #ifndef    lint
  14. static char SCCSid[] =
  15.     "@(#)dit.c: 91/03/26 Copyright 91/03/26 00:13:12 Chris Lewis";
  16. #endif
  17.  
  18. extern struct cattab tabN[], tabS[], *extidx;
  19. extern struct troff2befont *extchar;
  20.  
  21. /*    Translation of single character characters to cattab
  22.     entries and, hence, emittable strings via the backends.
  23.  */
  24. struct cattab **dittab;
  25.  
  26. /*    \(xx characters */
  27. struct cattab **spctab, **ts;
  28.  
  29. struct cattab *ditsearch(str)
  30. char *str; {
  31.     /* should do binary search */
  32.     register int l, mid, h, k;
  33.     l = 0;
  34.     h = extcount - 1;
  35. #ifdef    NEVER
  36.     for (ts = spctab; *ts; ts++)
  37.     if (strcmp((*ts)->ch_name, str) == 0)
  38.         return(*ts);
  39. #endif
  40.     while(l <= h) {
  41.     mid = (l + h) >> 1;
  42.     k = strcmp(str, spctab[mid]->ch_name);
  43.     if (k == 0)
  44.         return(spctab[mid]);
  45.     else if (k < 0)
  46.         h = mid - 1;
  47.     else
  48.         l = mid + 1;
  49.     }
  50.     return((struct cattab *) NULL);
  51. }
  52.  
  53. catcmp(a, b)
  54. struct cattab **a, **b; {
  55.     return(strcmp((*a)->ch_name, (*b)->ch_name));
  56. }
  57.  
  58. addtab(table)
  59. struct cattab *table; {
  60.     register struct cattab *p;
  61.     extern char *realloc();
  62.  
  63.     for (p = table; p->ch_name != NOC; p++) {
  64.     DBP((D_CAT, "Addtab: %s\n", p->ch_name));
  65.     if (p->ch_desc != NOC && p->ch_catidx != NTC)
  66.         if (strlen(p->ch_name) == 1)
  67.         dittab[p->ch_name[0]] = p;
  68.         else {
  69.         DBP((D_CAT, "AddtabS: %s %d\n", p->ch_name, extcount));
  70.         if (extcount > 0 && !(extcount%EXTCHUNK)) {
  71.             spctab = (struct cattab **) realloc(spctab,
  72.             sizeof(struct cattab *) * (extcount + EXTCHUNK + 1));
  73.             clrarray(&spctab[extcount], sizeof(struct cattab *) *
  74.             (EXTCHUNK+1));
  75.         }
  76.         spctab[extcount++] = p;
  77.         }
  78.     }
  79. }
  80.  
  81. fixtab() {
  82.     register int i;
  83.     extern char *malloc();
  84.  
  85.     dittab = (struct cattab **) mustmalloc(sizeof(struct cattab *) * 256,
  86.     "dittab");
  87.  
  88.     spctab = (struct cattab **) mustmalloc(sizeof(struct cattab *) *
  89.     (EXTCHUNK+1), "spctab");
  90.  
  91.     extcount = 0;
  92.  
  93.     addtab(tabN);
  94.     addtab(tabS);
  95.     addtab(extidx);
  96.  
  97.     /*    Magic */
  98.     dittab['-'] = &tabN[31];
  99.     dittab['_'] = &tabS[31];
  100.  
  101.     DBP((D_CAT, "End addtab: %d characters\n", extcount));
  102.  
  103.     spctab[extcount] = NULL;
  104.  
  105.     DBP((D_CAT, "After NULL\n"));
  106.  
  107.     if (debug&D_CAT) {
  108.  
  109.     for (ts = spctab; *ts; ts++)
  110.         DBP((D_CAT, "%s -> %08x (%d)\n", (*ts)->ch_name, *ts,
  111.         (*ts)->ch_catidx));
  112.  
  113.     }
  114.  
  115.     qsort(spctab, extcount, sizeof (struct cattab *), catcmp);
  116.  
  117.     DBP((D_CAT, "After qsort\n"));
  118.  
  119. #ifdef DEBUG
  120.     if (debug&D_CAT) {
  121.  
  122.     for (ts = spctab; *ts; ts++)
  123.         DBP((D_CAT, "%s -> %08x (%d)\n", (*ts)->ch_name, *ts,
  124.         (*ts)->ch_catidx));
  125.  
  126.     for (i = 0; i < 256; i++)
  127.         if (dittab[i])
  128.         DBP((D_CAT, "%d:%02x:%c: %d/%d\n", i, i, i, dittab[i]->ch_set,
  129.         dittab[i]->ch_catidx));
  130.     }
  131. #endif
  132. }
  133.  
  134. #ifdef    DIT
  135. int indtres;
  136.  
  137. int points, font, ch, i;
  138. int xpos, ypos;
  139.  
  140. dit() {
  141.     register int cmd, nc, i, j;
  142.     register struct cattab *p;
  143.     register struct cattab *last = (struct cattab *) NULL;
  144.     char special[512];
  145.     fixtab();
  146.     DBP((D_CAT, "Finished fixtab\n"));
  147.     while(1) {
  148.     switch(cmd = skipwhite()) {
  149.         case EOF:
  150.         goto finish;
  151.         case 's':
  152.         points = getnum();
  153.         DBP((D_CAT, "Pointsize %d\n", points));
  154.         break;
  155.         case 'f':
  156.         font = getnum();
  157.         if (font < 0 || font >= INTFONTS) {
  158.             fprintf(stderr,
  159.             "%s: font number %d too high - make INTFONTS bigger\n",
  160.             progname, font);
  161.             font = 1;
  162.         } else if (font == 0)
  163.             /* font 0 stuff - because I map font n to n-1 internally */
  164.             font = INTFONTS - 1;
  165.         else
  166.             font--;
  167.         DBP((D_CAT, "Font %d\n", font));
  168.         break;
  169.         case '0':
  170.         case '1':
  171.         case '2':
  172.         case '3':
  173.         case '4':
  174.         case '5':
  175.         case '6':
  176.         case '7':
  177.         case '8':
  178.         case '9':
  179.         xpos += (cmd - '0') * 10 + (getchar() - '0');
  180.         /*fallthru*/
  181.         case 'c':
  182.         p = dittab[ch = (getchar()&0xff)];
  183.         if (!p) {
  184.             char seq[2];
  185.  
  186.             if (ch == ' ')
  187.             break;
  188.             fprintf(stderr,
  189.             "%s: don't know this character: 0x%02x(%c)\n",
  190.             progname, ch, ch);
  191.             seq[0] = ch;
  192.             seq[1] = '\0';
  193.             ditemit(xpos, ypos, font, points, 0, seq);
  194.             break;
  195.         }
  196.         if (p->ch_wididx == NTC) /* extended character */
  197.             ditemit(xpos, ypos,
  198.             p->ch_set == N ? -font-1: -symidx-1,
  199.             points, p->ch_catidx,
  200.             extchars[p->ch_catidx].t2b_charseq);
  201.         else
  202.             ditemit(xpos, ypos,
  203.             p->ch_set == N ? font: symidx,
  204.             points, p->ch_catidx, (char *) NULL);
  205.         break;
  206.  
  207.         case 'u':        /* groff kern this sequence command */
  208.         j = getnum();
  209.         /* kern ignored for the moment - have to read the width
  210.            table */
  211.         /* fallthru */
  212.         case 't':        /* groff sequence */
  213.         { char ubuf[100];
  214.             /* should really read the width tables and
  215.                do each character individually, but for the
  216.                moment, this should work reasonably well */
  217. #ifdef    OPT
  218.             canonflush();
  219. #endif
  220.             while((ch = getchar()) != EOF && isspace(ch));
  221.             if (ch == EOF)
  222.             break;
  223.             ubuf[i++] = ch;
  224.             while((ch = getchar()) != EOF && !isspace(ch))
  225.             ubuf[i++] = ch;
  226.             p = dittab[ubuf[0]&0xff];
  227.             if (!p)
  228.             ditemit(xpos, ypos, font, points, 0, ubuf);
  229.             else if (p->ch_wididx == NTC)
  230.             ditemit(xpos, ypos,
  231.                 p->ch_set == N ? -font-1: -symidx-1,
  232.                 points, 0, ubuf);
  233.             else
  234.             ditemit(xpos, ypos, p->ch_set == N ? font: symidx,
  235.                 points, 0, ubuf);
  236.         }
  237.         case 'C':
  238.         i = 0;
  239.         while((ch = getchar()) != EOF && !isspace(ch))
  240.             special[i++] = ch;
  241.         special[i] = '\0';
  242.         if (last && strcmp(last->ch_name, special) == 0)
  243.             p = last;
  244.         else {
  245.             p = ditsearch(special);
  246.             last = p;
  247.         }
  248.         if (!p) {
  249.             fprintf(stderr,
  250.             "%s: don't know this character: %s\n", progname,
  251.             special);
  252.         } else {
  253.             if (p->ch_wididx == NTC) /* extended character */
  254.             ditemit(xpos, ypos,
  255.                 p->ch_set == N ? -font-1 : -symidx-1,
  256.                 points, p->ch_catidx,
  257.                 extchars[p->ch_catidx].t2b_charseq);
  258.             else
  259.             ditemit(xpos, ypos,
  260.                 p->ch_set == N ? font : symidx,
  261.                 points, p->ch_catidx, (char *) NULL);
  262.             DBP((D_CAT, "Special %s\n", special));
  263.         }
  264.         break;
  265.         case 'x':
  266.         {
  267.             char cmd[20], a1[20], a2[20], a3[20];
  268.             int cnt;
  269.             i = 0;
  270. #ifdef    OPT
  271.             canonflush();
  272. #endif
  273.             /* synchronize special X & Y to current position
  274.                (ie: so psfig will work */
  275.             specXPos = (int) ((long) xpos * TROFFRESOLUTION / indtres);
  276.             specYPos = (int) ((long) ypos * TROFFRESOLUTION / indtres);
  277.  
  278.             while((ch = getchar()) != EOF && isspace(ch));
  279.             special[i++] = ch;
  280.             while((ch = getchar()) != EOF && ch != '\n')
  281.             special[i++] = ch;
  282.             special[i] = '\0';
  283.             DBP((D_CAT, "Command %s\n", special));
  284.             i = sscanf(special, "%s %s %s %s", cmd, a1, a2, a3);
  285.             if (i <= 0) {
  286.             fprintf(stderr, "%s: bad x command: %s\n",
  287.                 progname, special);
  288.             exit(1);
  289.             }
  290.             switch(cmd[0]) {
  291.             case 'p':
  292.             case 'H':
  293.             case 'S':
  294.                 break;
  295.             case 'f':    /* font load */
  296.                 if (i != 3) {
  297.                 fprintf(stderr, "%s: bad font command: %s\n",
  298.                 progname, special);
  299.                 exit(1);
  300.                 }
  301.                 sprintf(special, "F%s%s", a1, a2);
  302.                 DBP((D_CAT, "FONT %s %s\n", a1, a2));
  303.                 dospecial(special);
  304.                 break;
  305.             case 'r':    /* specify resolution */
  306.                 if (i != 4) {
  307.                 fprintf(stderr, "%s: bad res command: %s\n",
  308.                 progname, special);
  309.                 exit(1);
  310.                 }
  311.                 indtres = atoi(a1);
  312.                 if (indtres <= 0) {
  313.                 if (i != 4) {
  314.                     fprintf(stderr,
  315.                     "%s: ridiculous res value: %s\n",
  316.                     progname, special);
  317.                     exit(1);
  318.                 }
  319.                 }
  320.                 DBP((D_CAT, "RES %d\n", indtres));
  321.                 break;
  322.             case 'i':
  323.                 DBP((D_CAT, "INIT\n"));
  324.                 if (be->beprolog)
  325.                 (*be->beprolog)();
  326.                 resetState();
  327.                 break;
  328.             case 't':
  329.                 DBP((D_CAT, "TRAILER\n"));
  330.                 break;
  331.             case 's':
  332.                 DBP((D_CAT, "STOP\n"));
  333.                 return;
  334.             case 'T':
  335.                 if (i != 2) {
  336.                 fprintf(stderr, "%s: bad x T command: %s\n",
  337.                     progname, special);
  338.                 exit(1);
  339.                 }
  340.                 device = mustmalloc(strlen(a1) + 1, "device");
  341.                 strcpy(device, a1);
  342.                 DBP((D_CAT, "TYPE %s\n", a1));
  343.                 break;
  344.             case 'X':
  345.                 switch(a1[0]) {
  346.                 case 'f':
  347.                     a1[0] = 'I';
  348.                     break;
  349.                 case 'p':
  350.                     a1[0] = 'P';
  351.                     break;
  352.                 }
  353.                 dospecial(a1);
  354.                 break;
  355.  
  356.             default:
  357.                 fprintf(stderr, "%s: unknown special: %s\n",
  358.                 progname, special);
  359.             }
  360.         }
  361.         break;
  362.         case 'H':
  363.         xpos = getnum();
  364.         DBP((D_CAT, "Hor: %d\n", xpos));
  365.         break;
  366.         case 'h':
  367.         xpos += getnum();
  368.         DBP((D_CAT, "Hor (inc): %d\n", xpos));
  369.         break;
  370.         case 'V':
  371. #ifdef    OPT
  372.         canonflush();
  373. #endif
  374.         ypos = getnum();
  375.         DBP((D_CAT, "Ver: %d\n", ypos));
  376.         break;
  377.         case 'v':
  378. #ifdef    OPT
  379.         canonflush();
  380. #endif
  381.         ypos += getnum();
  382.         DBP((D_CAT, "Ver (inc): %d\n", ypos));
  383.         break;
  384.         break;
  385.         case 'p':
  386.         ch = getnum();
  387.         DBP((D_CAT, "Page %d\n", ch));
  388.         if (be->bepage)
  389.             (*be->bepage)();
  390.         break;
  391.         case 'n':    /* end of line */
  392.         ch = getnum();
  393.         ch = skipwhite();
  394.         ungetc(ch, stdin);
  395.         ch = getnum();
  396.         break;
  397.         case 'i':    /* stipple? BERK */
  398.         ch = getnum();
  399.         break;
  400.         case 'P':    /* split end? BERK */
  401.         break;
  402.         case 'w':
  403. #ifdef    OPT
  404.         canonflush();
  405. #endif
  406.         break;
  407.         case '#':
  408.         case 'D':
  409.         case '!':
  410. #ifdef    OPT
  411.         canonflush();
  412. #endif
  413.         i = 1;
  414.         special[0] = cmd;
  415.         while((ch = getchar()) != EOF && isspace(ch));
  416.         special[i++] = ch;
  417.         while((ch = getchar()) != EOF && ch != '\n')
  418.             special[i++] = ch;
  419.         special[i] = '\0';
  420.         DBP((D_CAT, "#/D/! %s\n", special));
  421.  
  422.         switch(cmd) {
  423.             case '#':
  424.             break;
  425.             case '!':
  426.             special[0] = 'P';
  427.             dospecial(xpos * TROFFRESOLUTION / indtres,
  428.                      ypos * TROFFRESOLUTION / indtres,
  429.                      special);
  430.             break;
  431.             case 'D': {
  432.             short values[100];
  433.             int opcode, ct, newx, newy;
  434.  
  435.             if (!(opcode = drawparse(&ct, values, &special[1])))
  436.                 break;
  437.             if (!strchr("lcCeEa~tfpP", opcode)) {
  438.                 fprintf(stderr, "%s: unknown draw code %s\n",
  439.                 progname, special);
  440.                 break;
  441.             }
  442.             newx = xpos;
  443.             newy = ypos;
  444.             if (opcode == 'e' || opcode == 'E')
  445.                 newx += values[0];
  446.             else if (opcode != 't' && opcode != 'f') {
  447.                 for (i = 0; i < ct/2; i++) {
  448.                 newx += values[i*2];
  449.                 newy += values[i*2+1];
  450.                 }
  451.                 if (i*2 < ct)
  452.                 newx += values[i*2];
  453.             }
  454.             if (opcode != 't' && opcode != 'f')
  455.                 for (i = 0; i < ct; i++)
  456.                 values[i] = values[i] * TROFFRESOLUTION /
  457.                             indtres;
  458.  
  459. DBP((D_CAT, "Draw: xpos,ypos,opcode,ct,special = %d,%d,%d,%d,%s\n",
  460.     xpos, ypos, opcode, ct, special));
  461.  
  462.             if (be->bedraw)
  463.                 (be->bedraw)(xpos * TROFFRESOLUTION / indtres,
  464.                      ypos * TROFFRESOLUTION / indtres,
  465.                      opcode, ct, values, special);
  466.             xpos = newx;
  467.             ypos = newy;
  468.             }
  469.         }
  470.         break;
  471.     }
  472.     }
  473.     finish: ;
  474. }
  475.  
  476. skipwhite() {
  477.     int c;
  478.     while((c = getchar()) != EOF && isspace(c));
  479.     return(c);
  480. }
  481.  
  482. getnum() {
  483.     register int ret = 0;
  484.     int c;
  485.     while((c = getchar()) != EOF && isdigit(c))
  486.     ret = ret * 10 + (c - '0');
  487.     ungetc(c, stdin);
  488.     DBP((D_CAT, "Getnum: %d\n", ret));
  489.     return(ret);
  490. }
  491.  
  492. ditemit(x, y, font, points, troffChar, sequence)
  493. int x, y;
  494. int font, points, troffChar;
  495. register char *sequence; {
  496.     DBP((D_CAT, "x,y: %d/%d -> ", x, y));
  497.     x = (int) ((long) x * TROFFRESOLUTION / indtres);
  498.     y = (int) ((long) y * TROFFRESOLUTION / indtres);
  499.     DBP((D_CAT, "%d/%d (font,points,ch = %d,%d,%d)\n", x, y, font, points,
  500.     troffChar));
  501. #ifdef OPT
  502.     if (sequence) {
  503.     canonflush();
  504.     if (be->beputchar)
  505.         (*be->beputchar)(x, y, font, points, troffChar, sequence);
  506.     } else
  507.     canoninsert(x, y, font, points, troffChar);
  508. #else
  509.     if (be->beputchar)
  510.     (*be->beputchar)(x, y, font, points, troffChar, sequence);
  511. #endif
  512. }
  513. #endif
  514.