Attribute VB_Name = "ModPublics"
'ModPublic.bas

'All sorts!

Option Explicit

'Public Declare Function GetSystemMetrics Lib "user32" _
'   (ByVal nIndex As Long) As Long

'Public Const SM_CXSCREEN = 0  ' Screen Width
'Public Const SM_CYSCREEN = 1  ' Screen Height
'Public Const SM_CYCAPTION = 4 ' Height of window caption
'Public Const SM_CYMENU = 15   ' Height of menu
'Public Const SM_CXDLGFRAME = 7   ' Width of borders X & Y same + 1 for sizable
'Public Const SM_CYSMCAPTION = 51 ' Height of small caption (Tool Windows)
'Public ExtraBorder As Long
'Public ExtraHeight  As Long

Public STX As Long, STY As Long  ' ScreenTwipsPerPixelX/Y

'Main Menus
Public MMenu As Long
Public Enum EMMenu
   [MFile] = 0
   [MInfo] = 1
   [MTools] = 2
   [MColors] = 3
   [MFilters] = 4
   [MDeformers] = 5
   [MEffects] = 6
   [MDespeckle] = 7
   [MTextures] = 8
   [MSculpture] = 9
   [MText] = 10
   [MPrint] = 11
   [MLayer] = 12
   [MExtractor] = 13
   [MResize] = 14
   [MRotate] = 15
   [MShiftScroll] = 16
   [MTrace] = 17
   [MMakeGFX] = 18
   [MZscape] = 19
   [MHalfTone] = 20
End Enum
' File
Public aSaved As Boolean
'Public aThumbnail As Boolean   ' XP Thumbnail viewer available or not
'Public aThumbnailSelected As Boolean

Public aFocus As Boolean  ' When False skips picDRAW.Setfocus
                           ' used in Form_Load
' Main form
Public FWidORG As Long, FHitORG As Long  ' Init Form size
Public frmMainLeft As Long
Public frmMainTop As Long
Public frmMainWidth As Long
Public frmMainHeight As Long
Public TheWindowState As Long
Public RightMargin As Long, BottomMargin As Long ' Margin for scrollbars
Public FiletoMain As Long   ' (1) Prevent (0) Allow, File to Main menu
' Max Viewport size
Public MaxVPWidth  As Long
Public MaxVPHeight  As Long
Public aResize As Boolean
Public aaResize As Boolean
' Zoom Scroll params
Public aHookWheel As Boolean
Public aScrollZoom As Boolean
Public Zoom As Single
Public xlo As Long, ylo As Long ' picDATA() origin
Public XTL As Long, YTL As Long ' Top left coords in picDATA()
Public xp1 As Long, yp1 As Long ' MouseDown x,y
' Relative position of scroll bar thumbs
Public xlonew As Single
Public ylonew As Single

Public aScroll As Boolean
' Mode
Public aZoomMode As Boolean  ' False pixel mode, True image mode
' Cross hairs
Public aCrossHairs As Boolean
Public aDiagHairs As Boolean
' Data
Public picDATA() As Byte
Public picDATAORG() As Byte
Public picDATAREG() As Byte
' Global transparency
Public prevDATA() As Byte
Public Transparency As Single
Public GlobTrans As Long
' Drawing
Public aMouseDown As Boolean
Public SCOPY As Boolean   ' Shape available to copy
'' Drawing Surface size
Public LastWidth As Long
Public LastHeight As Long
' Colors
Public aPick As Boolean ' F/T T pick color from picDRAW
Public frmColorsLeft As Long
Public frmColorsTop As Long
Public aColors As Boolean
Public ColorCount As Long
' Despeckle
Public aDespeckle As Boolean
Public frmDespeckleLeft As Long
Public frmDespeckleTop As Long
' BigPAL
Public aBigPAL As Boolean
Public frmBigPALLeft As Long
Public frmBigPALTop As Long
'256Colors
Public frm256ColorsLeft As Long
Public frm256ColorsTop As Long
Public a256 As Boolean
' New
Public aNewSize As Boolean
' Filter
Public frmFiltersLeft As Long
Public frmFiltersTop As Long
Public aFilters As Boolean
' Deformers
Public frmDeformersLeft As Long
Public frmDeformersTop As Long
Public aDeformers As Boolean
' Extras
Public frmExtrasLeft As Long
Public frmExtrasTop As Long
Public aExtras As Boolean
' Grains
Public frmTexturesLeft As Long
Public frmTexturesTop As Long
Public aGrains As Boolean
' Rotate
Public frmRotateLeft As Long
Public frmRotateTop As Long
Public aRotate As Boolean
Public aRot As Boolean
' Resize
Public frmResizeLeft As Long
Public frmResizeTop As Long
Public aResizer As Boolean

'' Text
'Public TheFontName$
'Public TheFontSize As Long
'Public TheFontBold As Boolean
'Public TheFontItalic As Boolean
'Public ShadowFactor As Single
'Public zangtext As Single
'Public aText As Boolean
'Public TextLine$(0 To 1)
'Public NSTOREXY As Long
'Public STOREX() As Long, STOREY() As Long
'Public bT() As Long '^^^^^^^^^^^

' Text form
Public frmTextLeft As Long
Public frmTextTop As Long


' Print
Public aPrint As Boolean
' Magnifier
Public frmMagnifierLeft As Long
Public frmMagnifierTop As Long
Public aMag As Boolean
Public aThumb As Boolean
Public MagFactor As Long
Public MagSize As Long    ' Set in Form_Initialize =240
Public MagWidth As Long, MagHeight As Long   ' So far same value = MagSize
Public xprev As Long, yprev As Long
'For +Merge
Public frmMergeLeft As Long
Public frmMergeTop As Long
Public ImageSpec$
Public zalpha As Single
Public aMerge As Boolean
Public aFromClipboard As Boolean
Public MergeTransColor As Long
' For + Sculpture
Public frmSculptureLeft As Long
Public frmSculptureTop As Long
Public aSculpture As Boolean
' For Shift
Public frmShiftLeft As Long
Public frmShiftTop As Long
Public aShift As Boolean
' For Trace
Public picSelData() As Byte   ' with picSelect on Form1
Public PaperData() As Byte    ' with picPaper  on Form1
Public savepicSelData() As Byte   ' Trace Undo
Public savePaperData() As Byte    ' Trace Undo
Public tiw As Long, tih As Long
Public aDrawDone As Boolean
Public aTrace As Boolean
Public TraceTool As Long
Public TAlpha As Single
Public frmTraceLeft As Long
Public frmTraceTop As Long
Public Enum ETraceToolType
   [TNone] = 0
   [TDot]
   [TDraw]
   [TLine]
   [TBox]
   [TSmallEraser]
   [TLargeEraser]
