[reportlab-users] TrueType Fonts

Uwe C. Schroeder reportlab-users@reportlab.com
Mon, 17 Mar 2003 09:02:36 -0800


--------------Boundary-00=_COKWUZ5P7VBCTK5M5ULL
Content-Type: text/plain;
  charset="iso-8859-2"
Content-Transfer-Encoding: 8bit

On Monday 17 March 2003 04:42 am, Marek Pêtlicki wrote:
> Dnia 2003-03-13 19:28, Jarek Zgoda napisa³:
> > Dnia Thu, Mar 13, 2003 at 05:27:37PM +0100, Marek Pêtlicki pisze:
> >>from reportlab.lib.fonts import addMapping
> >>from reportlab.pdfbase import pdfmetrics
> >>
> >># Adding TT font Arial + mappings
> >>pdfmetrics.registerFont(TTFont('Arial', 'arial.ttf'))
>
> [...]
>
> > Is there any reason, that you cann't register the font with some
> > other name?
>
> no reason at all, but it is only 5% of the problem - still remains the
> problem with automatic addMapping (called by pdfmetrics.registerFont()).
> So after I do:
>
> pdfmetrics.registerFont(TTFont('MyOwnArial', 'arial.ttf'))
> pdfmetrics.registerFont(TTFont('MyOwnArial-Bold', 'arialb.ttf'))
> pdfmetrics.registerFont(TTFont('MyOwnArial-BoldItalic', 'arialbi.ttf'))
> pdfmetrics.registerFont(TTFont('MyOwnArial-Italic', 'ariali.ttf'))
>
>
> I can't do:
>
> addMapping('MyOwnArial', 0, 0, 'MyOwnArial')
> addMapping('MyOwnArial', 1, 0, 'MyOwnArial-Bold')
> addMapping('MyOwnArial', 0, 1, 'MyOwnArial-Italic')
> addMapping('MyOwnArial', 1, 1, 'MyOwnArial-BoldItalic')
>
> because it already has mappings defined (automatically, with only the
> first file: 'arial.ttf', so the whole virtual font doesn't contain
> versions for bold, italics and so on), and so it throws me a ValueError.
>
>

Maybe this helps you. I wrote a little prog that loads fonts from a fonts.dir 
file as is usual for *nix X Servers. I don't know if you have access to a 
fonts.dir file, so here is an example of what it looks like:

--------------
BT-normal-r-normal-utf8-0-0-0-0-p-0-iso10646-1
arialbi.ttf -misc-Arial-bold-i-normal-utf8-0-0-0-0-p-0-iso10646-1
arialbd.ttf -misc-Arial-bold-r-normal-utf8-0-0-0-0-p-0-iso10646-1
ariali.ttf -misc-Arial-normal-i-normal-utf8-0-0-0-0-p-0-iso10646-1
arial.ttf -misc-Arial-normal-r-normal-utf8-0-0-0-0-p-0-iso10646-1
ariblk.ttf -misc-Arial Black-normal-r-normal-utf8-0-0-0-0-p-0-iso10646-1
Arialnb.ttf -misc-Arial Narrow-bold-r-condensed-utf8-0-0-0-0-p-0-iso10646-1
Arialnbi.ttf -misc-Arial Narrow-bold-i-condensed-utf8-0-0-0-0-p-0-iso10646-1
--------------

My script separates the lines by '-' and mapps the fonts.
I attach the relevant file, otherwise the levels of indentation might be gone.
BTW: this file is in OOpyRep (oopyrep.sf.net) which is a renderer for 
OpenOffice.org files (not ready yet, but works so far).


	UC

--
Open Source Solutions 4U, LLC	2570 Fleetwood Drive
Phone:  +1 650 872 2425		San Bruno, CA 94066
Cell:   +1 650 302 2405		United States
Fax:    +1 650 872 2417

--------------Boundary-00=_COKWUZ5P7VBCTK5M5ULL
Content-Type: text/x-python;
  charset="iso-8859-2";
  name="PrintEngine.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="PrintEngine.py"

#! /usr/bin/env python
#
# (c) Uwe C. Schroeder, OSS4U, LLC 2003
# All rights reserved.
#
# This code is distributed under the BSD license
#

import os, string,cPickle, sys
from Document import Document
from DocumentParser import DocumentParser
from reportlab.lib.fonts import addMapping, ps2tt, tt2ps
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

class PrintEngine:
    def __init__(self):
        pass

    def addMapping(self,ffam,bold,ital,fnam,font):
        from reportlab.pdfbase.pdfmetrics import _fonts
        try:
            _fonts[fnam]=font
            addMapping(ffam,bold,ital,fnam)
        except:
            traceback.print_exc()
            pass
        
    def LoadFonts(self,dir):
        f=open(dir+os.sep+'fonts.dir')
        fb=f.readlines()
        for line in fb[1:]:
            fnam,desc=string.split(line,None,1)
            ds=string.split(desc,'-')
            fn=ds[2]
            bold=ds[3]
            ital=ds[4]
            #print "Loaded Font:",fn,bold,ital
            if bold=='bold' and ital=='r':
                # just bold
                try:
                    font=TTFont(fn+'-Bold',dir+os.sep+fnam)
                except:
                    continue
                if font._multiByte:
                    self.addMapping(fn,1,0,fn+'-Bold',font)
                else:
                    pdfmetrics.registerFont(font)

            elif bold=='bold' and ital=='i':
                # bold italic
                try:
                    font=TTFont(fn+'-BoldItalic',dir+os.sep+fnam)
                except:
                    continue
                if font._multiByte:
                    self.addMapping(fn,1,1,fn+'-BoldItalic',font)
                else:
                    pdfmetrics.registerFont(font)

            elif bold=='normal' and ital=='i':
                try:
                    font=TTFont(fn+'-Italic',dir+os.sep+fnam)
                except:
                    continue
                if font._multiByte:
                    self.addMapping(fn,0,1,fn+'-Italic',font)
                else:
                    pdfmetrics.registerFont(font)
            else:
                try:
                    font=TTFont(fn,dir+os.sep+fnam)
                except:
                    continue
                if font._multiByte:
                    self.addMapping(fn,0,0,fn,font)
                else:
                    pdfmetrics.registerFont(font)

    def printDocument(self,doc,outfile=None,merge=False,canvas=None):
        return doc.Print(outfile,merge,canvas)

if __name__ == '__main__':
    pe=PrintEngine()
    pe.LoadFonts('../fonts')

    if 1:
        # this reads the given file
        dp=DocumentParser('t1.sxw')
        doc1=dp.getDocument()
        dp=DocumentParser('t4.sxw')
        doc2=dp.getDocument()
        #doc.Save('out.pickle')
    else:
        # this loads a pickled version
        # created with doc.Save()
        file1=open('out.pickle','rb')
        doc1=cPickle.load(file1)
        print "DOC1 loaded"
        file1.close()
        file2=open('out1.pickle','rb')
        doc2=cPickle.load(file2)
        print "DOC2 loaded"
        file2.close()

    # as you can see you can merge several documents into one
    print "Printing doc1"
    canvas=pe.printDocument(doc1,'out.pdf',merge=True)
    print "Printing doc2"
    pe.printDocument(doc2,'out.pdf',merge=False,canvas=canvas)
    

--------------Boundary-00=_COKWUZ5P7VBCTK5M5ULL--