/****************************************************************************** * * parser -- parses device independent troff commands and calls * appropriate action routines * * John Mellor-Crummey (Xerox Corp) * * Copyright 1985 Xerox Corporation * ******************************************************************************/ #include #include #include "deviceinfo.h" #include "defs.h" /* constant and macro definitions */ #include "externs.h" /* declarations for global variables */ /*----------------------------------------------------------------------------- * ditroffToIpress -- parses the input file calling routines to perform * requested operations *---------------------------------------------------------------------------*/ ditroffToIpress(fptr) register FILE *fptr; { char buffer[BUFFERSIZE]; int c1,c2; int cmd; int flag = 1; while((cmd = getc(fptr)) != EOF) { switch(cmd) { case cmdPointSize: if (flag = (fscanf(fptr,"%d",&c1) == 1)) setPointSize(internalSize(c1)+1); break; case cmdFont: if (flag = (fscanf(fptr,"%d",&c1) == 1)) setFont(fontNumber(c1)); break; case cmdChar: if (flag = ((cmd = getc(fptr)) != EOF)) outputChar((unsigned int) cmd); break; case cmdSpecChar: if (flag = (fscanf(fptr,"%s",buffer) == 1)) outputString(buffer); break; case cmdAbsHoriz: if (flag = (fscanf(fptr,"%d",&c1) == 1)) hMov(c1); break; case cmdRelHoriz: if (flag = (fscanf(fptr,"%d",&c1) == 1)) hInc(c1); break; case cmdAbsVert: if (flag = (fscanf(fptr,"%d",&c1) == 1)) vMov(c1); break; case cmdRelVert: if (flag = (fscanf(fptr,"%d",&c1) == 1)) vInc(c1); break; case cmdEol: /* ignore arguments, call routine for newline */ flag = (fscanf(fptr,"%d %d",&c1,&c2) == 2); newLine(); break; case cmdWordSep: break; case cmdNewPage: if (flag = (fscanf(fptr,"%d",&c1) == 1)) newpage(c1); break; case cmdPushEnv: pushCurrentEnv(); break; case cmdPopEnv: popSavedEnv(); break; case cmdCharString: (void) fgets(buffer,BUFFERSIZE,fptr); /* no op -- this command causes no conversion * not expected in ditroff output */ break; case cmdComment: skipToNextLine(fptr); break; case cmdDraw: drawCommand(fptr); skipToNextLine(fptr); break; case cmdDevice: deviceCommand(fptr); skipToNextLine(fptr); break; case '\n': linenumber++; break; default: if(isdigit(cmd)) { /* command is 2 digit horizontal displacement * followed by a char */ if (flag = ((c1 = getc(fptr)) != EOF)) { hInc(c1 - '0' + 10 * (cmd - '0')); if (flag = ((c1 = getc(fptr)) != EOF)) outputChar((unsigned int) c1); } break; } else if (white(cmd) || (cmd == '\0')) break; /* handle trash in stream */ reportError(QUIT,"unrecognized character in input %o %c", (char *) cmd, (char *) cmd); } if (!flag) reportError(QUIT,"error in input for ditroff command %c", (char *) cmd); } } /*----------------------------------------------------------------------------- * drawCommand -- process ditroff draw commands *---------------------------------------------------------------------------*/ drawCommand(fptr) register FILE *fptr; { int c1,c2,c3,c4; int cmd,flag; char buffer[BUFFERSIZE]; if (flag = ((cmd = getc(fptr)) != EOF)) { switch(cmd) { case drawLine: /* draw from current x,y to c1,c2 */ /* read termination point */ if (flag = (fscanf(fptr,"%d %d",&c1,&c2) == 2)) drawline(c1,c2); break; case drawCircle: /* draw circle of diameter c1 with current x,y */ /* leftmost position on circle */ /* read circle diameter */ if (flag = (fscanf(fptr,"%d",&c1) == 1)) { c2 = (c1 + 1) / 2; if(!outputflag) /* won't be printed anyway */ break; gobj_size(hor_pos,ver_pos - c2,hor_pos + c1,ver_pos + c2); bitmapDrawCircle(c1); } break; case drawEllipse: /* draw ellipse with axes c1,c2 with current x,y */ /* leftmost point on ellipse */ /* read height and width */ if (flag = (fscanf(fptr,"%d %d",&c1,&c2) == 2)) { c3 = (c2 + 1) / 2; if(!outputflag) /* won't be printed anyway */ break; gobj_size(hor_pos,ver_pos - c3,hor_pos + c1,ver_pos + c3); bitmapDrawEllipse(c1,c2); } break; case drawArc: /* draw counter-clockwise arc with current x,y */ /* as start, c1,c2 represent relative x,y */ /* offset to center, c3,c4 represent relative */ /* x,y offset from center to ending point on arc */ /* read relative coords to current point: xc yc xt yt */ if (flag = (fscanf(fptr,"%d %d %d %d",&c1,&c2,&c3,&c4) == 4)) { if(!outputflag) /* won't be printed anyway */ break; g_sizearc(hor_pos,ver_pos,c1,c2,c3,c4); bitmapDrawArc(c1,c2,c3,c4); } break; case drawWigglyLine: /* read the rest of the command line containing a * list of x,y pairs into a buffer */ (void) fgets(buffer,BUFFERSIZE,fptr); if(!outputflag) /* won't be printed anyway */ break; g_sizeWigglyLine(buffer); bitmapDrawWigglyLine(buffer); break; default: flag = 0; break; } } if (!flag) reportError(QUIT,"ill formed draw command"); } /*----------------------------------------------------------------------------- * deviceCommand -- process ditroff device commands *---------------------------------------------------------------------------*/ deviceCommand(fptr) register FILE *fptr; { int flag,n; int c1; char st[20]; char buffer[80]; if (flag = (fscanf(fptr,"%s",st) == 1)) { switch(*st) { case deviceInit: initDevice(); readDeviceInitInfo(); break; case deviceName: flag = (fscanf(fptr,"%s",devicename) == 1); break; case deviceResolution: /* expect only resolution in spots per inch */ if (flag = (fscanf(fptr,"%d",&spotsPerInch) == 1)) setScale(spotsPerInch); break; case devicePause: /* ignore device pauses */ break; case deviceStop: resetDevice(); break; case deviceTrailer: /* a no op */ break; case deviceFont: if (flag = (fscanf(fptr,"%d %s",&n,buffer) == 2)) loadFont(n,buffer); break; case deviceHeight: /* a no op */ if (flag = (fscanf(fptr,"%d",&c1) == 1)) break; case deviceSlant: /* a no op */ if (flag = (fscanf(fptr,"%d",&c1) == 1)) break; } } if (!flag) reportError(QUIT,"ill formed device command"); } /*----------------------------------------------------------------------------- * skipToNextLine -- eat any trailing junk and newline *---------------------------------------------------------------------------*/ skipToNextLine(fptr) FILE *fptr; { int n; while ((n = getc(fptr)) != '\n') if (n == EOF) return; linenumber++; }