]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/groff/xditview/parse.c
Virgin import of FSF groff v1.10
[FreeBSD/FreeBSD.git] / contrib / groff / xditview / parse.c
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
281 static
282 ParseDeviceControl(dw)                          /* Parse the x commands */
283         DviWidget       dw;
284 {
285         char str[20], str1[50];
286         int c, n;
287         extern int LastPage, CurrentPage;
288
289         GetWord (dw, str, 20);
290         switch (str[0]) {                       /* crude for now */
291         case 'T':                               /* output device */
292                 GetWord (dw, str, 20);
293                 SetDevice (dw, str);
294                 break;
295         case 'i':                               /* initialize */
296                 InitTypesetter (dw);
297                 break;
298         case 't':                               /* trailer */
299                 break;
300         case 'p':                               /* pause -- can restart */
301                 break;
302         case 's':                               /* stop */
303                 StopSeen = 1;
304                 return;
305         case 'r':                               /* resolution when prepared */
306                 break;
307         case 'f':                               /* font used */
308                 n = GetNumber (dw);
309                 GetWord (dw, str, 20);
310                 GetLine (dw, str1, 50);
311                 SetFontPosition (dw, n, str, str1);
312                 break;
313         case 'H':                               /* char height */
314                 break;
315         case 'S':                               /* slant */
316                 break;
317         }
318         while (DviGetC (dw, &c) != '\n')        /* skip rest of input line */
319                 if (c == EOF)
320                         return;
321         return;
322 }
323
324
325 /*
326 Local Variables:
327 c-indent-level: 8
328 c-continued-statement-offset: 8
329 c-brace-offset: -8
330 c-argdecl-indent: 8
331 c-label-offset: -8
332 c-tab-always-indent: nil
333 End:
334 */