Attribute VB_Name = "ModExtraTools"
' ModExtraTools.bas

Option Explicit

' For Bezier
Public pts(1 To 4) As RPoint
Public kpts(1 To 4) As RPoint
Public aMovesBEZ As Boolean
Public SNum As Long
Public aBEZ As Boolean

' For Fractal bushes
Public BushSize() As Long
Public YBushMin As Single, YBushMax As Single  ' For coloring bushes
Public zAngP() As Single, zAngN() As Single
Public xBStep() As Single, yBStep() As Single
Public xBMul() As Single, yBMul() As Single
Public Axiom$(), PAxiom$(), QAxiom$(), RAxiom$(), SAxiom$()

Public xwarp As Single, ywarp As Single

Private bBushArray() As Byte

Public Sub ShadowBox(picDRAW As PictureBox)
' IN: xyxto(1 & 2)


'  xysto(1) -------------------
'           |                 |_
'           |   -----------  1| |
'           |   |          |  | |
'           |   |__________|  | |
'           | 3    xysto(2)  2| |
'           ------------------- |
'             |_________________|



Dim x1 As Single, y1 As Single
Dim x2 As Single, y2 As Single
Dim x3 As Single, y3 As Single
Dim zdxy As Single
Dim BS As Long, GS As Long, rs As Long
Dim BFin As Byte, GFin As Byte, RFin As Byte

Dim i As Long, k As Long
'Dim xdat As Long, ydat As Long
Dim zffincr As Single
Dim kupstep As Single
Dim zff As Single  ' background fraction
Dim zbase As Long  ' fixed RGB add
' SMOOTHING
Dim e As Long


   'If zdxy > Abs(xsto(2) - xsto(1)) Or zdxy > Abs(ysto(2) - ysto(1)) Then
   If Abs(xsto(2) - xsto(1)) > Abs(ysto(2) - ysto(1)) Then  ' W > H
      zdxy = Abs(ysto(2) - ysto(1)) / 10  ' Arbitrary 10th
      If zdxy < 2 Then
         MsgBox "Too small for shadow", vbOKOnly, "Shadow"
         Screen.MousePointer = vbDefault
         Exit Sub
      End If
   Else  ' Abs(xsto(2) - xsto(1)) <= Abs(ysto(2) - ysto(1)) ' W <= H
      zdxy = Abs(xsto(2) - xsto(1)) / 10  ' Arbitrary 10th
      If zdxy < 2 Then
         MsgBox "Too small for shadow", vbOKOnly, "Shadow"
         Screen.MousePointer = vbDefault
         Exit Sub
      End If
   End If
   
   ' Fill interior  ' Use aTransparent to allow fill or not
   ' Note assumes mouse pinned to outside box else inner box will be shadowed.
   ShadBoxDraw

   
   ' Start color: black
   rs = 0: GS = 0: BS = 0
   
   ' picDRAW coords
   x3 = xsto(1) + zdxy
   y3 = ysto(2) + 1
   x2 = xsto(2) + 1
   y2 = y3 'ysto(2) + 1
   x1 = x2 'xsto(2) + 1
   y1 = ysto(1) + zdxy
   
   ' Get picDATA() coords
'   xdat = x + xlo
'   ydat = picDRAW.Height - y + ylo - 1
   
   ' Adjust picDRAW coords to picDATA() coords
   ' xlo & ylo Public and set by ModZoomControl.Sub FixSBars_and_picDRAW
   x3 = xsto(1) + xlo + zdxy
   y3 = picDRAW.Height - ysto(2) + ylo '- 2
   x2 = xsto(2) + xlo + 1
   y2 = y3  'ysto(2) + 1
   x1 = x2  'xsto(2) + 1
   y1 = picDRAW.Height - (ysto(1) + zdxy) + ylo '- 1
   
   zff = 0  ' gives zero background component
   zffincr = 0.7 / zdxy  ' 0.7 = max component of background: arbitrary
   
   zbase = NumPoints '16 '0  ' determines how dark the shadow starts at
   
   For k = 0 To zdxy
      ' Vert lines fixed x1+k
      If y2 - k - 1 > y1 Then
         kupstep = 1
      Else
         kupstep = -1
      End If
      
      For i = y1 To y2 - k - 1 Step kupstep
         If i >= 0 Then
         If i <= FullH - 1 Then
         If x1 + k >= 0 Then
         If x1 + k <= FullW - 1 Then
            BFin = picDATAORG(0, x1 + k, i)
            GFin = picDATAORG(1, x1 + k, i)
            RFin = picDATAORG(2, x1 + k, i)
            If zff * BFin + zbase < 255 Then BS = zff * BFin + zbase
            If zff * GFin + zbase < 255 Then GS = zff * GFin + zbase
            If zff * RFin + zbase < 255 Then rs = zff * RFin + zbase
            picDATA(0, x1 + k, i) = BS
            picDATA(1, x1 + k, i) = GS
            picDATA(2, x1 + k, i) = rs
         End If
         End If
         End If
         End If
      Next i
      ' Horz lines  fixed y2-k-2
      If x2 + k > x3 Then
         kupstep = 1
      Else
         kupstep = -1
      End If
      
      For i = x3 To x2 + k Step kupstep
         If i >= 0 Then
         If i <= FullW - 1 Then
         If (y2 - k - 2) >= 0 Then
         If (y2 - k - 2) <= FullH - 1 Then
            BFin = picDATAORG(0, i, (y2 - k - 2))
            GFin = picDATAORG(1, i, (y2 - k - 2))
            RFin = picDATAORG(2, i, (y2 - k - 2))
            If zff * BFin + zbase < 255 Then BS = zff * BFin + zbase
            If zff * GFin + zbase < 255 Then GS = zff * GFin + zbase
            If zff * RFin + zbase < 255 Then rs = zff * RFin + zbase
            picDATA(0, i, (y2 - k - 2)) = BS
            picDATA(1, i, (y2 - k - 2)) = GS
            picDATA(2, i, (y2 - k - 2)) = rs
         End If
         End If
         End If
         End If
     Next i
      zff = zff + zffincr       ' Increase the background component
      If k > 3 * zdxy / 4 Then  ' Getting to last quarter of shadow: arbitrary
         'zbase = zbase + 8      ' Raise background components: arbitrary
         zff = zff + zffincr    ' Increase the background component further: arbitrary
         If zff > 0.7 Then zff = 0.7 ' Limit amount of background: arbitrary
      End If
   Next k
