PageRenderTime 30ms CodeModel.GetById 1ms app.highlight 24ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/groff/src/devices/xditview/parse.c

https://bitbucket.org/freebsd/freebsd-head/
C | 366 lines | 309 code | 30 blank | 27 comment | 50 complexity | 467aadd827aa1e57c11102ca9f6946f1 MD5 | raw file
  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
 14static int StopSeen = 0;
 15static void ParseDrawFunction(DviWidget, char *);
 16static void ParseDeviceControl(DviWidget);
 17static void push_env(DviWidget);
 18static void pop_env(DviWidget);
 19
 20/* draw.c */
 21extern int PutCharacter(DviWidget, char *);
 22extern int PutNumberedCharacter(DviWidget, int);
 23extern void HorizontalGoto(DviWidget, int);
 24extern void Word(DviWidget);
 25extern void VerticalGoto(DviWidget, int);
 26extern void VerticalMove(DviWidget, int);
 27extern void FlushCharCache(DviWidget);
 28extern void Newline(DviWidget);
 29extern void DrawLine(DviWidget, int, int);
 30extern void DrawCircle(DviWidget, int);
 31extern void DrawFilledCircle(DviWidget, int);
 32extern void DrawEllipse(DviWidget, int, int);
 33extern void DrawFilledEllipse(DviWidget, int, int);
 34extern void DrawArc(DviWidget, int, int, int, int);
 35extern void DrawPolygon(DviWidget, int *, int);
 36extern void DrawFilledPolygon(DviWidget, int *, int);
 37extern void DrawSpline(DviWidget, int *, int);
 38
 39/* Dvi.c */
 40extern void SetDevice(DviWidget, const char *);
 41
 42/* page.c */
 43extern void RememberPagePosition(DviWidget, int);
 44
 45/* font.c */
 46extern void SetFontPosition(DviWidget, int, const char *, const char *);
 47
 48/* lex.c */
 49extern int GetNumber(DviWidget);
 50
 51#define HorizontalMove(dw, delta)	((dw)->dvi.state->x += (delta))
 52
 53
 54int
 55ParseInput(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
194static void
195push_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
212static void
213pop_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
222static void
223InitTypesetter (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
233static void
234ParseDrawFunction(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
315static void
316ParseDeviceControl(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/*
358Local Variables:
359c-indent-level: 8
360c-continued-statement-offset: 8
361c-brace-offset: -8
362c-argdecl-indent: 8
363c-label-offset: -8
364c-tab-always-indent: nil
365End:
366*/