Draw with letters

Share your advanced PureBasic knowledge/code with the community.
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Draw with letters

Post by firace »

A new mod of an old code (now should be cross-platform!)

Left mouse button: paint
Right mouse button: delete
Ctrl+R: switch character set (randomly)
Ctrl+L: clear canvas

Note: the DPIaware compiler flag must be disabled.

Image

Code: Select all

;; updated 15 dec 2024

Procedure.s SetCharset(i)
  AllCharsets.s = "0123456789ABCDEF,abcdefghijklmnopqrstuvwxyz0123456789,01,AGTC,/\o,■,▒"
  
  If i = 0 : i = Random(CountString(AllCharsets, ","))+1 : EndIf 
  SelectedCharset.s = StringField(AllCharsets, i, ",")
  
  SetWindowTitle(0, "ASCII-Paint - charset: " + SelectedCharset)
  ProcedureReturn SelectedCharset
EndProcedure   

#CELLSIZE = 28
#XXX = 24
#YYY = 20

AreaX  = #CELLSIZE * #XXX
AreaY  = #CELLSIZE * #YYY

OpenCryptRandom()
LoadFont(9, "Lucida Console", 16)

OpenWindow( 0,0,0,AreaX+160,AreaY+20,"ASCII-Paint",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) 
SetWindowColor (0,0)

CanvasGadget(2,8,2,AreaX,AreaY)  

StartDrawing(CanvasOutput(2))    
Box(0,0, AreaX, AreaY,0) 
StopDrawing() 

;; init palette 
CanvasGadget(3,AreaX + 50 , 4, 100 ,AreaY + 10)  
StartDrawing(CanvasOutput(3))

Box(0,0, 100 , AreaY + 10 , $262626)

For gg = 0 To 8
  color = (RGB(Random(255), Random(255), Random(255))) :  Box(20, 18 + gg*30 , 20, 20, color)
Next 

For gg = 0 To 8
  color = (RGB(Random(255), Random(255), Random(255))) :  Box(50, 18 + gg*30 , 20, 20, color)
Next 

selectedColor = color 
Box(1, 1, 3, WindowHeight(0), selectedColor)

StopDrawing()
;; init palette end 

charset.s = SetCharset(2)
AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_L, 123)  ;; clear canvas
AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_R, 124)  ;; switch charset 

