      SUBROUTINE LINE(X,Y,N,ICON,IPNIN)
C***********************************************************************
      LOGICAL CLOSED
C***********************************************************************
      INTEGER PXZ00,PXZ08
C***********************************************************************
      DIMENSION ST07(7,1000),IST07(7,1000),OST07(7,2),IOST07(7,2)
      DIMENSION STX(2),STY(2),ISTPEN(2)
C***********************************************************************
      DIMENSION X(1),Y(1)
C
$INCLUDE:'pxz99.cmn'
C
C***********************************************************************
      COMMON/LINSAV/LST,STX,STY,ISTPEN,OST07,ST07
C***********************************************************************
C
      DIMENSION XC(2),YC(2)
C
      EQUIVALENCE (XC(1),XA),(XC(2),XB),
     1           (YC(1),YA),(YC(2),YB)
C***********************************************************************
      EQUIVALENCE (ST07(1,1),IST07(1,1)),(OST07(1,1),IOST07(1,1))
      DATA NST07/1000/
C***********************************************************************
C
C
C  CHECK INPUT CONTROL
C***********************************************************************
      IST=0
      IOST=0
      ICONIN=ICON
C
C     GET LINE COLOR
C
      CALL GETCOL(IPNIN,IPPNIN)
C
C   FMNL = NO. OF ADDITIONAL LINES TO DRAW ON EACH SIDE OF ORIGINAL LINE
C     FOR THICK LINE OPTION TO SUBROUTINE LINE.
C
      FMNL=-IPPNIN/8
      IPN=MOD(IPPNIN,8)
      IF(ICONIN.EQ.0) LST=0
C***********************************************************************
      IF (PXZ00(-1).NE.0) RETURN
      IF (N.GT.0) GO TO 10
      KER=11
      GO TO 20
   10 IF (IPN.GE.0.AND.IPN.LE.7) GO TO 30
      KER=16
   20 CALL PXZ02(KER)
      RETURN
C
C  INITIALIZATION SECTION
   30 NLINI=NLINI+N
      IDL=2*IPN+1
      NDOF=8*IPN
      IFST=0
      NDSL=NDASH(IPN+1)
      NDS=NDSL-1
      IPEN=0
      ILG=IDASH(IPN+1)
      IF (ICON.EQ.0) ILG=-1
      IF (ILG) 50,35,35
   35 FXRL=DASHL(IDL)
      FYRL=DASHL(IDL+1)
      ILG=ILG/8
      IF (ILG) 50,38,50
   38 IF (NDS.LE.0) GO TO 40
      DL=RDASH(IPN+1)
      NDS=IDASH(IPN+1)
      IPEN=IAND((NDS+1),1)
      IF (IPEN.NE.0) GO TO 50
   40 CALL PXZ07(FXRL,FYRL,1)
C***********************************************************************
      IF(FMNL.EQ.0.0) GO TO 50
      IF(IST.EQ.NST07) GO TO 600
      IST=IST+1
      ST07(1,IST)=FXRL
      ST07(2,IST)=FYRL
      IST07(3,IST)=1
C***********************************************************************
   50 CONTINUE
C
C  X-Y LOOP
      DO 370 I=1,N
C
C  CHECK RANGE
        ICG=PXZ08(X(I),FXR,1)+PXZ08(Y(I),FYR,2)*4
        IF (ICG) 360,55,56
   55   NLINO=NLINO+1
   56   IF (ILG)  330,60,80
   60   XA=FXRL
        YA=FYRL
        IF (ICG) 360,170,70
   70   K=2
        GO TO 100
   80   K=1
        IF (ICG) 360,90,100
   90   KE=-2
        GO TO 110
  100   KE=-3
C
C  BASIC WINDOWING CUT DETERMINATION SECTION.
C
C
C  CHECK IF POINTS ON SAME SIDE OF MIN/MAX
  110   IF (IAND(ICG,ILG))  330,115,330
C
C  NO, POSSIBLE CUTS
  115   ICLG=ICG+ILG
        DXX=FXR-FXRL
        DYY=FYR-FYRL
