Vector drawing: text with special shape

Just starting out? Need help? Post your questions and find answers here.
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Vector drawing: text with special shape

Post by Little John »

Hi,

how can I draw text with PB's vector drawing library that looks like this?

Image
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Vector drawing: text with special shape

Post by #NULL »

As I just tried, you could do funny things by getting the PathSegments() and manipulating the coordinates. But straight lines will stay straight and not get curved if you do non-linear manipulations because they just have beginning and end coordinates and don't get interpolated in between. You probably could add additional line steps in between manually to do that and with some trigonometry or whatever you could do all kinds of transformations.

Code: Select all

 If OpenWindow(0, 0, 0, 500, 500, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0, 0, 0, 500, 500)    
    
    If StartVectorDrawing(CanvasVectorOutput(0))
      VectorFont(LoadFont(0, "Times New Roman", 60, #PB_Font_Bold))
      
      MovePathCursor(50, 50)
      AddPathText("AUGUST")
      segments.s = PathSegments()
      segments2.s
      Debug segments
      n = CountString(segments, " ") + 1
      For i=1 To n
        seg.s = StringField(segments, i, " ")
        Select seg
          Case "M", "L", "C", "Z"
            coord = 0
          Default
            coord + 1
        EndSelect
        ;Debug seg + " // " + coord
        
        Define currentX.f
        Define currentY.f
        If coord = 0
          currentX.f = 0
          currentY.f = 0
        ElseIf coord % 2 = 1  ; odd / 1,3,5.. / x
          currentX = ValF(seg)
        ElseIf coord % 2 = 0  ; even / 2,4,6.. / y
          currentY = ValF(seg)
          currentY = currentY + Pow(currentY, 0.003 * currentX)
          seg = StrF(currentY);, 3)
          ;Debug seg
        EndIf
        segments2 + seg + " "
      Next
      ResetPath()
      
      Debug segments
      Debug segments2
      
      AddPathSegments(segments2)
      VectorSourceColor(RGBA(0, 0, 255, 128))
      FillPath()
      
      StopVectorDrawing()
    EndIf
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow
  EndIf
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Vector drawing: text with special shape

Post by Little John »

Very cool! 8) Image
That gives me a lot of possibilities to play with. :-)
Thank you so much!
User avatar
pf shadoko
Enthusiast
Enthusiast
Posts: 291
Joined: Thu Jul 09, 2015 9:07 am

Re: Vector drawing: text with special shape

Post by pf shadoko »

very good idea
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: Vector drawing: text with special shape

Post by RSBasic »

@#NULL
Very cool Image
Image
Image
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Vector drawing: text with special shape

Post by #NULL »

#NULL wrote:You probably could add additional line steps in between manually to do that
..or just replace lines segments (L) with analogue curve segments (C) before the manipulation.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Vector drawing: text with special shape

Post by srod »

That is neat. :)
I may look like a mule, but I'm not a complete ass.
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Vector drawing: text with special shape

Post by Little John »

Now I've put the decisive code into a procedure that accepts the text as parameter, and also the addresses of 2 callback functions: one for the upper border of the text, and one for its lower border.

//edit 2022-09-18: The code now also works as expected, when compiled with the “DPI aware” flag.

Code: Select all

; Version 1.01 (DPI compliant)
; tested with PB 6.00 LTS on Windows

CompilerIf #PB_Compiler_IsMainFile
   EnableExplicit
CompilerEndIf

Prototype.d protoY (x.d)