'''''''''''''''''''''''''''''''''''''''''''''
   
' SMOOTHING VERT LINES
   
   For k = 0 To zdxy
      ' Vert lines fixed x1+k
      If y2 - k - 1 > y1 Then
         kupstep = 1
      Else
         kupstep = -1
      End If
      y1 = y1 + 1
      For i = y1 To y2 - k - 1 Step kupstep
         If i - 1 >= 0 Then
         If i + 1 <= FullH - 1 Then
         If x1 + k >= 0 Then
         If x1 + k <= FullW - 1 Then
            BS = picDATA(0, x1 + k, i)
            GS = picDATA(1, x1 + k, i)
            rs = picDATA(2, x1 + k, i)

            BS = BS + picDATA(0, x1 + k - 1, i)
            GS = GS + picDATA(1, x1 + k - 1, i)
            rs = rs + picDATA(2, x1 + k - 1, i)

            BS = BS + picDATA(0, x1 + k + 1, i)
            GS = GS + picDATA(1, x1 + k + 1, i)
            rs = rs + picDATA(2, x1 + k + 1, i)


            BS = BS + picDATA(0, x1 + k, i - 1)
            GS = GS + picDATA(1, x1 + k, i - 1)
            rs = rs + picDATA(2, x1 + k, i - 1)

            BS = BS + picDATA(0, x1 + k, i + 1)
            GS = GS + picDATA(1, x1 + k, i + 1)
            rs = rs + picDATA(2, x1 + k, i + 1)

            BS = BS / 5
            GS = GS / 5
            rs = rs / 5
            picDATA(0, x1 + k, i) = BS
            picDATA(1, x1 + k, i) = GS
            picDATA(2, x1 + k, i) = rs
         End If
         End If
         End If
         End If
      Next i

   Next k
   
' SMOOTHING HORZ LINES
   
   y2 = y2 - 2
   x3 = x3 - 1
   For k = 0 To zdxy
      ' Horz lines  fixed y2-k
      If x2 + k > x3 Then
         kupstep = 1
      Else
         kupstep = -1
      End If
      
      For i = x3 To x2 + k Step kupstep
         If i - 1 >= 0 Then
         If i + 1 <= FullW - 1 Then
         If (y2 - k - 1) >= 0 Then
         If (y2 - k + 1) <= FullH - 1 Then

            BS = picDATA(0, i, y2 - k)
            GS = picDATA(1, i, y2 - k)
            rs = picDATA(2, i, y2 - k)
            
            BS = BS + picDATA(0, i, y2 - k - 1)
            GS = GS + picDATA(1, i, y2 - k - 1)
            rs = rs + picDATA(2, i, y2 - k - 1)
            
            BS = BS + picDATA(0, i, y2 - k + 1)
            GS = GS + picDATA(1, i, y2 - k + 1)
            rs = rs + picDATA(2, i, y2 - k + 1)
            
            BS = BS + picDATA(0, i - 1, y2 - k - 1)
            GS = GS + picDATA(1, i - 1, y2 - k - 1)
            rs = rs + picDATA(2, i - 1, y2 - k - 1)
            
            BS = BS + picDATA(0, i + 1, y2 - k + 1)
            GS = GS + picDATA(1, i + 1, y2 - k + 1)
            rs = rs + picDATA(2, i + 1, y2 - k + 1)
            
            BS = BS / 5
            GS = GS / 5
            rs = rs / 5
            picDATA(0, i, y2 - k) = BS
            picDATA(1, i, y2 - k) = GS
            picDATA(2, i, y2 - k) = rs
         End If
         End If
         End If
         End If
      Next i
   
   Next k

   DISPLAY Form1, Form1.picDRAW
End Sub


Public Sub ShadBoxDraw()
Dim k As Long
Dim svPixelSize As Long, svDrawWidth As Long
Dim svAA As Boolean
svAA = aAA
aAA = False

   svPixelSize = PixelSize
   svDrawWidth = Form1.picDRAW.DrawWidth
   Form1.picDRAW.DrawWidth = 1
   PixelSize = pxsv
   k = NumPoints + 1 ' Gap size
   If Not aTransparent Then ' Fill (Transparent CheckBox)
   
   BresBoxFill xsto(1) + 1, ysto(1) + 1, xsto(2) - 1, ysto(2) + 1 - 1, vbWhite, 0, 1  ' Fill outer box
   BresBox xsto(1), ysto(1), xsto(2), ysto(2) + 1, LeftColor, 1 ' Draw outer box
   BresBox xsto(1) + k, ysto(1) + k, xsto(2) - k, ysto(2) + 1 - k, LeftColor, 1 ' Draw inner box
   BresBoxFill xsto(1) + k + 1, ysto(1) + k + 1, xsto(2) - k - 1, ysto(2) - k - 1, RightColor, 0, 1  ' Fill inner box
   'BresBox xsto(1) + k, ysto(1) + k, xsto(2) - k, ysto(2) + 1 - k, LeftColor, 1 ' Draw inner box again
   
   Else  ' Transparent just draw outer and inner boxes
      BresBox xsto(1), ysto(1), xsto(2), ysto(2) + 1, LeftColor, 1 ' Draw outer box
      BresBox xsto(1) + k, ysto(1) + k, xsto(2) - k, ysto(2) + 1 - k, LeftColor, 1 ' Draw inner box
   
   End If
   DISPLAY Form1, Form1.picDRAW
   PixelSize = svPixelSize
   Form1.picDRAW.DrawWidth = svDrawWidth
   aAA = svAA
End Sub

Public Sub DoEraser(picDRAW As PictureBox, x As Single, y As Single)
' Adapted from Carles' PSC CodeId=34698
' Public SweepRad set by scrollbar
' NumPoints 1 to 10 set by scrollbar
Dim xdat As Long, ydat As Long
Dim RadSq As Single
Dim i As Long, j As Long
Dim ix As Long, iy As Long
Dim EB As Byte, EG As Byte, ER As Byte

   LngToRGB RightColor, ER, EG, EB
   ' Get picDATA() coords
   xdat = x + xlo
   ydat = picDRAW.Height - y + ylo - 1
   Form1.shpSweep.Left = x - SweepRad: Form1.shpSweep.TOp = y - SweepRad
   RadSq = SweepRad * SweepRad + 1
   For j = -SweepRad To SweepRad
      iy = j + ydat
      If iy >= 1 Then
      If iy < FullH - 1 Then
         For i = -SweepRad To SweepRad
            ix = i + xdat
            If ix >= 1 Then
            If ix < FullW - 1 Then
               If (i * i + j * j < RadSq) Then
                  picDATA(0, ix, iy) = EB
                  picDATA(1, ix, iy) = EG
                  picDATA(2, ix, iy) = ER
               End If
            End If
            End If
         Next i
      End If
      End If
   Next j
   DISPLAY Form1, Form1.picDRAW
End Sub

Public Sub DoSmudge(picDRAW As PictureBox, x As Single, y As Single)
' Adapted from Carles' PSC CodeId=34698
' Public SweepRad set by scrollbar
' NumPoints 1 to 10 set by scrollbar
Dim xdat As Long, ydat As Long
Dim RadSq As Single
Dim i As Long, j As Long
Dim ix As Long, iy As Long
Dim LR As Long, LG As Long, LB As Long
   ' Get picDATA() coords
   xdat = x + xlo
   ydat = picDRAW.Height - y + ylo - 1
   Form1.shpSweep.Left = x - SweepRad: Form1.shpSweep.TOp = y - SweepRad
   RadSq = SweepRad * SweepRad + 1
   For j = -SweepRad To SweepRad
      iy = j + ydat
      If iy >= 1 Then
      If iy < FullH - 1 Then
         For i = -SweepRad To SweepRad
            ix = i + xdat
            If ix >= 1 Then
            If ix < FullW - 1 Then
               If (i * i + j * j < RadSq) Then
                  LB = 1& * picDATA(0, ix - 1, iy) + _
                       picDATA(0, ix + 1, iy) + _
                       picDATA(0, ix, iy - 1) + _
                       picDATA(0, ix, iy + 1)
                  LG = 1& * picDATA(1, ix - 1, iy) + _
                       picDATA(1, ix + 1, iy) + _
                       picDATA(1, ix, iy - 1) + _
                       picDATA(1, ix, iy + 1)
                  LR = 1& * picDATA(2, ix - 1, iy) + _
                       picDATA(2, ix + 1, iy) + _
                       picDATA(2, ix, iy - 1) + _
                       picDATA(2, ix, iy + 1)
                       
                  picDATA(0, ix, iy) = LB \ 4
                  picDATA(1, ix, iy) = LG \ 4
                  picDATA(2, ix, iy) = LR \ 4
               End If
            End If
            End If
         Next i
      End If
      End If
   Next j
   DISPLAY Form1, Form1.picDRAW
End Sub


Public Sub DoStir(picDRAW As PictureBox, x As Single, y As Single)
' Public SweepRad set by scrollbar
' NumPoints 1 to 10 set by scrollbar
Dim xdat As Long, ydat As Long
Dim RadSq As Single
Dim i As Long, j As Long
Dim ix As Long, iy As Long
Dim zA As Single
Dim zR As Single
Dim zD As Single
Dim ixv As Long
Dim iyv As Long
Dim zPSWIRL As Single
   ' Get picDATA() coords
   xdat = x + xlo
   ydat = picDRAW.Height - y + ylo - 1
   zPSWIRL = 25
   RadSq = SweepRad * SweepRad '+ 1
   Form1.shpSweep.Width = 2 * SweepRad: Form1.shpSweep.Height = 2 * SweepRad
   Form1.shpSweep.Left = x - SweepRad: Form1.shpSweep.TOp = y - SweepRad
   zD = 2.828 * SweepRad  ' Sqr(Diam * Diam)
   For j = -SweepRad To SweepRad
      iy = j + ydat
      If iy >= 1 Then
      If iy < FullH - 1 Then
         For i = -SweepRad To SweepRad
            ix = i + xdat
            If ix >= 1 Then
            If ix < FullW - 1 Then
            If (i * i + j * j) < RadSq Then
               zA = zATan2(j, i)
               zR = Sqr(j * j + i * i)
               zA = zA + (zR / zD) * (zPSWIRL)
               ixv = xdat + zR * Cos(zA)
               iyv = ydat + Sgn(zPSWIRL) * zR * Sin(zA)
               If ixv > LOX - 1 Then
               If ixv <= HIX Then
               If iyv > LOY - 1 Then
               If iyv <= HIY Then
                  picDATA(0, ix, iy) = picDATAORG(0, ixv, iyv)
                  picDATA(1, ix, iy) = picDATAORG(1, ixv, iyv)
                  picDATA(2, ix, iy) = picDATAORG(2, ixv, iyv)
               End If
               End If
               End If
               End If
            End If
            End If
            End If
         Next i
      End If
      End If
   Next j
   DISPLAY Form1, Form1.picDRAW
End Sub

Public Sub DoBrightDark(picDRAW As PictureBox, x As Single, y As Single)
' Public SweepRad set by scrollbar
' Public HAR 1 to 10  Darkness/Brightness strength set by scrollbar
Dim xdat As Long, ydat As Long
Dim RadSq As Single
Dim i As Long, j As Long
Dim ix As Long, iy As Long
Dim k As Long
Dim Cul As Long
Dim zff As Single
   ' Get picDATA() coords
   xdat = x + xlo
   ydat = picDRAW.Height - y + ylo - 1
   RadSq = SweepRad * SweepRad '+ 1
   With Form1
      .shpSweep.Left = x - SweepRad
      .shpSweep.TOp = y - SweepRad
      .shpSweep.Width = 2 * SweepRad
      .shpSweep.Height = 2 * SweepRad
   End With
   If SweepTool = [Darker] Then
      'zff = 0.98 - (NumPoints - 1) / 10   ' 0.99 - 0.09
      zff = 0.98 - (HAR - 1) / 10   ' 0.99 - 0.09
   Else   ' SweepTool=Brighter
      'zff = 1 + (NumPoints) / 10 ' 1.1 - 2.0
      zff = 1 + (HAR) / 10 ' 1.1 - 2.0
   End If
   
   For j = -SweepRad To SweepRad
      iy = j + ydat
      If iy >= 1 Then
      If iy < FullH - 1 Then
         For i = -SweepRad To SweepRad
            ix = i + xdat
            If ix >= 1 Then
            If ix < FullW - 1 Then
               If (i * i + j * j) < RadSq Then
                  
                  ' To brighten black
                  If picDATAORG(0, ix, iy) < 5 Then
                  If picDATAORG(1, ix, iy) < 5 Then
                  If picDATAORG(2, ix, iy) < 5 Then
                     picDATAORG(0, ix, iy) = 32
                     picDATAORG(1, ix, iy) = 32
                     picDATAORG(2, ix, iy) = 32
                  End If
                  End If
                  End If
                  For k = 0 To 2
                     Cul = 1& * picDATAORG(k, ix, iy) * zff
                     If Cul > 255 Then Cul = 255
                     If Cul < 0 Then Cul = 0
                     picDATA(k, ix, iy) = Cul
                  Next k
   
               End If
            End If
            End If
         Next i
      End If
      End If
   Next j
   DISPLAY Form1, Form1.picDRAW
End Sub

Public Sub DoDiffuseBrightDark(picDRAW As PictureBox, x As Single, y As Single)
' Public SweepRad set by scrollbar
' Public HAR 1 to 10  Darkness/Brightness strength set by scrollbar
Dim xdat As Long, ydat As Long
Dim i As Long, j As Long
Dim ix As Long, iy As Long
Dim k As Long
Dim Cul As Long
Dim rSQ As Single
Dim RadSq As Single
Dim RRatio As Single
Dim zff As Single
   
   
   picDATA() = picDATAORG()  ' Stops trail so result is only under circle
   
   ' Get picDATA() coords
   xdat = x + xlo
   ydat = picDRAW.Height - y + ylo - 1
   RadSq = SweepRad * SweepRad '+ 1
   With Form1
      .shpSweep.Left = x - SweepRad
      .shpSweep.TOp = y - SweepRad
      .shpSweep.Width = 2 * SweepRad
      .shpSweep.Height = 2 * SweepRad
   End With
   For j = -SweepRad To SweepRad
      iy = j + ydat
      If iy >= 1 Then
      If iy < FullH - 1 Then
         For i = -SweepRad To SweepRad
            ix = i + xdat
            If ix >= 1 Then
            If ix < FullW - 1 Then
               rSQ = (i * i + j * j)
               If rSQ < RadSq Then
                  RRatio = Sqr(rSQ / RadSq)
   '               ' r=0-R  (RRatio-1) = -1 to 0  ' DiffDark
   '               ' r=0-R  (1-RRatio) =  1 to 0  ' DiffBright
                  Select Case SweepTool
                  Case [DiffDarker], [DiffLessBlue], [DiffLessGreen], [DiffLessRed]
                     zff = (RRatio - 1) * HAR * 50 ' 50 arbitrary
                  Case [DiffBrighter], [DiffMoreBlue], [DiffMoreGreen], [DiffMoreRed]
                     zff = (1 - RRatio) * HAR * 50
                  End Select
                  
                  ' k = 0 and 1   Brighter more blue & green, Darker less blue & green
                  ' k = 1 and 2   Brighter more green & red, Darker less green & red
                  ' k = 0 and 2   Brighter more blue & red, Darker less blue and red
                  
                  ' k=0 Bright more blue, Dark less blue
                  ' k=1 Bright more green, Dark less green
                  ' k=2 Bright more red, Dark less red
                  
                  ' NB zff changes with  rSQ = (i * i + j * j)

                  Select Case SweepTool
                  Case [DiffDarker], [DiffBrighter]
                  For k = 0 To 2    ' brighter/darker all RGB color
                     Cul = 1& * picDATAORG(k, ix, iy) + zff
                     If Cul > 255 Then Cul = 255
                     If Cul < 0 Then Cul = 0
                     picDATA(k, ix, iy) = Cul
                  Next k
                  Case [DiffLessBlue], [DiffMoreBlue]
                     k = 0
                     Cul = 1& * picDATAORG(k, ix, iy) + zff
                     If Cul > 255 Then Cul = 255
                     If Cul < 0 Then Cul = 0
                     picDATA(k, ix, iy) = Cul
                  Case [DiffLessGreen], [DiffMoreGreen]
                     k = 1
                     Cul = 1& * picDATAORG(k, ix, iy) + zff
                     If Cul > 255 Then Cul = 255
                     If Cul < 0 Then Cul = 0
                     picDATA(k, ix, iy) = Cul
                  Case [DiffLessRed], [DiffMoreRed]
                     k = 2
                     Cul = 1& * picDATAORG(k, ix, iy) + zff
                     If Cul > 255 Then Cul = 255
                     If Cul < 0 Then Cul = 0
                     picDATA(k, ix, iy) = Cul
                  
                  End Select
                  
               End If
            End If
            End If
         Next i
      End If
      End If
   Next j
   
   
   DISPLAY Form1, Form1.picDRAW
   
End Sub


Public Sub DoSharpen(picDRAW As PictureBox, x As Single, y As Single)
' Public SweepRad set by scrollbar
' NumPoints 1 to 10 set by scrollbar
Dim xdat As Long, ydat As Long
Dim RadSq As Single
Dim i As Long, j As Long
Dim ii As Long, jj As Long
Dim ix As Long, iy As Long
Dim r As Long, g As Long, B As Long
' SHARP
'-2 -2 -2
'-2 26 -2
'-2 -2 -2

   ' Get picDATA() coords
   xdat = x + xlo
   ydat = picDRAW.Height - y + ylo - 1
   RadSq = SweepRad * SweepRad '+ 1
   Form1.shpSweep.Width = 2 * SweepRad: Form1.shpSweep.Height = 2 * SweepRad
   Form1.shpSweep.Left = x - SweepRad: Form1.shpSweep.TOp = y - SweepRad
   For j = -SweepRad To SweepRad
      iy = j + ydat
      If iy > 1 Then
      If iy < FullH - 1 Then
         For i = -SweepRad To SweepRad
            ix = i + xdat
            If ix > 1 Then
            If ix < FullW - 1 Then
            If (i * i + j * j) < RadSq Then
               For jj = iy - 1 To iy + 1
               For ii = ix - 1 To ix + 1
                  If (jj <> iy Or ii <> ix) Then
                     B = B - 2 * picDATAORG(0, ii, jj)
                     g = g - 2 * picDATAORG(1, ii, jj)
                     r = r - 2 * picDATAORG(2, ii, jj)
                  Else
                     B = B + 26 * picDATAORG(0, ii, jj)
                     g = g + 26 * picDATAORG(1, ii, jj)
                     r = r + 26 * picDATAORG(2, ii, jj)
                  End If
               Next ii
               Next jj
               B = B \ 10
               r = r \ 10
               g = g \ 10
               If B < 0 Then B = 0 Else If B > 255 Then B = 255
               If g < 0 Then g = 0 Else If g > 255 Then g = 255
               If r < 0 Then r = 0 Else If r > 255 Then r = 255
               picDATA(0, ix, iy) = B
               picDATA(1, ix, iy) = g
               picDATA(2, ix, iy) = r
            End If
            End If
            End If
         Next i
      End If
      End If
   Next j
   DISPLAY Form1, Form1.picDRAW
End Sub


Public Sub DoSmooth(picDRAW As PictureBox, x As Single, y As Single)
' Public SweepRad set by scrollbar
' NumPoints 1 to 10 set by scrollbar
Dim xdat As Long, ydat As Long
Dim RadSq As Single
Dim i As Long, j As Long
Dim ix As Long, iy As Long
Dim r As Long, g As Long, B As Long

' Cross blur
' 0 1 0
' 1 0 1
' 0 1 0
   ' Get picDATA() coords
   xdat = x + xlo
   ydat = picDRAW.Height - y + ylo - 1
   RadSq = SweepRad * SweepRad '+ 1
   Form1.shpSweep.Width = 2 * SweepRad: Form1.shpSweep.Height = 2 * SweepRad
   Form1.shpSweep.Left = x - SweepRad: Form1.shpSweep.TOp = y - SweepRad
   For j = -SweepRad To SweepRad
      iy = j + ydat
      If iy > 1 Then
      If iy < FullH - 1 Then
         For i = -SweepRad To SweepRad
            ix = i + xdat
            If ix > 1 Then
            If ix < FullW - 1 Then
            If (i * i + j * j) < RadSq Then
               B = picDATAORG(0, ix, iy)
               g = picDATAORG(1, ix, iy)
               r = picDATAORG(2, ix, iy)
               
               B = B + picDATAORG(0, ix, iy - 1)
               g = g + picDATAORG(1, ix, iy - 1)
               r = r + picDATAORG(2, ix, iy - 1)
               
               B = B + picDATAORG(0, ix, iy + 1)
               g = g + picDATAORG(1, ix, iy + 1)
               r = r + picDATAORG(2, ix, iy + 1)
               
               B = B + picDATAORG(0, ix - 1, iy)
               g = g + picDATAORG(1, ix - 1, iy)
               r = r + picDATAORG(2, ix - 1, iy)
               
               B = B + picDATAORG(0, ix + 1, iy)
               g = g + picDATAORG(1, ix + 1, iy)
               r = r + picDATAORG(2, ix + 1, iy)
               B = B \ 5
               g = g \ 5
               r = r \ 5
               If B < 0 Then B = 0 Else If B > 255 Then B = 255
               If g < 0 Then g = 0 Else If g > 255 Then g = 255
               If r < 0 Then r = 0 Else If r > 255 Then r = 255
               picDATA(0, ix, iy) = B
               picDATA(1, ix, iy) = g
               picDATA(2, ix, iy) = r
            End If
            End If
            End If
         Next i
      End If
      End If
   Next j
   DISPLAY Form1, Form1.picDRAW
End Sub


Public Sub DoWarp(picDRAW As PictureBox, Button As Integer, Shift As Integer, x As Single, y As Single)
' Public SweepRad set by scrollbar
' NumPoints 1 to 10 set by scrollbar
Dim xdat As Long, ydat As Long
Dim RadSq As Single
Dim i As Long, j As Long
Dim ix As Long, iy As Long
Dim xd As Single, yd As Single
Dim absxd As Single, absyd As Single
Dim r As Long, g As Long, B As Long
   ' WARP
   '    LEFT        RIGHT            UP               DOWN
   '  Left button  Right button   Shift Left button  Shift Right button
   '  -1  0 +1     +1  0 -1       +1  0 +1           -1 0  -1    y-1
   '   0  8  0      0  8  0        0  8  0            0  8  0    y
   '  -1  0 +1     +1  0 -1       -1  0 -1           +1  0 +1    y+1
   ' x-1  x  x+1

   ' Get picDATA() coords
   xdat = x + xlo
   ydat = picDRAW.Height - y + ylo - 1
   RadSq = SweepRad * SweepRad '+ 1
   Form1.shpSweep.Width = 2 * SweepRad: Form1.shpSweep.Height = 2 * SweepRad
   Form1.shpSweep.Left = x - SweepRad: Form1.shpSweep.TOp = y - SweepRad
   ReDim m(1, 1)
   xd = x - xwarp
   yd = y - ywarp
   absxd = Abs(xd)
   absyd = Abs(yd)
   xwarp = x
   ywarp = y
   
   If absxd >= absyd Then  ' Left or Right
      If xd <= 0 Then ' Left
         m(0, 0) = -1
         m(1, 0) = 1
         m(0, 1) = -1
         m(1, 1) = 1
      Else  ' Right
         m(0, 0) = 1
         m(1, 0) = -1
         m(0, 1) = 1
         m(1, 1) = -1
      End If
   Else  ' Up or down
      If yd <= 0 Then ' Up
         m(0, 0) = 1
         m(1, 0) = 1
         m(0, 1) = -1
         m(1, 1) = -1
      Else  ' Down
         m(0, 0) = -1
         m(1, 0) = -1
         m(0, 1) = 1
         m(1, 1) = 1
      End If
   End If
   
   
   For j = -SweepRad To SweepRad
      iy = j + ydat
      If iy > 1 Then
      If iy < FullH - 1 Then
         For i = -SweepRad To SweepRad
            ix = i + xdat
            If ix > 1 Then
            If ix < FullW - 1 Then
            If (i * i + j * j) < RadSq Then
               B = 8 * picDATA(0, ix, iy)
               g = 8 * picDATA(1, ix, iy)
               r = 8 * picDATA(2, ix, iy)
               
               B = B + m(0, 0) * picDATA(0, ix - 1, iy - 1)
               g = g + m(0, 0) * picDATA(1, ix - 1, iy - 1)
               r = r + m(0, 0) * picDATA(2, ix - 1, iy - 1)

               B = B + m(1, 0) * picDATA(0, ix + 1, iy - 1)
               g = g + m(1, 0) * picDATA(1, ix + 1, iy - 1)
               r = r + m(1, 0) * picDATA(2, ix + 1, iy - 1)
               
               B = B + m(0, 1) * picDATA(0, ix - 1, iy + 1)
               g = g + m(0, 1) * picDATA(1, ix - 1, iy + 1)
               r = r + m(0, 1) * picDATA(2, ix - 1, iy + 1)

               B = B + m(1, 1) * picDATA(0, ix + 1, iy + 1)
               g = g + m(1, 1) * picDATA(1, ix + 1, iy + 1)
               r = r + m(1, 1) * picDATA(2, ix + 1, iy + 1)
               
               B = B \ 8
               r = r \ 8
               g = g \ 8
                  
               If B < 0 Then B = 0 Else If B > 255 Then B = 255
               If g < 0 Then g = 0 Else If g > 255 Then g = 255
               If r < 0 Then r = 0 Else If r > 255 Then r = 255
               picDATA(0, ix, iy) = B
               picDATA(1, ix, iy) = g
               picDATA(2, ix, iy) = r
            End If
            End If
            End If
         Next i
      End If
      End If
   Next j
   
   DISPLAY Form1, Form1.picDRAW
End Sub


Public Sub SetUpFractalBushes()
   ReDim BushSize(1 To 7)
   ReDim zAngP(1 To 7), zAngN(1 To 7)
   ReDim xBStep(1 To 7), yBStep(1 To 7)
   ReDim xBMul(1 To 7), yBMul(1 To 7)
   ReDim Axiom$(1 To 7)
   ReDim PAxiom$(1 To 7)
   ReDim QAxiom$(1 To 7)
   ReDim RAxiom$(1 To 7)
   ReDim SAxiom$(1 To 7)
   ' Sparse tree
   BushSize(1) = 1
   Axiom$(1) = "FG"
   PAxiom$(1) = "FG+[+F-F-F]-[-G+F+F]"
   zAngP(1) = 12
   zAngN(1) = -12
   xBStep(1) = 0
   yBStep(1) = -4
   xBMul(1) = 1.01
   yBMul(1) = 1.05
   ' Sparse Leaning bush
   BushSize(2) = 1
   Axiom$(2) = "F"
   'Axiom$(2) = "++F"  Lean over more
   PAxiom$(2) = "FF+[+F-F-F]-[-F+F+F]"
   zAngP(2) = 25
   zAngN(2) = -25
   xBStep(2) = 0
   yBStep(2) = -5
   xBMul(2) = 1
   yBMul(2) = 1
   ' Symmetrical fennel like
   BushSize(3) = 1
   Axiom$(3) = "F"
   'Axiom$(3) = "+F"  ' Lean over
   PAxiom$(3) = "F[+F[+F][-F]F][-F[+F][-F]F]F[+F][-F]F"
   zAngP(3) = 35
   zAngN(3) = -35
   xBStep(3) = 0
   yBStep(3) = -2
   xBMul(3) = 1.02
   yBMul(3) = 1.06
   
   ' Upright plant
   BushSize(4) = 1
   Axiom$(4) = "P"
   PAxiom$(4) = "F[+P][-P]FP"
   QAxiom$(4) = "FF"
   zAngP(4) = 25
   zAngN(4) = -25
   xBStep(4) = 0
   yBStep(4) = -0.3
   xBMul(4) = 1
   yBMul(4) = 1
   
   ' Elm like tree
   BushSize(5) = 1
   Axiom$(5) = "F"
   PAxiom$(5) = "F[+F]F[-F][F]"
   zAngP(5) = 30
   zAngN(5) = -30
   xBStep(5) = 0
   yBStep(5) = -2
   xBMul(5) = 1
   yBMul(5) = 1
   
   ' Fern like bush
   BushSize(6) = 1
   Axiom$(6) = "F"
   PAxiom$(6) = "FF-[-F+F+F]+[+F-F-F+FFF]"
   zAngP(6) = 30
   zAngN(6) = -30
   xBStep(6) = 0
   yBStep(6) = -2
   xBMul(6) = 1
   yBMul(6) = 1
   
   ' Tall plant
   BushSize(7) = 1
   Axiom$(7) = "P"
   PAxiom$(7) = "PFQ[+P][-P]"
   QAxiom$(7) = "Q[-FFF][+FFF]FQ"
   RAxiom$(7) = "RFS[+R][-R]"
   SAxiom$(7) = "S[-FFF][+FFF]FS"
   zAngP(7) = 25
   zAngN(7) = -25
   xBStep(7) = 0
   yBStep(7) = -1
   xBMul(7) = 1
   yBMul(7) = 0.995
End Sub

Public Sub StartEndFBush(picDRAW As PictureBox, x As Single, y As Single)
' From Mouse_Up
Dim Level As Long
   If NClicks <> 1 Then Exit Sub
   If NClicks = 1 Then
      Select Case SingleTool
      Case [FBush1]  ' Sparse tree
         Select Case NumPoints   ' Bush size
         Case 1: Level = 2
                 yBStep(1) = -4
                 yBMul(1) = 1.05
         Case 2: Level = 3
                 yBStep(1) = -4
                 yBMul(1) = 1.03
         Case 3: Level = 3
                 yBStep(1) = -5
                 yBMul(1) = 1.05
         Case 4: Level = 4
                 yBStep(1) = -5
                 yBMul(1) = 1.05
         End Select
      Case [FBush2]  ' Sparse Leaning bush
         Select Case NumPoints
         Case 1: Level = 2
                 yBStep(2) = -5
                 yBMul(2) = 1
         Case 2: Level = 3
                 yBStep(2) = -3
                 yBMul(2) = 1
         Case 3: Level = 3
                 yBStep(2) = -5
                 yBMul(2) = 1.01
         Case 4: Level = 4
                 yBStep(2) = -5
                 yBMul(2) = 1.01
         End Select
      
      Case [FBush3]  ' Symmetrical fennel like
         Select Case NumPoints
         Case 1: Level = 2
                 yBStep(3) = -1
                 yBMul(3) = 1.2
         Case 2: Level = 3
                 yBStep(3) = -1
                 yBMul(3) = 1.06
         Case 3: Level = 3
                 yBStep(3) = -2
                 yBMul(3) = 1.04
         Case 4: Level = 4
                 'yBStep(3) = -2
                 'yBMul(3) = 1.04
                 yBStep(3) = -1
                 yBMul(3) = 1.03
         End Select
      
      Case [FBush4]  ' Upright plant
         Select Case NumPoints
         Case 1: Level = 5 '2
                 yBStep(4) = -0.3
                 yBMul(4) = 1
         Case 2: Level = 6
                 yBStep(4) = -0.3
                 yBMul(4) = 1
         Case 3: Level = 7
                 yBStep(4) = -0.3
                 yBMul(4) = 1
         Case 4: Level = 8
                 yBStep(4) = -0.3
                 yBMul(4) = 1
         End Select
      
      Case [FBush5]  ' Elm like tree
         Select Case NumPoints
         Case 1: Level = 3
                 yBStep(5) = -2
                 yBMul(5) = 1
         Case 2: Level = 4
                 yBStep(5) = -2
                 yBMul(5) = 1
         Case 3: Level = 5
                 yBStep(5) = -2
                 yBMul(5) = 1
         Case 4: Level = 6
                 yBStep(5) = -2
                 yBMul(5) = 1
         End Select
      
      Case [FBush6]  ' Fern like bush
         Select Case NumPoints
         Case 1: Level = 2
                 yBStep(6) = -2
         Case 2: Level = 3
                 yBStep(6) = -2
         Case 3: Level = 3
                 yBStep(6) = -3
         Case 4: Level = 4
                 yBStep(6) = -3
         End Select
      
      Case [FBush7]  ' Tall plant
         Select Case NumPoints
         Case 1: Level = 2
                 yBStep(7) = -2
                 xBMul(7) = 1
                 yBMul(7) = 0.995
         Case 2: Level = 3
                 yBStep(7) = -1.4
                 xBMul(7) = 1
                 yBMul(7) = 0.995
         Case 3: Level = 3
                 yBStep(7) = -2
                 xBMul(7) = 1
                 yBMul(7) = 0.995
         Case 4: Level = 4
                 yBStep(7) = -2
                 xBMul(7) = 1
                 yBMul(7) = 0.995
         End Select
      
      End Select
      
      StartTwoCoords
      
      ' SingleTool-2 is [FBush1]=3 etc to get 1,2,3,4
      DisplayTree picDRAW, Level, SingleTool - 2, x, y, XorCul
      xp = x
      yp = y
'   ElseIf NClicks = 2 Then
'      CompleteBush picDRAW, X, Y, DCul
   End If
End Sub

Private Sub DisplayTree(picDRAW As PictureBox, Level As Long, IT As Long, _
                       ByVal xs As Single, ByVal ys As Single, DCul As Long)
Dim k As Long
Dim LL As Long
Dim zTmp As Single
Dim zCosAngP As Single
Dim zSinAngP As Single
Dim zCosAngN As Single
Dim zSinAngN As Single
Dim XStepSave As Single, YStepSave As Single
Dim NumBrackets As Long
Dim zSaveState(4000) As Single
Dim ExpandedAxiom$

   YBushMin = 10000
   YBushMax = -10000
   ExpandedAxiom$ = Axiom$(IT)
   
   Select Case SingleTool
   Case [FBush1], [FBush2], [FBush3], [FBush5], [FBush6] ' P
      For k = 1 To Level
         ExpandedAxiom$ = Replace$(ExpandedAxiom$, "F", PAxiom$(IT))
      Next k
   Case [FBush4]  ' P,Q Upright plant
      For k = 1 To Level
         ExpandedAxiom$ = Replace$(ExpandedAxiom$, "P", PAxiom$(IT))
         ExpandedAxiom$ = Replace$(ExpandedAxiom$, "F", QAxiom$(IT))
      Next k
      ' Remove redundant Ps
      ExpandedAxiom$ = Replace$(ExpandedAxiom$, "P", "")
   Case [FBush7]   ' P,Q,R,S  Tall plant
      For k = 1 To Level
         ExpandedAxiom$ = Replace$(ExpandedAxiom$, "P", RAxiom$(IT))
         ExpandedAxiom$ = Replace$(ExpandedAxiom$, "Q", SAxiom$(IT))
      
         ExpandedAxiom$ = Replace$(ExpandedAxiom$, "R", PAxiom$(IT))
         ExpandedAxiom$ = Replace$(ExpandedAxiom$, "S", QAxiom$(IT))
      Next k
      ' Remove redundant P,Q,R,Ss
      ExpandedAxiom$ = Replace$(ExpandedAxiom$, "P", "")
      ExpandedAxiom$ = Replace$(ExpandedAxiom$, "Q", "")
      ExpandedAxiom$ = Replace$(ExpandedAxiom$, "R", "")
      ExpandedAxiom$ = Replace$(ExpandedAxiom$, "S", "")
   End Select
   
   LL = Len(ExpandedAxiom$)
   ' Transfer characters to byte array
   ReDim bBushArray(LL)
   CopyMemory bBushArray(1), ByVal ExpandedAxiom$, LL
   ExpandedAxiom$ = ""
   
   NumBrackets = 0
   zCosAngP = Cos(zAngP(IT) * d2r#)
   zSinAngP = Sin(zAngP(IT) * d2r#)
   zCosAngN = Cos(zAngN(IT) * d2r#)
   zSinAngN = Sin(zAngN(IT) * d2r#)
   
   ' Save start steps for further drawing
   XStepSave = xBStep(IT)
   YStepSave = yBStep(IT)
   
   'If aAA Then
      pxsv = PixelSize
      If pxsv > 2 Then
         picDRAW.DrawWidth = 2
         PixelSize = 2
      End If
   'End If
   
   For k = 1 To LL
      
      Select Case bBushArray(k)
      Case 70, 71 ' F Pen Down, Advance:  G Pen Up, Advance
         
         If bBushArray(k) = 70 Then   ' F draw
            PointCount = PointCount + 1
            If PointCount > UBound(xsto()) Then
               ReDim Preserve xsto(1 To PointCount + 10), ysto(1 To PointCount + 10)
            End If
            xsto(PointCount) = CInt(xs + xBStep(IT))
            ysto(PointCount) = CInt(ys + yBStep(IT))
            picDRAW.Line (xsto(PointCount - 1), ysto(PointCount - 1))-(xsto(PointCount), ysto(PointCount)), DCul
            
            If ysto(PointCount) < YBushMin Then YBushMin = ysto(PointCount)
            If ysto(PointCount) > YBushMax Then YBushMax = ysto(PointCount)
            ' Shell bands
            'picDRAW.PSet (xsto(PointCount - 1), ysto(PointCount - 1)), DCul
            'picDRAW.Refresh
         End If
         'Advance
         xs = xs + xBStep(IT): ys = ys + yBStep(IT)
         xBStep(IT) = xBStep(IT) * xBMul(IT)
         yBStep(IT) = yBStep(IT) * yBMul(IT)
           
      Case 91  ' [  Push turtle state
         
         NumBrackets = NumBrackets + 1
         zSaveState(NumBrackets) = xs
         NumBrackets = NumBrackets + 1
         zSaveState(NumBrackets) = ys
         NumBrackets = NumBrackets + 1
         zSaveState(NumBrackets) = xBStep(IT) '''''
         NumBrackets = NumBrackets + 1
         zSaveState(NumBrackets) = yBStep(IT) ''''''
      
      Case 93  ' ] Pop turtle state
         
         yBStep(IT) = zSaveState(NumBrackets)  ''''''
         NumBrackets = NumBrackets - 1
         xBStep(IT) = zSaveState(NumBrackets)  ''''''
         NumBrackets = NumBrackets - 1
         ys = zSaveState(NumBrackets)
         NumBrackets = NumBrackets - 1
         xs = zSaveState(NumBrackets)
         NumBrackets = NumBrackets - 1
           
      Case 43   ' + turn left
   
         zTmp = xBStep(IT)
         xBStep(IT) = zCosAngP * zTmp - zSinAngP * yBStep(IT)
         yBStep(IT) = zSinAngP * zTmp + zCosAngP * yBStep(IT)
           
      Case 45   ' - turn right
       
         zTmp = xBStep(IT)
         xBStep(IT) = zCosAngN * zTmp - zSinAngN * yBStep(IT)
         yBStep(IT) = zSinAngN * zTmp + zCosAngN * yBStep(IT)
       
      'Case Else   'Ignore
      
      End Select
      
   Next k
   picDRAW.Refresh
   
   'If aAA Then
      PixelSize = pxsv
      picDRAW.DrawWidth = PixelSize
   'End If
   ' Restore start steps
   xBStep(IT) = XStepSave
   yBStep(IT) = YStepSave
   Erase zSaveState(), bBushArray()