C
C  CHECK IF LOWER/UPPER CUTS POSSIBLE
  120   IF (IAND(ICLG,12)) 140,140,122
  122   RXY=DXX/DYY
        CXY=FXRL-RXY*FYRL+.5
C
C  CHECK FOR LOWER CUT
        IF (IAND(ICLG,4))  130,130,124
  124   BXY=RYMIN
  126   FF=AINT(BXY*RXY+CXY)
        IF (FF.LT.RXMIN.OR.FF.GT.RXMAX)  GO TO 130
        YC(K)=BXY
        XC(K)=FF
        K=K+1
        IF (K+KE) 130,160,130
C
C  CHECK UPPER CUT
  130   IF (IAND(ICLG,8))  140,140,132
  132   ICLG=ICLG-8
        BXY=RYMAX
        GO TO 126
C
C  CHECK LEFT/RIGHT CUTS POSSIBLE
  140   IF (IAND(ICLG,3)) 150,150,142
  142   RXY=DYY/DXX
        CXY=FYRL-RXY*FXRL+.5
C
C  CHECK FOR LEFT CUT
        IF (IAND(ICLG,1))  150,150,144
  144   BXY=RXMIN
  146   FF=AINT(BXY*RXY+CXY)
        IF (FF.LT.RYMIN.OR.FF.GT.RYMAX)  GO TO 150
        XC(K)=BXY
        YC(K)=FF
        K=K+1
        IF (K+KE) 150,160,150
C
C  CHECK FOR RIGHT CUT
  150   IF (IAND(ICLG,2))  155,155,152
  152   ICLG=ICLG-2
        BXY=RXMAX
        GO TO 146
C
C  CHECK FOR PATHOLOGY
  155   ICLG=ILG*ICG
        IF (ICLG*(ICLG-32)*(ICLG-2))  330,158,330
  158   KER=56
        CALL PXZ02(KER)
        GO TO 375
C
  160   CONTINUE
C***********************************************************************
C
C   IF LINE INTERSECTS 2 DATA BOUNDARIES, ORDER THE BOUNDARY
C     INTERSECTIONS PTS IN DIRECTION OF ORIGINAL LINE.
C
      IF(K.LT.3) GO TO 165
      DX1=XA-FXRL
      DY1=YA-FYRL
      DX2=XB-FXRL
      DY2=YB-FYRL
      R1=DX1*DX1+DY1*DY1
      R2=DX2*DX2+DY2*DY2
      IF(R1.LE.R2) GO TO 165
      DX1=XA
      DY1=YA
      XA=XB
      YA=YB
      XB=DX1
      YB=DY1
C***********************************************************************
  165   IF (ICG)  180,170,180
  170   XB=FXR
        YB=FYR
  180   IF (IFST) 200,190,190
  190   IF (ILG) 210,220,210
  200   IFST=0
  210   CALL PXZ07(XA,YA,1)
C***********************************************************************
      IF(FMNL.EQ.0.0) GO TO 219
      IF(IST.EQ.NST07) GO TO 600
      IST=IST+1
      ST07(1,IST)=XA
      ST07(2,IST)=YA
      IST07(3,IST)=1
  219 CONTINUE
C***********************************************************************
        IPEN=0
  220   IF (NDS)  300,300,230
C
C  DASH LINE CONTROL SECTION
  230   DX=XB-XA
        DY=YB-YA
        D=SQRT(DX*DX+(DY*RYXRS)**2)
        IF (D)  235,370,235
  235   DS=0.
C
C  PUT IN LOOP FOR NO BACKWARD REFERENCES AND
C  CHECK ON DASH CONTROL
        DO 280 JD=1,32767
          DS=DS+DL
          RD=DS/D
          IF (RD-1.) 240,290,290
  240     XF=RD*DX+XA
          YF=RD*DY+YA
          CALL PXZ07(XF,YF,IPEN)
C***********************************************************************
      IF(FMNL.EQ.0.0) GO TO 279
      IF(IST.EQ.NST07) GO TO 600
      IST=IST+1
      ST07(1,IST)=XF
      ST07(2,IST)=YF
      IST07(3,IST)=IPEN
  279 CONTINUE
