[reportlab-users] Re: Verdana and TTF error

Henning von Bargen reportlab-users@reportlab.com
Sat, 8 May 2004 15:02:19 +0200


Ulrich, Andy and Dinu:

I finally found out how to use TrueType fonts in Platypus
with support for <b> and <i>.

This is how to do it:

1. Ensure that the _tt2psmap dict in reportlab/lib/fonts.py
contains only the standard fonts (remove verdana etc.).
It should look like this:
_tt2ps_map = {
            #face, bold, italic -> ps name
            ('times', 0, 0) :'Times-Roman',
            ('times', 1, 0) :'Times-Bold',
            ('times', 0, 1) :'Times-Italic',
            ('times', 1, 1) :'Times-BoldItalic',

            ('courier', 0, 0) :'Courier',
            ('courier', 1, 0) :'Courier-Bold',
            ('courier', 0, 1) :'Courier-Oblique',
            ('courier', 1, 1) :'Courier-BoldOblique',

            ('helvetica', 0, 0) :'Helvetica',
            ('helvetica', 1, 0) :'Helvetica-Bold',
            ('helvetica', 0, 1) :'Helvetica-Oblique',
            ('helvetica', 1, 1) :'Helvetica-BoldOblique',

            # there is only one Symbol font
            ('symbol', 0, 0) :'Symbol',

            # ditto for dingbats
            ('zapfdingbats', 0, 0) :'ZapfDingbats',
            }

2. Insert the following def into reportlab/lib/pdfmetrics.py
  (it is a copy of registerFont, but with the addMapping commands commented
out) :

def myRegisterFont(font):
    "Registers a font, including setting up info for accelerated
stringWidth"
    #assert isinstance(font, Font), 'Not a Font: %s' % font
    fontName = font.fontName
    _fonts[fontName] = font
    if font._multiByte:
        # CID fonts don't need to have typeface registered.
        #need to set mappings so it can go in a paragraph even if within
        # bold tags
        from reportlab.lib import fonts
        ttname = string.lower(font.fontName)
        #fonts.addMapping(ttname, 0, 0, font.fontName)
        #fonts.addMapping(ttname, 1, 0, font.fontName)
        #fonts.addMapping(ttname, 0, 1, font.fontName)
        #fonts.addMapping(ttname, 1, 1, font.fontName)
        #cannot accelerate these yet...
    else:
        if _stringWidth:
            _rl_accel.setFontInfo(string.lower(fontName),
                                  _dummyEncoding,
                                  font.face.ascent,
                                  font.face.descent,
                                  font.widths)

3. The following script show how to use it:

---------------------------------------------------------------------
#copyright ReportLab Inc. 2000-2001
#see license.txt for license details
"""Tests for the reportlab.platypus.paragraphs module.
"""

import sys, os, tempfile
from string import split, strip, join, whitespace
from operator import truth
from types import StringType, ListType

from reportlab.test import unittest
from reportlab.test.utils import makeSuiteForClasses

from reportlab.pdfbase.pdfmetrics import
stringWidth,registerFont,myRegisterFont
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.fonts import addMapping

from reportlab.lib.colors import Color
from reportlab.lib.units import cm
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.lib.utils import _className
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus.paragraph import Paragraph
from reportlab.platypus.frames import Frame
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from reportlab.platypus.paragraph import *


def myMainPageFrame(canvas, doc):
    "The page frame used for all PDF documents."

    canvas.saveState()

    canvas.rect(2.5*cm, 2.5*cm, 15*cm, 25*cm)
    canvas.setFont('Times-Roman', 12)
    pageNumber = canvas.getPageNumber()
    canvas.drawString(10*cm, cm, str(pageNumber))

    canvas.restoreState()


class MyDocTemplate(BaseDocTemplate):
    _invalidInitArgs = ('pageTemplates',)

    def __init__(self, filename, **kw):
        frame1 = Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')
        self.allowSplitting = 0
        apply(BaseDocTemplate.__init__, (self, filename), kw)
        template = PageTemplate('normal', [frame1], myMainPageFrame)
        self.addPageTemplates(template)

