[reportlab-users] Circular text (was: iCards...)
Dinu Gherman
reportlab-users@reportlab.com
Wed, 29 Jan 2003 11:48:50 +0100
--Apple-Mail-4--1041862128
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
Jerome Alet:
> One thing bothers me : I did my best to translate the postscript
> algorithm into Python+ReportLab but I'm not sure it's correct
> because some strings look "not so circular" when drawn.
>
> Maybe that's just an optical problem or a rounding one, did you
> see this too ?
I'm attaching an experimental function which does circular text,
using Drawings, mostly as I like. I think it needs some kind of
compensation for a certain uglyness resulting from the modified
kerning between characters due to the bending effect. Maybe Just
can tell us how to do it in a typographically more satisfactory
way? ;-)
Dinu
--Apple-Mail-4--1041862128
Content-Disposition: attachment;
filename=circularText.py
Content-Transfer-Encoding: 7bit
Content-Type: application/text;
x-unix-mode=0644;
x-mac-type=54455854;
name="circularText.py"
#! /usr/bin/env python
from math import pi, sqrt, sin, cos
from reportlab.lib import colors
from reportlab.graphics import shapes
from reportlab.graphics import renderPDF, renderPM
from reportlab.pdfbase.pdfmetrics import stringWidth
def addCT(group, x, y, radius, angle, text, fontname, fontsize, counterClockWise=0):
"An experimental function to add some circular text to a Group shape."
ccw = counterClockWise
fn, fs, = fontname, fontsize
width = stringWidth(text, fn, fs)
alpha = width / radius / pi*180
b = {0: -angle, 1: 180-angle}[ccw]
for letter in text:
# create a group containing one letter
h = shapes.Group()
h.add(shapes.Circle(0, 0, 3, fillColor=colors.red))
s = shapes.String(0, 0, letter, textAnchor="middle")
s.fontName = fn
s.fontSize = fs
h.add(s)
# translate it to new origin: x,y
h.translate(x, y)
# translate to circle border: dx,dy
width = stringWidth(letter, fn, fs)
beta = width / radius / pi*180
phi = alpha/2-b-beta/2
if ccw:
phi = 180 - phi
dx = -sin(phi*pi/180)*radius
dy = cos(phi*pi/180)*radius
h.translate(dx, dy)
# rotate as needed
if ccw:
phi = phi - 180
h.rotate(phi)
# increment used letter widths in degrees
b = b + beta
group.add(h)
return group
def main() :
w, h = 200, 200
x, y = 100, 100
r = 50
fn, fs = "Helvetica-Bold", 24
d = shapes.Drawing(w, h)
g = shapes.Group()
# add a couple of helping widgets
g.add(shapes.Rect(0, 0, w, h, fillColor=None))
g.add(shapes.Circle(x, y, 3, fillColor=colors.black))
g.add(shapes.Circle(x, y, r, fillColor=None))
g.add(shapes.Circle(x, y, r+fs, fillColor=None))
# add two circular texts
addCT(g, x, y, 50, 45, "Python", fn, fs)
addCT(g, x, y, 50, -180-45, "powered", fn, fs, counterClockWise=1)
d.add(g)
# renderPM.drawToFile(d, "circularText.jpg", "JPG")
renderPDF.drawToFile(d, "circularText.pdf")
if __name__ == "__main__" :
main()
--Apple-Mail-4--1041862128
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
--
Dinu C. Gherman
......................................................................
"Questions are never indiscreet. Answers sometimes are." (Oscar Wilde)
--Apple-Mail-4--1041862128--