C***********************************************************************
          IPEN=1-IPEN
          IF (NDS.EQ.NDSL) NDS=0
          NDS=NDS+1
          DL=DASHT(NDS+NDOF)
  280     CONTINUE
C
C  NOTE..  FALL OUT OF ABOVE LOOP SHOULD NOT HAPPEN.
C  IF IT DOES IT IS MOST LIKELY DUE TO BAD DASH LINE
C  CONTROL VALUES.
        KER=55
        CALL PXZ02(KER)
        STOP 755
C
  290   IF (IPEN) 300,300,310
  300   CALL PXZ07(XB,YB,IPEN)
C***********************************************************************
      IF(FMNL.EQ.0.0) GO TO 309
      IF(IST.EQ.NST07) GO TO 600
      IST=IST+1
      ST07(1,IST)=XB
      ST07(2,IST)=YB
      IST07(3,IST)=IPEN
  309 CONTINUE
C***********************************************************************
        IF (NDS.LE.0) GO TO 350
  310   DL=DS-D
        IF (DL) 320,320,350
  320   IF (NDS.GE.NDSL) NDS=0
        NDS=NDS+1
        DL=DASHT(NDS+NDOF)
        IF (IPEN.EQ.0) IPEN=1
        GO TO 350
C
  330   IFST=-1
        IF (NDS) 350,350,340
  340   DL=DASHT(NDOF+1)
        NDS=1
  350   FXRL=FXR
        FYRL=FYR
  360   ILG=ICG
  370   CONTINUE
C
  375 DASHL(IDL)=FXRL
      DASHL(IDL+1)=FYRL
      IF (NDS) 400,400,380
  380 IF (ILG) 400,390,400
  390 RDASH(IPN+1)=DL
      IDASH(IPN+1)=NDS
      GO TO 410
  400 IDASH(IPN+1)=ILG*8
  410 IPXZY=PXZ00(0)
      IF (KER.NE.0)  CALL PXZ02(KER)
C***********************************************************************
C
C   THICK LINE OPTION.
C
      IF(FMNL.EQ.0.0.OR.IST.EQ.0) RETURN
      FNL=1.
C
C   CHECK ST07 ARRAY SO AS TO HAVE NO DUPLICATE POINTS.
C
      IBEG=1
      IF(LST.EQ.0) GO TO 393
C
C   CHECK 1ST PT VS. LAST PT OF LAST CALL FOR DUPLICATE PTS WHEN
C     CONTINUING LINE.
C
  391 IF(STX(LST).NE.ST07(1,IBEG).OR.STY(LST).NE.ST07(2,IBEG)) GO TO 392
      IBEG=IBEG+1
      IF(IBEG.GT.IST) THEN
      CALL GETCOL(0,IDUMM)
      RETURN
      ENDIF
      GO TO 391
  392 IF(IBEG.EQ.1) GO TO 393
C
C   IBEG = 1ST PT IN ST07 ARRAY ^= (STX(LST),STY(LST)).
C
      ST07(1,1)=ST07(1,IBEG)
      ST07(2,1)=ST07(2,IBEG)
      IST07(3,1)=IST07(3,IBEG)
      IF(IBEG.NE.IST) GO TO 394
      IST=1
      GO TO 415
  393 IF(IST.EQ.1) GO TO 415
C
C   NOTE:  PT AT POSN IBEG IN ST07 ARRAY ALREADY COPIED TO POSN 1.
C
  394 IOUT=2
      IBEG1=IBEG+1
      DO 398 I2ND=IBEG1,IST
      I1ST=I2ND-1
      IF(ST07(1,I1ST).EQ.ST07(1,I2ND).AND.ST07(2,I1ST).EQ.
     1ST07(2,I2ND)) GO TO 398
      IF(IOUT.EQ.I2ND) GO TO 396
