/* hist */ /* 3 6 84 changed color index mapping so index 1 is pen 1 */ #include "ratdef.h"; #define MAXxHPxBUFFER 80 #define MOVE 1 #define DRAW 2 #define YES 1 #define NO 0 #define UNSUCCESSFUL 0 /* Unsuccessful GIN operation */ #define SUCCESSFUL 1 /* Unsuccessful GIN operation */ #define DEFAULT 1 /* Default GIN device number */ #define PLOTTER 6 /* Plotter device number for GIN */ int max0(), min0(); unsigned int wxmin, wymin, wxmax, wymax; int x_fetch(), y_fetch(); DD747X (paraseg,paraoff) int paraoff,paraseg; { /************************************************************************ * * * Function: Device Driver for Hewlett Packard 747x pen plotter * * * * Input Parameters: * * paraseg - parameter segment * * paraoff - parameter offset * * * * Output Parameters: * * none * * * * Routines Called: * * Dbufhp - buffered output for HP plotter * * Gznfpl - prompt the user for a new sheet of paper * * Dr747x - move/draw for HP plotter * * Dp747x - Change pens on the HP 747x plotter * * Dt747x - Set text size on HP 747x plotter * * Gitoch - convert integer to characters * * Gchtoi - convert character string to integer * * Gimnmx - Function to place integer value in a range * * * ************************************************************************/ #include "ddcom.h" int opcode; int i, i2, j, gimnmx(), ierror, ival, istop, tries, ginok, icnvt[6], ibuf[50]; unsigned int xy[2], savexy[2]; int temp, gitoch(), length; unsigned int x1, y1, x2, y2; unsigned int hlfsiz, fulsiz; extern int pens[7], clrred[7], clrgrn[7], clrblu[7]; /* Start arc definition /PD;AA/ */ static int arcstart[] = {BIGP, BIGD, SEMICOL, BIGA, BIGA}; /* End arc definition /,5;/ */ static int arcend[] = {COMMA, DIG7, SEMICOL}; /* Set up for solid fill /FT1;PT;/ */ static int solfill[] = {BIGF,BIGT,DIG1,SEMICOL,BIGP,BIGT,SEMICOL}; /* Set up for hatching /FT3,90, ;/ */ static int hatfill[] = {BIGF,BIGT,DIG3,COMMA,DIG9,DIG0,COMMA,0,0,0,SEMICOL}; /* Wedge command /WG/ */ static int wedge[] = {BIGW,BIGG}; /* Eedge wedge command /EW/ */ static int edgewedge[] = {BIGE,BIGW}; /* Set label(text) font /CSSS;;/ */ static int setfnt[8] = {BIGC, BIGS, DIG0, DIG0, SEMICOL, BIGS, BIGS, SEMICOL}; /* Set rotation /DI/ */ static int rotate[2] ={BIGD, BIGI}; /* Text output set up /LB/ */ static int txtout[2] = {BIGL, BIGB}; /* Marker size, output /SM<0>;/ */ static int mrkout[4] = {BIGS, BIGM, DIG0, SEMICOL}; /* Set line style to solid /LT;/ */ static int solid[3] ={BIGL, BIGT, SEMICOL}; /* Line style /LT<0>,2;/ */ static int lstyle[6] ={BIGL, BIGT, DIG0, COMMA, DIG2, SEMICOL}; /* Set up - Turn plotter on .( Set handshake mode 2 .I81;5;6: Initialize the plotter: DF; */ static int setup[] = {BIGI,BIGN,SEMICOL,ESC, PERIOD, LPAREN, ESC, PERIOD, BIGR, ESC,PERIOD,BIGI,DIG8,DIG1,SEMICOL,DIG5,SEMICOL,DIG6,COLON,ENQ }; static int setup2[] = {BIGD,BIGF,SEMICOL,BIGD,BIGI,DIG0,COMMA,MINUS,DIG1,SEMICOL, ESC,PERIOD,ATSIGN,SEMICOL,DIG0,DIG0,COLON,ESC,PERIOD,BIGM,DIG1, DIG0,COLON,ESC,PERIOD,BIGN,DIG1,DIG0,COLON }; /* Stop graphics - /.)/ */ static int stopgr[3] = {ESC, PERIOD, RPAREN}; static int mrktbl[5] = {PERIOD, PLUS, STAR, BIGO, BIGX}; static int gogin[4] = {BIGD, BIGP, SEMICOL, NEWLINE}; static int inqsta[4] = {BIGO, BIGS, SEMICOL, NEWLINE}; static int getgin[4] = {BIGO, BIGD, SEMICOL, NEWLINE}; static int comma = COMMA; static int endtxt = ETX; static int semcol = SEMICOL; static int home[2] = {0, 0}; static int iniino[45] = { /* initial intout array for open workstation*/ 0,0, METERS, /* Device coordinates are meters */ 25, /* Step size in micrometers on x axis */ 25, /* Step size in micrometers on y axis */ 0, /* Number of character heights (continuous) */ 7, /* Number of line types */ 1, /* Number of line widths */ 5, /* Number of marker types */ 0, /* Number of marker sizes (continuous) */ 5, /* Number of text fonts */ 0, /* Number of patterns */ 6, /* Number of hatch styles */ 6, /* Number of predefined colors */ 1, /* Number of GDPs */ 1,-1,-1,-1,-1, /* GDPs, except BARS, do not exist */ -1,-1,-1,-1,-1,3,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1, /* Device is capable of color */ 1, /* Device is capable of text rotation */ 1, /* Device is capable of filled area */ 0, /* Device is not capable of pixel operations*/ 0, /* Number of colors available (continuous */ /* pen colors) */ 1, /* Number of locator devices available */ 0, /* Number of valuator devices available */ 0, /* Number of choice devices available */ 0, /* Number of string devices available */ 2}; /* Workstation type (input/output) */ static int inipto[12] = { /* initial ptsout array for open workstation */ 0, 60, /* Minimum character height in DC space */ /* .15cm = 60 steps */ 0, 0, 1, /* Minimum line width in DC space */ 0, 1, /* Maximum line width in DC space */ 0, 0, 80, /* Minimum marker height in DC space */ /* .20cm = 80 steps */ 0, 0}; static getwindw[] = {BIGO, BIGP, SEMICOL}; /* Get window command OW; */ static getid[] = {BIGO, BIGI, SEMICOL}; /* Get plotter ID (7470 or 7475) */ extern int conoff, iinoff, pinoff, ioutoff, poutoff, LFETCH(); extern int conseg, iinseg, pinseg, ioutseg, poutseg; conoff=LFETCH(paraseg,paraoff,0); conseg=LFETCH(paraseg,paraoff,1); iinoff=LFETCH(paraseg,paraoff,2); iinseg=LFETCH(paraseg,paraoff,3); pinoff=LFETCH(paraseg,paraoff,4); pinseg=LFETCH(paraseg,paraoff,5); ioutoff=LFETCH(paraseg,paraoff,6); ioutseg=LFETCH(paraseg,paraoff,7); poutoff=LFETCH(paraseg,paraoff,8); poutseg=LFETCH(paraseg,paraoff,9); opcode=LFETCH(conseg,conoff,OPCODE); LSTORE(conseg,conoff,2,0); /*Assume no vertices are being passed back*/ /* opcode open workstation */ switch (opcode) { case OPENxWORKSTATION: LSTORE(conseg,conoff,2,6); /* Set to number of output vertices */ LSTORE(conseg,conoff,4,45); /* Length of array intout */ /* set up output capability array */ for (i=0;i<45;++i) LSTORE(ioutseg,ioutoff,i,iniino[i]); for (i=0;i<12;++i) LSTORE(poutseg,poutoff,i,inipto[i]); ndlntp = max0 (LFETCH(iinseg,iinoff,1)-1, 0); /*Set current device line style*/ if (ndlntp > 6) ndlntp = 0; ndlntp = ndlntp + DIG0; ndclrl = max0 (LFETCH(iinseg,iinoff,2), 1); /*Set current polyline color index*/ ndmktp = LFETCH(iinseg,iinoff,3); /*Set current marker type*/ if (ndmktp < 1 | ndmktp > 5) ndmktp=3; ndclrm = max0 (LFETCH(iinseg,iinoff,4), 1); /*Set current polymarker color index*/ /*Set current text font*/ ndclrt = max0 (LFETCH(iinseg,iinoff,6), 1); /*Set current text color index*/ ndclrf = max0 (LFETCH(iinseg,iinoff,9), 1); /*Set current fill area color index*/ ndstyf = max0 (LFETCH(iinseg,iinoff,8), 1); /*Set current fill style index*/ if (ndstyf > 6)ndstyf = 1; ndistyf = max0 (LFETCH(iinseg,iinoff,7),0); /*Set current fill interior style*/ if (ndistyf > 3)ndistyf = 0; ndmkht = 20; /*Set default marker height .2cm*/ ndtxsz = 15; /*Set default character width .15 cm*/ ndtysz = 15; /*Set default character height .15cm*/ ndtxrt = 0; /*Set default rotation to 0 degrees*/ ndclrp = -1; /*Set current device color */ /*initialize plotter */ ndotkt = 0; /*Initialize the plotter ouput counter. This */ /* counter is used by the routine 'dbufhp' */ outstr (20, setup); /*Must use outstr because block mode is set */ /*in initialization sequence. */ RDRIN(&i); dbufhp (29, setup2); if (ndlntp == DIG0) /*Set line type to initial value */ dbufhp (3, solid); /*Solid */ else { /*Dashed */ lstyle[2] = ndlntp; dbufhp (6, lstyle); } dt747x (ndtxsz, ndtysz); /*Set initial text size */ dbufhp (-1,setup); dbufhp (3, getwindw); /*Get the current window size*/ instr (50,ibuf,&i); for (i=0;(i<50)&&((ibuf[i]DIG9));++i); gchtoi (ibuf,i,&wxmin,&i); gchtoi (ibuf,i+1,&wymin,&i); gchtoi (ibuf,i+1,&wxmax,&i); gchtoi (ibuf,i+1,&wymax,&i); LSTORE (ioutseg,ioutoff,1,wxmax-wxmin); LSTORE (ioutseg,ioutoff,0,wymax-wymin); inipto[3] = inipto[11] = (wxmax-wxmin)/2; LSTORE (poutseg,poutoff,3,inipto[3]); LSTORE (poutseg,poutoff,11,inipto[3]); dbufhp (3, getid); /* Get the plotter id */ instr (30,ibuf,&i); gchtoi (ibuf,0,&temp,&i); nmbrpens = (temp==7475) ? 6 : 2; nmbrfonts = (temp==7475) ? 19 : 5; i = gimnmx (LFETCH(iinseg,iinoff,5), 1, nmbrfonts) - 1; if (i>4) i=i+1; if (i>9) i=i+20; setfnt[2] = i/10 + DIG0; setfnt[3] = (i%10) + DIG0; dbufhp (8, setfnt); /*Output command */ LSTORE (ioutseg,ioutoff,13,nmbrpens); LSTORE (ioutseg,ioutoff,10,nmbrfonts); for (i=0; i<=nmbrpens; ++i) pens[i] = i; /*Station 1 holds index 1 */ clrred[0] = 0; /*Define color index 0 to black */ clrgrn[0] = 0; clrblu[0] = 0; for (i=1;i= 0) && (x2 <= wxmax) && /* watch out for portrait mode changes*/ (y2 <= wymax)) /*Marker fits on device */ dr747x (MOVE, xy); /*Move to center point and display */ j += 2; /*Increment ptr to coords */ } mrkout[2] = SEMICOL; dbufhp (3,mrkout); /*Exit marker mode */ /*restore the user's text size */ dt747x (ndtxsz, ndtysz); break; /* opcode text */ case TEXT: dp747x (ndclrt); /*Change color to text color */ xy[0]=x_fetch(0); xy[1]=y_fetch(0); dr747x (MOVE, xy); /*Move to start point */ j = LFETCH(conseg,conoff,INTEGERxINxLENGTH);/*Get the string length */ dbufhp (-1, &endtxt); /*Force the buffer to be cleared */ dbufhp (2, txtout); /*Text command */ for (i = 0; i < j; ++i) { /*Loop to keep buffer from overflowing*/ xy[0]=LFETCH(iinseg,iinoff,i); dbufhp (1, xy); } dbufhp (1, &endtxt); /*terminate string */ break; /* opcode fill area */ case FILLxAREA: dp747x (ndclrf); /*Change color to fill color */ gsxfill (ndistyf, ndstyf, ndlntp, LFETCH(conseg,conoff,1)); break; /* opcode cell array */ case CELLxARRAY: savexy[0] = x_fetch(0); /*Save boundary points */ savexy[1] = y_fetch(0); x2 = x_fetch(2); y2 = y_fetch(2); dp747x (ndclrl); /*Change color to line color */ dr747x (MOVE, savexy); /*Move to first point */ dbufhp (3, solid); /*Set solid line type */ xy[0] = x2; /*Draw boundary around area */ xy[1] = savexy[1]; dr747x (DRAW, xy); xy[1] = y2; dr747x (DRAW, xy); xy[0] = savexy[0]; dr747x (DRAW, xy); dr747x (DRAW, savexy); if (ndlntp != DIG0) { /*restore line type if not solid */ lstyle[2] = ndlntp; dbufhp (6, lstyle); } break; /* opcode GDP's */ case GENERALIZEDxDRAWINGxPRIMITIVE: i=LFETCH(conseg,conoff,5); if(i==1) { /* BARS - supported by both plotters */ dp747x (ndclrf); /*Change color to fill color */ for (j=2; j<8; ++j) ibuf[j-2] = LFETCH(pinseg,pinoff,j); x1 = LFETCH(pinseg,pinoff,0); y1 = LFETCH(pinseg,pinoff,1); x2 = LFETCH(pinseg,pinoff,2); y2 = LFETCH(pinseg,pinoff,3); LSTORE(pinseg,pinoff,2,x2); LSTORE(pinseg,pinoff,3,y1); LSTORE(pinseg,pinoff,4,x2); LSTORE(pinseg,pinoff,5,y2); LSTORE(pinseg,pinoff,6,x1); LSTORE(pinseg,pinoff,7,y2); gsxfill(ndistyf,ndstyf,ndlntp,4); for (j=2; j<8; ++j) LSTORE(pinseg,pinoff,j,ibuf[j-2]); } if (i>1 && nmbrpens==6) { switch (i) { case 2: /*ARC */ dp747x (ndclrl); /*Change color to line color */ xy[0] = x_fetch(2); xy[1] = y_fetch(2); dr747x (MOVE, xy); /*Move to first point of arc */ dbufhp (5,arcstart); length = gitoch(x_fetch(0), icnvt, 6, &ierror); dbufhp (length,icnvt); dbufhp (1, &comma); length = gitoch(y_fetch(0), icnvt, 6, &ierror); dbufhp (length,icnvt); dbufhp (1, &comma); length = gitoch((LFETCH(iinseg,iinoff,1)-LFETCH(iinseg,iinoff,0))/10, icnvt, 6, &ierror); dbufhp (length,icnvt); dbufhp (3, arcend); break; case 3: /*Pie Slices */ case 4: /*Circles */ dp747x (ndclrf); /*Change color to line color */ xy[0] = x_fetch(0); xy[1] = y_fetch(0); dr747x (MOVE, xy); /*Move to center of slice */ if (ndistyf==1 || ndistyf==3) { for (j=0;j<2;++j) { if (ndistyf==1 ) dbufhp (7,solfill); else { ival = ndstyf; if (ndstyf > 4) ival -= 3; if (j==1) ival = (ndstyf==6) ? 4 : 1; switch (ival) { case 1: hatfill[7]=SP; hatfill[8]=DIG9; hatfill[9]=DIG0; break; case 2: hatfill[7]=hatfill[8]=SP; hatfill[9]=DIG0; break; case 3: hatfill[7]=SP; hatfill[8]=DIG4; hatfill[9]=DIG5; break; case 4: hatfill[7]=DIG1; hatfill[8]=DIG3; hatfill[9]=DIG5; break; } dbufhp (11, hatfill); } dbufhp (2, wedge); temp = (i==3) ? 6 : 4; length = gitoch(max0(2,LFETCH(pinseg,pinoff,temp)), icnvt, 6, &ierror); dbufhp (length,icnvt); dbufhp (1, &comma); temp = (i==3) ? (LFETCH(iinseg,iinoff,0)/10 + 270) : 0; length = gitoch(temp, icnvt, 6, &ierror); dbufhp (length,icnvt); dbufhp (1, &comma); temp = (i==3) ? (LFETCH(iinseg,iinoff,1)/10 + 270 - temp) : 360; length = gitoch(temp, icnvt, 6, &ierror); dbufhp (length,icnvt); dbufhp (3, arcend); if (ndistyf==1 || ndstyf<5) break; } } dbufhp (2, edgewedge); temp = (i==3) ? 6 : 4; length = gitoch(max0(2,LFETCH(pinseg,pinoff,temp)), icnvt, 6, &ierror); dbufhp (length,icnvt); dbufhp (1, &comma); temp = (i==3) ? (LFETCH(iinseg,iinoff,0)/10 + 270) : 0; length = gitoch(temp, icnvt, 6, &ierror); dbufhp (length,icnvt); dbufhp (1, &comma); temp = (i==3) ? (LFETCH(iinseg,iinoff,1)/10 + 270 - temp) : 360; length = gitoch(temp, icnvt, 6, &ierror); dbufhp (length,icnvt); dbufhp (3, arcend); break; } } break; /* opcode set character height */ case SxCHxHEIGHT: /*The input parameters represent the text height of a character */ /*cell excluding gap. The 747x plotter command for text size only requires */ /*the character width and height itself and does its own inter-line */ /*inter-character spacing. The plotter sets the character cell width */ /*to 1.5 * character width and the character cell height to 2 * character */ /*height. /*To avoid using real numbers we store the height and width in */ /*.01 cm units with an implied decimal point two places to */ /*the left (100 = 1 cm). 4 plotter steps = .01 cm */ /*Make sure not too small >=.15cm and not too large */ ndtysz = gimnmx (LFETCH(pinseg,pinoff,1), 60, inipto[3]); ndtxsz = (ndtysz * 6)/10; /*Pick appropriate width w = .6 * h */ ndtxsz = max0 (ndtxsz, 60); /*Make sure not too small >=.15cm */ /*Convert text width in dcs to .01 centimeters */ /* width = dc / (steps per .01 cm = 4) */ ndtxsz = ndtxsz/4; /*Convert text height dcs to .01 centimeters */ /* height = dc / (steps per .01 cm = 4) */ ndtysz = ndtysz/4; dt747x (ndtxsz, ndtysz); /*Set the text size */ LSTORE(conseg,conoff,2,2); /*One output coordinate pair*/ LSTORE(poutseg,poutoff,0,savexy[0] = ndtxsz * 4); LSTORE(poutseg,poutoff,1,savexy[1] = ndtysz * 4); /*cell width = 1.5 * char width */ /*cell height = 2 * char heght */ LSTORE(poutseg,poutoff,2,(savexy[0]*300)/200); LSTORE(poutseg,poutoff,3,savexy[1]*2); break; /* opcode set character up vector */ case SxCHxUPxVECTOR: ndtxrt = LFETCH(iinseg,iinoff,0); /*Device can rotate continuously */ dbufhp (2,rotate); length = gitoch (LFETCH(iinseg,iinoff,2), icnvt, 6, &ierror); dbufhp (length, icnvt); /*Output run*/ dbufhp (1, &comma); length = gitoch (-1*LFETCH(iinseg,iinoff,1), icnvt, 6, &ierror); dbufhp (length,icnvt); /*Output rise (remember portrait mode) */ /*New run = old rise, New rise = -1 * old run */ dbufhp (1,&semcol); /*End that command*/ LSTORE(ioutseg,ioutoff,0,ndtxrt); /*Inform upper level of angle */ break; /* opcode set color */ case SxCOLORxREPRESENTATION: /*Save 2 or 6 color indices, 1 for each pen station. The requested */ /*value is the same as the realized value */ i = gimnmx (LFETCH(iinseg,iinoff,0), 0, nmbrpens); /*Get color index in range */ clrred[i] = LFETCH(iinseg,iinoff,1); clrgrn[i] = LFETCH(iinseg,iinoff,2); clrblu[i] = LFETCH(iinseg,iinoff,3); break; /* opcode set line type */ case SxPLxLINETYPE: ndlntp = LFETCH(iinseg,iinoff,0); if (ndlntp < 1 | ndlntp > 7) ndlntp = 1; LSTORE(iinseg,iinoff,0,ndlntp); /*Return linetype selected */ ndlntp = ndlntp - 1 + DIG0; /*Map to device parameter */ if (ndlntp == DIG0) /*Line type solid */ dbufhp(3, solid); else { /*Line type not solid */ lstyle[2] = ndlntp; dbufhp(6, lstyle); } break; /* opcode polyline color index */ case SxPLxCOLORxINDEX: ndclrl = max0 ( 0, LFETCH(iinseg,iinoff,0)); LSTORE(ioutseg,ioutoff,ndclrl); /*Return color index selected */ break; /* opcode set marker type */ case SxPMxTYPE: ndmktp = LFETCH(iinseg,iinoff,0); if (ndmktp < 1 | ndmktp > 5) ndmktp = 3; /*Marker type 3 is default */ LSTORE(ioutseg,ioutoff,ndmktp); /*Return type selected */ break; /* opcode polymarker scale */ case SxPMxSCALE: ndmkht = gimnmx (LFETCH(pinseg,pinoff,1), 60, inipto[11]);/*Make sure size not too */ /*small or too large */ LSTORE(conseg,conoff,2,1); /*Return 1 coordinate pair */ LSTORE(poutseg,poutoff,0,0); LSTORE(poutseg,poutoff,1,ndmkht); /*Return size selected */ /*convert height in dcs to .01 centimeters */ /* height = dc / (steps per .01 cm = 4) */ ndmkht = ndmkht/4; break; /* opcode polymarker color index */ case SxPMxCOLORxINDEX: LSTORE(ioutseg,ioutoff,0,ndclrm = max0 ( 0, LFETCH(iinseg,iinoff,0))); break; /* opcode set text font */ case SxTXxFONT: i = j = gimnmx (LFETCH(iinseg,iinoff,0), 1, nmbrfonts) - 1; if (i>4) i=i+1; if (i>9) i=i+20; setfnt[2] = i/10 + DIG0; setfnt[3] = (i%10) + DIG0; dbufhp (8, setfnt); /*Output command */ LSTORE(ioutseg,ioutoff,0,j); /*Return actual font selected */ break; /* opcode text color index */ case SxTXxCOLORxINDEX: LSTORE(ioutseg,ioutoff,0,ndclrt = max0(0,LFETCH(iinseg,iinoff,0))); break; /* opcode set fill color index */ case SxFxCOLORxINDEX: LSTORE(ioutseg,ioutoff,0,ndclrf = max0(0,LFETCH(iinseg,iinoff,0))); break; /* opcode set fill interior sytle index */ case SxFxINTERIORxSTYLE: ndistyf = max0(LFETCH(iinseg,iinoff,0),0); if (ndistyf > 3) ndistyf = 0; LSTORE(ioutseg,ioutoff,0,ndistyf); break; /* opcode set fill style index */ case SxFxSTYLExINDEX: ndstyf = max0(LFETCH(iinseg,iinoff,0),1); if (ndstyf > 6) ndstyf = 1; LSTORE(ioutseg,ioutoff,0,ndstyf); break; /* opcode inquire color representation */ case INQxCOLORxREPRESENTATION: i = gimnmx (LFETCH(iinseg,iinoff,0), 0, nmbrpens); /*Map index 0-5 to 1-6 */ LSTORE(ioutseg,ioutoff,0,i + 1); /*Color index selected */ LSTORE(ioutseg,ioutoff,1,clrred[i]); /*Set values are same as realized */ LSTORE(ioutseg,ioutoff,2,clrgrn[i]); LSTORE(ioutseg,ioutoff,3,clrblu[i]); break; /* opcode input locator */ case INPxLOCATOR: LSTORE(poutseg,poutoff,0,0); LSTORE(poutseg,poutoff,1,0); LSTORE(conseg,conoff,4,UNSUCCESSFUL); i = LFETCH(iinseg,iinoff,0); /*check input device number */ if (i != DEFAULT && i != PLOTTER) return; xy[0]=x_fetch(0); xy[1]=y_fetch(0); dr747x (MOVE, xy); /*move to initial point*/ dbufhp (-1, gogin); /*First flush the buffer */ outstr (4, gogin); /*Arm to do a point input */ for (;;) { /*Go until the key was pressed */ outstr (4, inqsta); /*Ask for a status byte */ instr (40, ibuf, &temp); /*Get the answer */ for (j=0; (j<40) && (ibuf[j]==0);++j); gchtoi (ibuf, j, &ival, &istop); j = (ival>>2) % 2; if (j == 1) break; /*the third bit was on */ } outstr (4, getgin); /*Ask for the gin report */ instr (18, ibuf, &temp); /*Get the gin report */ LSTORE(conseg,conoff,4,SUCCESSFUL); /*Request was successful */ LSTORE(conseg,conoff,2,1); /*Output 1 coordinate pair */ gchtoi (ibuf, 0, &i, &istop); LSTORE(poutseg,poutoff,1,i-wxmin); gchtoi (ibuf, istop+1, &i, &istop); LSTORE(poutseg,poutoff,0,wymax-i); LSTORE(ioutseg,ioutoff,0,ibuf[istop+1] - DIG0 + SP); /*Return SP or ! (pen up/down)*/ break; /* opcode set input mode */ case SxINPUTxMODE: LSTORE(ioutseg,ioutoff,0,1); /*Default mode is request */ break; } dbufhp (-1, stopgr); /*Dump buffer */ dbufhp (3, stopgr); /*Terminate graphics */ } dr747x (opcode, xy) int opcode, xy[]; { /*********************************************************************** * * * Function: Device Driver move/draw for HP747x * * * * Input Parameters: * * opcode - driver function, either move/draw * * xy - coordinates to move or draw to * * xy [0] = x-coordinate * * xy [1] = y-coordinate * * * * Output Parameters: none * * * * Routines Called: * * dbufhp - output a string to the HP747x plotter * * gitoch - convert integer to character string * * * ************************************************************************/ int length, iconvt[10], ierror, gitoch(); static int movdrw[5] = {BIGP, BIGU, SEMICOL, BIGP, BIGA}; static int semcol[1] = {SEMICOL}; static int comma[1] = {COMMA}; movdrw[1] = BIGU; /*Always prepare to do a move */ if (opcode == DRAW) movdrw[1] = BIGD; /*Change it for a draw */ dbufhp (5, movdrw); length = gitoch (xy[0],iconvt,5,&ierror); dbufhp (length,iconvt); dbufhp (1,comma); length = gitoch (xy[1],iconvt,5,&ierror); dbufhp (length,iconvt); dbufhp (1,semcol); } dt747x (wid, hgt) unsigned int wid,hgt; { /*********************************************************************** * * * Function: Set text size on HP 747x plotter * * * * Input Parameters: * * wid - width of character in .01 cm units (1cm =100units)* * hgt - height of character in .01 cm units (1cm=100units)* * Output Parameters: * * none * * * * Routines Called: * * gitoch - convert integer to character string * * dbufhp - output a command to a hp plotter * ***********************************************************************/ int icnvt[10], j, ierror, length; unsigned int i; int gitoch(); /* Set label(text) size /SI/ */ static int txtsiz[2] = {BIGS, BIGI}; static int comma[1] = {COMMA}; static int period[1] = {PERIOD}; static int semcol[1] = {SEMICOL}; static int zero[1] = {DIG0}; dbufhp (2, txtsiz); /*Put out text size command */ /*To avoid using real numbers we store the height and width in */ /*.01 cm units with an implied decimal point two places to */ /*the left (100 = 1 cm). 4 plotter steps = .01 cm */ j = wid % 100; i = wid / 100; /*Get whole number of centimeters */ /*and remainder j=mod(wid,100) */ length = gitoch (i, icnvt, 6, &ierror); /*Output whole # of centimeters */ dbufhp (length, icnvt); dbufhp (1, period); if (j < 10) dbufhp (1, zero); /*Output tenths digit if 0 */ length = gitoch (j, icnvt, 6, &ierror); /*Output fractional centimeters */ dbufhp (length, icnvt); dbufhp (1,comma); j = hgt % 100; i = hgt / 100; /*Get whole # of centimeters */ /*and remainder j=mod(hgt,100) */ length = gitoch (i, icnvt, 6, &ierror); /*Output whole # of centimeters */ dbufhp (length, icnvt); dbufhp (1, period); if (j < 10) dbufhp (1, zero); /*Output tenths digit if 0 */ length = gitoch (j, icnvt, 6, &ierror); /*Output fractional centimeters */ dbufhp (length, icnvt); dbufhp (1,semcol); } dp747x (color) int color; { /*********************************************************************** * * * Function: Change the color on the H P 747x plotter * * * * Input Parameters: * * color - color to change to * * Output Parameters: * * none * * * * Routines Called: * * gznppl - prompt for new pen on plotter * * dbufhp - output a command to a hp plotter * ***********************************************************************/ int newsta; extern int pens[], clrred[], clrgrn[], clrblu[]; #include "ddcom.h"; /* Change pens */ static int penclr[4] = { BIGS, BIGP, DIG0, SEMICOL }; /* SP0; */ if (ndclrp != color) { /*prompt for new pen on plotter if necessary */ gznppl (color, nmbrpens, pens, &newsta); ndclrp = color; /*Set the current color */ penclr[2] = newsta + DIG0; /*Load this pen station */ dbufhp (4, penclr); } } dbufhp (icount, iarray) int icount, iarray[]; { /*********************************************************************** * * * Function: HP747x buffered output handler * * * * Input Parameters: * * icount - number of characters in iarray to be output * * -1 flushes the buffer * * * * iarray - Array of characters to be output * * * * Output Parameters: none * * * * Routines Called: * * RDRIN - get a character from the plotter * * PCHOUT - output a character to the plotter * * outstr - output a string to the plotter * * * ***********************************************************************/ int adechar, k; #include "ddcom.h"; k = icount; if (k < 0) k = 0; if (((ndotkt+k) > MAXxHPxBUFFER) || (icount < 0)) { PCHOUT (ENQ); /*Output buffer terminating character */ ndotkt = 0; /*Reset the plotter buffer counter */ /*Wait for prompt response from device. The prompt in most cases is */ /* the ack (6) character. */ adechar = 0; do RDRIN (&adechar); while ((adechar != NEWLINE) && (adechar != ACK)); } outstr (k, iarray); ndotkt = ndotkt + k; /*Update the plotter buffer counter */ } gznfpl() { /*********************************************************************** * * * Function: Issue prompt to change paper and wait for input * * * * Input Parameters: * * none * * Output Parameters: * * none * * * * Routines Called: * * TTYIN - get keyboard input * * TTYOUT - output text to console * ***********************************************************************/ int i; static int string[] = { BIGC,BIGH,BIGA,BIGN,BIGG,BIGE,SP,BIGP,BIGA,BIGP,BIGE,BIGR,COMMA, SP,BIGT,BIGH,BIGE,BIGN,SP,BIGP,BIGR,BIGE,BIGS,BIGS,SP,BIGR,BIGE, BIGT,BIGU,BIGR,BIGN,CR,LF }; i=0; do TTYOUT(string[i]); while (string[i++]!=LF); TTYIN(&i); } gznppl(color, npens, pens, newstat) int color, npens, pens[], *newstat; { /*********************************************************************** * * * Function: Issue prompt to change pens and wait for input * * * * Input Parameters: * * color - new color * * npens - number of pens on plotter * * pens - pen station array * * * * Output Parameters: * * newstat - new station * * * * Routines Called: * * TTYIN - get keyboard input * * TTYOUT - output text to console * ***********************************************************************/ int i,j; static string[] = { BIGP,BIGL,BIGA,BIGC,BIGE,SP,BIGP,BIGE,BIGN,SP,SP,SP,SP,SP,SP,SP,BIGI,BIGN,SP,BIGD,BIGE, BIGS,BIGI,BIGR,BIGE,BIGD,SP,BIGP,BIGE,BIGN,SP,BIGS,BIGT,BIGA,BIGT,BIGI, BIGO,BIGN,COMMA,SP,BIGT,BIGH,BIGE,BIGN,SP,BIGE,BIGN,BIGT,BIGE,BIGR,SP, BIGS,BIGT,BIGA,BIGT,BIGI,BIGO,BIGN,SP,BIGN,BIGU,BIGM,BIGB,BIGE,BIGR,COLON, SP,-1 }; *newstat=-1; for (i=0; i<=npens; ++i) if (pens[i]==color) *newstat=i; if (*newstat==-1) { for (i=10;i<14;++i) string[i]=SP; gitoch(color,&string[10],5,&i); i=0; do TTYOUT(string[i]); while (string[++i]>=0); TTYIN(&i); TTYOUT(i); TTYOUT(CR); TTYOUT(LF); *newstat = gimnmx(i-'0',0,npens); pens[*newstat]=color; } } instr (lenin,string,lenout) int lenin, string[], *lenout; { /*********************************************************************** * * * Function: Input a string from the plotter * * * * Input Parameters: * * lenin - maximum length of string * * * * Output Parameters: * * string - array of ADE values received from plotter * * lenout - actual length of string * * * * Routines Called: * * RDRIN - get plotter input * ***********************************************************************/ int i, tmplen; /* check for valid length */ *lenout = 1; if (lenin>0) { tmplen = min0(lenin,81); i=-1; do { RDRIN(&(string[++i])); *lenout = i; } while (imax)) return(0); else {*ierror=0; return(l);} } int gimnmx (value, min, max) int value, min, max; { /********************************************************************* * * * FUNCTION: CHECK THAT AN INTEGER IS WITHIN A GIVEN RANGE * * * * INPUT PARAMETERS: * * VALUE - INTEGER TO CHECK * * MIN - MINIMUM LEGAL VALUE * * MAX - MAXIMUM LEGAL VALUE * * * * OUTPUT PARAMETERS: * * GIMNMX - VALUE RETURNED * * * * ROUTINES CALLED: * * NONE * *********************************************************************/ return (min0(max0(min,value),max)); } nb2ade(number,chars,number_char) int number,*number_char; int *chars; /*********************************************************************** * * * Function: Convert a number to an ade-string * * * * Input Parameters: * * number - value to convert * * * * Output Parameters: * * chars - array of ade values * * number_char - length of chars * * * * Routines Called: * * none * ***********************************************************************/ { int digit,i,first,tens[5]; tens[0]=10000; tens[1]=1000; tens[2]=100; tens[3]=10; tens[4]=1; if (number==0) { *number_char=1; *(chars++)='0'; } else { *number_char=0; first=0; if (number<0) { *number_char=1; *(chars++)='-'; number*=-1; } for (i=0;i<=4;++i) { digit=number/tens[i]; if (digit>0 || first!=0) { *(chars++)=digit + '0'; ++*number_char; number-=digit*tens[i]; first=1; } } } } gchtoi (string, start, value, stop) int string[], start, *value, *stop; { /********************************************************************* * * * FUNCTION: CONVERT AN ADE STRING TO AN INTEGER * * * * INPUT PARAMETERS: * * STRING - ARRAY CONTAINING THE STRING * * START - POSITION IN STRING TO START CONVERSION * * * * OUTPUT PARAMETERS: * * VALUE - THE INTEGER VALUE * * STOP - THE LAST POSITION OF THE STRING IN THE ARRAY * * * * ROUTINES CALLED: * * NONE * *********************************************************************/ int sign; sign = 1; for (*stop=start; string[*stop]==' '; *stop++); if (string[*stop] == '+' || string[*stop] == '-' ) /* sign */ sign = (string[(*stop)++]=='+') ? 1 : -1; for (*value = 0; string[*stop] >= '0' && string[*stop] <= '9'; (*stop)++) *value = 10 * *value + string[*stop] - '0'; *value = sign * *value; } int min0 (a,b) int a,b; { /********************************************************************* * * * FUNCTION: RETURN THE MINIMUM OF A AND B * * * * INPUT PARAMETERS: * * A, B - VALUES TO FIND THE MINIMUM OF * * * * OUTPUT PARAMETERS: * * MIN0 - FUNCTION VALUE RETURNED * * * * ROUTINES CALLED: * * NONE * *********************************************************************/ return((ab) ? a : b); } gsxfill (int_style, style_index, line_style, length) int int_style, style_index, length; /*********************************************************************** * * * Function: Prepare data for polygon-fill routine * * * * Input Parameters: * * int_style - interior style * * style_index - interior style index * * line_style - current line style * * length - number of points in polygon * * * * Output Parameters: * * none * * * * Routines Called: * * LSTORE - long store * * LFETCH - long fetch * * plyfill - polygon fill * * dr747x - move/draw on plotter * * dbufhp - send string to plotter * ***********************************************************************/ { int savexy[2], xy[2], ival, i, j, distance; /* Set line style to solid /LT;/ */ static int solid[3] ={BIGL, BIGT, SEMICOL}; /* Line style /LT<0>,2;/ */ static int lstyle[6] ={BIGL, BIGT, DIG0, COMMA, DIG2, SEMICOL}; dbufhp (3, solid); /*Set linetype to solid */ if (ndistyf==1 || ndistyf==3) { savexy[0]=LFETCH(pinseg,pinoff,2*length); savexy[1]=LFETCH(pinseg,pinoff,2*length+1); LSTORE(pinseg,pinoff,2*length,LFETCH(pinseg,pinoff,0)); LSTORE(pinseg,pinoff,2*length+1,LFETCH(pinseg,pinoff,1)); distance = (ndistyf==1) ? 12 : 120; if (ndistyf==1) ival = 2; else { ival = ndstyf; if (ndstyf > 4) ival -= 3; } plyfill (ival, distance, length+1); if (ndistyf==3 && ndstyf>4) { ival = (ndstyf==5) ? 1 : 4; plyfill (ival, distance, length+1); } LSTORE(pinseg,pinoff,2*length,savexy[0]); LSTORE(pinseg,pinoff,2*length+1,savexy[1]); } xy[0]=x_fetch(0); xy[1]=y_fetch(0); dr747x (MOVE, xy); /*Move to first point */ dr747x (MOVE, xy); /*Move to repostion pen */ j = 2; for (i=2; i<=length; ++i) { /*draw between subsequent points */ xy[0]=x_fetch(j); xy[1]=y_fetch(j); dr747x (DRAW, xy); j += 2; } xy[0]=x_fetch(0); xy[1]=y_fetch(0); dr747x (DRAW, xy); /*draw to first point to make sure */ /*polygon closed */ dr747x (MOVE, xy); /*Move to the point to pick the pen up */ if (ndlntp != DIG0) { /*restore line type if not solid */ lstyle[2] = ndlntp; dbufhp (6, lstyle); } } int x_fetch(position) {return(LFETCH(pinseg,pinoff,position+1)+wxmin);} int y_fetch(position) {return(wymax-LFETCH(pinseg,pinoff,position));} plyfill(pattern,distance,length) int pattern, distance, length; /*********************************************************************** * * * Function: Fill a polygon * * * * Input Parameters: * * pattern - fill pattern * * distance - distance between fill lines * * length - number of points in polygon * * * * Output Parameters: * * none * * * * Routines Called: * * LSTORE - long store * * LFETCH - long fetch * * MULDIV - muliply and divide using 32-bits * * INTERCPT - calculate intercept formula in 32 bits * * dr2x0 - move/draw on plotter * ***********************************************************************/ { int incr, i, j, raster, intx[50], LFETCH(), MULDIV(), INTERCPT(), wmin, wmax; int x1, x2, y1, y2, j2, xy[2], temp, oldx, oldy; int oxmin, oxmax, oymin, oymax, intercept, sign, evenodd; int x_fetch(),y_fetch(); incr = distance; if (pattern > 2) incr = (distance*7)/5; sign = (pattern == 4) ? -1 : 1; oxmax = oymax = -1; oxmin = oymin = 32767; x1 = x_fetch(0); y1 = y_fetch(0); for (i=2*length-4; i>0; i-=2) { oldx = x_fetch(i); oldy = y_fetch(i); if (pattern==1 && oldy!=y1) break; if (pattern==2 && oldx!=x1) break; if (pattern>2 && (oldx-oldy)!=(-1*sign*(x1-y1))) break; } for (i=0; i<2*length; i+=2) { x1 = x_fetch(i); y1 = y_fetch(i); if (oxmax < x1) oxmax = x1; if (oxmin > x1) oxmin = x1; if (oymax < y1) oymax = y1; if (oymin > y1) oymin = y1; } switch (pattern) { case 2: wmin = oxmin; wmax = oxmax; break; case 1: wmin = oymin; wmax = oymax; break; case 4: wmin = oymin - oxmax; wmax = oymax - oxmin; break; case 3: wmax = oxmax + oymax; wmin = oxmin + oymin; break; } evenodd=0; for (raster=wmax; raster>=wmin; raster-=incr) { j = 0; evenodd = (++evenodd)%2; for (i=0; i<(2*length-2); i+=2) { x1 = x_fetch(i); y1 = y_fetch(i); x2 = x_fetch(i+2); y2 = y_fetch(i+2); intercept = -1; switch (pattern) { case 2: if ((x1<=raster && x2>=raster) || (x1>=raster && x2<=raster)) if (x1!=x2) { intercept = y1 + MULDIV(raster-x1,y1-y2,x1-x2); if ((x1==raster) && ((x2raster) || (x2>raster && oldx=raster) || (y1>=raster && y2<=raster)) if (y1!=y2) { intercept = x1 + MULDIV(raster-y1,x1-x2,y1-y2); if ((y1==raster) && ((y2raster) || (y2>raster && oldy=raster) || ((sign*x1+y1)>=raster && (sign*x2+y2)<=raster)) if (((x1!=x2) || (y1!=y2)) && (((y1-y2)+sign*(x1-x2))!=0)) { intercept = INTERCPT(raster,sign,x1,y1,x2,y2); if (((sign*x1+y1)==raster) && (((sign*x2+y2)raster) || ((sign*x2+y2)>raster && (sign*oldx+oldy)=0) { intx[j++]=intercept; l_insert(intx,j-1,intx[j-1],evenodd); } } i = 0; for (j2=0; j2 value && evenodd==0) || (array[j] < value && evenodd!=0)) { for (j2=length-1; j2>=j; --j2) array[j2+1]=array[j2]; array[j]=value; break; } }