End Sub

Public Sub MoveBush(picDRAW As PictureBox, x As Single, y As Single)
Dim dx As Long, DY As Long
Dim k As Long
   
   'If aAA Then
      pxsv = PixelSize
      If pxsv > 2 Then
         picDRAW.DrawWidth = 2
         PixelSize = 2
      End If
   'End If
   ' Clear bush
   For k = 2 To PointCount
      picDRAW.Line (xsto(k - 1), ysto(k - 1))-(xsto(k), ysto(k)), XorCul
   Next k
   
   If TheKey = vbKeySpace Then
      For k = 2 To PointCount
         picDRAW.Line (xsto(k - 1), ysto(k - 1))-(xsto(k), ysto(k)), XorCul
      Next k
      TheKey = 0
   End If
   
   ' Draw Bush
   dx = x - xp
   DY = y - yp
   For k = 1 To PointCount
      xsto(k) = xsto(k) + dx     ' Bump
      ysto(k) = ysto(k) + DY
   Next k
   
   ' Draw
   For k = 2 To PointCount
      picDRAW.Line (xsto(k - 1), ysto(k - 1))-(xsto(k), ysto(k)), XorCul
   Next k
   xp = x
   yp = y

   'If aAA Then
      PixelSize = pxsv
      picDRAW.DrawWidth = PixelSize
   'End If
