[reportlab-users] Built-in versus embedded fonts

Robin Becker robin at reportlab.com
Thu Jun 25 05:36:54 EDT 2015


On 24/06/2015 20:05, Glenn Linderman wrote:
> On 6/24/2015 3:14 AM, Robin Becker wrote:
>>
>> If I add these lines immediately prior to the final for loop in your example
>>
>> myPDFinit()
>> myPDF.register_fonts()
>> print myPDF.canv._fontname
>> print myPDF.rlfonts.keys()
>> for txt in ('012', 'abc', 'ABC'):
>>
>> then I see this in the output
>>
>>> C:\Users\rptlab\Downloads>rl-test.py
>>> Times-New-Roman
>>> ['Times-BoldItalic', 'Times-Italic', 'Times-Bold', 'Times']
>>> ('thiswid:', 30.0)
>>> Traceback (most recent call last):
>>>   File "C:\Users\rptlab\Downloads\rl-test.py", line 82, in <module>
>>
>>
>> so perhaps you should consider making the font set up code a bit more transparent
>
> OK, something clicked, but something is _VERY_ unclear.
>
> I changed my code to pass "Times-New-Roman" to Canvas.stringWidth, and that works.
>
> Before, I had only tried "Times", "times", and "Times New Roman".
>
......

ReportLab effectively ignores the internal names for ttf fonts. The token name 
is everything. Your code for adding the fonts looks terribly complicated and 
clearly the names in the private fonts thing don't match.

as a test I created a 3.1.8 reportlab environment and then ran this code


import sys, os
#####################################
class PDFu:
     #####################################
     def __init__( self ):
         import reportlab.rl_config
         import reportlab.pdfbase.ttfonts
         import reportlab.lib
         import reportlab.pdfgen.canvas
         import reportlab.platypus
         import reportlab.lib.styles
         import reportlab.platypus.tables
         import reportlab.lib.units
         import reportlab.pdfbase
         import reportlab.lib.pagesizes
         self.colors = reportlab.lib.colors
         self.Canvas = reportlab.pdfgen.canvas.Canvas
         self.StyleSheet1 = reportlab.lib.styles.StyleSheet1
         self.ParagraphStyle = reportlab.lib.styles.ParagraphStyle
         self.ListStyle = reportlab.lib.styles.ListStyle
         self.TA_LEFT = reportlab.lib.styles.TA_LEFT
         self.TA_CENTER = reportlab.lib.styles.TA_CENTER
         self.black = reportlab.lib.styles.black
         self.TableStyle = reportlab.platypus.tables.TableStyle
         self.Table = reportlab.platypus.tables.Table
         self.inch = reportlab.lib.units.inch
         self.mm = reportlab.lib.units.mm
         self.pdfmetrics = reportlab.pdfbase.pdfmetrics
         self.TTFont = reportlab.pdfbase.ttfonts.TTFont
         self.LETTER = reportlab.lib.pagesizes.LETTER
         self.A4 = reportlab.lib.pagesizes.A4
         self.LEGAL = reportlab.lib.pagesizes.LEGAL
         self.ELEVENSEVENTEEN = reportlab.lib.pagesizes.ELEVENSEVENTEEN
         self.PageBreak = reportlab.platypus.PageBreak
         self.Paragraph = reportlab.platypus.Paragraph
         self.ListFlowable = reportlab.platypus.ListFlowable
         self.BaseDocTemplate = reportlab.platypus.BaseDocTemplate
         self.Frame = reportlab.platypus.Frame
         self.PageTemplate = reportlab.platypus.PageTemplate
         self.rlfonts = {}
         try:
             self.register_fonts()
         except Exception as exc:
             print('register fonts exception:', exc )
         reportlab.rl_config._SAVED['canvas_basefontname'] = 'Times-New-Roman'
         reportlab.rl_config._startUp()
         self.canv = self.Canvas( sys.stdout )
     #####################################
     def register_font_group( self, nick, font, ffn ):
         #*NB* all the nick, font etc etc is ignored
         from reportlab.pdfbase.ttfonts import TTFont
         from reportlab.pdfbase.pdfmetrics import registerFont, registerFontFamily
         for token, fn in (
                             ('Times-New-Roman','times.ttf'),
                             ('Times-New-Roman-bold','timesbd.ttf'),
                             ('Times-New-Roman-italic','timesi.ttf'),
                             ('Times-New-Roman-bolditalic','timesbi.ttf'),
                         ):
             ttf = TTFont(token,fn)
             registerFont(ttf)
             self.rlfonts[token] = ttf

         registerFontFamily('Times-New-Roman',
                             normal='Times-New-Roman',
                             bold='Times-New-Roman-bold',
                             italic='Times-New-Roman-italic',
                             boldItalic='Times-New-Roman-bolditalic')

     #####################################
     def register_fonts( self ):
         self.register_font_group('Times-New-Roman', 'Times-New-Roman', 'times')
     #####################################
     def get_registered_font_chars( self, nick ):
         all = set()
         ctg = self.rlfonts[ nick ].face.charToGlyph
         for ix in ctg:
             all.add( chr( ix ))
         return all
     #####################################
     def stringWidth( self, text, font, size ):
         # draw_text( pdf, font, size, 100, 100, text )
         return self.canv.stringWidth( text, font, size )
#####################################
myPDF = None
def myPDFinit():
     global myPDF
     if not myPDF:
         myPDF = PDFu()
myPDFinit()
myPDF.register_fonts()
print myPDF.canv._fontname
print myPDF.rlfonts.keys()
for txt in ('012', 'abc', 'ABC'):
     print('thiswid:', myPDF.rlfonts['Times-New-Roman'].stringWidth( txt,  20 ))
     print('thatwid:', myPDF.stringWidth( txt, 'Times-New-Roman', 20 ))

which changes the code that registers fonts to use the simpler technology. This 
works exactly as expected and produces

(glenn) C:\Users\rptlab\Downloads>python rl-test.py
Times-New-Roman
['Times-New-Roman', 'Times-New-Roman-bold', 'Times-New-Roman-italic', 
'Times-New-Roman-bolditalic']
('thiswid:', 30.0)
('thatwid:', 30.0)
('thiswid:', 27.75390625)
('thatwid:', 27.75390625)
('thiswid:', 41.123046875)
('thatwid:', 41.123046875)

something is amiss with your approach to font registration.
-- 
Robin Becker


More information about the reportlab-users mailing list