[reportlab-users] Cursive Font Question

Richie Marini richardjmarini at gmail.com
Fri Jun 3 06:54:55 EDT 2011

Thanks, turns out it wasn't so much the kerning function. But rather the
same changes in terms of calling pyribidi.log2vis that are made elsewhere
in reportlab to allow for RTL text I had to also apply to the stringWidth
function. That solved some of the problem in that the stringWidth
function returns the correct length no3 (I'll see if I can get this merged
back into the reportlab-rtl repository.

Now, I have another issue causing a similar problem with the
zero-non-breaking-space character 0xffef coming up in text and I think
it's not provided as a glyph in the ArialUnicode MS.tff I'm using and
therefore the ordinal for this character is not in the charWidths table
so the defaltWidth of 1000 is being used by the stringWidth function which
is creating a large gap in the middle of my text now. But the "word"
width is at least correct now.

So looks like I had two issues causing the same thing and was at least
able to solve one of them at the moment. This second non-breaking-space
issues I'll just have to test for and perhaps use a different defaultWidth
for that character for the time being.

I basically created my own stringWidth like this and simile inserted the
call to log2vis to solve the first issue:

def stringWidth_log2vis(c, text, encoding='utf-8', direction= 'LTR'):
directions= { 'LTR': DIR_LTR, 'RTL': DIR_RTL }

if type(text) is not UnicodeType:
text = unicode(text, encoding or 'utf-8') # encoding defaults to

text= log2vis(text, directions.get(direction, DIR_ON))
font= pdfmetrics.getFont(c._fontname)
size= c._fontsize

g= font.face.charWidths.get
dw= font.face.defaultWidth
return .001*size*sum([g(ord(u),dw) for u in text])

Thanks for the reponse!

On Fri, 3 Jun 2011, Henning von Bargen wrote:

> I don't know if that helps you,

> because I've never tested it with anything else but german text

> (plain ol' left-to-right), but wordaxe (http://deco-cow.sourceforge.net)

> contains a

> replacement for the reportlab.platypus.paragraph.Paragraph class

> that supports kerning for TrueType fonts.


> Perhaps you can look at the source code and extract the kerning

> functions to create your own (low-level) functions for stringwidth

> and text output with kerning support.


> Unfortunately, it's more or less impossible to create an

> inherited class from ReportLab's Paragraph class, since many

> functions are _xxxx in the module, not in the class.


> But you may be able to make a copy of the paragraph.py file

> under a different name and try to modify the stringwidth function

> in there.


> Take a look at the kerning_formatText and kerning_textOut functions

> in the NewParagraph.py file and the function stringWidth_kerning

> int the kerning_info.py file.


> Of course I'd like it best if you'd try out wordaxe and if it doesn't

> work for arabic (right-to-left) text, extend it somehow...


> Henning


> P.S.

> If you add code to your message, please do not use anything

> but ASCII characters - use the \uXXXX notation for anything else

> (see http://docs.python.org/howto/unicode.html#unicode-literals-in-python-source-code).

> Otherwise other people cannot run your code.

> Here's what I see in your code:


> text= u"??? ?? ???? ?????? ???? ???????"



> -----Ursprüngliche Nachricht-----


> I'm using the reportlab with pyfribidi to create pdf's with Arabic fonts.

> I'm noticing that canvas.StringWidth() returns a value larger then the

> actual rendered string which is causing me some issues. From what I'm

> guessing this has to do with the "cursive" nature of the glyphs in that

> they overlap each other a little to make the cursive connection to the

> glyph next to it? Therefore, string width is simply returning the

> summation of widths of all the glyphs used and not accounting for the

> overlapping. So the value return is the width of all the Glyph's and not

> the amount of space the entire string is taking up on the canvas.

> So, if I were to render two separate words on a canvas with two separate

> calls to render and increment the X value by the stringWidth() of the

> first string I get a large white space between the two because the width

> returned is to big. For example:


> ### START ###

> #!/usr/bin/env python

> # -*- coding: utf-8 -*-


> from reportlab.pdfgen import canvas

> from reportlab.pdfbase import pdfmetrics

> from reportlab.pdfbase.ttfonts import TTFont


> pdfmetrics.registerFont(TTFont('Arabic', '/Library/fonts/Arial

> Unicode.ttf'))


> c= canvas.Canvas(filename= "test.pdf")


> x= 10

> y= 500

> text= u"??? ?? ???? ?????? ???? ???????"


> c.setFont('Arabic', 12)


> c.drawString(x, y, text)


> x+= c.stringWidth(text)


> c.drawString(x, y, text)


> c.showPage()

> c.save()



> ### END ###



> Wondering if there's a least a way to get the summed value of the

> overlapped glyph's so I can at least substract that value from that

> returned from stringWidth()? Or maybe, it's a different problem all

> together?


> Thanks,

> -richie

> _______________________________________________

> reportlab-users mailing list

> reportlab-users at lists2.reportlab.com

> http://two.pairlist.net/mailman/listinfo/reportlab-users


More information about the reportlab-users mailing list