End Sub

Public Sub CompleteBush(picDRAW As PictureBox, x As Single, y As Single, DTool As Long)
' DTol=SingleTool  [FBush1] to [FBush7]
Dim k As Long
Dim LSwap As Boolean   ' False
   
   'If aAA Then
      pxsv = PixelSize
      If pxsv > 2 Then
         picDRAW.DrawWidth = 2
         PixelSize = 2
      End If
   'End If
   ' Clear
   For k = 2 To PointCount
      picDRAW.Line (xsto(k - 1), ysto(k - 1))-(xsto(k), ysto(k)), XorCul
   Next k
   
   ' Draw
   picDRAW.DrawMode = vbCopyPen
   LSwap = False
   Select Case DTool
   Case [FBush4], [FBush7]    ' Upright plant, Tall plant +/- swap colors
      If zAngP(DTool - 2) >= 0 Then
         k = RightColor
         RightColor = LeftColor
         LeftColor = k
         LSwap = True
      End If
   End Select
If PixelSize > 2 Then PixelSize = 2
   NSteps = PointCount
   If NSteps < 1 Then NSteps = 1
   GetColorSteps
   For k = 2 To PointCount
      'If Not aAA Then
         If PixelSize = 1 Then
            BresLine xsto(k - 1), ysto(k - 1), xsto(k), ysto(k), _
                     CByte(zRL), CByte(zGL), CByte(zBL), 0, 1
         ElseIf PixelSize = 2 Then
            BresLine xsto(k - 1), ysto(k - 1), xsto(k), ysto(k), _
                     CByte(zRL), CByte(zGL), CByte(zBL), 1, 1
         
