     	PROGRAM DIGITI_MAIN
C
C  PROGRAMMER:  RONG-SHENG ZHOU
C		BOSTON COLLEGE, 12/88
C
C	THIS ROUTINE PERFORMS DIGITIZATION ON A HP7550/HP7221 PLOTTER
C	WHICH IS ASSUMED PLUGGED IN THE ON-LINE TERMINAL PRINT PORT
C	SUPPORTTING ANSI PRINT CONTROLLER MODE PROTOCOL:
C
C		<ESC>[5i  ----  PRINT PORT ON
C		<ESC>[4i  ----  PRINT PORT OFF
C
     	CHARACTER IQS*1, FNAME*32

     	CALL IFINIT_SESSION
    	CALL IFANSI_CLEAR(0)
    	CALL IFANSI_MARGIN(16,0)
    	CALL IFANSI_TITLE('GRAFIT: Digitization of Analog Curves')
     	CALL IFANSI_VIDEO(47)

    	WRITE(6,1000)
1000	FORMAT(/
     +' This routine implements digitization on a HP7550-HPGL or a',
     +' HP7221'/' series pen plotter only. To begin with, the plotter',
     +' must be plugged'/' in your terminal print port which must be',
     +' enabled to support ANSI'/' printer controller mode.'//
     +' You should do the following before continuing with the',
     +' program:'//'    (1) Manually load the digitizing sight into',
     +' the pen holder.'/'    (2) Turn on the plotter into ON-LINE.'/
     +'    (3) Place the graph to be digitized on the plotter'/
     +'        in an orientation you prefer.'/)
C
C  GET TYPE OF PLOTTER ON LINE...
C
 2	WRITE(6,2000)
2000	FORMAT(' Type of plotter on-line (1>HP7221,2>HP7550) [1] ',$)
     	READ(5,2001,ERR=2,END=999) IDEV
2001	FORMAT(2I)
     	IF( IDEV.LT.0 .OR. IDEV.GT.2 ) GOTO 2
     	IF( IDEV.NE.2 ) IDEV = 1
C
C  INITIALIZE THE PLOTTER...
C
     	CALL DIGITI_INIT(IDEV)
C
C  GET OUTPUT DATA FILE...
C
 3	WRITE(6,3000)
3000	FORMAT(' Output data filename [JUNK.DAT] ',$)
	READ(5,3001,ERR=3,END=999) FNAME
3001	FORMAT(A)
	IF( FNAME.EQ.' ' ) FNAME = 'JUNK.DAT'
C
C  GET PLOT ALIGNMENT...
C
 4	WRITE(6,4000)
4000	FORMAT(' Enter graph origin coordinate values [0.0,0.0] ',$)
    	READ(5,4001,ERR=4,END=888) XORG, YORG
4001	FORMAT(2G)
     	WRITE(6,4002)
4002	FORMAT(' Move plotter pen to the origin and press [ENTER]',
     +' on plotter...',$)
	CALL DIGITI_POINT( IORX, IORY )
 5	WRITE(6,5000)
5000	FORMAT(' Enter the coordinate value of a point',
     +' on the x-axis: ',$)
    	READ(5,*,ERR=5,END=888) XEND
     	IF( XEND.EQ.XORG ) THEN
     	    WRITE(6,5001)
5001	    FORMAT('_oops: This point must be away from the origin.')
     	    GOTO 5
     	ENDIF
 55	WRITE(6,4002)
	CALL DIGITI_POINT( IX1, IY1 )
     	IF( IX1.EQ.IORX ) THEN
     	    WRITE(6,5001)
     	    GOTO 55
     	ENDIF
 6	WRITE(6,6000)
6000	FORMAT(' Enter the coordinate value of a point',
     +' on the y-axis: ',$)
    	READ(5,*,ERR=6,END=888) YEND
     	IF( YEND.EQ.YORG ) THEN
     	    WRITE(6,5001)
     	    GOTO 6
     	ENDIF
 66	WRITE(6,4002)
	CALL DIGITI_POINT( IX2, IY2 )
     	IF( IY2.EQ.IORY ) THEN
     	    WRITE(6,5001)
     	    GOTO 66
     	ENDIF
C
C  GET THE AXIS TYPE...
C
 7	WRITE(6,7000)
7000	FORMAT(' Type of x,y axis on graph (1>Linear,2>Log10) [1,1] ',$)
    	READ(5,2001,ERR=7,END=888) LXAX,LYAX
     	IF( LXAX.LT.0 .OR. LXAX.GT.2 ) GOTO 7
     	IF( LYAX.LT.0 .OR. LYAX.GT.2 ) GOTO 7
     	IF( LXAX.NE.2 ) LXAX = 1
     	IF( LYAX.NE.2 ) LYAX = 1
C
C  GATHER POINTS FROM PLOTTER...
C
     	CALL IFANSI_CURSOR(8,1)
     	CALL IFANSI_CLEAR(2)
     	WRITE(6,8000)
8000	FORMAT(
     +' You can now proceed to gather data points from the graph.'/
     +' Move plotter pen following the trace of a curve incrementally',
     +' and'/' then depressing the [ENTER] key on the plotter to',
     +' gather data points.'/' There is no limit to how many points',
     +' can be gathered from a curve.'/' Typically, 100 to 200 points',
     +' should reproduce the curve satisfactorily.')
     	CALL IFANSI_VIDEO(30)
     	WRITE(6,8001)
8001	FORMAT('  Press [ENTER] twice to finish gathering data',
     +' points from a curve. '/)
     	CALL IFANSI_VIDEO(47)
C
C  CALCULATE AXIS ROTATIONS AND SCALES...
C
     	XLEN = SQRT(FLOAT(IY1-IORY)**2+FLOAT(IX1-IORX)**2)
     	STHX = FLOAT(IY1-IORY)/XLEN
     	CTHX = FLOAT(IX1-IORX)/XLEN
     	YLEN = SQRT(FLOAT(IY2-IORY)**2+FLOAT(IX2-IORX)**2)
     	STHY = FLOAT(IX2-IORX)/YLEN
     	CTHY = FLOAT(IY2-IORY)/YLEN
     	DETT = CTHX*CTHY + STHX*STHY
    	IF( LXAX.EQ.1 ) XSCL = ( XEND-XORG ) / XLEN
    	IF( LXAX.EQ.2 ) XSCL = ( LOG10(XEND)-LOG10(XORG) ) / XLEN
    	IF( LYAX.EQ.1 ) YSCL = ( YEND-YORG ) / YLEN
    	IF( LYAX.EQ.2 ) YSCL = ( LOG10(YEND)-LOG10(YORG) ) / YLEN
C
C  OPEN THE OUTPUT DATA FILE...
C
     	OPEN(UNIT=1,FILE=FNAME,STATUS='NEW',FORM='FORMATTED')

1111	NPT = 0		!START DATA POINT COUNTER
    	IX2 = IORX
    	IY2 = IORY
2222	CALL DIGITI_POINT( IX1, IY1 )
     	IF( NPT.GT.0 .AND. IX1.EQ.IX2 .AND. IY1.EQ.IY2 ) GOTO 4444
     	IF( NPT.GT.0 ) WRITE(1,3334) XLEN, YLEN
     	IX2 = IX1
     	IY2 = IY1
     	XLEN = (FLOAT(IX2-IORX)*CTHY+FLOAT(IY2-IORY)*STHY) / DETT
     	YLEN = (FLOAT(IY2-IORY)*CTHX-FLOAT(IX2-IORX)*STHX) / DETT
    	IF( LXAX.EQ.1 ) XLEN =        XLEN*XSCL+XORG
    	IF( LXAX.EQ.2 ) XLEN = 10.0**(XLEN*XSCL+LOG10(XORG))
    	IF( LYAX.EQ.1 ) YLEN =        YLEN*YSCL+YORG
    	IF( LYAX.EQ.2 ) YLEN = 10.0**(YLEN*YSCL+LOG10(YORG))
     	NPT = NPT + 1
     	NDG = IFMISC_DIGITS(NPT)
     	WRITE(6,3333) NPT, XLEN, YLEN
3333	FORMAT(' #',I4,':',G12.5,'(X),',G12.5,'(Y)')
3334	FORMAT(2G13.5)
	GOTO 2222

4444	IF( NPT.LT.2 ) GOTO 2222
C
C  END OF ONE DATA SET...
C
     	WRITE(6,9000)
9000	FORMAT(' Enter a data set ID label: ',$)
    	READ(5,3001,END=9001) FNAME
C
C  WRITE THE LAST POINT WITH DATA SET ID...
C
9001	WRITE(1,9002) XLEN, YLEN, FNAME
9002	FORMAT(2G13.5,',,1 !',A32)
     	WRITE(6,9003)
9003	FORMAT(' Another set of data from the graph? (Y,N) [N] ',$)
    	READ(5,3001,END=888) IQS
	IF( IQS.NE.'Y' .AND. IQS.NE.'y' ) GOTO 888
	GOTO 1111
C
C  END OF THE RUN...
C
888	CLOSE(UNIT=1)
999	CALL IFINIT_EXIT
     	CALL EXIT
	END

     	SUBROUTINE DIGITI_INIT( IDEV )
C
C	THIS ROUTINE INITIALIZES THE ON-LINE PLOTTER.
C
    	BYTE PTON(7), PTOFF(7)
     	COMMON/DIGITI_PLOTTER/ IHP, PTON, PTOFF
     	DATA PTON  / 27, 91, 53, 105, 27, 46, 40 /	!<ESC>[5i<ESC>.(
     	DATA PTOFF / 27, 46, 41, 27, 91, 52, 105 /	!<ESC>.)<ESC>[4i

     	IHP = IDEV
     	IF( IHP.EQ.1 ) WRITE(6,1000) PTON,PTOFF
     	IF( IHP.EQ.2 ) WRITE(6,2000) PTON,PTOFF
1000	FORMAT(X,7A1,'~_}',7A1,$)
2000	FORMAT(X,7A1,'IN;',7A1,$)
     	RETURN
     	END

	SUBROUTINE DIGITI_POINT( IX, IY )
C
C  PROGRAMMER:  RONG-SHENG ZHOU
C		BOSTON COLLEGE, 12/88
C
C	THIS ROUTINE READS A DIGITIZED POINT FROM THE PLOTTER.
C	THE PEN IS POSITIONED OVER THE POINT TO READ AND THE
C	[ENTER] KEY ON THE PLOTTER DEPRESSED.
C
C 	IX: X COORDINATE IN PLOTTER UNITS.
C	IY: Y COORDINATE IN PLOTTER UNITS.
C
    	BYTE PTON(7), PTOFF(7), BELL
     	COMMON/DIGITI_PLOTTER/ IHP, PTON, PTOFF
    	BYTE OUTDP0(3), OUTDP1(3), OUTDP2(3), OUTSTA(3), OUTDIP(3)
    	DATA OUTDIP / 27, 46, 68 /		!<ESC>.D
    	DATA OUTDP0 / 68, 80, 59 /		! D P ;
    	DATA OUTDP1 / 79, 68, 59 /		! O D ;
    	DATA OUTSTA / 79, 83, 59 /		! O S ;
     	DATA BELL   / 7 /

111	FORMAT(x,8A1$)
222	FORMAT(2I)
     	WRITE(6,111) PTON			!TURN ON PLOTTER
    	IF( IHP.EQ.1 ) THEN
    	    WRITE(6,111) OUTDIP			!OUTPUT DIGITIZED POINT
    	    READ(5,222)  IXPS,IYPS		!READ THE PLOTTER REPLY
    	ENDIF
    	IF( IHP.EQ.2 ) THEN
    	    WRITE(6,111) OUTDP0			!ENTER DIGITIZE MODE
333	    WRITE(6,111) OUTSTA			!OUTPUT THE STATUS
    	    READ(5,222)  ISTAT			!READ THE PLOTTER REPLY
    	    ISTAT = ISTAT / 4			!SHIFTS BITS RIGHT 2
    	    IF(ISTAT.EQ.INT(ISTAT/2)*2)GOTO 333 !NO DIGITIZED POINT
    	    WRITE(6,111) OUTDP1			!OUTPUT DIGITIZED POINT
    	    READ(5,222)  IXPS,IYPS		!READ THE PLOTTER REPLY
    	ENDIF
    	WRITE(6,111) PTOFF, BELL		!TURN OFF PLOTTER
     	IX = IXPS
     	IY = IYPS

    	RETURN
    	END