C
C   HERE PT I1ST DIFFERS FROM PT I2ND.  OUTPUT I2ND.
C
      ST07(1,IOUT)=ST07(1,I2ND)
      ST07(2,IOUT)=ST07(2,I2ND)
      IST07(3,IOUT)=IST07(3,I2ND)
  396 IOUT=IOUT+1
  398 CONTINUE
      IST=IOUT-1
  415 CLOSED=.FALSE.
      IF(ICONIN.EQ.0.OR.LST.EQ.0) GO TO 422
C
C   CONTINUE FROM LAST LINE.  MUST USE LAST 2 STORED POINTS
C    TOGETHER WITH 1ST FROM CURRENT CALL TO MAKE SMOOTH JUNCTION.
C    CALL PXZ07 WITH 3RD PARM = 1 (PEN UP).
C
      XLAST=STX(LST)
      YLAST=STY(LST)
      IF(LST.LT.2) GO TO 446
C
C   HERE WE HAVE 2 PTS TO CONTINUE FROM.  DRAW LINE FROM PERPENDICULAR
C     (IF PEN WAS DOWN AT (STX(2),STY(2)) DURING LAST CALL), TO ANGLE
C      AT (STX(2),STY(2)), TO NEW PT, & CONTINUE THRU INPUT ARRAY.
C
      IF(ISTPEN(2).EQ.1) GO TO 441
      CALL RTOFF(STX(1),STY(1),STX(2),STY(2),DELX,DELY)
      XOUT=STX(2)+DELX
      YOUT=STY(2)+DELY
      CALL CHKPT1(XOUT,YOUT,1,INOUT)
      IOST=1
      OST07(1,1)=STX(2)
      OST07(2,1)=STY(2)
      IOST07(3,1)=1
      OST07(4,1)=DELX
      OST07(5,1)=DELY
  441 CALL OFF3PT(STX(1),STY(1),STX(2),STY(2),ST07(1,1),ST07(2,1),
     1STH1,CTH1,DELX,DELY)
      IF(ISTPEN(2).EQ.0) GO TO 445
C
C   SINCE THE PEN WAS UP AT PT (STX(2),STY(2)) DURING THE LAST CALL,
C     OUTPUT THE FIRST PT AT THE ANGLE CALCULATED AT THAT PT, WITH
C     THE PEN UP.
C
      XOFF2=STX(2)+DELX
      YOFF2=STY(2)+DELY
      CALL CHKPT1(XOFF2,YOFF2,1,INOUT)
      IOST=1
      OST07(1,1)=STX(2)
      OST07(2,1)=STY(2)
      IOST07(3,1)=1
      OST07(4,1)=DELX
      OST07(5,1)=DELY
      GO TO 447
C
C   CHECK TO SEE IF NEW LINE INTERSECTS OLD.  IF SO, DELX & DELY ARE
C     IN WRONG DIRECTION.
C
  445 CALL LININT(XOUT,YOUT,STX(2),STY(2),STX(1),STY(1),STH1,CTH1,
     1DELX,DELY,XOFF2,YOFF2)
      IOFPN=ISTPEN(2)
C
C   CHECK HERE TO SEE IF LINE (XOUT,YOUT),(XOFF2,YOFF2) REVERSES
C     DIRECTION FROM LINE (STX(1),STY(1)),(STX(2),STY(2)).
C     (I.E. X2P-X1P < 0.0)  IF SO, LIFT PEN TO POSN (XOFF2,YOFF2).
C
C     CALL LINREV(XOUT,YOUT,XOFF2,YOFF2,STX(1),STY(1),STH1,CTH1,IOFPN)
      IF((XOFF2-XOUT)*CTH1+(YOFF2-YOUT)*STH1.LT.0.0) IOFPN=1
      CALL RSBNDY(XOUT,YOUT,XOFF2,YOFF2,INOUT,IOFPN)
      IOST=2
      OST07(1,2)=STX(2)
      OST07(2,2)=STY(2)
      IOST07(3,2)=ISTPEN(2)
      OST07(4,2)=DELX
      OST07(5,2)=DELY
      OST07(6,2)=STH1
      OST07(7,2)=CTH1
