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