End Enum
Public TraceSpec$, TracePath$
' For Fillers
Public frmUFillLeft As Long
Public frmUFillTop As Long
Public aImageFiller As Boolean

' For StampBrush
Public frmStampBrushLeft As Long
Public frmStampBrushTop As Long
Public aStamp As Boolean
Public StampW As Long, StampH As Long ' Also Brush size

' For Browser
Public frmBrowserLeft As Long
Public frmBrowserTop As Long

' Image or canvas size
Public FullW  As Long
Public FullH  As Long
Public LowerX As Long, HigherX As Long
Public LowerY As Long, HigherY As Long
' Selection
Public LOX As Long, HIX As Long
Public LOY As Long, HIY As Long
Public MaskArray() As Long
Public aExternal As Boolean
Public aSelectAccepted As Boolean


Public frmSelectorLeft As Long
Public frmSelectorTop As Long

' Zoom menu
Public frmZoomLeft As Long
Public frmZoomTop As Long

'' Background color
'Public Const SlateBlue As Long = &HDC826E  'RGB(100, 130, 220)
'Public Const LightPurple As Long = &HFFC0C0
'Public Const DarkGrey As Long = &H808080
' Color scheme
Public BackCul As Long
Public CoverValue() As Long
' Color Park
Public CulParkIndex As Integer
Public aCulPark As Boolean
Public CulParkValue() As Long
Public frmCulParkLeft As Long
Public frmCulParkTop As Long
' Xtractor
Public aXtractor As Boolean
Public frmXtractorLeft As Long
Public frmXtractorTop As Long
Public XtractorCul As Long
Public aXtract As Boolean
' Z-Scape
Public aZScape As Boolean
Public aDished As Boolean
Public aReflected As Boolean
Public LandScapeDone As Boolean
Public frmZScapeLeft As Long
Public frmZScapeTop As Long
'HalfTone
Public aHalfTone As Boolean
Public frmHalfToneLeft As Long
Public frmHalfToneTop As Long

' Small BMPs
Public aSBMP As Boolean
' Help
Public HelpSpec$
Public HelpCHM$
' To Block/Unblock a form_Unload
Public aUnloading As Boolean
' For Space bar copying
Public TheKey As Integer
' Files
Public aReload As Boolean
Public aa$
Public PathSpec$, CurrPath$, FileSpec$, SavePath$, SaveSpec$

Public Sub HLXY()
   If aSelectAccepted And Not aExternal Then   ' Internal (Inside selection)
      LowerX = LOX
      HigherX = HIX
      LowerY = LOY
      HigherY = HIY
   Else  ' Whole image or External (Outside selection)
      LowerX = 0
      HigherX = FullW - 1
      LowerY = 0
      HigherY = FullH - 1
   End If
End Sub


Public Sub INITDrawStoreClicks()
   ' For Drawing coords
 '  PointCount = 1
 '  ReDim xsto(1 To 20), ysto(1 To 20)
   StartClick = 0
   NClicks = 0
   NLeftClicks = 0
   NRightClicks = 0
   aMouseDown = False
End Sub

Public Sub FixExtension(FSpec$, Ext$)
' In: FileSpec$ & Ext$ (".xxx")
Dim p As Long
   If Len(FSpec$) = 0 Then Exit Sub
   Ext$ = LCase$(Ext$)
   p = InStr(1, FSpec$, ".")
   If p = 0 Then
      FSpec$ = FSpec$ & Ext$
   Else
      FSpec$ = Mid$(FSpec$, 1, p - 1) & Ext$
   End If
End Sub

Public Function GetFileName(FSpec$) As String
' VB5 also
Dim L As Long
Dim k As Long
   GetFileName = ""
   L = Len(FSpec$)
   If L < 1 Then Exit Function
   For k = L To 1 Step -1
      If Mid$(FSpec$, k, 1) = "\" Then Exit For
   Next k
   If k = 0 Then
      GetFileName = FSpec$
   Else
      GetFileName = Right$(FSpec$, L - k)
   End If
End Function

Public Function FileExists(FSpec$) As Boolean
On Error Resume Next   ' Needed if CD, Zip etc. disk removed
   'If Dir(FSpec$) <> "" Then FileExists = True
   FileExists = LenB(Dir$(FSpec$))
End Function

Public Function GetPath(FSpec$) As String
' VB5 also
Dim L As Long
Dim k As Long
   GetPath = ""
   L = Len(FSpec$)
   If L < 1 Then Exit Function
   For k = L To 1 Step -1
      If Mid$(FSpec$, k, 1) = "\" Then Exit For
   Next k
   If k <> 0 Then
      GetPath = Left$(FSpec$, k)  ' NB includes last \
   
   End If
End Function

Public Function FindExtension$(FSpec$)
Dim p As Long
   p = FindLastCharPos(FSpec$, ".")
   If p = 0 Then
      FindExtension$ = ""
   Else
      FindExtension$ = Mid$(FSpec$, p + 1)
   End If
End Function

Public Function FindLastCharPos(InString$, SerChar$) As Long
' Also VB5
Dim p As Long
    For p = Len(InString$) To 1 Step -1
      If Mid$(InString$, p, 1) = SerChar$ Then Exit For
    Next p
    If p < 1 Then p = 0
    FindLastCharPos = p
End Function

