Home | History | Annotate | Line # | Download | only in xditview
      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
     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
    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
    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
    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
    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
    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