C
C   XLAST, YLAST ARE VALUES STORED FOR LAST NON-OFFSET PT.
C    XOUT, YOUT = LAST OFFSET PT.
C
  447 XOUT=XOFF2
      YOUT=YOFF2
      IF(IST.EQ.1) GO TO 450
      GO TO 418
  446 CALL RTOFF(STX(1),STY(1),ST07(1,1),ST07(2,1),DELX,DELY)
      XOUT=STX(1)+DELX
      YOUT=STY(1)+DELY
      CALL CHKPT1(XOUT,YOUT,1,INOUT)
      IOST=1
      OST07(1,1)=STX(1)
      OST07(2,1)=STY(1)
      IOST07(3,1)=1
      OST07(4,1)=DELX
      OST07(5,1)=DELY
      IF(IST.GT.1) GO TO 418
C
C   1 PT IN CURRENT CALL.
C
      XOFF2=ST07(1,1)+DELX
      YOFF2=ST07(2,1)+DELY
      IOFPN=IST07(3,1)
      CALL RSBNDY(XOUT,YOUT,XOFF2,YOFF2,INOUT,IOFPN)
      ST07(4,1)=DELX
      ST07(5,1)=DELY
      GO TO 427
C
C   HERE HAVE MORE THAN 2 PTS IN CURRENT LINE; USE 3 PTS TO MAKE
C    NICE JUNCTION.
C    AT 422 COMPUTE PERPENDICULAR OFFSET FOR 1ST PT; THEN LOOP THRU 3 PT
C    SETS, AS HERE.
C
C   USING (XLAST,YLAST),(ST07(1,1),ST07(2,1)), & (ST07(1,2),ST07(2,2)),
C    COMPUTE THE OFFSET PT FOR THE MIDDLE NODE.  CHECK THAT IT IS
C    ON THE CORRECT SIDE.
C
  418 CALL OFF3PT(XLAST,YLAST,ST07(1,1),ST07(2,1),ST07(1,2),
     1ST07(2,2),STH1,CTH1,DELX,DELY)
C
C   CHECK TO SEE IF NEW LINE INTERSECTS OLD.  IF SO, DELX & DELY ARE
C     IN WRONG DIRECTION.
C
      CALL LININT(XOUT,YOUT,ST07(1,1),ST07(2,1),XLAST,YLAST,STH1,CTH1,
     1DELX,DELY,XOFF2,YOFF2)
      IOFPN=IST07(3,1)
C
C   CHECK HERE TO SEE IF LINE (XOUT,YOUT),(XOFF2,YOFF2) REVERSES
C     DIRECTION FROM LINE (XLAST,YLAST),(ST07(1,1),ST07(2,1)).
C     (I.E. X2P-X1P < 0.0)  IF SO, LIFT PEN TO POSN (XOFF2,YOFF2).
C
C     CALL LINREV(XOUT,YOUT,XOFF2,YOFF2,XLAST,YLAST,STH1,CTH1,IOFPN)
      IF((XOFF2-XOUT)*CTH1+(YOFF2-YOUT)*STH1.LT.0.0) IOFPN=1
      CALL RSBNDY(XOUT,YOUT,XOFF2,YOFF2,INOUT,IOFPN)
      ST07(4,1)=DELX
      ST07(5,1)=DELY
      ST07(6,1)=STH1
      ST07(7,1)=CTH1
      XOUT=XOFF2
      YOUT=YOFF2
C
C   NOW LOOP THRU 3 PT SETS IN ST07 ARRAY, USING PERPENDICULAR OFFSET
C    FOR THE LAST 2.
C
      GO TO 420
C
C   HERE WE ARE NOT CONTINUING FROM PREVIOUS LINE.  USE 1ST 2 PTS IN
C    ST07 ARRAY TO COMPUTE PERPENDICULAR OFFSET.  IF ONLY 1 PT, RETURN.
C
  422 IF(IST.EQ.1) GO TO 469
      IF(IST-3) 490,490,481
