pythonpdfcanvasreportlab

How Do I Arch Text In Reportlab


text = 'Hello World'
length = len(text)
can.translate(400, 293)
can.rotate(-1 * 200 / 1.06)
can.rotate(-1 * (200 / length) / 1.06)
for n in text:
    can.rotate(200 / length)
    can.translate(0, -1 * 0.8*inch)        
    can.drawString(0, 0, n)

Here is what I have tried. The text is arched however the letters are rotated. What is the correct way to do this?

curved text

Here is what I would like the text to look like. arched text


Solution

  • It would probably be easier if you would use an easier formula to draw your letters. Since you rotate + translate your letters at the same time it can be tough to rotate the letters back vertically.

    Using cosinus and sinus seems to be a good idea since you want to draw your letters in a circle without the use of rotate.

    here is an example:

    from reportlab.pdfgen import canvas
    import numpy as np
    
    can = canvas.Canvas("rl-hello_again.pdf", pagesize=(595.27, 841.89))
    text = 'Hello World'
    length = len(text)
    can.translate(400, 293)
    degrees_perletter = 180 / length
    i = 0
    for n in text:
        x = np.sin(np.radians(degrees_perletter * i)) * 20
        y = np.cos(np.radians(degrees_perletter * i)) * 20
        can.translate(x, y)
        can.drawString(0, 0, n)
        i += 1
    
    can.showPage()
    can.save()
    

    enter image description here

    In a second step if you want to rotate the letters. Then i advise to only rotate the letter after the translation and in a second step rotate the letter back to its vertical position. Like this its easier to not get lost between rotations and translations.

    See code below:

    from reportlab.pdfgen import canvas
    import numpy as np
    
    can = canvas.Canvas("rl-hello_again.pdf", pagesize=(595.27, 841.89))
    text = 'Hello World'
    length = len(text)
    can.translate(400, 293)
    degrees_perletter = 180 / (length+2)
    i = 1
    for n in text:
        x = np.sin(np.radians(degrees_perletter * i)) * 20
        y = np.cos(np.radians(degrees_perletter * i)) * 20
        degrees_l=-degrees_perletter*i+90
        can.translate(x, y)
        can.rotate(degrees_l)
        can.drawString(0, 0, n)
        can.rotate(-degrees_l)
        i += 1
    
    can.showPage()
    can.save()
    

    enter image description here