Repeat 
  Select WaitWindowEvent(): 
    Case #PB_Event_Menu  
      Select EventMenu()
        Case 123
          StartDrawing(CanvasOutput(2))    
          Box(0,0, AreaX, AreaY,0) 
          StopDrawing() 
        Case 124 
          charset.s = SetCharset(0)
      EndSelect
      
    Case #PB_Event_CloseWindow: End 
      
    Case #PB_Event_Gadget 
      Select EventGadget() 
        Case 3
          If EventType() = #PB_EventType_LeftClick
            StartDrawing(CanvasOutput(3))
            selectedColor = Point(GetGadgetAttribute(3, #PB_Canvas_MouseX), GetGadgetAttribute(3, #PB_Canvas_MouseY))
            Box(1, 1, 3, WindowHeight(0), selectedColor)
            StopDrawing()
          EndIf 
          
        Case 2
          Select EventType()
            Case #PB_EventType_LeftButtonDown
              pendown=1
              
            Case #PB_EventType_RightButtonDown
              delmode=1 :              pendown=1
              
            Case #PB_EventType_LeftButtonUp, #PB_EventType_RightButtonUp
              pendown=0 :              delmode=0
              
            Case #PB_EventType_MouseMove 
              If pendown=1
                mx=GetGadgetAttribute(2, #PB_Canvas_MouseX) : my=GetGadgetAttribute(2, #PB_Canvas_MouseY) 
                
                mxx=(mx/#CELLSIZE) * #CELLSIZE : myy=(my/#CELLSIZE) * #CELLSIZE 
                
                StartDrawing(CanvasOutput(2)) 
                DrawingFont(FontID(9))
                If delmode
                  RoundBox(mxx,myy, #CELLSIZE - 2, #CELLSIZE - 2,2,2, 0) 
                Else   
                  char$ = Mid(charset, CryptRandom(Len(charset)), 1)
                  DrawText(mxx, myy, char$ , selectedColor)
                EndIf 
                
                StopDrawing() 
              EndIf
          EndSelect
      EndSelect 
  EndSelect 
ForEver 
Last edited by firace on Sun Dec 15, 2024 10:44 am, edited 7 times in total.
threedslider
Enthusiast
Enthusiast
Posts: 396
Joined: Sat Feb 12, 2022 7:15 pm

Re: Draw with letters

Post by threedslider »

Thanks for sharing :mrgreen:

It works but in some wrong color draw but you did a great job :wink:
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Re: Draw with letters

Post by firace »

threedslider wrote: Sat Dec 14, 2024 4:36 pm Thanks for sharing :mrgreen:

It works but in some wrong color draw but you did a great job :wink:
Thanks!

What do you mean by "some wrong color draw"?
(Please confirm your PB version - I've tested the code on PB 5.73 x64)
threedslider
Enthusiast
Enthusiast
Posts: 396
Joined: Sat Feb 12, 2022 7:15 pm

Re: Draw with letters

Post by threedslider »

firace wrote: Sat Dec 14, 2024 5:09 pm What do you mean by "some wrong color draw"?
(Please confirm your PB version - I've tested the code on PB 5.73 x64)
I have tested in PB 6.12 and when I choose some color then it draws in wrong color :shock:

Dunno why is it ? Maybe a bug ? I don't know.
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Draw with letters

Post by ChrisR »

Nice :)
The DPIaware flag must be disabled otherwise it doesn't look good and it crashes when a color is selected, Point() is outside the drawing area
AZJIO
Addict
Addict
Posts: 2187
Joined: Sun May 14, 2017 1:48 am

Re: Draw with letters

Post by AZJIO »

If you use these constants, then your code will work on all OS.

Code: Select all

#PB_EventType_LeftButtonUp
#PB_EventType_LeftButtonDown
#PB_EventType_MouseMove
x = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseX)
y = GetGadgetAttribute(#Canvas, #PB_Canvas_MouseY)
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Re: Draw with letters

Post by firace »

AZJIO, ChrisR: thanks for the feedback! I've modified the code and first post according to your suggestions.

threedslider: could you try the new code to see if it fixes the color issue?

I've added 2 new features: Ctrl+R to change the character set, Ctrl+L to clear the canvas
threedslider
Enthusiast
Enthusiast
Posts: 396
Joined: Sat Feb 12, 2022 7:15 pm

Re: Draw with letters

Post by threedslider »

@firace : It works ! But now it is a problem of DPI scaling so it is small and not fitting the screen :D

Great job and thanks for sharing !
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Re: Draw with letters

Post by firace »

threedslider wrote: Sun Dec 15, 2024 12:58 pm @firace : It works ! But now it is a problem of DPI scaling so it is small and not fitting the screen :D

Great job and thanks for sharing !
Cool!
About the DPI issue, try to *disable* this option in compiler settings:

Image
threedslider
Enthusiast
Enthusiast
Posts: 396
Joined: Sat Feb 12, 2022 7:15 pm

Re: Draw with letters

Post by threedslider »

@firace : Thank you ! :D
Fred
Administrator
Administrator
Posts: 18207
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Draw with letters

Post by Fred »

To be DPI aware, you should always use OutputWidth()/Height() instead of using the window dimension, as the pixel size of drawn elements are not static when changing DPI
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Draw with letters

Post by ChrisR »

DPI aware version using OutputWidth()/Height() and some DesktopScaledX/Y
Ctrl+P to reset the Palette

Code: Select all

;; updated 20 dec 2024 DPIaware support
EnableExplicit

#DrawBackColor    = 0
#PaletteBackColor = $262626

Global SelectedColor

Macro SX(_X_) : DesktopScaledX(_X_) : EndMacro
Macro SY(_Y_) : DesktopScaledY(_Y_) : EndMacro

Macro DrawShortcut(_Color_)
  DrawingFont(FontID(0))
  TxtHeight = TextHeight("Abc")
  DrawText(SX(8), OutputHeight()-9*TxtHeight, "Reset Palette",  _Color_, #PaletteBackColor)
  DrawText(SX(8), OutputHeight()-8*TxtHeight, "  (Ctrl+P)",     _Color_, #PaletteBackColor)
  DrawText(SX(8), OutputHeight()-6*TxtHeight, "Switch Charset", _Color_, #PaletteBackColor)
  DrawText(SX(8), OutputHeight()-5*TxtHeight, "  (Ctrl+R)",     _Color_, #PaletteBackColor)
  DrawText(SX(8), OutputHeight()-3*TxtHeight, "Clear Canvas",   _Color_, #PaletteBackColor)
  DrawText(SX(8), OutputHeight()-2*TxtHeight, "  (Ctrl+L)",     _Color_, #PaletteBackColor)
EndMacro

Procedure.s SetCharset(i)
  Protected.s SelectedCharset, AllCharsets = "0123456789ABCDEF,abcdefghijklmnopqrstuvwxyz0123456789,01,AGTC,/\o,■,▒"
  
  If i = 0 : i = Random(CountString(AllCharsets, ",")) +1 : EndIf
  SelectedCharset = StringField(AllCharsets, i, ",")
  
  SetWindowTitle(0, "ASCII-Paint - Charset: " + SelectedCharset)
  ProcedureReturn SelectedCharset
EndProcedure

Procedure InitPalette()
  Protected Color, TxtHeight, gg
  
  If StartDrawing(CanvasOutput(1))
    Box(0, 0, OutputWidth(), OutputHeight(), #PaletteBackColor)
    
    For gg = 0 To 8
      Color = (RGB(Random(255),Random(255),Random(255))) : Box(SX(12), SY(10+gg*25), SX(20), SY(20), Color)
    Next
    For gg = 0 To 8
      Color = (RGB(Random(255),Random(255),Random(255))) : Box(SX(37), SY(10+gg*25), SX(20), SY(20), Color)
    Next
    
    SelectedColor = Color
    Box(SX(2), SY(2), SX(3), OutputHeight()-SY(4), SelectedColor)
    DrawShortcut(SelectedColor)
    
    StopDrawing()
  EndIf
EndProcedure

;- Main
#XXX = 24
#YYY = 20

Define CellSize = SX(21)   ; Text Height = 21 with "Lucida Console" size 16 at 100% scaling 
Define AreaX = CellSize * #XXX, AreaY  = CellSize * #YYY, TxtHeight
Define PointColor, PenDown, DelMode, mx, mxx, my, myy
Define.s Charset, Char$

OpenCryptRandom()
LoadFont(0, "Lucida Console", 6)
LoadFont(1, "Lucida Console", 16)

OpenWindow(0, 0, 0, AreaX+92, AreaY+8, "ASCII-Paint", #PB_Window_Invisible|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
SetWindowColor(0, #DrawBackColor)

CanvasGadget(0, 4, 4, AreaX, AreaY)
If StartDrawing(CanvasOutput(0))
  DrawingFont(FontID(1))
  CellSize = TextHeight("A")   ; Real Text Height DPI aware
  StopDrawing()
EndIf

AreaX  = CellSize * #XXX : AreaY  = CellSize * #YYY   ; Adjust Window and Canvas size from Cell size
ResizeWindow(0, #PB_Ignore, #PB_Ignore, AreaX+92, AreaY+8)
ResizeGadget(0, #PB_Ignore, #PB_Ignore, AreaX, AreaY)
If StartDrawing(CanvasOutput(0))
  Box(0, 0, OutputWidth(), OutputHeight(), #DrawBackColor)
  StopDrawing()
EndIf

; palette
CanvasGadget(1, AreaX + 8, 4, 80, AreaY)
InitPalette()

Charset = SetCharset(2)
AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_P, 0)  ;; Reset Palette
AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_R, 1)  ;; Switch Charset
AddKeyboardShortcut(0, #PB_Shortcut_Control | #PB_Shortcut_L, 2)  ;; Clear Canvas
HideWindow(0, #False)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Menu
      Select EventMenu()
        Case 0
          InitPalette()
        Case 1
          Charset = SetCharset(0)
        Case 2
          If StartDrawing(CanvasOutput(0))
            Box(0, 0, OutputWidth(), OutputHeight(), #DrawBackColor)
            StopDrawing()
          EndIf
      EndSelect
      
    Case #PB_Event_CloseWindow: End
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          If EventType() = #PB_EventType_LeftClick
            If StartDrawing(CanvasOutput(1))
              PointColor = Point(GetGadgetAttribute(1, #PB_Canvas_MouseX), GetGadgetAttribute(1, #PB_Canvas_MouseY))
              If PointColor <> #PaletteBackColor
                SelectedColor = PointColor
                Box(SX(2), SY(2), SX(3), OutputHeight()-SY(4), SelectedColor)
                DrawShortcut(SelectedColor)
              EndIf
              StopDrawing()
            EndIf
          EndIf
          
        Case 0
          Select EventType()
            Case #PB_EventType_LeftButtonDown
              PenDown=1 : DelMode=0
              
            Case #PB_EventType_RightButtonDown
              PenDown=1 : DelMode=1
              
            Case #PB_EventType_LeftButtonUp, #PB_EventType_RightButtonUp
              PenDown=0 : DelMode=0
              
            Case #PB_EventType_MouseMove
              If PenDown=1
                mx=GetGadgetAttribute(0, #PB_Canvas_MouseX) : my=GetGadgetAttribute(0, #PB_Canvas_MouseY)
                mxx=(mx/CellSize)*CellSize                  : myy=(my/CellSize)*CellSize
                
                If StartDrawing(CanvasOutput(0))
                  DrawingFont(FontID(1))
                  If DelMode
                    Box(mxx, myy, CellSize, CellSize, #DrawBackColor)
                  Else
                    Char$ = Mid(Charset, CryptRandom(Len(Charset)), 1)
                    DrawText(mxx, myy, Char$, SelectedColor, #DrawBackColor)
                  EndIf
                  StopDrawing()
                EndIf
                
              EndIf
          EndSelect
      EndSelect
  EndSelect
ForEver
Last edited by ChrisR on Fri Dec 20, 2024 1:20 am, edited 5 times in total.
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Re: Draw with letters

Post by firace »

That's awesome, thanks ChrisR 8)
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Draw with letters

Post by ChrisR »

Ha, you're welcome, just my 2 cts, I have a little time and I appreciate your example, all credit to you :)
I added Global selectedColor, required now that it's in InitPalette()
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Draw with letters

Post by ChrisR »

Small change so that Cell size is DPI aware too.
Post Reply