[5.40b1]Vector paint application

Share your advanced PureBasic knowledge/code with the community.
User avatar
[blendman]
Enthusiast
Enthusiast
Posts: 297
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

[5.40b1]Vector paint application

Post by [blendman] »

Hi

I've tried to create a little drawing application, with the new lib VectorDrawing.
It's not optimised, but it works, except with the "zoom" (if you use the zoom, it's slower).

If you have some ideas to optimise this, you can post it ;).

Please, compile with the 5.40.
Code (not optimised for the moment) :

Code: Select all

; Exemple by blendman
; (VectorDrawing) - vector paint application
; PB 5.40b1 - september 2015

Enumeration ; Gadget
 
  #G_Canvas
  #G_BrushSize
  #G_BrushAlpha
  #G_BrushColor
  #G_BrushTexture
   
EndEnumeration

Enumeration ; menu
   
  #Menu_Clear
  #Menu_Save
  #Menu_ZoomPlus
  #Menu_ZoomLess
  #Menu_ZoomReset
  #Menu_Zoom20
  #Menu_Zoom50
  #Menu_Zoom100
  #Menu_Zoom200
 
EndEnumeration

Global z.d=1,canvasX.w,canvasY.w
Global w = 1024, h = 768

;{ Structures
Structure sBrush
  Size.w
  Alpha.a
  Color.q
  Texture.a
EndStructure
Global Brush.sbrush
Brush\Alpha = 120
Brush\Size = 20
brush\Color = RGBA(Red(color),Green(color),Blue(color),Brush\Alpha)


Structure sStroke
  Array dot.point(0)
  nbdot.i
  col.sBrush
EndStructure
Global Dim Stroke.sStroke(0)
NbStroke = -1
;}


UsePNGImageEncoder()
UsePNGImageDecoder()
UseJPEGImageDecoder()

Procedure SetZoom(zoom)
 
  If zoom = 1
    If z < 1
      z+0.1                     
    Else
      z +1
    EndIf   
  ElseIf zoom = -1
    If z > 1
      z-1
    Else
      If z > 0.1
        z-0.1                     
      EndIf
    EndIf
  Else   
     z = zoom*0.01
  EndIf
 
 
  If StartVectorDrawing(CanvasVectorOutput(0))                   
    ; the white bg
    AddPathBox(0,0,w,h)
    VectorSourceColor(RGBA(255,255,255,255))
    FillPath()
    ; the image (layer)
    MovePathCursor(canvasX,canvasY)             
    DrawVectorImage(ImageID(1),255,w*z*2,h*z*2)                     
    StopVectorDrawing()   
  EndIf
 
EndProcedure