'         ElseIf aRound Then
'            ZDrawAALine xsto(k - 1), ysto(k - 1), xsto(k), ysto(k), RGB(zRL, zGL, zBL)
'         Else  ' Not AA but Square ends
'            ZDrawAALine xsto(k - 1), ysto(k - 1), xsto(k), ysto(k), RGB(zRL, zGL, zBL), 0.5
         End If
'      Else  ' AA
'         picDRAW.DrawMode = vbCopyPen
'         ZDrawAALine xsto(k - 1), ysto(k - 1), xsto(k), ysto(k), RGB(zRL, zGL, zBL), 0.5
'      End If
      GetNextColors
   Next k
   
   DISPLAY Form1, picDRAW
   
   If LSwap Then
      k = RightColor
      RightColor = LeftColor
      LeftColor = k
   End If
   
   'If aAA Then
      PixelSize = pxsv
      picDRAW.DrawWidth = PixelSize
   'End If
End Sub

Public Sub FindWhichShape(frm As Form, x As Single, y As Single, SN As Long)
   With frm
   If x > .sBEZ1(0).Left Then
   If y > .sBEZ1(0).TOp Then
   If x < .sBEZ1(0).Left + .sBEZ1(0).Width Then
   If y < .sBEZ1(0).TOp + .sBEZ1(0).Height Then
      aMovesBEZ = True
      SN = 1
   End If
   End If
   End If
   End If
   If Not aMovesBEZ Then
      If x > .sBEZ2(0).Left Then
      If y > .sBEZ2(0).TOp Then
      If x < .sBEZ2(0).Left + .sBEZ2(0).Width Then
      If y < .sBEZ2(0).TOp + .sBEZ2(0).Height Then
         aMovesBEZ = True
         SN = 2
      End If
      End If
      End If
      End If
   End If
   If Not aMovesBEZ Then
      If x > .sBEZ3(0).Left Then
      If y > .sBEZ3(0).TOp Then
      If x < .sBEZ3(0).Left + .sBEZ3(0).Width Then
      If y < .sBEZ3(0).TOp + .sBEZ3(0).Height Then
         aMovesBEZ = True
         SN = 3
      End If
      End If
      End If
      End If
   End If
   If Not aMovesBEZ Then
      If x > .sBEZ4(0).Left Then
      If y > .sBEZ4(0).TOp Then
      If x < .sBEZ4(0).Left + .sBEZ4(0).Width Then
      If y < .sBEZ4(0).TOp + .sBEZ4(0).Height Then
         aMovesBEZ = True
         SN = 4
      End If
      End If
      End If
      End If
   End If
   End With