C
C   CHECK HERE TO SEE IF 1ST PT IN CURRENT CALL IS THE SAME AS THE LAST
C     PT IN CURRENT CALL (MORE THAN 3 PTS).
C
  481 IF(ST07(1,1).NE.ST07(1,IST).OR.
     1   ST07(2,1).NE.ST07(2,IST)) GO TO 490
C
C   CURRENT CALL IS A CLOSED LOOP.
C
      CLOSED=.TRUE.
C
C   CALCULATE OFFSET FROM PT 1.  SAVE XOUT,YOUT FOR CLOSING LOOP.
C
      I1=IST-1
      CALL OFF3PT(ST07(1,I1),ST07(2,I1),ST07(1,1),ST07(2,1),
     1ST07(1,2),ST07(2,2),STH1ST,CTH1ST,DELX,DELY)
      XOUT=ST07(1,1)+DELX
      YOUT=ST07(2,1)+DELY
      CALL CHKPT1(XOUT,YOUT,1,INOUT)
      ST07(4,1)=DELX
      ST07(5,1)=DELY
      DELX1=DELX
      DELY1=DELY
      ST07(6,IST)=STH1ST
      ST07(7,IST)=CTH1ST
      GO TO 420
C
C   THIS IS IDENTICAL CODE TO 1ST PT CONTINUED FROM LAST LINE.
C
  490 CALL RTOFF(ST07(1,1),ST07(2,1),ST07(1,2),ST07(2,2),DELX,DELY)
      XOUT=ST07(1,1)+DELX
      YOUT=ST07(2,1)+DELY
      CALL CHKPT1(XOUT,YOUT,1,INOUT)
      ST07(4,1)=DELX
      ST07(5,1)=DELY
C
C   AT 420, CALCULATE OFFSET FROM PT 2, ETC., IN ST07 ARRAY, USING PTS
C    1,2,3.  LAST OFFSET ALREADY OUTPUT (XOUT,YOUT) WAS FROM PT 1.
C    WHEN ONLY 2 PTS IN ST07 ARRAY REMAIN, COMPUTE PERPENDICULAR OFFSET
C    FROM LAST POINT.
C
  420 XLAST=ST07(1,1)
      YLAST=ST07(2,1)
      IF(IST.EQ.2) GO TO 450
      DO 440 I3=3,IST
      I2=I3-1
C
C   COMPUTE THE OFFSET PT FOR I2.  CHECK THAT IT IS ON THE CORRECT SIDE.
C
      CALL OFF3PT(XLAST,YLAST,ST07(1,I2),ST07(2,I2),ST07(1,I3),
     1ST07(2,I3),STH1,CTH1,DELX,DELY)
C
C   CHECK TO SEE IF NEW LINE INTERSECTS OLD.  IF SO, DELX & DELY ARE
C     IN WRONG DIRECTION.
C
      CALL LININT(XOUT,YOUT,ST07(1,I2),ST07(2,I2),XLAST,YLAST,STH1,
     1CTH1,DELX,DELY,XOFF2,YOFF2)
      IOFPN=IST07(3,I2)
C
C   CHECK HERE TO SEE IF LINE (XOUT,YOUT),(XOFF2,YOFF2) REVERSES
C     DIRECTION FROM LINE (XLAST,YLAST),(ST07(1,I2),ST07(2,I2)).
C     (I.E. X2P-X1P < 0.0)  IF SO, LIFT PEN TO POSN (XOFF2,YOFF2).
C
C     CALL LINREV(XOUT,YOUT,XOFF2,YOFF2,XLAST,YLAST,STH1,CTH1,IOFPN)
      IF((XOFF2-XOUT)*CTH1+(YOFF2-YOUT)*STH1.LT.0.0) IOFPN=1
      CALL RSBNDY(XOUT,YOUT,XOFF2,YOFF2,INOUT,IOFPN)
      ST07(4,I2)=DELX
      ST07(5,I2)=DELY
      ST07(6,I2)=STH1
      ST07(7,I2)=CTH1
      XOUT=XOFF2
      YOUT=YOFF2
      XLAST=ST07(1,I2)
      YLAST=ST07(2,I2)
  440 CONTINUE