Public Function ShortenString$(n$, L As Long)
' API for this ?
' Called LabFilePath = ShortenString$(GetPath(FileSpec$), 30)
' N$ = FindName$(FSpec$)
Dim LN As Long
   LN = Len(n$)
   If LN >= L Then
      LN = (L - 4) \ 2
      ShortenString$ = Left$(n$, LN) & "...." & Right$(n$, LN)
   Else
      ShortenString$ = n$
   End If
End Function

'Public Sub ListBoxHorScroll(lbListBox As ListBox, bShow As Boolean)
'    Const SB_HORZ = 0, SB_CTL = 2, SB_BOTH = 3
'    If bShow Then
'        Call ShowScrollBar(lbListBox.hwnd, SB_HORZ, 1&)
'    Else
'        Call ShowScrollBar(lbListBox.hwnd, SB_HORZ, 0&)
'    End If
'End Sub

Public Sub MouseKeys(KeyCode As Integer, Shift As Integer, Button As Integer, _
   x As Single, y As Single, xprev As Long, yprev As Long)
Dim retval As Long
Dim lp As RPoint
Dim ix As Long, iy As Long
Dim imul As Long
Dim ixm As Long, iym As Long
Dim ixp As Long, iyp As Long
' +  107
' -  109
' =  187
' Shift = 16
' Ctrl  = 17

   
   lp.kx = 0
   lp.ky = 0
   retval = ClientToScreen(Form1.picDRAW.hwnd, lp)
   ix = lp.kx   'picDRAW position from left of Screen
   iy = lp.ky   'picDRAW position from top of Screen
   
   If KeyCode = 68 Then    ' D  dot
      GetCursorPos lp
      x = lp.kx - ix
      y = lp.ky - iy
      Button = 1
      Exit Sub
   End If
   
   ix = ix + xprev
   iy = iy + yprev
   
   imul = 1
   If Shift = 1 Then imul = 8
   
   If (xprev - imul) > 0 Then ixm = (xprev - imul) + lp.kx Else ixm = lp.kx
   If (yprev - imul) > 0 Then iym = (yprev - imul) + lp.ky Else iym = lp.ky
   If (xprev + imul) <= Form1.picDRAW.Width Then
      ixp = (xprev + imul) + lp.kx
   Else
      ixp = (Form1.picDRAW.Width - 1) + lp.kx
   End If
   If (yprev + imul) <= Form1.picDRAW.Height Then
      iyp = (yprev + imul) + lp.ky
   Else
      iyp = (Form1.picDRAW.Height - 1) + lp.ky
   End If
   Select Case KeyCode
   ' Arrows & Keypad
   Case 37, 100: SetCursorPos ixm, iy  ' LeftA, 4
   Case 38, 104: SetCursorPos ix, iym  ' UpA, 8
   Case 39, 102: SetCursorPos ixp, iy  ' RightA, 6
   Case 40, 98: SetCursorPos ix, iyp   ' DownA, 2
   
   ' Keypad only
   Case 36, 103 ' TL
         SetCursorPos ixm, iym   ' 7 XLeft, YUp
   Case 33, 105 ' TR
         SetCursorPos ixp, iym   ' 9 XRight, YUp
   Case 34, 99  ' BR
         SetCursorPos ixp, iyp   ' 3 XRight, YDown
   Case 35, 97  ' BL
         SetCursorPos ixm, iyp   ' 1 XLeft, YDown
   
   Case 13: Button = 1: SetCursorPos ix, iy  ' Enter
       x = ix: y = iy   'LC
       mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
       mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
   Case 8: Button = 2: SetCursorPos ix, iy  ' BackSpace or  -
       x = ix: y = iy   'RC
       mouse_event MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0
       mouse_event MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0

   Case 115: MagFactor = 4   ' F4
     If aMag Then
      frmMagnifier.optMag(1).Value = True
      ModPublics.MAGNIFIER Form1.picDRAW, x + 1, y
     End If
   Case 117: MagFactor = 6   ' F6
      If aMag Then
         frmMagnifier.optMag(2).Value = True
         ModPublics.MAGNIFIER Form1.picDRAW, x + 1, y
      End If
   Case 119: MagFactor = 8   ' F8
      If aMag Then
         frmMagnifier.optMag(3).Value = True
         ModPublics.MAGNIFIER Form1.picDRAW, x + 1, y
      End If
   Case 123: MagFactor = 12  ' F12
      If aMag Then
         frmMagnifier.optMag(4).Value = True
         ModPublics.MAGNIFIER Form1.picDRAW, x + 1, y
      End If
   
   Case 16  ' Shift
   Case 17  ' Ctrl
   
   
   End Select

   If aMag And KeyCode = vbKeyT Then   ' Thumbnail
      frmMagnifier.cmdThumb_Click 'optMag(5).Value = True
      ModPublics.MAGNIFIER Form1.picDRAW, x + 1, y
   End If
End Sub

Public Sub MagThumbnail(Data() As Byte, PIC As PictureBox, Side As Long)

' Eg picDATA(), frmMagnifier.picMag, 240, X, Y

Dim BS As BITMAPINFOHEADER
Dim zAspect As Single
Dim WW As Long, HH As Long

   WW = UBound(Data(), 2) + 1
   HH = UBound(Data(), 3) + 1
   'With frmMagnifier
   zAspect = WW / HH
   If WW > Side Or HH > Side Then
      ' Resize to fit keeping aspect ratio
      ' NB Fullzise picDraw is 240x240, Aspect FullW/FullH = 1.0
      If WW >= HH Then ' zAspect >= 1
         If WW > Side And zAspect >= 1# Then
               PIC.Width = Side
               PIC.Height = Side / zAspect
         Else ' FullW <= 240
            PIC.Height = Side
            PIC.Width = Side * zAspect
         End If
      Else  ' FullW < FullH   ' zAspect < 1
         If HH > Side Then
            PIC.Height = Side
            PIC.Width = Side * zAspect
         End If
      End If
   Else
      PIC.Width = WW
      PIC.Height = HH
   End If
   
   ' Public BHI always set with picDATA()

   With BS
      .biSize = 40
      .biPlanes = 1
      .biWidth = WW
      .biHeight = HH
      .biBitCount = 32
   End With
   
   
   SetStretchBltMode PIC.hDC, HALFTONE
   
   Call StretchDIBits(PIC.hDC, _
   0, 0, _
   PIC.Width, PIC.Height, _
   0, 0, _
   WW, HH, _
   Data(0, 0, 0), _
   BS, 0, vbSrcCopy)
   
   PIC.Picture = PIC.Image