End Sub

Public Sub MovesBEZs(frm As Form, x As Single, y As Single, SN As Long)
   With frm
      Select Case SN
      Case 1
         .sBEZ1(0).Left = x - .sBEZ1(0).Width \ 2
         .sBEZ1(0).TOp = y - .sBEZ1(0).Height \ 2
      Case 2
         .sBEZ2(0).Left = x - .sBEZ2(0).Width \ 2
         .sBEZ2(0).TOp = y - .sBEZ2(0).Height \ 2
      Case 3
         .sBEZ3(0).Left = x - .sBEZ3(0).Width \ 2
         .sBEZ3(0).TOp = y - .sBEZ3(0).Height \ 2
      Case 4
         .sBEZ4(0).Left = x - .sBEZ4(0).Width \ 2
         .sBEZ4(0).TOp = y - .sBEZ4(0).Height \ 2
      End Select
   End With
End Sub

Public Sub Convert_pts_to_kpts()
' Align pts to picDATA
'   ix1 = ix1 + xlo
'   iy1 = Form1.picDRAW.Height - iy1 + ylo
'   ix2 = ix2 + xlo
'   iy2 = Form1.picDRAW.Height - iy2 + ylo

Dim j As Long
   For j = 1 To 4
      kpts(j).kx = pts(j).kx + xlo
      'kpts(j).ky = pts(j).ky 'Form1.picDRAW.Height - pts(j).ky - ylo
      kpts(j).ky = pts(j).ky + (Form1.ScrVert.Min - ylo)
   Next j
