/****************************************************************************** * * parser -- parses device independent troff commands and calls * appropriate action routines * * John Mellor-Crummey (Xerox Corp) * * Copyright 1985,6 Xerox Corporation * * HISTORY * 24-Feb-86 Lee Moore (lee) at Xerox Webster Research Center * Added new Xerox device control parsing. The syntax for the only * comand is: * x Xerox IP fileName * x Xerox RES anchor resolution fileName * ******************************************************************************/ #include <stdio.h> #include <ctype.h> #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 cmdStippleFamily: if (flag = (fscanf(fptr,"%d",&c1) == 1)) newStippleFamily(c1); 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 drawThick: /* set line thickness */ if (flag = (fscanf(fptr,"%d",&c1) == 1)) lineThickness = c1; break; case drawStyle: /* set line style */ if (flag = (fscanf(fptr,"%d",&c1) == 1)) lineStyle = c1; break; 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 drawGremlinSpline: /* close approximation... */ 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; case drawPolygon: case drawUbPolygon: /* read the rest of the command line containing a * list of x,y pairs into a buffer */ fgets(buffer,BUFFERSIZE,fptr); iPdrawPolygon(buffer, cmd); 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; case deviceXerox: /* handle Xerox extended commands */ parseXeroxCommand(fptr); 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++; } /*--------------------------------------------------------------------------- * parseXeroxCommand -- parse extended Xerox commands *---------------------------------------------------------------------------*/ parseXeroxCommand(fptr) FILE *fptr; { char operation[80], fileName[1024], anchor[40], resolution[40]; if( fscanf(fptr, "%s", operation) != 1 ) { reportError(QUIT,"ill formed device command"); return; } switch (operation[0]) { case xeroxDeviceInsertIP: if (fscanf(fptr, "%s", fileName) != 1) { reportError(QUIT,"ill formed device command"); return; } doSequenceInsertIP(fileName); break; case xeroxDeviceInsertRES: if (fscanf(fptr, "%s %s %s", anchor, resolution, fileName) != 3) { reportError(QUIT,"ill formed device command"); return; } doSequenceInsertRES(anchor, resolution, fileName); break; default: reportError(QUIT,"unknown Xerox device request"); break; } }