C
C   HANDLE LAST PT HERE, WITH PERPENDICULAR OFFSET.
C
  450 IF(.NOT.CLOSED) GO TO 451
C
C   CHECK TO SEE IF NEW LINE INTERSECTS OLD.  IF SO, DELX1 & DELY1
C     ARE IN WRONG DIRECTION.
C
      CALL LININT(XOUT,YOUT,ST07(1,1),ST07(2,1),XLAST,YLAST,
     1STH1ST,CTH1ST,DELX1,DELY1,XOFF,YOFF)
      ST07(4,IST)=DELX1
      ST07(5,IST)=DELY1
C
C   CHECK HERE TO SEE IF LINE (XOUT,YOUT),(XOFF,YOFF) REVERSES
C     DIRECTION FROM LINE (ST07(1,IST-1),ST07(2,IST-1)),
C     (ST07(1,1),ST07(2,1)).  (I.E. X2P-X1P < 0.0)  IF SO,
C     GO TO 427
C
      IOFPN=IST07(3,IST)
C     CALL LINREV(XOUT,YOUT,XOFF,YOFF,XLAST,YLAST,STH1ST,
C    1CTH1ST,IOFPN)
      IF((XOFF-XOUT)*CTH1ST+(YOFF-YOUT)*STH1ST.LT.0.0) IOFPN=1
      IF(IOFPN.EQ.1) GO TO 427
C
C   CALL 1ST PT AGAIN TO COMPLETE CLOSED LOOP.
C
      CALL RSBNDY(XOUT,YOUT,XOFF,YOFF,INOUT,IOFPN)
      GO TO 427
  451 CALL RTOFF(XLAST,YLAST,ST07(1,IST),ST07(2,IST),DELX,DELY)
C
C   CHECK TO SEE IF NEW LINE INTERSECTS OLD.  IF SO, DELX & DELY ARE
C     IN WRONG DIRECTION.
C
  454 DENY=ST07(2,IST)-YLAST
      DENX=ST07(1,IST)-XLAST
      R=SQRT(DENX*DENX+DENY*DENY)
      STH1=DENY/R
      CTH1=DENX/R
      CALL LININT(XOUT,YOUT,ST07(1,IST),ST07(2,IST),XLAST,YLAST,
     1STH1,CTH1,DELX,DELY,XOFF,YOFF)
      IOFPN=IST07(3,IST)
C
C   CHECK HERE TO SEE IF LINE (XOUT,YOUT),(XOFF,YOFF) REVERSES
C     DIRECTION FROM LINE (XLAST,YLAST),(ST07(1,IST),ST07(2,IST)).
C     (I.E. X2P-X1P < 0.0)  IF SO, LIFT PEN TO POSN (XOFF,YOFF).
C
C     CALL LINREV(XOUT,YOUT,XOFF,YOFF,XLAST,YLAST,STH1,CTH1,IOFPN)
      IF((XOFF-XOUT)*CTH1+(YOFF-YOUT)*STH1.LT.0.0) IOFPN=1
      CALL RSBNDY(XOUT,YOUT,XOFF,YOFF,INOUT,IOFPN)
      ST07(4,IST)=DELX
      ST07(5,IST)=DELY
      ST07(6,IST)=STH1
      ST07(7,IST)=CTH1
  427 I1ST=1
  430 IF(FNL) 428,429,429
  428 IF(FNL.EQ.FMNL) GO TO 468
      FNL=1.-FNL
      GO TO 431
  429 FNL=-FNL
  431 IF(LST-1) 500,510,520
C
C   HANDLE 1ST PT FOR NEW LINE.
C
  500 XOUT=ST07(1,1)+FNL*ST07(4,1)
      YOUT=ST07(2,1)+FNL*ST07(5,1)
      CALL CHKPT1(XOUT,YOUT,1,INOUT)
      XLAST=ST07(1,1)
      YLAST=ST07(2,1)
      I1ST=2
      GO TO 540