End Sub

Public Sub CopyALLsBEZ0to1(frm As Form)
   With frm
   .sBEZ1(1).Left = .sBEZ1(0).Left
   .sBEZ1(1).TOp = .sBEZ1(0).TOp
   .sBEZ2(1).Left = .sBEZ2(0).Left
   .sBEZ2(1).TOp = .sBEZ2(0).TOp
   .sBEZ3(1).Left = .sBEZ3(0).Left
   .sBEZ3(1).TOp = .sBEZ3(0).TOp
   .sBEZ4(1).Left = .sBEZ4(0).Left
   .sBEZ4(1).TOp = .sBEZ4(0).TOp
   End With
End Sub

Public Sub MovesBEZstopts(frm As Form)
   With frm
   .sBEZ1(0).Left = pts(1).kx - .sBEZ1(0).Width \ 2
   .sBEZ1(0).TOp = pts(1).ky - .sBEZ1(0).Height \ 2
   .sBEZ2(0).Left = pts(2).kx - .sBEZ2(0).Width \ 2
   .sBEZ2(0).TOp = pts(2).ky - .sBEZ2(0).Height \ 2
   .sBEZ3(0).Left = pts(3).kx - .sBEZ3(0).Width \ 2
   .sBEZ3(0).TOp = pts(3).ky - .sBEZ3(0).Height \ 2
   .sBEZ4(0).Left = pts(4).kx - .sBEZ4(0).Width \ 2
   .sBEZ4(0).TOp = pts(4).ky - .sBEZ4(0).Height \ 2
   End With
   CopyALLsBEZ0to1 frm
End Sub

