h19630
s 00003/00004/00415
d D 1.11 83/03/18 13:24:54 mrk 11 10
c bug in solid fill
e
s 00043/00050/00376
d D 1.10 83/03/17 12:50:48 mrk 10 9
c new fancy pie fill patterns
e
s 00004/00001/00422
d D 1.9 83/03/08 18:09:53 mrk 9 8
c modified fill intervals and fixed divid parameter error
e
s 00001/00001/00422
d D 1.8 83/03/07 05:39:39 mrk 8 7
c increased the gap slightly
e
s 00002/00002/00421
d D 1.7 83/03/06 21:24:39 mrk 7 6
c changed the spacing determination
e
s 00004/00004/00419
d D 1.6 83/03/03 16:41:06 mrk 6 5
c fix of polygon fill glitch
e
s 00164/00163/00259
d D 1.5 83/02/28 11:28:49 mrk 5 4
c outline polygon at the end
e
s 00001/00001/00421
d D 1.4 83/02/24 18:23:04 mrk 4 3
c put upper bound on fill
e
s 00366/00206/00056
d D 1.3 83/02/24 18:08:07 mrk 3 2
c integer fill algorithm, finally.
e
s 00011/00008/00251
d D 1.2 83/01/28 14:01:25 tes 2 1
c initial_internal_update
e
s 00259/00000/00000
d D 1.1 83/01/28 13:04:43 tes 1 0
c date and time created 83/01/28 13:04:43 by tes
e
u
tes
mjb
mrk
mmm
U
t
T
I 1
D 3
subroutine gzemfl (ldata, xarray, yarray, scrtch, ipat, icolor)
E 3
I 3
subroutine gzemfl (icnt, iplygn, xyvert, jfill, icolor)
E 3
########################################################################
#                                                                      #
#          THIS MATERIAL IS CONFIDENTIAL AND IS FURNISHED UNDER        #
#          A WRITTEN LICENSE AGREEMENT.  IT MAY NOT BE USED,           #
#          COPIED OR DISCLOSED TO OTHERS EXCEPT IN ACCORDANCE          #
#          WITH THE TERMS OF THAT AGREEMENT.                           #
#                                                                      #
#          COPYRIGHT (C) 1982 GRAPHIC SOFTWARE SYSTEMS INC.            #
#          ALL RIGHTS RESERVED.                                        #
#                                                                      #
D 3
#     Function: Emulate general polygon fill                           #
E 3
I 3
#     Function: Fill polygon                                           #
E 3
#                                                                      #
#     Input Parameters:                                                #
D 3
#            ldata  - number of input vertices                         #
#            xarray - array of x coordinates                           #
#            yarray - array of y coordinates                           #
#            scrtch - scratch array used for fill pattern intersections#
#            ipat  - fill area interior style (HOLLOW,SOLID,HATCH)     #
#            icolor  - fill area style index                           #
#                                                                      #
E 3
I 3
#            icnt - number of points in polygon in 0-1 space           #
#            iplygn - array of vertices in 32k integer space           #
#            jfill - fill pattern to use                               #
#            icolor - color to use as the fill                         #
E 3
#     Output Parameters:                                               #
#            none                                                      #
#                                                                      #
#     Routines Called:                                                 #
D 3
#            gpsatt - Set an attribute on the current device           #
#            gzints - determine if 2 line segments intersect           #
#            gpesrt - sort a list of edge intersections                #
#                                                                      #
E 3
I 3
#            ddint - compute intersection of lines                     #
#            ddsort - sort values in ascending order                   #
E 3
########################################################################
D 3
define(`HATCHxWIDTH',`.015')
 
I 2
implicit integer (i)
E 2
integer ldata, ipat, icolor
real xarray(1), yarray(1), scrtch(1)
 
integer i, j, k, loop, kpat, jint, im1, khatch, 
        lkount, kount, kntout, ndpndt, ndir, iout
E 3

D 3
real xmin, xmax, ymin, ymax, dx, dy, temp1, temp2
real xd(2), yd(2), x1inc, x2inc, y1inc, y2inc
real dist, xe, ye, xf1, xf2, yf1, yf2
logical qint
E 3
I 3
integer icnt, iplygn(1), xyvert(1), jfill, icolor
E 3

D 3
integer gimnmx
E 3
I 3
integer x(75), y(75)
integer count, i, j, k, x1, y1, x2, y2, sortdr, ndir, kntout, xdelt, ydelt
integer xint, yint, temp, delta, first, qint, incmnt, ipat, icntm1
D 10
integer ymin, ymax, xmin, xmax, start, stop, nxtfil, oldelt
E 10
I 10
integer ymin, ymax, xmin, xmax, start, stop, nxtfil, oldelt, pattrn(7)
E 10
integer contrl(5), intin(1), ptsin(4), intout(1), ptsout(1)
D 7
integer muldiv
E 7
I 7
integer muldiv, divid
E 7
E 3

I 3
integer kfill, intcpt, slope

E 3
include(`pltcom')
D 3
 
#   Assumptions:
#      Input arrays, xarray/yarray, represent a clipped closed polygon in
#         ndc space.
#
#   Algorithm:
#      Think of the area to be filled as a rectangular area with the lower
#      left hand corner at xmin,ymin and the upper right hand corner at
#      xmax,ymax. (The coordinates xmin,ymin and xmax,ymax are obtained
#      from the input data extremes.)
#      There are 8 predefined fills
#            0 - no fill
#            1 - solid fill
#            2 - horizontal hatch
#            3 - vertical hatch
#            4 - 45 degree hatch
#            5 - -45 degree hatch
#            6 - combine 2 and 3
#            7 - combine 4 and 5
#      All filling begins from the lower left corner of the rectangular area.
#      Variables are used for the end points of the fill pattern and provide
#      the means to parameterize the filling algorithm.
#      When the fill pattern is a combination of two patterns, the fill
#      loop is traversed twice changing the parameterized end points to
#      provide the second pattern.
#      The end points of the fill line moves along the extremes of the
#      rectangular area. In the case of a horizontal pattern (pattern = 3)
#      the end points would be the minimum and maximum x extents and the
#      y coordinate would be used to increment through the area and fill.
#      At each increment of the fill line, all intersections of the fill
#      line and the polygon vertices are calculated and saved.
#      These intersection coordinates are then sorted and then each
#      intersection pair is moved to and then drawn.
#      It should be noted that a flag is passed to the sorting routine to
#      provide a means to control sorting (ascending and descending) of the
#      intersection points which minimizes pen movement for plotters.
 
   # Set line style to solid
   call gpsatt (SETxPOLYLINExLINETYPE, 1, iout)
E 3
I 3
common /polygn/ kfill, intcpt, slope
E 3

I 10
D 11
data pattrn /0, 96, 64, 32, 96, 64, 32/
E 11
I 11
data pattrn /1, 96, 64, 32, 96, 64, 32/
E 11

E 10
D 3
   # Set the line color
   call gpsatt (SETxPOLYLINExCOLORxINDEX, icolor, iout)
 
D 2
   # move to the first point of the polygon
   call imove (ABSOLUTE, xarray(1), yarray(1))

   k = ldata
   for (i=2; i<=k; i=i+1) { # Output polygon edge
      call idraw (ABSOLUTE, xarray(i), yarray(i))
      }
 
E 2
   kpat = gimnmx (ipat, 0, 7)  # Legal patterns are 0-7
E 3
I 3
define(`FILLx0', 0)
define(`FILLx1', 1)
define(`FILLx2', 2)
define(`FILLx3', 3)
define(`FILLx4', 4)
define(`FILLx5', 5)
define(`FILLx6', 6)
define(`FILLx7', 7)
define(`ENDxFILL', 23)
define(`NEXTxFILL', 22)
define(`ABSOLUTE', 1)
define(`HOLLOW', 0)
define(`SOLID',1)
E 3

D 3
   if (kpat >  0) {     # We are filling either solid or hatch
I 2
      k = ldata
E 2
      xmin = 32767.           # Initialize minimum and maximum extents to
      ymin = xmin             #    ridiculous
      xmax = -xmin
      ymax = xmax
      for (i=1; i<=k; i=i+1) {   # Determine minimum/maximum extents
         temp1 = xarray(i)
         temp2 = yarray(i)
         if (temp1 < xmin ) xmin = temp1 - ZEPS
         if (temp1 > xmax ) xmax = temp1 + ZEPS
         if (temp2 < ymin ) ymin = temp2 - ZEPS
         if (temp2 > ymax ) ymax = temp2 + ZEPS
         }
 
      ndpndt = 1      # Independent variable is x
      x1inc = 0.0     # Initialize fill end points increments to 0.0
      x2inc = x1inc
      y1inc = x1inc
      y2inc = x1inc
      dx = xmax - xmin   # Determine width and height of rectangular area
      dy = ymax - ymin
      loop = 1           # Initialize for a single loop
 
      if (kpat == 1) {
         dist = zpxly   # Set fill distance for solid
         if (dy/zpxly > dx/zpxlx) {
            kpat = 2   # If taller than wide do vertical lines
            dist = zpxlx
E 3
I 3
# Save the current line type and set to solid
call gpsatt (SETxPOLYLINExLINETYPE, 1, i)

# Set the line color
call gpsatt (SETxPOLYLINExCOLORxINDEX, icolor, i)
D 4
kfill = jfill
E 4
I 4
kfill = min0( jfill, 7)
E 4

D 5
# Outline the polygon
contrl(OPCODE) = POLYLINE
contrl(VERTICESxIN) = icnt
call gzddop (contrl, intin, iplygn, intout, ptsout)
E 5
I 5
if (kfill > HOLLOW ) {          # Do not fill if hollow
E 5

D 5
if (kfill == HOLLOW ) return    # Do not fill if hollow
E 5
I 5
   j = min0 (icnt, 75)
   k = 1
   do i = 1, j  {  # Transform points into device space
      x(i) = muldiv(iplygn(k), nxrast, 32767)
      y(i) = muldiv(iplygn(k+1), nyrast, 32767)
      k = k + 2
      }
E 5

D 5
j = min0 (icnt, 75)
k = 1
do i = 1, j  {  # Transform points into device space
   x(i) = muldiv(iplygn(k), nxrast, 32767)
   y(i) = muldiv(iplygn(k+1), nyrast, 32767)
   k = k + 2
   }
E 5
I 5
   # determine min and max x,y of polygon 
   ymin = 32767
   ymax = -32767
   xmin = ymin
   xmax = ymax
   
   for (i=1; i<=icnt; i=i+1 ) {
      temp = x(i)              # get x-coordinate
      xmin = min0 (xmin, temp)    # check for min/max
      xmax = max0 (xmax, temp)
      temp = y(i)            # get y-coordinate
      ymin = min0 (ymin, temp)    # check for min/max
      ymax = max0 (ymax, temp)
      }
E 5

D 5
# determine min and max x,y of polygon 
ymin = 32767
ymax = -32767
xmin = ymin
xmax = ymax
E 5
I 5
   # Set up for the fills
D 7
   incmnt = 10
E 7
I 7
D 8
   incmnt = divid (nxrast, 100)  # Make a line be 1/100 of an axis
E 8
I 8
D 9
   incmnt = divid (nxrast, 64)  # Make a line be 1/64 of an axis
E 9
I 9
D 10
   # Make a line be 1/64 of an axis
   incmnt = divid (nxrast, 64, i)
E 10
I 10
   incmnt = divid( nxrast, pattrn(kfill), i)

   nxtfil = 0
   if (kfill > 4)  nxtfil = 3
   if (kfill > 1)  kfill = 2
E 10
E 9
E 8
E 7
   sortdr = 2
D 10
   NEXTxFILL  nxtfil = 0
   
   goto (FILLx1, FILLx2, FILLx3, FILLx4, FILLx5, FILLx6, FILLx7), kfill
E 10
E 5

I 10
   NEXTxFILL  goto (FILLx1, FILLx2, FILLx3), kfill

E 10
D 5
for (i=1; i<=icnt; i=i+1 ) {
   temp = x(i)              # get x-coordinate
   xmin = min0 (xmin, temp)    # check for min/max
   xmax = max0 (xmax, temp)
   temp = y(i)            # get y-coordinate
   ymin = min0 (ymin, temp)    # check for min/max
   ymax = max0 (ymax, temp)
   }
E 5
I 5
   FILLx1   continue     # Solid fill , determine shortest direction
      incmnt = 1
      if (ymax-ymin < xmax-xmin)   {  # Fill using horizontal fill
D 10
         kfill = FILLx3
         go to FILLx3
E 10
I 10
         slope = -1
         start = ymin
         stop = ymax
         sortdr = 1
E 10
         }
D 10
      kfill = FILLx2  # Let fall through for vertical
E 5

D 5
# Set up for the fills
incmnt = 10
sortdr = 2
NEXTxFILL  nxtfil = 0
E 5
I 5
   FILLx2    continue   # Vertical fill
      start = xmin
      stop = xmax
E 10
I 10
      else {
         slope = 1
D 11
         sortdr = 1
E 11
         start = xmin
         stop = xmax
	 }
E 10
      go to    ENDxFILL
E 5

D 5
goto (FILLx1, FILLx2, FILLx3, FILLx4, FILLx5, FILLx6, FILLx7), kfill
E 5
I 5
D 10
   FILLx3   continue   # Horizontal fill
      start = ymin
      stop = ymax
      sortdr = 1
      go to    ENDxFILL
E 5

D 5
FILLx1   continue     # Solid fill , determine shortest direction
   incmnt = 1
   if (ymax-ymin > xmax-xmin)   {  # Fill using vertical fill
E 5
I 5
   FILLx4   continue     # Positive 45 degree fill
   FILLx5   continue     # Negative 45 degree fill
I 9
      # Diagonal fills must be further apart by 64/root(2.)
      incmnt = divid (nxrast, 45, i)
E 9
      if (kfill == FILLx5)   {
E 10
I 10
   FILLx2   continue     # Positive 45 degree fill
   FILLx3   continue     # Negative 45 degree fill
      if (kfill == FILLx3)   {
E 10
         slope = -1
         intcpt = ymin + xmin 
         }
      else   {
         slope = 1
         intcpt = ymin - xmax
         }
      start = ymin-ymax
      stop = xmax - xmin
D 10
      go to    ENDxFILL
E 10

D 10
   FILLx6   continue     # Horizontal and vertical
E 5
      kfill = FILLx3
I 5
      nxtfil = FILLx2
E 5
      go to FILLx3
D 5
      }
   kfill = FILLx2  # Let fall through for horizontal
E 5

D 5
FILLx2   continue   # Horizontal fill
   start = ymin
   stop = ymax
   sortdr = 1
   go to    ENDxFILL
E 5
I 5
   FILLx7   continue     # Narrow cross hatching
       kfill = FILLx4
       nxtfil = FILLx5
       go to FILLx4
E 5

E 10
D 5
FILLx3    continue   # Vertical fill
   start = xmin
   stop = xmax
   go to    ENDxFILL
E 5
I 5
   ENDxFILL  continue
E 5

D 5
FILLx4   continue     # Positive 45 degree fill
FILLx5   continue     # Negative 45 degree fill
   if (kfill == FILLx5)   {
      slope = -1
      intcpt = ymin + xmin 
      }
   else   {
      slope = 1
      intcpt = ymin - xmax
      }
   start = ymin-ymax
   stop = xmax - xmin
   go to    ENDxFILL
E 5

D 5
FILLx6   continue     # Horizontal and vertical
   kfill = FILLx3
   nxtfil = FILLx2
   go to FILLx3
E 5
I 5
   icntm1 = icnt - 1
   ndir = -1
   for (ipat=start; ipat <= stop; ipat=ipat+incmnt) {
E 5

D 5
FILLx7   continue     # Narrow cross hatching
    kfill = FILLx4
    nxtfil = FILLx5
    go to FILLx4
E 5
I 5
D 10
      if (kfill < FILLx4)   intcpt = ipat
E 10
I 10
      if (kfill == FILLx1)  intcpt = ipat
E 10
      else                  intcpt = intcpt + incmnt
      count = 1      # initialize intersection count 
      first = -1      # initialize pointer to first edge with intersection 
E 5

D 5
ENDxFILL  continue


icntm1 = icnt - 1
ndir = -1
for (ipat=start; ipat <= stop; ipat=ipat+incmnt) {

   if (kfill < FILLx4)   intcpt = ipat
   else                  intcpt = intcpt + incmnt
   count = 1      # initialize intersection count 
   first = -1      # initialize pointer to first edge with intersection 

   # loop over edges of polygon computing intersections with scan line 
   for (j=1; j <=icnt; j=j+1) {
      temp = j                     # Doing normal point
      if (temp == icnt)  {         # Redo the first line intersected with
	 if (first < 0) next       # If no intersections, go to next line
	 temp = first
	 }
      x1 = x(temp)                 # get first pt                   
      y1 = y(temp)
      if (temp == icntm1) {          # doing last edge                
	 x2 = x(1)                
	 y2 = y(1)
	 }
      else {                       # not doing last edge            
	 x2 = x(temp+1)              
	 y2 = y(temp+1)
	 }
E 5
I 5
      # loop over edges of polygon computing intersections with scan line 
      for (j=1; j <=icnt; j=j+1) {
         temp = j                     # Doing normal point
         if (temp == icnt)  {         # Redo the first line intersected with
	    if (first < 0) next       # If no intersections, go to next line
	    temp = first
	    }
         x1 = x(temp)                 # get first pt                   
         y1 = y(temp)
         if (temp == icntm1) {          # doing last edge                
	    x2 = x(1)                
	    y2 = y(1)
	    }
         else {                       # not doing last edge            
D 10
	    x2 = x(temp+1)              
	    y2 = y(temp+1)
E 10
I 10
	    temp = temp+1
	    x2 = x(temp)              
	    y2 = y(temp)
E 10
	    }
E 5
      
D 5
      call ddint (x1, y1, x2, y2, qint, xint, yint)  # intersection ? 
E 5
I 5
         call ddint (x1, y1, x2, y2, qint, xint, yint)  # intersection ? 
E 5

D 5
      if (qint == YES) {
	 xdelt = x2 - x1
	 ydelt = y2 - y1
	 if      (kfill == FILLx2)   delta = ydelt
	 else if (kfill == FILLx3)   delta = xdelt
	 else if (kfill == FILLx4)   delta = xdelt - ydelt
	 else                        delta = xdelt + ydelt
E 5
I 5
         if (qint == YES) {
	    xdelt = x2 - x1
	    ydelt = y2 - y1
D 10
	    if      (kfill == FILLx2)   delta = xdelt
	    else if (kfill == FILLx3)   delta = ydelt
	    else if (kfill == FILLx4)   delta = xdelt - ydelt
E 10
I 10
	    if (kfill == FILLx1)  {
	       if (slope == 1)          delta = xdelt
	       else                     delta = ydelt
	       }
	    else if (kfill == FILLx2)   delta = xdelt - ydelt
E 10
	    else                        delta = xdelt + ydelt
E 5

D 5
	 if (delta > 0) {                # positive slope 
	    if (first < 0) {             # this is first intersection-used 
					 #   to initialize algorithm. It   
					 #   must be saved and run through 
					 #   a second time to get correct  
					 #   intersecton point.            
               first = j
	       oldelt = delta
	       qint = NO
E 5
I 5
D 6
	    if (delta > 0) {                # positive slope 
E 6
I 6
	    if (delta >= 0) {               # positive slope 
E 6
	       if (first < 0) {             # this is first intersection-used 
					    #   to initialize algorithm. It   
					    #   must be saved and run through 
					    #   a second time to get correct  
					    #   intersecton point.            
                  first = j
	          oldelt = delta
	          qint = NO
	          }
D 6
               else {                       # not first intersection          
	          if (oldelt > 0) qint = NO # no dir change - dont keep pt
E 6
I 6
               else {                        # not first intersection          
	          if (oldelt >= 0) qint = NO # no dir change - dont keep pt
E 6
	          }
               }
D 6
            else if (delta <0)  {           # negative slope 
E 6
I 6
            else {           # negative slope 
E 6
	       if (first < 0) {             # this is first intersection-used 
					    #   to initialize algorithm. It   
					    #   must be saved and run through 
					    #   a second time to get correct  
					    #   intersecton point.            
                  first = j
	          oldelt = delta
	          qint = NO
	          }
               else {                       # not first intersection          
	          if (oldelt < 0) qint = NO # no dir change - dont keep pt
	          }
               }
            oldelt = delta
            if (qint == YES) {              # intersection valid 
	       xyvert(count) = xint
	       xyvert(count+1) = yint
	       count = count + 2
E 5
	       }
D 5
            else {                       # not first intersection          
	       if (oldelt > 0) qint = NO # no dir change - dont keep pt
	       }
E 3
            }
D 3
         }
      else
         dist = HATCHxWIDTH  # Set fill distance for hatch
 
      switch (kpat) {         # Switch on the input pattern index
         case 1,3,5: {          # Solid, horizontal, -45 degrees
            xe = xmax
            ye = ymin
            y2inc = dist
            if (kpat == 5) {
               x1inc = dist
               xe = xmin
               dx = dx + dy
               }
            else
               y1inc = dist
E 3
I 3
         else if (delta <0)  {           # negative slope 
	    if (first < 0) {             # this is first intersection-used 
					 #   to initialize algorithm. It   
					 #   must be saved and run through 
					 #   a second time to get correct  
					 #   intersecton point.            
               first = j
	       oldelt = delta
	       qint = NO
	       }
            else {                       # not first intersection          
	       if (oldelt < 0) qint = NO # no dir change - dont keep pt
	       }
E 3
            }
D 3
         default: {             # Vertical, 45 degrees, vertical/horizontal,
            xe = xmin              # and 45 degree/-45 degree
            ye = ymax
            x1inc = dist
            x2inc = dist
            if ((kpat == 2)|(kpat == 6)) ndpndt = 2
            else if ((kpat == 4)|(kpat == 7)) {
               xmin = xmin - dy
               dx = dx + dy
               }
           if (kpat > 5) loop = 2
            }
         }
E 3
I 3
         oldelt = delta
         if (qint == YES) {              # intersection valid 
	    xyvert(count) = xint
	    xyvert(count+1) = yint
	    count = count + 2
	    }
         }  # intersection test
      }   # end of loop over edges         
E 5
I 5
            }  # intersection test
         }   # end of loop over edges         
   
      count = count - 1
E 5

D 5
   count = count - 1
E 5
I 5
      if (count > 3)  {  # Do the fill
         ndir = -1*ndir
         kntout = count/2   # Number of intescetions
E 5

D 5
   if (count > 3)  {  # Do the fill
      ndir = -1*ndir
      kntout = count/2   # Number of intescetions
E 5
I 5
         call ddsort (kntout, xyvert, sortdr, ndir)   # sort x-vertices                
         # draw the edges
         j = 1
         contrl(OPCODE) = POLYLINE
         contrl(VERTICESxIN) = 2   # Always 2 points
E 5

D 5
      call ddsort (kntout, xyvert, sortdr, ndir)   # sort x-vertices                
      # draw the edges
      j = 1
      contrl(OPCODE) = POLYLINE
      contrl(VERTICESxIN) = 2   # Always 2 points
E 5
I 5
         do i=1, kntout , 2  {
	    ptsin(1) = muldiv( xyvert(j), 32767, nxrast)
	    ptsin(2) = muldiv( xyvert(j+1), 32767, nyrast)
	    ptsin(3) = muldiv( xyvert(j+2), 32767, nxrast)
	    ptsin(4) = muldiv( xyvert(j+3), 32767, nyrast)
	    call gzddop (contrl, intin, ptsin, intout, ptsout)
	    j = j + 4
	    }
         }
      }   # End of a scan line 
E 5

D 5
      do i=1, kntout , 2  {
	 ptsin(1) = muldiv( xyvert(j), 32767, nxrast)
	 ptsin(2) = muldiv( xyvert(j+1), 32767, nyrast)
	 ptsin(3) = muldiv( xyvert(j+2), 32767, nxrast)
	 ptsin(4) = muldiv( xyvert(j+3), 32767, nyrast)
	 call gzddop (contrl, intin, ptsin, intout, ptsout)
	 j = j + 4
	 }
E 5
I 5
   if (nxtfil !=0) { 
D 10
      kfill = nxtfil
E 10
I 10
      nxtfil = 0
      kfill = 3
E 10
      go to NEXTxFILL   # Some patterns take two passes
E 5
      }
D 5
   }   # End of a scan line 

if (nxtfil !=0) { 
   kfill = nxtfil
   go to NEXTxFILL   # Some patterns take two passes
E 5
   }
I 5
	
# Outline the polygon
contrl(OPCODE) = POLYLINE
contrl(VERTICESxIN) = icnt
call gzddop (contrl, intin, iplygn, intout, ptsout)
E 5

return
end
subroutine ddint (x1, y1, x2, y2, qint, xint, yint)
########################################################################
#                                                                      #
#          THIS MATERIAL IS CONFIDENTIAL AND IS FURNISHED UNDER        #
#          A WRITTEN LICENSE AGREEMENT.  IT MAY NOT BE USED,           #
#          COPIED OR DISCLOSED TO OTHERS EXCEPT IN ACCORDANCE          #
#          WITH THE TERMS OF THAT AGREEMENT.                           #
#                                                                      #
#          COPYRIGHT (C) 1982 GRAPHIC SOFTWARE SYSTEMS INC.            #
#          ALL RIGHTS RESERVED.                                        #
#                                                                      #
#     Function: Determine intersection of scan line with polygon edge  #
#                                                                      #
#     Input Parameters:                                                #
#            x1,y1 - first point of line                               #
#            x2,y2 - second point of line                              #
#     Output Parameters:                                               #
#            qint - 1 if lines intersect, else 0                       #
#            xint - x-coordinate of intersection                       #
#            yint - y-coordinate of intersection                       #
#                                                                      #
#     Routines Called:                                                 #
#            none                                                      #
#                                                                      #
########################################################################
integer x1, y1, x2, y2, qint, xint, yint

integer x, y, dx, dy, d, adx, ady, adx2, ady2
integer xtmp1, xtmp2, ytmp1, ytmp2, xend, temp, xincr
integer qchang
integer mult

integer nfill, intcpt, slope
common /polygn/ nfill, intcpt, slope

qint = NO
xtmp1 = x1
xtmp2 = x2
ytmp1 = y1
ytmp2 = y2
E 3
 
D 3
      do khatch=1, loop {      # Loop once for patterns 1 thru 5, twice for
         xf1 = xmin            #    patterns 6 and 7
         yf1 = ymin
         xf2 = xe
         yf2 = ye
         ndir = -1             # Initialize sort direction to decending order
E 3
I 3
dx = xtmp2 - xtmp1
dy = ytmp2 - ytmp1
D 5
if (nfill == FILLx2 & dy == 0) return   # throw away horizontal lines 
if (nfill == FILLx3 & dx == 0) return   # throw away vertical lines 
E 5
I 5
D 10
if (nfill == FILLx3 & dy == 0) return   # throw away horizontal lines 
if (nfill == FILLx2 & dx == 0) return   # throw away vertical lines 
E 10
E 5

I 10
if (nfill == FILLx1)  {  # Special cases for perpendicular lines
   if (slope == 1 & dy == 0) return   # throw away horizontal lines 
   if (slope == -1 & dx == 0) return   # throw away vertical lines 
   }

E 10
call solvit (xtmp1, ytmp1, qint) # test for intersection at endpoints 
if (qint == YES) { 
   xint = xtmp1
   yint = ytmp1
   return
   }
call solvit (xtmp2, ytmp2, qint) # test for intersection at endpoints 
if (qint == YES) { 
   xint = xtmp2
   yint = ytmp2
   return
   }

adx = iabs (dx)
ady = iabs (dy)
qchang = NO
E 3
 
D 3
         # Calculate the number of fill lines to be drawn
E 3
I 3
if (ady > adx) {     # switch x and y if slope > 1 
   temp = xtmp1
   xtmp1 = ytmp1
   ytmp1 = temp
   temp = xtmp2
   xtmp2 = ytmp2
   ytmp2 = temp
   temp = adx
   adx = ady
   ady = temp
   qchang = YES
   }
E 3
 
D 3
         if (x1inc != 0.0)  lkount = dx/x1inc + 1
         else               lkount = dy/y1inc + 1
E 3
I 3
adx2 = mult (adx, 2)
ady2 = mult (ady, 2)
temp = ady2 - adx2
E 3
 
D 3
         for (kount=1; kount<=lkount; kount=kount+1) {  # Fill the rectangular
            jint = 1                                    #    area
E 3
I 3
# reverse step direction if delta x and delta y not in same direction 
xincr = 1
if ((isign(1, dx)) != (isign(1, dy))) xincr = -1
E 3
 
D 3
            for (i=2; i<=ldata; i=i+1) {   # Calculate the intersection of the
               im1 = i - 1                 # fill line with the polygon edges
               xd(1) = xarray(im1)
               yd(1) = yarray(im1)
               xd(2) = xarray(i)
               yd(2) = yarray(i)
               call gzints (xd(1), yd(1), xd(2), yd(2), xf1, yf1, xf2, yf2,
                           qint, temp1, temp2)
E 3
I 3
if (ytmp1 <= ytmp2) {   # Determine start point 
   x = xtmp1
   y = ytmp1
   xend = xtmp2
   }
else {
   x = xtmp2
   y = ytmp2
   xend = xtmp1
   }
E 3
 
D 3
               if (qint) {         # Save the coordinate of the intersection
                  scrtch(jint) = temp1
                  scrtch(jint+1) = temp2
                  jint = jint + 2
                  }   # End of if qint block
               }
            jint = jint - 1
 
            if (jint > 3) {# If at least 2 intersections, sort the
               ndir = -1*ndir               # intersections and draw the lines
               kntout = jint/2
               call gpesrt (kntout, scrtch, ndpndt, ndir)
               j = 1
               do i=1, kntout,2 {   # Output each intersection pair
		  # output points in scrtch
		  call imove (ABSOLUTE, scrtch(j), scrtch(j+1))
		  call idraw (ABSOLUTE, scrtch(j+2), scrtch(j+3))
                  j = j + 4
                  }
               }
            xf1 = xf1 + x1inc   # Increment the fill line coordinate pairs
            yf1 = yf1 + y1inc
            xf2 = xf2 + x2inc
            yf2 = yf2 + y2inc
            }
 
         if (loop == 2) { # If this is a combined cross hatch set up for the
            x2inc = 0.0     #    second pass
            y2inc = HATCHxWIDTH
            ye = ymin
            if (kpat == 6) {    # Set up for horizontal pattern
               ndpndt = 1
               x1inc = 0.0
               y1inc = y2inc
               xe = xmax
               }
            else                # Set up for -45 degree pattern
               xmin = xmin + dy
            }
         }
E 3
I 3
d = ady2 - adx              # Compute initial error 

while (x != xend) {      # loop until done with line 
   if (d < 0) {
      d = d + ady2
E 3
I 2
      }
D 3
 
   # Now outline the polygon since we are done with the fill
   # move to the first point of the polygon
   call imove (ABSOLUTE, xarray(1), yarray(1))
E 3
I 3
   else {
      d = d + temp      # temp = ady2 - adx2 
      y = y + 1         # move up to next raster line 
      }
E 3

D 3
   k = ldata
   for (i=2; i<=k; i=i+1) { # Output polygon edge
      call idraw (ABSOLUTE, xarray(i), yarray(i))
E 3
I 3
   x = x + xincr         # move over one pixel 

   # test for intersection 
   if (qchang == YES) {     # x & y switched 
      yint = x
      xint = y
E 3
E 2
      }
D 3
 
   return
E 3
I 3
   else {                   # x & y not switched 
      xint = x
      yint = y
      }
   call solvit (xint, yint, qint)
   if (qint == YES)  return
   } 
return
E 3
end
D 3
##########################################################################
subroutine gpesrt (kin, array, index, idir)
integer kin, index, idir, kout, i, m1, j, k1, k2, k, m
real array(1), delta, temp, adir
E 3
I 3
subroutine ddsort (kin, xy, index, idir)
integer kin, xy(1), index, idir 
integer kout, i, m1, j, k1, k2, k, m, delta, temp
E 3
 
D 3
   # Bubble sort the coordinates passed in array. "Index" identifies which
E 3
I 3
   # Bubble sort the coordinates passed in xy. "Index" identifies which
E 3
   #  of the coordinate pairs (x or y) is to be used for sorting. "IDIR"
   #  specifies ascending (1) or decending sort.
 
   kout = kin
D 3
   adir = idir
E 3
   for (i=kout; i>1; i=i-1) {
      m = index
      m1 = 1
      for (j=1; j<i; j=j+1) {
D 3
         delta = adir*(array(m) - array(m+2))
         if (delta > 0.0) {
E 3
I 3
         delta =idir*(xy(m) - xy(m+2))
         if (delta > 0) {
E 3
            k1 = m1
            k2 = m1 + 1
            do k=k1, k2 {
D 3
               temp = array(k)
               array(k) = array(k+2)
               array(k+2) = temp
E 3
I 3
               temp = xy(k)
               xy(k) = xy(k+2)
               xy(k+2) = temp
E 3
               }
            }
         m = m + 2
         m1 = m1 + 2
         }
      }
 
I 3
   return
end
subroutine solvit (x, y, qint)
integer x, y, qint
integer i

integer nfill, intcpt, slope
common /polygn/ nfill, intcpt, slope

   qint = NO
D 10
   if (nfill > FILLx3)   {   # Then solve equation
E 10
I 10
   if (nfill > FILLx1)   {   # Then solve equation
E 10
      i = slope*x + intcpt
      if (y == i | y+1 == i) {    # report intersection pt 
         qint = YES
         }
      }
D 5
   else if (nfill == FILLx3 & x == intcpt)  { # This one did it
E 5
I 5
D 10
   else if (nfill == FILLx2 & x == intcpt)  { # This one did it
E 5
      qint = YES
      }
D 5
   else if (nfill == FILLx2 & y == intcpt)  { # It was this case
E 5
I 5
   else if (nfill == FILLx3 & y == intcpt)  { # It was this case
E 5
      qint = YES
E 10
I 10
   else {
D 11
      if (slope == 1 & x == intcpt)  qint = YES
      else if (y == intcpt) qint = YES
E 11
I 11
      if      (slope == 1 & x == intcpt)  qint = YES
      else if (slope == -1 & y == intcpt) qint = YES
E 11
E 10
      }
E 3
   return
end
E 1
