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