End Sub

'Public Sub GetExtras(BStyle As Byte)
'' Not used
'
'' IN:  BStyle = Me.BorderStyle
'' OUT: Public ExtraBorder, ExtraHeight
'
'''------------------------------------------------------------------------------
'''  This required instead of Screen.Height & Width for resizing
''Public Declare Function GetSystemMetrics Lib "user32" _
''(ByVal nIndex As Long) As Long
''
''Public Const SM_CXSCREEN = 0  ' Screen Width
''Public Const SM_CYSCREEN = 1  ' Screen Height
''Public Const SM_CYCAPTION = 4 ' Height of window caption
''Public Const SM_CYMENU = 15   ' Height of menu
''Public Const SM_CXDLGFRAME = 7   ' Width of borders X & Y same + 1 for sizable
''Public Const SM_CYSMCAPTION = 51 ' Height of small caption (Tool Windows)
''
'''------------------------------------------------------------
'Dim Border As Long
'Dim CapHeight As Long
'Dim MenuHeight As Long
'' BStyle 1 to 5 (not 0)
'' BStyle = Form1.BorderStyle
'
'Border = GetSystemMetrics(SM_CXDLGFRAME)
'If BStyle = 2 Or BStyle = 5 Then Border = Border + 1 ' Sizable
'If BStyle > 3 Then
'   CapHeight = GetSystemMetrics(SM_CYSMCAPTION) ' Small cap - ToolWindow
'Else
'   CapHeight = GetSystemMetrics(SM_CYCAPTION)   ' Standard cap
'End If
'ExtraBorder = 2 * Border
'ExtraHeight = CapHeight + ExtraBorder
'
'MenuHeight = GetSystemMetrics(SM_CYMENU)
'ExtraHeight = CapHeight + MenuHeight + ExtraBorder
'
'' Win98  ExtraBorder=6 or 8, ExtraHeight= 41 - 46
'' WinXP  ExtraBorder=6 or 8, ExtraHeight= 44 - 54
'End Sub

Public Sub MAGNIFIER(picDRAW As PictureBox, px1 As Single, py1 As Single)
' Public MagSize   ' =240
' ShapeC
Dim ShapeLeft As Long, ShapeTop As Long
Dim ShapeWidth As Long, ShapeHeight As Long
Dim BoxLeft As Long, BoxTop As Long

' picDRAW source
Dim SrcLeft As Long, SrcTop As Long
Dim SrcRight As Long, SrcBottom As Long
Dim SrcWidth As Long, SrcHeight As Long
Dim WW As Long, HH As Long

Dim RR As Byte, GG As Byte, BB As Byte


' Mag dest
Dim DestWidth As Long, DestHeight As Long
Dim xm As Single, ym As Single

   LngToRGB picDRAW.Point(px1, py1), RR, GG, BB
   frmMagnifier.Label1(0) = RR
   frmMagnifier.Label1(1) = GG
   frmMagnifier.Label1(2) = BB
   
   If MagFactor = 1 Then   ' ie Thumbnail
      With frmMagnifier
         ' Transform coords picDRAW to picMAG
         xm = (xlo + (px1 / Zoom)) * (.picMag.Width / FullW)
         ym = (FullH - ylo + (py1 - Form1.picDRAW.Height) / Zoom) * (.picMag.Height / FullH)
         
         ' For ym
         ' xlo        becomes   (FullH - ylo)
         ' (px1/Zoom) becomes   (py1 - Form1.picDRAW.Height) / Zoom
         
         .ShapeC.Left = xm - 2
         .ShapeC.TOp = ym - 2
         .ShapeC.Width = 6
         .ShapeC.Height = 6
         .ShapeC.Visible = True
         Exit Sub
      End With
   End If
   ' MagFactor = 2,4,6,8,12
   WW = picDRAW.ScaleWidth
   HH = picDRAW.ScaleHeight
   
   frmMagnifier.ShapeC.Visible = True
   ' Formula to adjust ShapeC position
   '  depending on MagFactor & PixelSize
   ' ShapeC Left & Top
      ' Tests
      'BoxLeft = (PixelSize * MagFactor) \ 2 - 2  ' Mag=2,4 -2 spot on all Pixelsizes
      'BoxLeft = (PixelSize * MagFactor) \ 2 - 3  ' Mag=6  OK
      'BoxLeft = (PixelSize * MagFactor) \ 2 - 4  ' Mag=8  OK
      'BoxLeft = (PixelSize * MagFactor) \ 2 - 6  ' Mag=12  OK
   If (PixelSize And 1) = 0 Then   ' Even
      BoxLeft = (PixelSize * MagFactor) \ 2
   Else  ' Odd
      If MagFactor = 2 Then
         BoxLeft = (PixelSize * MagFactor) \ 2 - 2
      Else
         BoxLeft = (PixelSize * MagFactor) \ 2 - (MagFactor \ 2)
      End If
   End If
   BoxTop = BoxLeft
   
   ' Set initial pixel-box ShapeC at center of mag
   ShapeLeft = MagSize \ 2 - BoxLeft
   ShapeTop = MagSize \ 2 - BoxTop
   ShapeWidth = MagFactor * PixelSize
   ShapeHeight = MagFactor * PixelSize
   
   ' Initial picDRAW source rectangle
   SrcLeft = px1 - MagSize \ (2 * MagFactor)
   SrcWidth = MagSize \ MagFactor
   If SrcWidth > WW Then SrcWidth = WW
   SrcRight = SrcLeft + SrcWidth - 1
   SrcTop = py1 - MagSize \ (2 * MagFactor)
   SrcHeight = MagSize \ MagFactor
   If SrcHeight > HH Then SrcHeight = HH
   SrcBottom = SrcTop + SrcHeight - 1
   
   ' Test left boundary
   If SrcLeft < 0 Then
      ' Move pixel-box ShapeC to left
      ShapeLeft = ShapeLeft + SrcLeft * MagFactor
      If ShapeLeft < 0 Then
        'ShapeWidth = ShapeWidth + ShapeLeft
        ShapeLeft = 0
      End If
      
      SrcLeft = 0
      SrcRight = SrcWidth
      If SrcRight > WW - 1 Then
         SrcRight = WW - 1
         SrcWidth = SrcRight + 1
      End If
   End If
   
   ' Test top boundary
   If SrcTop < 0 Then
      ' Move pixel-box ShapeC up
      ShapeTop = ShapeTop + SrcTop * MagFactor
      If ShapeTop < 0 Then
         'ShapeHeight = ShapeHeight + ShapeTop
         ShapeTop = 0
      End If
      
      SrcTop = 0
      SrcBottom = SrcHeight
      If SrcBottom > HH - 1 Then
         SrcBottom = HH - 1
         SrcHeight = SrcBottom + 1
      End If
   End If
   
   ' Test right boundary
   If SrcRight > WW - 1 Then
      ' Adjust pixel-box ShapeC to right
      ShapeLeft = ShapeLeft + (SrcRight - (WW - 1)) * MagFactor
      
      SrcRight = WW - 1
      SrcLeft = SrcRight - SrcWidth + 1
      If SrcLeft < 0 Then
         SrcLeft = 0
         SrcWidth = SrcRight + 1
      End If
   End If
   
   ' Test bottom boundary
   If SrcBottom > HH - 1 Then
      ' Adjust pixel-box ShapeC down
      ShapeTop = ShapeTop + (SrcBottom - (HH - 1)) * MagFactor

      SrcBottom = HH - 1
      SrcTop = SrcBottom - SrcHeight + 1
      If SrcTop < 0 Then
         SrcTop = 0
         SrcHeight = SrcBottom + 1
      End If
   End If
   
   DestWidth = SrcWidth * MagFactor
   DestHeight = SrcHeight * MagFactor
   
   frmMagnifier.picMag.Picture = LoadPicture
   'CheckerpicC frmMagnifier.picMag
   
   StretchBlt frmMagnifier.picMag.hDC, 0, 0, DestWidth, DestHeight, _
      picDRAW.hDC, SrcLeft, SrcTop, SrcWidth, SrcHeight, vbSrcCopy
   
   With frmMagnifier
      .ShapeC.Left = ShapeLeft
      .ShapeC.TOp = ShapeTop
      .ShapeC.Width = ShapeWidth   ''''''''
      .ShapeC.Height = ShapeHeight
   End With
   
   frmMagnifier.picMag.Picture = frmMagnifier.picMag.Image
End Sub

Public Sub fraMOVER(frm As Form, fra As Frame, Button As Integer, _
   x As Single, y As Single, Xfra As Single, Yfra As Single)
Dim fraLeft As Long
Dim fraTop As Long

   If Button = vbLeftButton Then

      fraLeft = fra.Left + (x - Xfra) \ STX
      If fraLeft < 0 Then fraLeft = 0
      If fraLeft + fra.Width > frm.Width \ STX Then
         fraLeft = frm.Width \ STX - fra.Width - 4
      End If
      fra.Left = fraLeft

      fraTop = fra.TOp + (y - Yfra) \ STY
      If fraTop < 0 Then fraTop = 0
      If fraTop + fra.Height > frm.Height \ STY Then
         fraTop = frm.Height \ STY - fra.Height - 8
      End If
      fra.TOp = fraTop

   End If
End Sub

'Public Sub CheckerpicC(picC As PictureBox)
' Not used
'Dim i As Long, j As Long
'      picC.BackColor = vbWhite
'      For j = 0 To picC.Height Step 32
'      For i = 0 To picC.Width Step 32
'         picC.Line (i, j)-(i + 16, j + 16), &HD0E0D0, BF
'         picC.Line (i + 16, j + 16)-(i + 32, j + 32), &HD0E0D0, BF
'      Next i
'      Next j
'End Sub

Public Sub Clear_picSelect(frm As Form)
' And picPaper
   With frm
      .picSelect.Picture = LoadPicture
      .picSelect.Width = 4
      .picSelect.Height = 4
      .picSelect.Visible = False
      .picSelect.Left = .Width + 1000
      .picPaper.Picture = LoadPicture
      .picPaper.Width = 4
      .picPaper.Height = 4
      .picPaper.Visible = False
      .picPaper.Left = .Width + 1000
      .shpSmallRubber.Left = -7
      .shpSmallRubber.TOp = -7
      .shpLargeRubber.Left = -15
      .shpLargeRubber.TOp = -15
      .shpSmallRubber.Visible = False
      .shpLargeRubber.Visible = False
   
      .LineSM(0).Visible = False
      .LineSM(1).Visible = False
      .LineSM(2).Visible = False
   End With
End Sub

Public Sub LocateForm(frm As Form, FH As Long, FW As Long, fLeft As Long, fTop As Long)
   frm.Left = fLeft
   If frm.Left < 10 Then
      frm.Left = Form1.Left + 30
   End If
   If frm.Left + frm.Width / 2 > Screen.Width Then
      frm.Left = Screen.Width - frm.Width / 2
   End If
   frm.TOp = fTop
   If frm.TOp < 10 Then
      frm.TOp = Form1.TOp + 1400
   End If
   If frm.TOp > Screen.Height - 1400 Then
      frm.TOp = Form1.TOp + 1400
   End If
   wFlags = &H40 Or &H2   ' Colors, Filters, etc
   SetWindowPos frm.hwnd, hWndInsertAfter, 0, 0, _
      FW \ STX, FH \ STY, wFlags
End Sub

Public Sub InitFormLocations(Optional FormLocsOnly As Boolean = False)
Dim MTOP As Long
MTOP = 1500
   If Not FormLocsOnly Then
      aSelect = False
      aMouseDown = False
      aNewSize = False
      aColors = False
      aBigPAL = False
      aFilters = False
      aDeformers = False
      aExtras = False
      aRotate = False
      aResizer = False
      aText = False
      aPrint = False
      aMag = False
      aMerge = False
      aSculpture = False
      aShift = False
      aTrace = False
      aImageFiller = False
      aXtract = False
      aZScape = False
      aHalfTone = False
   End If
   '[FormLocs]
   frmColorsLeft = 600
   frmColorsTop = MTOP
   frmFiltersLeft = 600
   frmFiltersTop = MTOP
   frmDeformersLeft = 600
   frmDeformersTop = MTOP
   frmDespeckleLeft = 600
   frmDespeckleTop = MTOP
   frmExtrasLeft = 600
   frmExtrasTop = MTOP
   frmTexturesLeft = 600
   frmTexturesTop = MTOP
   frmRotateLeft = 600
   frmRotateTop = MTOP
   frmResizeLeft = 600
   frmResizeTop = MTOP
   frmTextLeft = 600
   frmTextTop = MTOP
   frmMagnifierLeft = 600
   frmMagnifierTop = 600
   frmMergeLeft = 600
   frmMergeTop = MTOP
   frmSculptureLeft = 600
   frmSculptureTop = MTOP
   frmShiftLeft = 600
   frmShiftTop = MTOP
   frmCulParkLeft = 600
   frmCulParkTop = MTOP
   frmTraceLeft = 600
   frmTraceTop = MTOP
   frmUFillLeft = 600
   frmUFillTop = 600
   
   frmStampBrushLeft = 600
   frmStampBrushTop = MTOP
   
   frm256ColorsLeft = 600
   frm256ColorsTop = 900
   frmBigPALLeft = 600
   frmBigPALTop = 900
   
   frmXtractorLeft = 600
   frmXtractorTop = MTOP
   
   frmZScapeLeft = 600
   frmZScapeTop = MTOP
   
   frmSelectorLeft = 600
   frmSelectorTop = MTOP
   
   frmZoomLeft = 600
   frmZoomTop = MTOP
   
   frmBrowserLeft = 600
   frmBrowserTop = MTOP
   
   frmHalfToneLeft = 600
   frmHalfToneTop = MTOP
   
   
   frmMainLeft = (Screen.Width - FWidORG) \ 2
   frmMainTop = (Screen.Height - FHitORG) \ 2
   frmMainWidth = FWidORG
   frmMainHeight = FHitORG
   
   LastWidth = 565
   LastHeight = 429

End Sub

Public Sub WriteFormLocs()
   WriteINI "FormLocs", "frmColorsLeft", Trim$(Str$(frmColorsLeft)), IniSpec$
   WriteINI "FormLocs", "frmColorsTop", Trim$(Str$(frmColorsTop)), IniSpec$
   WriteINI "FormLocs", "frmFiltersLeft", Trim$(Str$(frmFiltersLeft)), IniSpec$
   WriteINI "FormLocs", "frmFiltersTop", Trim$(Str$(frmFiltersTop)), IniSpec$
   WriteINI "FormLocs", "frmDeformersLeft", Trim$(Str$(frmDeformersLeft)), IniSpec$
   WriteINI "FormLocs", "frmDeformersTop", Trim$(Str$(frmDeformersTop)), IniSpec$
   WriteINI "FormLocs", "frmExtrasLeft", Trim$(Str$(frmExtrasLeft)), IniSpec$
   WriteINI "FormLocs", "frmExtrasTop", Trim$(Str$(frmExtrasTop)), IniSpec$
   
   WriteINI "FormLocs", "frmTexturesLeft", Trim$(Str$(frmTexturesLeft)), IniSpec$
   WriteINI "FormLocs", "frmTexturesTop", Trim$(Str$(frmTexturesTop)), IniSpec$
   
   WriteINI "FormLocs", "frmRotateLeft", Trim$(Str$(frmRotateLeft)), IniSpec$
   WriteINI "FormLocs", "frmRotateTop", Trim$(Str$(frmRotateTop)), IniSpec$
   WriteINI "FormLocs", "frmResizeLeft", Trim$(Str$(frmResizeLeft)), IniSpec$
   WriteINI "FormLocs", "frmResizeTop", Trim$(Str$(frmResizeTop)), IniSpec$
   WriteINI "FormLocs", "frmTextLeft", Trim$(Str$(frmTextLeft)), IniSpec$
   WriteINI "FormLocs", "frmTextTop", Trim$(Str$(frmTextTop)), IniSpec$
   WriteINI "FormLocs", "frmMagnifierLeft", Trim$(Str$(frmMagnifierLeft)), IniSpec$
   WriteINI "FormLocs", "frmMagnifierTop", Trim$(Str$(frmMagnifierTop)), IniSpec$
   WriteINI "FormLocs", "frmMergeLeft", Trim$(Str$(frmMergeLeft)), IniSpec$
   WriteINI "FormLocs", "frmMergeTop", Trim$(Str$(frmMergeTop)), IniSpec$
   WriteINI "FormLocs", "frmSculptureLeft", Trim$(Str$(frmSculptureLeft)), IniSpec$
   WriteINI "FormLocs", "frmSculptureTop", Trim$(Str$(frmSculptureTop)), IniSpec$
   WriteINI "FormLocs", "frmShiftLeft", Trim$(Str$(frmShiftLeft)), IniSpec$
   WriteINI "FormLocs", "frmShiftTop", Trim$(Str$(frmShiftTop)), IniSpec$
   WriteINI "FormLocs", "frmCulParkLeft", Trim$(Str$(frmCulParkLeft)), IniSpec$
   WriteINI "FormLocs", "frmCulParkTop", Trim$(Str$(frmCulParkTop)), IniSpec$
   
   WriteINI "FormLocs", "frmStampBrushLeft", Trim$(Str$(frmStampBrushLeft)), IniSpec$
   WriteINI "FormLocs", "frmStampBrushTop", Trim$(Str$(frmStampBrushTop)), IniSpec$
   
   WriteINI "FormLocs", "frm256ColorsLeft", Trim$(Str$(frm256ColorsLeft)), IniSpec$
   WriteINI "FormLocs", "frm256ColorsTop", Trim$(Str$(frm256ColorsTop)), IniSpec$

   WriteINI "FormLocs", "frmBigPALLeft", Trim$(Str$(frmBigPALLeft)), IniSpec$
   WriteINI "FormLocs", "frmBigPALTop", Trim$(Str$(frmBigPALTop)), IniSpec$

   WriteINI "FormLocs", "frmDespeckleLeft", Trim$(Str$(frmDespeckleLeft)), IniSpec$
   WriteINI "FormLocs", "frmDespeckleTop", Trim$(Str$(frmDespeckleTop)), IniSpec$

   WriteINI "FormLocs", "frmXtractorLeft", Trim$(Str$(frmXtractorLeft)), IniSpec$
   WriteINI "FormLocs", "frmXtractorTop", Trim$(Str$(frmXtractorTop)), IniSpec$
   
   'Selector
   WriteINI "FormLocs", "frmSelectorLeft", Trim$(Str$(frmSelectorLeft)), IniSpec$
   WriteINI "FormLocs", "frmSelectorTop", Trim$(Str$(frmSelectorTop)), IniSpec$

   'frmZoom
   WriteINI "FormLocs", "frmZoomLeft", Trim$(Str$(frmZoomLeft)), IniSpec$
   WriteINI "FormLocs", "frmZoomTop", Trim$(Str$(frmZoomTop)), IniSpec$

   'frmZScape
   WriteINI "FormLocs", "frmZScapeLeft", Trim$(Str$(frmZScapeLeft)), IniSpec$
   WriteINI "FormLocs", "frmZScapeTop", Trim$(Str$(frmZScapeTop)), IniSpec$
   
   'frmHalfTone
   WriteINI "FormLocs", "frmHalfToneLeft", Trim$(Str$(frmHalfToneLeft)), IniSpec$
   WriteINI "FormLocs", "frmHalfToneTop", Trim$(Str$(frmHalfToneTop)), IniSpec$
End Sub

Public Sub GetFormLocs()
Dim ret$
   If GetINI("FormLocs", "frmColorsLeft", ret$, IniSpec$) Then frmColorsLeft = Val(ret$)
   If GetINI("FormLocs", "frmColorsTop", ret$, IniSpec$) Then frmColorsTop = Val(ret$)
   If GetINI("FormLocs", "frmFiltersLeft", ret$, IniSpec$) Then frmFiltersLeft = Val(ret$)
   If GetINI("FormLocs", "frmFiltersTop", ret$, IniSpec$) Then frmFiltersTop = Val(ret$)
   If GetINI("FormLocs", "frmDeformersLeft", ret$, IniSpec$) Then frmDeformersLeft = Val(ret$)
   If GetINI("FormLocs", "frmDeformersTop", ret$, IniSpec$) Then frmDeformersTop = Val(ret$)
   If GetINI("FormLocs", "frmExtrasLeft", ret$, IniSpec$) Then frmExtrasLeft = Val(ret$)
   If GetINI("FormLocs", "frmExtrasTop", ret$, IniSpec$) Then frmExtrasTop = Val(ret$)
   
   
   If GetINI("FormLocs", "frmTexturesLeft", ret$, IniSpec$) Then frmTexturesLeft = Val(ret$)
   If GetINI("FormLocs", "frmTexturesTop", ret$, IniSpec$) Then frmTexturesTop = Val(ret$)
   
   If GetINI("FormLocs", "frmRotateLeft", ret$, IniSpec$) Then frmRotateLeft = Val(ret$)
   If GetINI("FormLocs", "frmRotateTop", ret$, IniSpec$) Then frmRotateTop = Val(ret$)
   If GetINI("FormLocs", "frmResizeLeft", ret$, IniSpec$) Then frmResizeLeft = Val(ret$)
   If GetINI("FormLocs", "frmResizeTop", ret$, IniSpec$) Then frmResizeTop = Val(ret$)
   If GetINI("FormLocs", "frmTextLeft", ret$, IniSpec$) Then frmTextLeft = Val(ret$)
   If GetINI("FormLocs", "frmTextTop", ret$, IniSpec$) Then frmTextTop = Val(ret$)
   If GetINI("FormLocs", "frmMagnifierLeft", ret$, IniSpec$) Then frmMagnifierLeft = Val(ret$)
   If GetINI("FormLocs", "frmMagnifierTop", ret$, IniSpec$) Then frmMagnifierTop = Val(ret$)
   If GetINI("FormLocs", "frmMergeLeft", ret$, IniSpec$) Then frmMergeLeft = Val(ret$)
   If GetINI("FormLocs", "frmMergeTop", ret$, IniSpec$) Then frmMergeTop = Val(ret$)
   If GetINI("FormLocs", "frmSculptureLeft", ret$, IniSpec$) Then frmSculptureLeft = Val(ret$)
   If GetINI("FormLocs", "frmSculptureTop", ret$, IniSpec$) Then frmSculptureTop = Val(ret$)
   If GetINI("FormLocs", "frmShiftLeft", ret$, IniSpec$) Then frmShiftLeft = Val(ret$)
   If GetINI("FormLocs", "frmShiftTop", ret$, IniSpec$) Then frmShiftTop = Val(ret$)
   If GetINI("FormLocs", "frmCulParkLeft", ret$, IniSpec$) Then frmCulParkLeft = Val(ret$)
   If GetINI("FormLocs", "frmCulParkTop", ret$, IniSpec$) Then frmCulParkTop = Val(ret$)

   If GetINI("FormLocs", "frmStampBrushLeft", ret$, IniSpec$) Then frmStampBrushLeft = Val(ret$)
   If GetINI("FormLocs", "frmStampBrushTop", ret$, IniSpec$) Then frmStampBrushTop = Val(ret$)

   If GetINI("FormLocs", "frm256ColorsLeft", ret$, IniSpec$) Then frm256ColorsLeft = Val(ret$)
   If GetINI("FormLocs", "frm256ColorsTop", ret$, IniSpec$) Then frm256ColorsTop = Val(ret$)

   If GetINI("FormLocs", "frmBigPALLeft", ret$, IniSpec$) Then frmBigPALLeft = Val(ret$)
   If GetINI("FormLocs", "frmBigPALTop", ret$, IniSpec$) Then frmBigPALTop = Val(ret$)

   If GetINI("FormLocs", "frmDespeckleLeft", ret$, IniSpec$) Then frmDespeckleLeft = Val(ret$)
   If GetINI("FormLocs", "frmDespeckleTop", ret$, IniSpec$) Then frmDespeckleTop = Val(ret$)

   If GetINI("FormLocs", "frmXtractorLeft", ret$, IniSpec$) Then frmXtractorLeft = Val(ret$)
   If GetINI("FormLocs", "frmXtractorTop", ret$, IniSpec$) Then frmXtractorTop = Val(ret$)
   
'      frmSelectorLeft = 600
   If GetINI("FormLocs", "frmSelectorLeft", ret$, IniSpec$) Then frmSelectorLeft = Val(ret$)
   If GetINI("FormLocs", "frmSelectorTop", ret$, IniSpec$) Then frmSelectorTop = Val(ret$)
    
   If GetINI("FormLocs", "frmZoomLeft", ret$, IniSpec$) Then frmZoomLeft = Val(ret$)
   If GetINI("FormLocs", "frmZoomTop", ret$, IniSpec$) Then frmZoomTop = Val(ret$)
 
   If GetINI("FormLocs", "frmZScapeLeft", ret$, IniSpec$) Then frmZScapeLeft = Val(ret$)
   If GetINI("FormLocs", "frmZScapeTop", ret$, IniSpec$) Then frmZScapeTop = Val(ret$)
 
   'frmHalfTone
   If GetINI("FormLocs", "frmHalfToneLeft", ret$, IniSpec$) Then frmHalfToneLeft = Val(ret$)
   If GetINI("FormLocs", "frmHalfToneTop", ret$, IniSpec$) Then frmHalfToneTop = Val(ret$)
   
End Sub

Public Sub CheckFile(FSpec$, Message$)
Dim FFileNum As Long, FSize As Long
Dim IntegerMarker(1 To 2) As Integer
'Dim res As Long
   Message$ = ""
   FFileNum = FreeFile
   Open FSpec$ For Binary As #FFileNum
   FSize = LOF(FFileNum)
   Select Case LCase$(FindExtension$(FSpec$))
   Case "bmp"
      Get #FFileNum, , IntegerMarker(1) ' 19778 = 42 4Dh BM
      If IntegerMarker(1) <> 19778 Then Message$ = "Invalid bmp file "
   Case "jpg", "jpeg", "jpe"
      Get #FFileNum, , IntegerMarker(1)            ' -9985 = FF D8 BEndian
      If IntegerMarker(1) <> -9985 Then Message$ = "Invalid jpeg file, FF D8 marker 1 wrong ": GoTo CloseIt
      
' END MARKER NOT CRITICAL ??
'      Get #FFileNum, FSize - 1, IntegerMarker(2)   ' FF D9 BEndian
'      If IntegerMarker(2) <> -9729 Then
'         res = MsgBox("Wrong End Marker" & "Proceed anyway?", vbYesNo, "CheckFile")
'         If res = vbNo Then
'            Message$ = "Invalid jpeg file, FF D9 wrong End Marker "
'            GoTo CloseIt
'         End If
'      End If
   Case "gif"
      Message$ = Space$(6)
      Get #FFileNum, , Message$ ' GIF87a or GIF89a
      If Message$ <> "GIF87a" And Message$ <> "GIF89a" Then
         Message$ = "Invalid gif file ": GoTo CloseIt
      Else
         Message$ = ""
      End If
' END MARKER NOT CRITICAL ??
'      Message$ = Space$(1)
'      Get #FFileNum, FSize, Message$    ' ; 3B
'      If Message$ <> ";" Then
'         Message$ = "Invalid gif file, wrong End Marker (ie not 3B)": GoTo CloseIt
'      Else
'         Message$ = ""
'      End If
   
   Case "png"
      Message$ = Space$(4)   ' *png
      Get #FFileNum, , Message$ ' PNG
      If Right$(Message$, 3) <> "PNG" Then
         Message$ = "Invalid png file ": GoTo CloseIt
      Else
         Message$ = ""
      End If
   Case "tif", "tiff"  ' II Single page
      Message$ = Space$(2)
      Get #FFileNum, , Message$ ' II
      If Message$ <> "II" Then
         Message$ = "Can't read this tif file ": GoTo CloseIt
      Else
         Message$ = ""
      End If
   
   End Select
CloseIt:
   Close #FFileNum
End Sub

Public Sub picDATATopicCopy(PIC As PictureBox)
' Public BHI As BITMAPINFOHEADER
' Public xlo,ylo
Dim BB As BITMAPINFOHEADER
   SetStretchBltMode PIC.hDC, HALFTONE 'COLORONCOLOR 'HALFTONE
   ' COLORONCOLOR for setting pixels
   ' HALFTONE for smoothing
   
      With BB
      .biSize = 40
      .biPlanes = 1
      .biWidth = FullW
      .biHeight = FullH
      .biBitCount = 32
   End With
   
   Call StretchDIBits(PIC.hDC, _
   0, 0, _
   PIC.Width, PIC.Height, _
   0, 0, _
   FullW, FullH, _
   picDATA(0, 0, 0), _
   BB, 0, vbSrcCopy)
   PIC.Refresh
End Sub