Public Sub SetptstosBEZs(frm As Form)
'Dim j As Long
   With frm
   pts(1).kx = .sBEZ1(0).Left + .sBEZ1(0).Width \ 2
   pts(1).ky = .sBEZ1(0).TOp + .sBEZ1(0).Height \ 2
   pts(2).kx = .sBEZ2(0).Left + .sBEZ2(0).Width \ 2
   pts(2).ky = .sBEZ2(0).TOp + .sBEZ2(0).Height \ 2
   pts(3).kx = .sBEZ3(0).Left + .sBEZ3(0).Width \ 2
   pts(3).ky = .sBEZ3(0).TOp + .sBEZ3(0).Height \ 2
   pts(4).kx = .sBEZ4(0).Left + .sBEZ4(0).Width \ 2
   pts(4).ky = .sBEZ4(0).TOp + .sBEZ4(0).Height \ 2
   End With
'   For j = 1 To 4
'      pts(j).kx = pts(j).kx + xlo
'      pts(j).ky = pts(j).ky - ylo
'   Next j
End Sub

Public Sub ShowsBEZs(frm As Form)
   With frm
   .sBEZ1(0).Visible = True
   .sBEZ1(1).Visible = True
   .sBEZ2(0).Visible = True
   .sBEZ2(1).Visible = True
   .sBEZ3(0).Visible = True
   .sBEZ3(1).Visible = True
   .sBEZ4(0).Visible = True
   .sBEZ4(1).Visible = True
   End With
End Sub
Public Sub ClearsBEZS(frm As Form)
   With frm
   .sBEZ1(0).Visible = False
   .sBEZ1(1).Visible = False
   .sBEZ2(0).Visible = False
   .sBEZ2(1).Visible = False
   .sBEZ3(0).Visible = False
   .sBEZ3(1).Visible = False
   .sBEZ4(0).Visible = False
   .sBEZ4(1).Visible = False
   End With
End Sub

Public Sub Resetpts(dx As Long, DY As Long)
   pts(1).kx = pts(1).kx + dx
   pts(1).ky = pts(1).ky + DY
   pts(2).kx = pts(2).kx + dx
   pts(2).ky = pts(2).ky + DY
   pts(3).kx = pts(3).kx + dx
   pts(3).ky = pts(3).ky + DY
   pts(4).kx = pts(4).kx + dx
   pts(4).ky = pts(4).ky + DY
End Sub

Public Sub LocateBez(x As Single, y As Single)
' To locate Bez near cursor
' X,Y is where the 2nd right-click was located
Dim dx As Long, DY As Long
   dx = x - (pts(1).kx + pts(4).kx) \ 2
   DY = y - (pts(1).ky + pts(4).ky) \ 2
   Resetpts dx, DY
End Sub

Public Sub SetInitpts(frm As Form)
   'AdjustBoxPoints xsto(1), ysto(1), xsto(2), ysto(2)  '??
   pts(1).kx = xsto(1)
   pts(1).ky = ysto(1)
   pts(2).kx = xsto(1) + (xsto(2) - xsto(1)) \ 3
   pts(2).ky = ysto(1) + (ysto(2) - ysto(1)) \ 3
   pts(3).kx = xsto(1) + 2 * (xsto(2) - xsto(1)) \ 3
   pts(3).ky = ysto(1) + 2 * (ysto(2) - ysto(1)) \ 3
   pts(4).kx = xsto(2)
   pts(4).ky = ysto(2)
   
   MovesBEZstopts frm

   frm.picDRAW.ForeColor = XorCul
   PolyBezier frm.picDRAW.hDC, pts(1), 4
   frm.picDRAW.Picture = frm.picDRAW.Image
   ShowsBEZs Form1

End Sub

Public Sub DrawBezier(picDRAW As PictureBox, DCul As Long, Optional Anti As Long = 0)
' RR modified
' Basic maths from PSC CodeId=22556 by K. O. Thaha Hussain

Dim ax As Single, bx As Single, cx As Single
Dim ay As Single, by As Single, cy As Single
Dim xt As Single, yt As Single, t As Single
Dim t3 As Single, t2 As Single

Dim prevxpt As Single, prevypt As Single

On Error Resume Next
     
   cx = 3 * (pts(2).kx - pts(1).kx)
   bx = 3 * (pts(3).kx - pts(2).kx) - cx
   ax = pts(4).kx - pts(1).kx - cx - bx
   
   cy = 3 * (pts(2).ky - pts(1).ky)
   by = 3 * (pts(3).ky - pts(2).ky) - cy
   ay = pts(4).ky - pts(1).ky - cy - by
   
   prevxpt = pts(1).kx
   prevypt = pts(1).ky
   For t = 0.025 To 1 Step 0.025
      t2 = t * t
      t3 = t2 * t
      xt = ax * t3 + bx * t2 + cx * t + pts(1).kx
      yt = ay * t3 + by * t2 + cy * t + pts(1).ky
      
      ZDrawAALine prevxpt, prevypt, xt, yt, DCul, 0.1, Anti
      If PixelSize = 1 And Anti = 0 Then
         ZDrawAALine prevxpt, prevypt, xt, yt, DCul, 0.1, 1
      End If
      prevxpt = xt
      prevypt = yt
   Next t
   DISPLAY Form1, picDRAW
End Sub

Public Sub AngleXHV(ByVal xs As Single, ByVal ys As Single, x As Single, y As Single, LO As Long)
'      @ Mouse_Down
'      xs = x: ys = y
'      xp = x: yp = y
'      @ Mouse_Move
'      x
'      y

' LO = 0 Line, = 1 Oval, Box
Dim ixe As Single, iye As Single
   
   ixe = x: iye = y
   
   If (y = ys) And (x = xs) Then
      Exit Sub
   End If
   zangle = r2d# * zAng(y - ys, x - xs)  ' Degrees, could do radians
   Select Case zangle
   Case 22.5 To 67.5, 202.5 To 247.5       ' 45 degrees   /
      iye = y
      ixe = xs + ys - y
   Case 112.5 To 157.5, 292.5 To 337.5     ' 45 degrees   \
      ixe = x
      iye = x - xs + ys
   End Select
   
   If LO = 0 Then ' Line
      Select Case zangle
      Case 67.51 To 112.49, 247.61 To 292.49  ' Vert
         ixe = xs
         iye = y
      Case 157.51 To 202.49                   ' Horz to left
         iye = ys
         ixe = x
      Case 0.01 To 22.49, 337.49 To 360       ' Horz to right
         iye = ys
         ixe = x
      End Select
   End If
   x = ixe
   y = iye
End Sub

Public Function ExtractFirstICON(FileStream() As Byte, IconStream() As Byte) As Boolean

' Extract first icon into a single icon image in IconStream()
' Input:  FileStream() (BStream() from Get icon file)
' Output: IconStream()
'Dim a$
Dim k As Long
Dim imSize As Long
Dim imOffset As Long

On Error GoTo ExtractICONERROR

   imSize = FileStream(14) + 256& * FileStream(15) + 65536 * FileStream(16)
   imOffset = FileStream(18) + 256& * FileStream(19) + 65536 * FileStream(20)

   ReDim IconStream(0 To 6 + 16 + imSize)
   
   For k = 0 To 5
     IconStream(k) = FileStream(k)
   Next k
   IconStream(4) = 1 ' 1 icon
   For k = 6 To 21
     IconStream(k) = FileStream(k)
   Next k
   IconStream(18) = 22   ' Offset for single icon
   For k = 19 To 21      ' zero rest of offset bytes
     IconStream(k) = 0
   Next k
   For k = 22 To 22 + imSize - 1
     IconStream(k) = FileStream(imOffset + (k - 22))
   Next k
   ' Could use CopyMemory but fast enough and more descriptive as is
   
   ExtractFirstICON = True
   Exit Function
'=========
ExtractICONERROR:
   MsgBox "Extract Icon Error", vbCritical, "ExtractFirstICON"
   
End Function

