home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / util / gnu / groff_src.lha / groff-1.10src / xditview / parse.c < prev    next >
C/C++ Source or Header  |  1991-10-09  |  6KB  |  335 lines

  1. /*
  2.  * parse.c
  3.  *
  4.  * parse dvi input
  5.  */
  6.  
  7. #include <X11/Xos.h>
  8. #include <X11/IntrinsicP.h>
  9. #include <X11/StringDefs.h>
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include "DviP.h"
  13.  
  14. static int StopSeen = 0;
  15. static ParseDrawFunction(), ParseDeviceControl();
  16. static push_env(), pop_env();
  17.  
  18. #define HorizontalMove(dw, delta)    ((dw)->dvi.state->x += (delta))
  19.  
  20.  
  21. ParseInput(dw)
  22.     register DviWidget    dw;
  23. {
  24.     int        n, k;
  25.     int        c;
  26.     char        Buffer[BUFSIZ];
  27.     int        NextPage;
  28.     int        otherc;
  29.  
  30.     StopSeen = 0;
  31.  
  32.     /*
  33.      * make sure some state exists
  34.      */
  35.  
  36.     if (!dw->dvi.state)
  37.         push_env (dw);
  38.     for (;;) {
  39.         switch (DviGetC(dw, &c)) {
  40.         case '\n':    
  41.             break;
  42.         case ' ':    /* when input is text */
  43.         case 0:        /* occasional noise creeps in */
  44.             break;
  45.         case '{':    /* push down current environment */
  46.             push_env(dw);
  47.             break;
  48.         case '}':
  49.             pop_env(dw);
  50.             break;
  51.         /*
  52.          * two motion digits plus a character
  53.          */
  54.         case '0': case '1': case '2': case '3': case '4':
  55.         case '5': case '6': case '7': case '8': case '9':
  56.             HorizontalMove(dw, (c-'0')*10 +
  57.                        DviGetC(dw,&otherc)-'0');
  58.             /* fall through */
  59.         case 'c':    /* single ascii character */
  60.             DviGetC(dw,&c);
  61.                 if (c == ' ')
  62.                 break;
  63.             Buffer[0] = c;
  64.             Buffer[1] = '\0';
  65.             (void) PutCharacter (dw, Buffer);
  66.             break;
  67.         case 'C':
  68.             GetWord (dw, Buffer, BUFSIZ);
  69.             (void) PutCharacter (dw, Buffer);
  70.             break;
  71.         case 't':
  72.             Buffer[1] = '\0';
  73.             while (DviGetC (dw, &c) != EOF
  74.                    && c != ' ' && c != '\n') {
  75.                 Buffer[0] = c;
  76.                 HorizontalMove (dw, PutCharacter (dw, Buffer));
  77.             }
  78.             break;
  79.         case 'u':
  80.             n = GetNumber(dw);
  81.             Buffer[1] = '\0';
  82.             while (DviGetC (dw, &c) == ' ')
  83.                 ;
  84.             while (c != EOF && c != ' ' && c != '\n') {
  85.                 Buffer[0] = c;
  86.                 HorizontalMove (dw,
  87.                         PutCharacter (dw, Buffer) + n);
  88.                 DviGetC (dw, &c);
  89.             }
  90.             break;
  91.  
  92.         case 'D':    /* draw function */
  93.             (void) GetLine(dw, Buffer, BUFSIZ);
  94.             if (dw->dvi.display_enable)
  95.                 ParseDrawFunction(dw, Buffer);
  96.             break;
  97.         case 's':    /* ignore fractional sizes */
  98.             n = GetNumber(dw);
  99.             dw->dvi.state->font_size = n;
  100.             break;
  101.         case 'f':
  102.             n = GetNumber(dw);
  103.             dw->dvi.state->font_number = n;
  104.             break;
  105.         case 'H':    /* absolute horizontal motion */
  106.             k = GetNumber(dw);
  107.             HorizontalGoto(dw, k);
  108.             break;
  109.         case 'h':    /* relative horizontal motion */
  110.             k = GetNumber(dw);
  111.             HorizontalMove(dw, k);
  112.             break;
  113.         case 'w':    /* word space */
  114.             Word (dw);
  115.             break;
  116.         case 'V':
  117.             n = GetNumber(dw);
  118.             VerticalGoto(dw, n);
  119.             break;
  120.         case 'v':
  121.             n = GetNumber(dw);
  122.             VerticalMove(dw, n);
  123.             break;
  124.         case 'P':    /* new spread */
  125.             break;
  126.         case 'p':    /* new page */
  127.             (void) GetNumber(dw);
  128.             NextPage = dw->dvi.current_page + 1;
  129.             RememberPagePosition(dw, NextPage);
  130.             FlushCharCache (dw);
  131.             return(NextPage);
  132.         case 'N':
  133.             n = GetNumber(dw);
  134.             PutNumberedCharacter (dw, n);
  135.             break;
  136.         case 'n':    /* end of line */
  137.             GetNumber(dw);
  138.             GetNumber(dw);
  139.             Newline (dw);
  140.             HorizontalGoto(dw, 0);
  141.             break;
  142.         case '+':    /* continuation of X device control */
  143.         case '#':    /* comment */
  144.             GetLine(dw, NULL, 0);
  145.             break;
  146.         case 'x':    /* device control */
  147.             ParseDeviceControl(dw);
  148.             break;
  149.         case EOF:
  150.             dw->dvi.last_page = dw->dvi.current_page;
  151.             FlushCharCache (dw);
  152.             return dw->dvi.current_page;
  153.         default:
  154.             break;
  155.         }
  156.     }
  157. }
  158.  
  159. static
  160. push_env(dw)
  161.     DviWidget    dw;
  162. {
  163.     DviState    *new;
  164.  
  165.     new = (DviState *) XtMalloc (sizeof (*new));
  166.     if (dw->dvi.state)
  167.         *new = *(dw->dvi.state);
  168.     else {
  169.         new->font_size = 10;
  170.         new->font_number = 1;
  171.         new->x = 0;
  172.         new->y = 0;
  173.     }
  174.     new->next = dw->dvi.state;
  175.     dw->dvi.state = new;
  176. }
  177.  
  178. static
  179. pop_env(dw)
  180.     DviWidget    dw;
  181. {
  182.     DviState    *old;
  183.  
  184.     old = dw->dvi.state;
  185.     dw->dvi.state = old->next;
  186.     XtFree ((char *) old);
  187. }
  188.  
  189. static
  190. InitTypesetter (dw)
  191.     DviWidget    dw;
  192. {
  193.     while (dw->dvi.state)
  194.         pop_env (dw);
  195.     push_env (dw);
  196.     FlushCharCache (dw);
  197. }
  198.  
  199. #define DRAW_ARGS_MAX 128
  200.  
  201. static
  202. ParseDrawFunction(dw, buf)
  203. DviWidget    dw;
  204. char        *buf;
  205. {
  206.     int v[DRAW_ARGS_MAX];
  207.     int i;
  208.     char *ptr;
  209.     
  210.     v[0] = v[1] = v[2] = v[3] = 0;
  211.     
  212.     if (buf[0] == '\0')
  213.         return;
  214.     ptr = buf+1;
  215.     
  216.     for (i = 0; i < DRAW_ARGS_MAX; i++) {
  217.         if (sscanf(ptr, "%d", v + i) != 1)
  218.             break;
  219.         while (*ptr == ' ')
  220.             ptr++;
  221.         while (*ptr != '\0' && *ptr != ' ')
  222.             ptr++;
  223.     }
  224.     
  225.     switch (buf[0]) {
  226.     case 'l':                /* draw a line */
  227.         DrawLine(dw, v[0], v[1]);
  228.         break;
  229.     case 'c':                /* circle */
  230.         DrawCircle(dw, v[0]);
  231.         break;
  232.     case 'C':
  233.         DrawFilledCircle(dw, v[0]);
  234.         break;
  235.     case 'e':                /* ellipse */
  236.         DrawEllipse(dw, v[0], v[1]);
  237.         break;
  238.     case 'E':
  239.         DrawFilledEllipse(dw, v[0], v[1]);
  240.         break;
  241.     case 'a':                /* arc */
  242.         DrawArc(dw, v[0], v[1], v[2], v[3]);
  243.         break;
  244.     case 'p':
  245.         DrawPolygon(dw, v, i);
  246.         break;
  247.     case 'P':
  248.         DrawFilledPolygon(dw, v, i);
  249.         break;
  250.     case '~':                /* wiggly line */
  251.         DrawSpline(dw, v, i);
  252.         break;
  253.     case 't':
  254.         dw->dvi.line_thickness = v[0];
  255.         break;
  256.     case 'f':
  257.         if (i > 0 && v[0] >= 0 && v[0] <= DVI_FILL_MAX)
  258.             dw->dvi.fill = v[0];
  259.         break;
  260.     default:
  261. #if 0
  262.         warning("unknown drawing function %s", buf);
  263. #endif
  264.         break;
  265.     }
  266.     
  267.     if (buf[0] == 'e') {
  268.         if (i > 0)
  269.             dw->dvi.state->x += v[0];
  270.     }
  271.     else {
  272.         while (--i >= 0) {
  273.             if (i & 1)
  274.                 dw->dvi.state->y += v[i];
  275.             else
  276.                 dw->dvi.state->x += v[i];
  277.         }
  278.     }
  279.  
  280. static
  281. ParseDeviceControl(dw)                /* Parse the x commands */
  282.     DviWidget    dw;
  283. {
  284.         char str[20], str1[50];
  285.     int c, n;
  286.     extern int LastPage, CurrentPage;
  287.  
  288.     GetWord (dw, str, 20);
  289.     switch (str[0]) {            /* crude for now */
  290.     case 'T':                /* output device */
  291.         GetWord (dw, str, 20);
  292.         SetDevice (dw, str);
  293.         break;
  294.     case 'i':                /* initialize */
  295.         InitTypesetter (dw);
  296.         break;
  297.     case 't':                /* trailer */
  298.         break;
  299.     case 'p':                /* pause -- can restart */
  300.         break;
  301.     case 's':                /* stop */
  302.         StopSeen = 1;
  303.         return;
  304.     case 'r':                /* resolution when prepared */
  305.         break;
  306.     case 'f':                /* font used */
  307.         n = GetNumber (dw);
  308.         GetWord (dw, str, 20);
  309.         GetLine (dw, str1, 50);
  310.         SetFontPosition (dw, n, str, str1);
  311.         break;
  312.     case 'H':                /* char height */
  313.         break;
  314.     case 'S':                /* slant */
  315.         break;
  316.     }
  317.     while (DviGetC (dw, &c) != '\n')    /* skip rest of input line */
  318.         if (c == EOF)
  319.             return;
  320.     return;
  321. }
  322.  
  323.  
  324. /*
  325. Local Variables:
  326. c-indent-level: 8
  327. c-continued-statement-offset: 8
  328. c-brace-offset: -8
  329. c-argdecl-indent: 8
  330. c-label-offset: -8
  331. c-tab-always-indent: nil
  332. End:
  333. */
  334.