parse.c revision 151497
1151497Sru/* 2151497Sru * parse.c 3151497Sru * 4151497Sru * parse dvi input 5151497Sru */ 6151497Sru 7151497Sru#include <X11/Xos.h> 8151497Sru#include <X11/IntrinsicP.h> 9151497Sru#include <X11/StringDefs.h> 10151497Sru#include <stdio.h> 11151497Sru#include <ctype.h> 12151497Sru#include "DviP.h" 13151497Sru 14151497Srustatic int StopSeen = 0; 15151497Srustatic void ParseDrawFunction(DviWidget, char *); 16151497Srustatic void ParseDeviceControl(DviWidget); 17151497Srustatic void push_env(DviWidget); 18151497Srustatic void pop_env(DviWidget); 19151497Sru 20151497Sru/* draw.c */ 21151497Sruextern int PutCharacter(DviWidget, char *); 22151497Sruextern int PutNumberedCharacter(DviWidget, int); 23151497Sruextern void HorizontalGoto(DviWidget, int); 24151497Sruextern void Word(DviWidget); 25151497Sruextern void VerticalGoto(DviWidget, int); 26151497Sruextern void VerticalMove(DviWidget, int); 27151497Sruextern void FlushCharCache(DviWidget); 28151497Sruextern void Newline(DviWidget); 29151497Sruextern void DrawLine(DviWidget, int, int); 30151497Sruextern void DrawCircle(DviWidget, int); 31151497Sruextern void DrawFilledCircle(DviWidget, int); 32151497Sruextern void DrawEllipse(DviWidget, int, int); 33151497Sruextern void DrawFilledEllipse(DviWidget, int, int); 34151497Sruextern void DrawArc(DviWidget, int, int, int, int); 35151497Sruextern void DrawPolygon(DviWidget, int *, int); 36151497Sruextern void DrawFilledPolygon(DviWidget, int *, int); 37151497Sruextern void DrawSpline(DviWidget, int *, int); 38151497Sru 39151497Sru/* Dvi.c */ 40151497Sruextern void SetDevice(DviWidget, const char *); 41151497Sru 42151497Sru/* page.c */ 43151497Sruextern void RememberPagePosition(DviWidget, int); 44151497Sru 45151497Sru/* font.c */ 46151497Sruextern void SetFontPosition(DviWidget, int, const char *, const char *); 47151497Sru 48151497Sru/* lex.c */ 49151497Sruextern int GetNumber(DviWidget); 50151497Sru 51151497Sru#define HorizontalMove(dw, delta) ((dw)->dvi.state->x += (delta)) 52151497Sru 53151497Sru 54151497Sruint 55151497SruParseInput(register DviWidget dw) 56151497Sru{ 57151497Sru int n, k; 58151497Sru int c; 59151497Sru char Buffer[BUFSIZ]; 60151497Sru int NextPage; 61151497Sru int otherc; 62151497Sru 63151497Sru StopSeen = 0; 64151497Sru 65151497Sru /* 66151497Sru * make sure some state exists 67151497Sru */ 68151497Sru 69151497Sru if (!dw->dvi.state) 70151497Sru push_env (dw); 71151497Sru for (;;) { 72151497Sru switch (DviGetC(dw, &c)) { 73151497Sru case '\n': 74151497Sru break; 75151497Sru case ' ': /* when input is text */ 76151497Sru case 0: /* occasional noise creeps in */ 77151497Sru break; 78151497Sru case '{': /* push down current environment */ 79151497Sru push_env(dw); 80151497Sru break; 81151497Sru case '}': 82151497Sru pop_env(dw); 83151497Sru break; 84151497Sru /* 85151497Sru * two motion digits plus a character 86151497Sru */ 87151497Sru case '0': case '1': case '2': case '3': case '4': 88151497Sru case '5': case '6': case '7': case '8': case '9': 89151497Sru HorizontalMove(dw, (c-'0')*10 + 90151497Sru DviGetC(dw,&otherc)-'0'); 91151497Sru /* fall through */ 92151497Sru case 'c': /* single ascii character */ 93151497Sru DviGetC(dw,&c); 94151497Sru if (c == ' ') 95151497Sru break; 96151497Sru Buffer[0] = c; 97151497Sru Buffer[1] = '\0'; 98151497Sru (void) PutCharacter (dw, Buffer); 99151497Sru break; 100151497Sru case 'C': 101151497Sru GetWord (dw, Buffer, BUFSIZ); 102151497Sru (void) PutCharacter (dw, Buffer); 103151497Sru break; 104151497Sru case 't': 105151497Sru Buffer[1] = '\0'; 106151497Sru while (DviGetC (dw, &c) != EOF 107151497Sru && c != ' ' && c != '\n') { 108151497Sru Buffer[0] = c; 109151497Sru HorizontalMove (dw, PutCharacter (dw, Buffer)); 110151497Sru } 111151497Sru break; 112151497Sru case 'u': 113151497Sru n = GetNumber(dw); 114151497Sru Buffer[1] = '\0'; 115151497Sru while (DviGetC (dw, &c) == ' ') 116151497Sru ; 117151497Sru while (c != EOF && c != ' ' && c != '\n') { 118151497Sru Buffer[0] = c; 119151497Sru HorizontalMove (dw, 120151497Sru PutCharacter (dw, Buffer) + n); 121151497Sru DviGetC (dw, &c); 122151497Sru } 123151497Sru break; 124151497Sru 125151497Sru case 'D': /* draw function */ 126151497Sru (void) GetLine(dw, Buffer, BUFSIZ); 127151497Sru if (dw->dvi.display_enable) 128151497Sru ParseDrawFunction(dw, Buffer); 129151497Sru break; 130151497Sru case 's': /* ignore fractional sizes */ 131151497Sru n = GetNumber(dw); 132151497Sru dw->dvi.state->font_size = n; 133151497Sru break; 134151497Sru case 'f': 135151497Sru n = GetNumber(dw); 136151497Sru dw->dvi.state->font_number = n; 137151497Sru break; 138151497Sru case 'H': /* absolute horizontal motion */ 139151497Sru k = GetNumber(dw); 140151497Sru HorizontalGoto(dw, k); 141151497Sru break; 142151497Sru case 'h': /* relative horizontal motion */ 143151497Sru k = GetNumber(dw); 144151497Sru HorizontalMove(dw, k); 145151497Sru break; 146151497Sru case 'w': /* word space */ 147151497Sru Word (dw); 148151497Sru break; 149151497Sru case 'V': 150151497Sru n = GetNumber(dw); 151151497Sru VerticalGoto(dw, n); 152151497Sru break; 153151497Sru case 'v': 154151497Sru n = GetNumber(dw); 155151497Sru VerticalMove(dw, n); 156151497Sru break; 157151497Sru case 'P': /* new spread */ 158151497Sru break; 159151497Sru case 'p': /* new page */ 160151497Sru (void) GetNumber(dw); 161151497Sru NextPage = dw->dvi.current_page + 1; 162151497Sru RememberPagePosition(dw, NextPage); 163151497Sru FlushCharCache (dw); 164151497Sru return(NextPage); 165151497Sru case 'N': 166151497Sru n = GetNumber(dw); 167151497Sru PutNumberedCharacter (dw, n); 168151497Sru break; 169151497Sru case 'n': /* end of line */ 170151497Sru GetNumber(dw); 171151497Sru GetNumber(dw); 172151497Sru Newline (dw); 173151497Sru HorizontalGoto(dw, 0); 174151497Sru break; 175151497Sru case 'F': /* input files */ 176151497Sru case '+': /* continuation of X device control */ 177151497Sru case 'm': /* color */ 178151497Sru case '#': /* comment */ 179151497Sru GetLine(dw, NULL, 0); 180151497Sru break; 181151497Sru case 'x': /* device control */ 182151497Sru ParseDeviceControl(dw); 183151497Sru break; 184151497Sru case EOF: 185151497Sru dw->dvi.last_page = dw->dvi.current_page; 186151497Sru FlushCharCache (dw); 187151497Sru return dw->dvi.current_page; 188151497Sru default: 189151497Sru break; 190151497Sru } 191151497Sru } 192151497Sru} 193151497Sru 194151497Srustatic void 195151497Srupush_env(DviWidget dw) 196151497Sru{ 197151497Sru DviState *new_state; 198151497Sru 199151497Sru new_state = (DviState *) XtMalloc (sizeof (*new_state)); 200151497Sru if (dw->dvi.state) 201151497Sru *new_state = *(dw->dvi.state); 202151497Sru else { 203151497Sru new_state->font_size = 10; 204151497Sru new_state->font_number = 1; 205151497Sru new_state->x = 0; 206151497Sru new_state->y = 0; 207151497Sru } 208151497Sru new_state->next = dw->dvi.state; 209151497Sru dw->dvi.state = new_state; 210151497Sru} 211151497Sru 212151497Srustatic void 213151497Srupop_env(DviWidget dw) 214151497Sru{ 215151497Sru DviState *old; 216151497Sru 217151497Sru old = dw->dvi.state; 218151497Sru dw->dvi.state = old->next; 219151497Sru XtFree ((char *) old); 220151497Sru} 221151497Sru 222151497Srustatic void 223151497SruInitTypesetter (DviWidget dw) 224151497Sru{ 225151497Sru while (dw->dvi.state) 226151497Sru pop_env (dw); 227151497Sru push_env (dw); 228151497Sru FlushCharCache (dw); 229151497Sru} 230151497Sru 231151497Sru#define DRAW_ARGS_MAX 128 232151497Sru 233151497Srustatic void 234151497SruParseDrawFunction(DviWidget dw, char *buf) 235151497Sru{ 236151497Sru int v[DRAW_ARGS_MAX]; 237151497Sru int i, no_move = 0; 238151497Sru char *ptr; 239151497Sru 240151497Sru v[0] = v[1] = v[2] = v[3] = 0; 241151497Sru 242151497Sru if (buf[0] == '\0') 243151497Sru return; 244151497Sru ptr = buf+1; 245151497Sru 246151497Sru for (i = 0; i < DRAW_ARGS_MAX; i++) { 247151497Sru if (sscanf(ptr, "%d", v + i) != 1) 248151497Sru break; 249151497Sru while (*ptr == ' ') 250151497Sru ptr++; 251151497Sru while (*ptr != '\0' && *ptr != ' ') 252151497Sru ptr++; 253151497Sru } 254151497Sru 255151497Sru switch (buf[0]) { 256151497Sru case 'l': /* draw a line */ 257151497Sru DrawLine(dw, v[0], v[1]); 258151497Sru break; 259151497Sru case 'c': /* circle */ 260151497Sru DrawCircle(dw, v[0]); 261151497Sru break; 262151497Sru case 'C': 263151497Sru DrawFilledCircle(dw, v[0]); 264151497Sru break; 265151497Sru case 'e': /* ellipse */ 266151497Sru DrawEllipse(dw, v[0], v[1]); 267151497Sru break; 268151497Sru case 'E': 269151497Sru DrawFilledEllipse(dw, v[0], v[1]); 270151497Sru break; 271151497Sru case 'a': /* arc */ 272151497Sru DrawArc(dw, v[0], v[1], v[2], v[3]); 273151497Sru break; 274151497Sru case 'p': 275151497Sru DrawPolygon(dw, v, i); 276151497Sru break; 277151497Sru case 'P': 278151497Sru DrawFilledPolygon(dw, v, i); 279151497Sru break; 280151497Sru case '~': /* wiggly line */ 281151497Sru DrawSpline(dw, v, i); 282151497Sru break; 283151497Sru case 't': 284151497Sru dw->dvi.line_thickness = v[0]; 285151497Sru break; 286151497Sru case 'f': 287151497Sru if (i > 0 && v[0] >= 0 && v[0] <= DVI_FILL_MAX) 288151497Sru dw->dvi.fill = v[0]; 289151497Sru no_move = 1; 290151497Sru break; 291151497Sru default: 292151497Sru#if 0 293151497Sru warning("unknown drawing function %s", buf); 294151497Sru#endif 295151497Sru no_move = 1; 296151497Sru break; 297151497Sru } 298151497Sru 299151497Sru if (!no_move) { 300151497Sru if (buf[0] == 'e') { 301151497Sru if (i > 0) 302151497Sru dw->dvi.state->x += v[0]; 303151497Sru } 304151497Sru else { 305151497Sru while (--i >= 0) { 306151497Sru if (i & 1) 307151497Sru dw->dvi.state->y += v[i]; 308151497Sru else 309151497Sru dw->dvi.state->x += v[i]; 310151497Sru } 311151497Sru } 312151497Sru } 313151497Sru} 314151497Sru 315151497Srustatic void 316151497SruParseDeviceControl(DviWidget dw) /* Parse the x commands */ 317151497Sru{ 318151497Sru char str[20], str1[50]; 319151497Sru int c, n; 320151497Sru 321151497Sru GetWord (dw, str, 20); 322151497Sru switch (str[0]) { /* crude for now */ 323151497Sru case 'T': /* output device */ 324151497Sru GetWord (dw, str, 20); 325151497Sru SetDevice (dw, str); 326151497Sru break; 327151497Sru case 'i': /* initialize */ 328151497Sru InitTypesetter (dw); 329151497Sru break; 330151497Sru case 't': /* trailer */ 331151497Sru break; 332151497Sru case 'p': /* pause -- can restart */ 333151497Sru break; 334151497Sru case 's': /* stop */ 335151497Sru StopSeen = 1; 336151497Sru return; 337151497Sru case 'r': /* resolution when prepared */ 338151497Sru break; 339151497Sru case 'f': /* font used */ 340151497Sru n = GetNumber (dw); 341151497Sru GetWord (dw, str, 20); 342151497Sru GetLine (dw, str1, 50); 343151497Sru SetFontPosition (dw, n, str, str1); 344151497Sru break; 345151497Sru case 'H': /* char height */ 346151497Sru break; 347151497Sru case 'S': /* slant */ 348151497Sru break; 349151497Sru } 350151497Sru while (DviGetC (dw, &c) != '\n') /* skip rest of input line */ 351151497Sru if (c == EOF) 352151497Sru return; 353151497Sru return; 354151497Sru} 355151497Sru 356151497Sru 357151497Sru/* 358151497SruLocal Variables: 359151497Sruc-indent-level: 8 360151497Sruc-continued-statement-offset: 8 361151497Sruc-brace-offset: -8 362151497Sruc-argdecl-indent: 8 363151497Sruc-label-offset: -8 364151497Sruc-tab-always-indent: nil 365151497SruEnd: 366151497Sru*/ 367