[reportlab-users] Built-in versus embedded fonts

Glenn Linderman v+python at g.nevcal.com
Sun Jun 21 17:36:37 EDT 2015

On 21 June 2015 at 02:16, Glenn Linderman <v+python at g.nevcal.com> wrote:

> As an outgrowth of the "Helvetica" reference (and I've got working code to
> avoid it now, but would like the Canvas parameter for initial_fontname in
> time, thanks), I found some code that is using "Times-Roman" (also built in)
> to determine which string is longer... The strings are _actually_ placed in
> the document using "Times New Roman" (TTF)... but...
> 1) pdfmetrics.stringWidth doesn't seem to work for TTF fonts.
> 2) I couldn't find an obvious way to obtain the information for TTF fonts.
> 3) If kerning gets implemented, the stringWidth should reflect that.
> I vaguely recall implementing this "proxy for reality" late one night in a
> coding frenzy... is there an easy way to obtain stringWidth for a TTF font?

On 6/21/2015 12:32 PM, Andy Robinson wrote:
> As far as I remember, if you register a TrueType Font,
> pdfmetrics.stringwidth(..) gives the right answer.
> It gets aliased to various functions in C accelerators so it may not
> be obvious from reading the code....

Well, I couldn't get it to work using any of the nick name I assigned, 
the full font name, or the font file name. It would give an error (same 
error in all cases, full reportlab traceback shown for last one.
   File "C:\Python34\lib\site-packages\reportlab\pdfbase\pdfmetrics.py", 
line 612, in getTypeFace
     return _typefaces[faceName]
KeyError: 'Times'
   File "C:\Python34\lib\site-packages\reportlab\pdfbase\pdfmetrics.py", 
line 612, in getTypeFace
     return _typefaces[faceName]
KeyError: 'Times New Roman'
Traceback (most recent call last):
   File "C:\Python34\lib\site-packages\reportlab\pdfbase\pdfmetrics.py", 
line 671
, in getFont
     return _fonts[fontName]
KeyError: 'times'

During handling of the above exception, another exception occurred:

   File "C:\Python34\lib\site-packages\reportlab\pdfbase\pdfmetrics.py", 
line 707
, in stringWidth
     return getFont(fontName).stringWidth(text, fontSize, encoding=encoding)
   File "C:\Python34\lib\site-packages\reportlab\pdfbase\pdfmetrics.py", 
line 673
, in getFont
     return findFontAndRegister(fontName)
   File "C:\Python34\lib\site-packages\reportlab\pdfbase\pdfmetrics.py", 
line 655
, in findFontAndRegister
     face = getTypeFace(fontName)
   File "C:\Python34\lib\site-packages\reportlab\pdfbase\pdfmetrics.py", 
line 612
, in getTypeFace
     return _typefaces[faceName]
KeyError: 'times'

On 6/21/2015 1:40 AM, Laura Creighton wrote:
> does instanceStringWidthTTF(self,text,size,encoding) get the
> correct size?
> Laura

In trying to find the method in your suggestion I found the code in 
ttfonts.py that says:

     from _rl_accel import _instanceStringWidthTTF
     import new
     TTFont.stringWidth = new.instancemethod(_instanceStringWidthTTF,None,TTFont)
except ImportError:

So I decided to try using stringWidth from the TTFont class returned 
from registering the font, which I had kept around for other reasons 
anyway.... First try it told me it needed the size as a second parameter 
(no real surprise there), and second try worked.

Fiddling a bit, Times Roman (PDF built-in) font is an excellent proxy 
for Times New Roman (they had the exact same length in every case that I 
tried).  Nonetheless, I am pleased to find TTFont.stringWidth works, 
because I will be using some fonts for which there is not a built-in 
proxy, excellent or otherwise, so now I have a solution for that case.

Whether pdfmetrics.stringWidth is _supposed to_ or _could be improved 
to_ detect the existence of the TTFont and call the TTFont.stringWidth, 
I couldn't say.  It would be a user-friendly feature, but then it might 
cause a small performance degradation.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist2.pair.net/pipermail/reportlab-users/attachments/20150621/b044e641/attachment.html>

More information about the reportlab-users mailing list