class TTFTestCase(unittest.TestCase):
    "Test TrueType Fonts in paragraphs."


    def test0(self):
        "Test using TTF in paragraph font markup."

        story = []
        styleSheet = getSampleStyleSheet()
        bt = styleSheet['BodyText']
        fonts = ["Helvetica",
                 "Courier",
                 "Verdana",
                 "Comic",
                ]
        text = '<para>%s : <font face="%s">plain, <b>bold,</b> <i>italic</i>
and <b><i>BoldItalic</b></i></font></para>'

        myRegisterFont(TTFont("Verdana", "verdana.ttf"))
        myRegisterFont(TTFont("Verdana-Bold", "verdanab.ttf"))
        myRegisterFont(TTFont("Verdana-Italic", "verdanai.ttf"))
        myRegisterFont(TTFont("Verdana-BoldItalic", "verdanaz.ttf"))
        addMapping('verdana',0,0,'Verdana')
        addMapping('verdana',1,0,'Verdana-Bold')
        addMapping('verdana',0,1,'Verdana-Italic')
        addMapping('verdana',1,1,'Verdana-BoldItalic')

        myRegisterFont(TTFont("Comic", "comic.ttf"))
        myRegisterFont(TTFont("Comic-Bold", "comicbd.ttf"))
        addMapping('comic',0,0,'Comic')
        addMapping('comic',1,0,'Comic-Bold')
        addMapping('comic',0,1,'Comic')
        addMapping('comic',1,1,'Comic-Bold')

        story.append (Paragraph("Note: The Comic TrueType font does not
support italics.", bt))
        for fontName in fonts:
            story.append(Paragraph(text % (fontName,fontName), bt))

        doc = MyDocTemplate('test_platypus_paragraphs_ttf.pdf')
        doc.build(story)

#noruntests
def makeSuite():
    return makeSuiteForClasses(TTFTestCase)


#noruntests
if __name__ == "__main__":
    unittest.TextTestRunner().run(makeSuite())

---------------------------------------------------------------------

4. See the output generated in test_platypus_paragraphs_ttf.pdf

However, I think some refactoring would be useful (perhaps Marius or Andy
could do it)?
I think it could all be combined into ONE routine
registerTTFont (basename, ttf_fname_plain, ttf_fname_bold=None,
ttf_fname_italic=None, ttf_fname_bolditalic=None)

Usually, there's one TTF file for each style (see the verdana font in the
example),
but other fonts do not support italic (see the comic font in the example),
so the last 2 arguments would be ommitted.

HTH

Henning

> -----Ursprüngliche Nachricht-----
> Von:	reportlab-users-request@reportlab.com
[SMTP:reportlab-users-request@reportlab.com]
> Gesendet am:	Samstag, 8. Mai 2004 08:07
> An:	reportlab-users@reportlab.com
> Betreff:	reportlab-users digest, Vol 2 #105 - 3 msgs
> 
> Send reportlab-users mailing list submissions to
> 	reportlab-users@reportlab.com
> 
> To subscribe or unsubscribe via the World Wide Web, visit
> 	http://two.pairlist.net/mailman/listinfo/reportlab-users
> or, via email, send a message with subject or body 'help' to
> 	reportlab-users-request@reportlab.com
> 
> You can reach the person managing the list at
> 	reportlab-users-admin@reportlab.com
> 
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of reportlab-users digest..."
> 
> 
> Today's Topics:
> 
>    1. Re: Verdana and TTF error (Ulrich Wisser)
>    2. Prinston downloads (Andy Robinson)
>    3. Re: Verdana and TTF error (Robin Becker)
> 
> --__--__--
> 
> Message: 1
> Date: Fri, 07 May 2004 08:35:54 +0200
> From: Ulrich Wisser <ulrich.wisser@relevanttraffic.se>
> Organization: Relevant Traffic AB
> To: reportlab-users@reportlab.com
> Subject: Re: [reportlab-users] Verdana and TTF error
> Reply-To: reportlab-users@reportlab.com
> 
> Hello,
> 
> thanks for all the help. I have been able to use the Verdana font.
> Nevertheless I would like to tell you about my struggles, as it seems 
> that some thing is not going as expected.
> 
> The trick to register the font as XVerdana
>  >>     pdfmetrics.registerFont(TTFont('XVerdana', 'VERDANA.TTF'))
> did not work. It still complained about already registered mappings.
> 
> I had to remove the verdana data in
> 	reportlab/lib/fonts.py
> 
> When I registered Verdana, it would not let me alter the bold mapping. I 
> reviewed the code and did recognize that registerFont maps the font for 
> all mappings directly. The mapping can not be changed later. But this 
> won't give me bold text when I used <b> markup in my paragraph objects.
> 
> For me it was easy to solve, I had only none bold or all bold paragraphs 
> which I assigned Verdana or Verdana-Bold as font.
> 
> How should I procede to get the <b> markup working?
> 
> Thanks
> 
> Ulrich
> 
> 
> --__--__--
> 
> Message: 2
> From: "Andy Robinson" <andy@reportlab.com>
> To: <JEYANANDAN KUMAR [jayaa@hotmail.com]@two.pairlist.net>
> Cc: "Reportlab-Users@Reportlab. Com" <reportlab-users@reportlab.com>
> Date: Fri, 7 May 2004 09:44:57 +0100
> Subject: [reportlab-users] Prinston downloads
> Reply-To: reportlab-users@reportlab.com
> 
> > Sir,
> > i would like to download a file from 
> > http://www.reportlab.org/community/prinston/MSN-Part_1.zip
> > for which i need to register i suppose for username and password how to 
> > approch.
> > thank you.
> 
> I am sorry to tell you this will not be allowed.
> 
> The prinston company deliberately abused a download area aimed
> only for software developers in our user group who are making 
> programs with our own software package.  They put huge files 
> there without telling us and thousands of people started downloading 
> them, which would have cost us thousands of dollars per month
> in bandwidth fees.  So, we stopped this and deleted all the files.  
> 
> If you have a contact in this company, let me know, so we can 
> tell them how angry we are!  In the meantime prinston will have to
> set up and pay for their own download facilities somewhere else.
> 
> I am sorry if you are inconvenienced by this but they have
> behaved very badly both towards us and their own customers.
> 
> Best Regards,
> 
> Andy Robinson
> CEO/Chief Architect
> ReportLab Europe Ltd.
> 
> 
> 
> 
> --__--__--
> 
> Message: 3
> Date: Fri, 07 May 2004 10:48:48 +0100
> From: Robin Becker <robin@reportlab.com>
> To: reportlab-users@reportlab.com
> Subject: Re: [reportlab-users] Verdana and TTF error
> Reply-To: reportlab-users@reportlab.com
> 
> Ulrich Wisser wrote:
> 
> ......
> > 
> > How should I procede to get the <b> markup working?
> > 
> > Thanks
> > 
> > Ulrich
> ......
> 
> The stuff in reportlab/lib/fonts.py is exactly that which is needed to do
the 
> transitions.
> 
> So in the _tt2ps map we need something like
> 
> ('verdana', 0, 0) :'Verdana',
> ('verdana', 1, 0) :'Verdana-Bold',
> ('verdana', 0, 1) :'Verdana-Oblique',
> ('verdana', 1, 1) :'Verdana-BoldOblique',
> 
> 
> so we need to register the verdana fonts with the right names
> 
> pdfmetrics.registerFont(TTFont('Verdana', 'VERDANA.TTF'))
> pdfmetrics.registerFont(TTFont('Verdana-Bold', 'VERDANAB.TTF'))
> pdfmetrics.registerFont(TTFont('Verdana-Italic', 'VERDANAI.TTF'))
> pdfmetrics.registerFont(TTFont('Verdana-BoldItalic', 'VERDANAZ.TTF'))
> 
> then use addmapping from reportlab.lib.fonts
> 
> addMapping('verdana',0,0,'Verdana')
> addMapping('verdana',1,0,'Verdana-Bold')
> addMapping('verdana',0,1,'Verdana-Italic')
> addMapping('verdana',1,1,'Verdana-BoldItalic')
> 
> This is probably not exactly right either as we attempt to calculate the
inverse 
> mappings from the same information.
> -- 
> Robin Becker
> 
> 
> --__--__--
> 
> _______________________________________________
> reportlab-users mailing list
> reportlab-users@reportlab.com
> http://two.pairlist.net/mailman/listinfo/reportlab-users
> 
> 
> End of reportlab-users Digest