parse.c revision 151498
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*/ 367