If OpenWindow(0, 0, 0, w, h, "Vector paint application", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_Maximize)
 
  ;{ Menu
  CreateMenu(0,WindowID(0))
  MenuTitle("Files")
  MenuItem(#Menu_Clear,"Clear")
  MenuItem(#Menu_Save,"Save")
  MenuTitle("Edit")
  MenuItem(#Menu_ZoomReset,"ResetZoom") 
  MenuItem(#Menu_Zoom20,"Zoom 20% ")
  MenuItem(#Menu_Zoom50,"Zoom 50% ")
  MenuItem(#Menu_Zoom100,"Zoom 100% ")
  MenuItem(#Menu_Zoom200,"Zoom 200% ")
  MenuBar()
  MenuItem(#Menu_ZoomPlus,"Zoom + ")
  MenuItem(#Menu_ZoomLess,"Zoom - ")
  ;}
 
  ;{ gadget 
  If CanvasGadget(0, 150, 0, w, h, #PB_Canvas_Keyboard) : EndIf
  y1 = 10
  If SpinGadget(#G_BrushSize,   10,y1,100,20,1,200,#PB_Spin_Numeric)
    GadgetToolTip(#G_BrushSize,"Size of the brush")
    SetGadgetState(#G_BrushSize,brush\size)
    y1+30
  EndIf
  If SpinGadget(#G_BrushAlpha,  10,y1,100,20,0,255,#PB_Spin_Numeric)
    SetGadgetState(#G_BrushAlpha,brush\Alpha)
    GadgetToolTip(#G_BrushAlpha,"Alpha of the brush")
    y1+30
  EndIf
 
  If ComboBoxGadget(#G_BrushTexture,  10,y1,100,20)
    AddGadgetItem(#G_BrushTexture,0,"Use Color")
    AddGadgetItem(#G_BrushTexture,1,"Use Texture")
    AddGadgetItem(#G_BrushTexture,2,"Change Texture")
   y1+30
  EndIf
 
  If ImageGadget(#G_BrushColor, 10,y1,50,50,CreateImage(2,50,50)) : y1+110 : EndIf
 
  ;}
 
 
  LoadImage(0, #PB_Compiler_Home + "examples/Sources/Data/PureBasicLogo.bmp")
  CreateImage(1,w*2,h*2,32,#PB_Image_Transparent)
 
  If StartDrawing(ImageOutput(1))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    ClearColor = RGBA(230,230,230,255)
    Box(0,0,OutputWidth(),OutputHeight(),ClearColor) ; on efface l'image
    StopDrawing()
  EndIf
   
  Repeat
   
    Event       = WaitWindowEvent()
    EventGadget = EventGadget()
    EventMenu   = EventMenu()
   
    Select event
       
      Case #PB_Event_Menu
       
        Select EventMenu
           
          Case #Menu_Zoom20
            SetZoom(20)
          Case #Menu_Zoom50
            SetZoom(50)
          Case #Menu_Zoom200
            SetZoom(200) 
          Case #Menu_Zoom100
            SetZoom(100)
          Case #Menu_ZoomReset
            CanvasX = 0
            CanvasY = 0
            SetZoom(100)           
          Case #Menu_ZoomPlus
            SetZoom(1)
          Case #Menu_ZoomLess
           SetZoom(-1)
          Case #Menu_Clear
            If StartVectorDrawing(CanvasVectorOutput(0))                   
              AddPathBox(0, 0, w,h)
              VectorSourceColor(RGBA(255,255,255,255))
              FillPath()
              StopVectorDrawing()
            EndIf
            If StartDrawing(ImageOutput(1))
              DrawingMode(#PB_2DDrawing_AlphaBlend)
              Box(0,0,OutputWidth(),OutputHeight(),ClearColor) ; on efface l'image
              StopDrawing()
            EndIf
           
          Case #Menu_Save
            SaveImage(1,"save01.png",#PB_ImagePlugin_PNG)
           
        EndSelect
       
      Case #PB_Event_Gadget
       
        Select EventGadget
           
          Case #G_Canvas
           
            If GetGadgetAttribute(0, #PB_Canvas_Key) = #PB_Shortcut_Space
              space = 1
            EndIf
           
            If EventType() = #PB_EventType_LeftButtonUp
              space = 0
            ElseIf EventType() = #PB_EventType_LeftButtonDown
              startx.d = GetGadgetAttribute(0, #PB_Canvas_MouseX)/z
              starty.d = GetGadgetAttribute(0, #PB_Canvas_MouseY)/z 
              OldCanvasX = CanvasX
              OldCanvasY = CanvasY
             
              ; create a new stroke_path
              NbStroke+1
              ReDim Stroke(NbStroke)
              stroke(NbStroke)\nbdot+1             
              n = stroke(NbStroke)\nbdot
              ReDim Stroke(NbStroke)\dot(n)
              Stroke(NbStroke)\dot(1)\x = startx-canvasX/z
              Stroke(NbStroke)\dot(1)\y = starty-canvasY/z
              Stroke(NbStroke)\col\Alpha = brush\alpha
              Stroke(NbStroke)\col\Size = brush\Size
              Stroke(NbStroke)\col\Texture = brush\Texture
              Stroke(NbStroke)\col\Color = brush\Color
              Stroke(NbStroke)\col\Color = brush\Color
                             
            ElseIf(EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
             
              If space = 1 ; we move the canvas
                canvasX = GetGadgetAttribute(0, #PB_Canvas_MouseX) - startX + OldCanvasX
                canvasY = GetGadgetAttribute(0, #PB_Canvas_MouseY) - startY + OldCanvasY
              Else ; we paint on the image
                If StartVectorDrawing(ImageVectorOutput(1))
                  x.d = GetGadgetAttribute(0, #PB_Canvas_MouseX) / z
                  y.d = GetGadgetAttribute(0, #PB_Canvas_MouseY) / z
                 
                  ; erase the image
                  AddPathBox(0,0,ImageWidth(1),ImageHeight(1))
                  VectorSourceColor(ClearColor)
                  FillPath()
                 
                  ; draw all the stroke // not optimised !
                  stroke(NbStroke)\nbdot+1
                  n = stroke(NbStroke)\nbdot
                  ReDim Stroke(NbStroke)\dot(n)
                  Stroke(NbStroke)\dot(n)\x = x-canvasX/z
                  Stroke(NbStroke)\dot(n)\y = y-canvasY/z
                 
                  For j=0 To NbStroke
                    With Stroke(j)
                      For i = 2 To ArraySize(\dot())
                        MovePathCursor(\dot(i)\x,\dot(i)\y)
                        AddPathLine(\dot(i-1)\x-\dot(i)\x, \dot(i-1)\y-\dot(i)\y,#PB_Path_Relative)
                      Next i                     
                      VectorSourceColor(\col\color)
                      If \col\texture = 1
                        VectorSourceImage(ImageID(0),\col\alpha,ImageWidth(0),ImageHeight(0),#PB_VectorImage_Repeat)
                      EndIf             
                      StrokePath(\col\size ,#PB_Path_RoundEnd)
                    EndWith
                  Next
                  StopVectorDrawing()
                EndIf
               
                StartX = Stroke(NbStroke)\dot(n)\x
                StartY = Stroke(NbStroke)\dot(n)\y
               
              EndIf
             
              ; update the canvas
              If StartVectorDrawing(CanvasVectorOutput(0))
                ; the white bg
                AddPathBox(0, 0, w,h)
                VectorSourceColor(RGBA(255,255,255,255))
                FillPath()
                ; the image (layer)
                MovePathCursor(canvasX,canvasY)             
                DrawVectorImage(ImageID(1),255,w*z*2,h*z*2)                     
                StopVectorDrawing()
              EndIf
             
            EndIf
           
          Case #G_BrushColor
            If EventType() = #PB_EventType_LeftClick
              color = ColorRequester(brush\Color)
              brush\Color = RGBA(Red(color),Green(color),Blue(color),Brush\Alpha)
              If StartDrawing(ImageOutput(2))
                Box(0,0,50,50,color)
                StopDrawing()
              EndIf
              SetGadgetState(#G_BrushColor,ImageID(2))
            EndIf
         
          Case #G_BrushTexture 
            Select GetGadgetState(#G_BrushTexture)
              Case 0
                brush\Texture = 0
              Case 1
                brush\Texture = 1
              Case 2
                file$ = OpenFileRequester("Change texture","","Image|*.jpg;*.png;*.bmp",0)
                If file$ <> ""
                  If LoadImage(0, file$) =0
                    MessageRequester("Error","Unable To load the image")
                  EndIf
                EndIf
               
            EndSelect           
           
          Case #G_BrushAlpha, #G_BrushSize
            Brush\Alpha = GetGadgetState(#G_BrushAlpha)
            brush\Color = RGBA(Red(color),Green(color),Blue(color),Brush\Alpha)
            Brush\Size = GetGadgetState(#G_BrushSize)
           
        EndSelect
               
      Case #PB_Event_CloseWindow
        quit = 1
       
    EndSelect
   
  Until quit = 1
 
EndIf