C
C   HANDLE 1ST PT FOR CONTINUED LINE, WITH 1 SAVED PT FROM PREVIOUS CALL.
C
  510 XOUT=OST07(1,1)+FNL*OST07(4,1)
      YOUT=OST07(2,1)+FNL*OST07(5,1)
      CALL CHKPT1(XOUT,YOUT,1,INOUT)
      XLAST=OST07(1,1)
      YLAST=OST07(2,1)
      IF(IST.GT.1) GO TO 540
C
C   HANDLE THE ONLY PT IN 1 PT LINE CALL.
C
      XOFF=ST07(1,1)+FNL*ST07(4,1)
      YOFF=ST07(2,1)+FNL*ST07(5,1)
      CALL RSBNDY(XOUT,YOUT,XOFF,YOFF,INOUT,IST07(3,1))
      GO TO 430
C
C   HANDLE 1 OR 2 PTS FOR CONTINUED LINE CALL, WITH 2 SAVED PTS FROM
C     PREVIOUS CALL.
C
  520 XOUT=OST07(1,1)+FNL*OST07(4,1)
      YOUT=OST07(2,1)+FNL*OST07(5,1)
      CALL CHKPT1(XOUT,YOUT,1,INOUT)
      XLAST=OST07(1,1)
      YLAST=OST07(2,1)
      IF(IOST.EQ.1) GO TO 540
      XOFF=OST07(1,2)+FNL*OST07(4,2)
      YOFF=OST07(2,2)+FNL*OST07(5,2)
      IOFPN=IOST07(3,2)
C     CALL LINREV(XOUT,YOUT,XOFF,YOFF,XLAST,YLAST,OST07(6,2),
C    1OST07(7,2),IOFPN)
      IF((XOFF-XOUT)*OST07(7,2)+(YOFF-YOUT)*OST07(6,2).LT.0.0) IOFPN=1
      CALL RSBNDY(XOUT,YOUT,XOFF,YOFF,INOUT,IOFPN)
      XOUT=XOFF
      YOUT=YOFF
      XLAST=OST07(1,2)
      YLAST=OST07(2,2)
C
C   HANDLE THE INPUT POINTS TO LINE CALL.
C
  540 DO 550 I=I1ST,IST
      XOFF=ST07(1,I)+FNL*ST07(4,I)
      YOFF=ST07(2,I)+FNL*ST07(5,I)
      IOFPN=IST07(3,I)
C     CALL LINREV(XOUT,YOUT,XOFF,YOFF,XLAST,YLAST,ST07(6,I),ST07(7,I),
C    1IOFPN)
      IF((XOFF-XOUT)*ST07(7,I)+(YOFF-YOUT)*ST07(6,I).LT.0.0) IOFPN=1
      CALL RSBNDY(XOUT,YOUT,XOFF,YOFF,INOUT,IOFPN)
      XOUT=XOFF
      YOUT=YOFF
      XLAST=ST07(1,I)
      YLAST=ST07(2,I)
  550 CONTINUE
      GO TO 430
  468 IF(IST-1) 480,469,473
C
C   SAVE 1 PT.
C
  469 IF(LST-1) 470,470,472
  470 LST=LST+1
  471 STX(LST)=ST07(1,1)
      STY(LST)=ST07(2,1)
      ISTPEN(LST)=IST07(3,1)
      GO TO 480
  472 STX(1)=STX(2)
      STY(1)=STY(2)
      ISTPEN(1)=ISTPEN(2)
      GO TO 471
C
C   SAVE LAST 2 PTS.
C
  473 LST=2
      STX(1)=ST07(1,IST-1)
      STY(1)=ST07(2,IST-1)
      ISTPEN(1)=IST07(3,IST-1)
      STX(2)=ST07(1,IST)
      STY(2)=ST07(2,IST)
      ISTPEN(2)=IST07(3,IST)
  480 CALL PXZ07(STX(LST),STY(LST),1)
      RETURN
C
  600 WRITE(6,601) NST07
  601 FORMAT(2X,'ERROR--MAX NO. OF PTS ( = ',I4,') EXCEEDED ',
     1'IN SUBROUTINE LINE.')
      STOP
C
      END