Procedure DrawVectorTextEx (text$, *upper.protoY, *lower.protoY)
   ; in: text$ : text to draw
   ;     *upper: address of a callback function that defines the upper border of the text
   ;     *lower: address of a callback function that defines the lower border of the text
   Protected segmentsIn$, segmentsOut$, seg$
   Protected.i n, i, coord
   Protected.d x, y, xd, yr
   Protected x0.d = PathCursorX()               ; x-coordinate of the beginning of the text
   Protected yd_max.d = VectorTextHeight(text$) / 2
   Protected y0.d = PathCursorY() + yd_max      ; y-coordinate of the middle of the text
   
   AddPathText(text$)
   segmentsIn$ = PathSegments()
   
   Debug segmentsIn$
   Debug "-------------------------------------"
   
   n = CountString(segmentsIn$, " ") + 1
   For i = 1 To n
      seg$ = StringField(segmentsIn$, i, " ")
      Select seg$
         Case "M", "L", "C", "Z"
            coord = 0
         Default
            coord + 1
      EndSelect
      ; Debug seg$ + " // " + coord
      
      If coord = 0
         ; do nothing
      ElseIf coord % 2 = 1              ; odd  -> x-coordinate
         x = ValD(seg$)
         xd = DesktopUnscaledX(x - x0)  ; distance from x0
      ElseIf coord % 2 = 0              ; even -> y-coordinate
         y = ValD(seg$)
         yr = (y - y0) / yd_max         ; relative distance from y0  (1.0 means yd_max)
         If yr < 0
            y = y0 + DesktopScaledY(yr * *upper(xd))
         Else
            y = y0 - DesktopScaledY(yr * *lower(xd))
         EndIf   
         seg$ = StrD(y)
      EndIf
      
      segmentsOut$ + seg$ + " "
   Next
   
   Debug segmentsOut$
   Debug "====================================="
   
   ResetPath()
   AddPathSegments(segmentsOut$)
   FillPath()
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
   ; -- Demo
   
   Procedure.d up1 (x.d)
      ProcedureReturn 0.2 * x + 10
   EndProcedure
   
   Procedure.d lo1 (x.d)
      ProcedureReturn -0.2 * x - 10
   EndProcedure
   
   
   Procedure.d up2 (x.d)
      ProcedureReturn 0.003 * Pow(x-160, 2.0) + 50
   EndProcedure
   
   Procedure.d lo2 (x.d)
      ProcedureReturn -0.003 * Pow(x-160, 2.0) - 50
   EndProcedure
   
   
   Procedure.d up3 (x.d)
      ProcedureReturn -0.003 * Pow(x-160, 2.0) + 100
   EndProcedure
   
   Procedure.d lo3 (x.d)
      ProcedureReturn 0.003 * Pow(x-160, 2.0) - 100
   EndProcedure
   
   
   Define event.i
   
   If OpenWindow(0, 0, 0, 500, 500, "Advanced vector text drawing (DPI compliant)", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) = 0
      MessageRequester("Fatal error", ~"Can't open main window.\nProgram terminated.")
      End
   EndIf
   
   CanvasGadget(0, 0, 0, 500, 500)   
   
   If StartVectorDrawing(CanvasVectorOutput(0))
      VectorFont(LoadFont(0, "Times New Roman", 60, #PB_Font_Bold))
      
      VectorSourceColor(RGBA(255, 0, 0, 128))
      MovePathCursor(DesktopScaledX(60), DesktopScaledY(40))
      DrawVectorTextEx("AUGUST", @up1(), @lo1())
      
      VectorSourceColor(RGBA(0, 255, 0, 128))
      MovePathCursor(DesktopScaledX(60), DesktopScaledY(200))
      DrawVectorTextEx("AUGUST", @up2(), @lo2())
      
      VectorSourceColor(RGBA(0, 0, 255, 128))
      MovePathCursor(DesktopScaledX(60), DesktopScaledY(350))
      DrawVectorTextEx("AUGUST", @up3(), @lo3())
      
      StopVectorDrawing()
   EndIf
   
   Repeat
      event = WaitWindowEvent()
   Until event = #PB_Event_CloseWindow
CompilerEndIf
Last edited by Little John on Sun Sep 18, 2022 1:35 pm, edited 1 time in total.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Vector drawing: text with special shape

Post by davido »

@Little John,

Impressive. You've made a great idea work.
An august piece of work, if I may say so.

Thank you for sharing. :D
DE AA EB
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Vector drawing: text with special shape

Post by Little John »

Davido,

many thanks for your kind words!
At least half of the credits is due to #NULL. :-)
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Vector drawing: text with special shape

Post by Little John »

I updated the code in the 8th post of this thread, so that it now also works as expected, when compiled with the “DPI aware” flag.
Post Reply