[reportlab-users] Font Helvetica always used?

2,640 views
Skip to first unread message

EasyClassPage via reportlab-users

unread,
Jun 14, 2015, 3:50:31 AM6/14/15
to reportl...@lists2.reportlab.com, EasyClassPage
Hi all,

I'm using version 3.1 of the python library and have a question concerning the embedded fonts. I only use external (and free) fonts (eg. DejaVu) for my documents. These fonts are correctly embedded in the final document. But in the font list there is also a font type "Helvetica". I do not use such a font. Is this something internal? How to rid of this font?

Regards Klaus
_______________________________________________
reportlab-users mailing list
reportl...@lists2.reportlab.com
https://pairlist2.pair.net/mailman/listinfo/reportlab-users

Andy Robinson

unread,
Jun 14, 2015, 4:54:48 PM6/14/15
to reportlab-users
It's always declared as the default font when we make a new document -
the one that would be used if you just drew some text without changing
the font - but there is no font file embedded. Helvetica, Courier
and Times-Roman are always available on any Postscript printer or PDF
reader, so they don't need embedding. There is nothing to get rid
of, and no significant file size consumed by it.

Hope this helps,

Andy Robinson

On 14 June 2015 at 08:50, EasyClassPage via reportlab-users

Tim Roberts

unread,
Jun 15, 2015, 1:18:37 PM6/15/15
to reportlab-users
EasyClassPage via reportlab-users wrote:
> I'm using version 3.1 of the python library and have a question concerning the embedded fonts. I only use external (and free) fonts (eg. DejaVu) for my documents. These fonts are correctly embedded in the final document. But in the font list there is also a font type "Helvetica". I do not use such a font. Is this something internal? How to rid of this font?

Helvetica is the default font for PDF files. It, along with Times and
Courier, are part of the PostScript standard and are required to be
resident in all PostScript devices. The fact that it is named does not
necessarily mean it is being used.

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

ECP Admin via reportlab-users

unread,
Jun 16, 2015, 10:36:21 AM6/16/15
to reportlab-users, ECP Admin
Thanks for answering. Yes you are right, the 14 default fonts (including Helvetica) are always available in every PDF document. So what's the problem? I have created a PDF document with 3 external fonts. The result is a document that lists 3 embedded fonts and one (unused) internal font (Helvetica). I have send this document to a german online printing service (flyeralarm.de), but the data check complains
and the document was rejected. The reason: Only embedded font are allowed. Hmm ... perculiar, perhaps a gray area. In my case the Helvetica font isn't used, so it isn't necessary to include this font. A similar document without the Helvetica font is accepted. So my question is: Is there any chance that you only incorporate the really used fonts in the document header?

Regards Klaus


Glenn Linderman

unread,
Jun 16, 2015, 12:43:41 PM6/16/15
to reportl...@lists2.reportlab.com
On 6/16/2015 7:36 AM, ECP Admin via reportlab-users wrote:
Thanks for answering. Yes you are right, the 14 default fonts (including Helvetica) are always available in every PDF document. So what's the problem? I have created a PDF document with 3 external fonts. The result is a document that lists 3 embedded fonts and one (unused) internal font (Helvetica). I have send this document to a german online printing service (flyeralarm.de), but the data check complains
and the document was rejected. The reason: Only embedded font are allowed. Hmm ... perculiar, perhaps a gray area. In my case the Helvetica font isn't used, so it isn't necessary to include this font. A similar document without the Helvetica font is accepted. So my question is: Is there any chance that you only incorporate the really used fonts in the document header?

Regards Klaus

Sounds like the german online printing service data check is inappropriately rejecting the standard fonts that _all_ PDF viewers are required to support.

Is there any chance they could conform to the standard?

The 14 default fonts are _implicitly_ embedded, so should not be rejected by such a data checker.

Robin Becker

unread,
Jun 16, 2015, 12:51:55 PM6/16/15
to reportlab-users
On 16/06/2015 15:36, ECP Admin via reportlab-users wrote:
> Thanks for answering. Yes you are right, the 14 default fonts (including
> Helvetica) are always available in every PDF document. So what's the
> problem? I have created a PDF document with 3 external fonts. The result is
> a document that lists 3 embedded fonts and one (unused) internal font
> (Helvetica). I have send this document to a german online printing service (
> flyeralarm.de), but the data check complains
> and the document was rejected. The reason: Only embedded font are allowed.
> Hmm ... perculiar, perhaps a gray area. In my case the Helvetica font isn't
> used, so it isn't necessary to include this font. A similar document
> without the Helvetica font is accepted. So my question is: Is there any
> chance that you only incorporate the really used fonts in the document
> header?
>
> Regards Klaus
>
........
I've been looking at this issue from the other direction ie try to refer to a
truetype font without embedding. I suspect this might be easy to fix in both
cases. I will take a look at some simple cases tomorrow.
--
Robin Becker

Robin Becker

unread,
Jun 16, 2015, 12:54:20 PM6/16/15
to reportlab-users
On 16/06/2015 17:43, Glenn Linderman wrote:
.........
>
> Sounds like the german online printing service data check is inappropriately
> rejecting the standard fonts that _all_ PDF viewers are required to support.
>
> Is there any chance they could conform to the standard?
>
> The 14 default fonts are _implicitly_ embedded, so should not be rejected by
> such a data checker.
....
this might be a case of us referencing by default. I'm not sure that we need to.
These are marked as required resources, but in fact they may not be referenced.
Except by us using them as say the canvas default.
--
Robin Becker

Axel P. Kielhorn

unread,
Jun 16, 2015, 3:04:59 PM6/16/15
to reportl...@lists2.reportlab.com

> Am 16.06.2015 um 18:43 schrieb Glenn Linderman <v+py...@g.nevcal.com>:
>
> On 6/16/2015 7:36 AM, ECP Admin via reportlab-users wrote:
>> Thanks for answering. Yes you are right, the 14 default fonts (including Helvetica) are always available in every PDF document. So what's the problem? I have created a PDF document with 3 external fonts. The result is a document that lists 3 embedded fonts and one (unused) internal font (Helvetica). I have send this document to a german online printing service (flyeralarm.de), but the data check complains
>> and the document was rejected. The reason: Only embedded font are allowed. Hmm ... perculiar, perhaps a gray area. In my case the Helvetica font isn't used, so it isn't necessary to include this font. A similar document without the Helvetica font is accepted. So my question is: Is there any chance that you only incorporate the really used fonts in the document header?
>>
>> Regards Klaus
>
> Sounds like the german online printing service data check is inappropriately rejecting the standard fonts that _all_ PDF viewers are required to support.

They should support Helvetica, but which version?

Some year ago the Euro was introduced.
The Helvetica I have on my computer contains the Euro glyph.
The Helvetica in my printer does not.

Assuming that a font with the correct name is suitable to print the document is dangerous.

PDF/X (and PDF/A) requires all fonts to be embedded.

I can understand that the printer rejected the job.

Axel

Glenn Linderman

unread,
Jun 16, 2015, 5:23:02 PM6/16/15
to reportl...@lists2.reportlab.com
On 6/16/2015 12:04 PM, Axel P. Kielhorn wrote:

      
Am 16.06.2015 um 18:43 schrieb Glenn Linderman <v+py...@g.nevcal.com>:

On 6/16/2015 7:36 AM, ECP Admin via reportlab-users wrote:
Thanks for answering. Yes you are right, the 14 default fonts (including Helvetica) are always available in every PDF document. So what's the problem? I have created a PDF document with 3 external fonts. The result is a document that lists 3 embedded fonts and one (unused) internal font (Helvetica). I have send this document to a german online         printing service (flyeralarm.de), but the data check complains
and the document was rejected. The reason: Only embedded font are allowed. Hmm ... perculiar, perhaps a gray area. In my case the Helvetica font isn't used, so it isn't necessary to include this font. A similar document without the Helvetica font is accepted. So my question is: Is there any chance that you only incorporate the really used fonts in the document header?

Regards Klaus
Sounds like the german online printing service data check is inappropriately rejecting the standard fonts that _all_ PDF viewers are required to support.
They should support Helvetica, but which version?

The version assumed and documented by PDF....



Some year ago the Euro was introduced.
The Helvetica I have on my computer contains the Euro glyph.
The Helvetica in my printer does not.

...which wouldn't include Euro glyph, because it predates the Euro glyph...



Assuming that a font with the correct name is suitable to print the document is dangerous.

... but that does make for an interesting issue, too bad the PDF-defined names are so commonly used outside of PDF definitions...



PDF/X (and PDF/A) requires all fonts to be embedded.

I can understand that the printer rejected the job.

... so I guess I can understand it too, when you point out this issue... to pre-check that only characters defined in the PDF-defined font are used in the document would be much more complex than "all fonts must be embedded".

On the other hand, reportlab is fine for generating documents that are readable by most PDF viewers, and most computing devices have one, making such file nearly ubiquitously readable. But it doesn't have support for kerning or combining glyphs, both of which are required for quality typesetting results in various languages. I've expressed my sadness and dismay at these lacks in other threads. But I guess not every printed document is required to be high quality.

Axel

Robin Becker

unread,
Jun 17, 2015, 8:09:49 AM6/17/15
to reportlab-users
On 14/06/2015 08:50, EasyClassPage via reportlab-users wrote:
> Hi all,
>
> I'm using version 3.1 of the python library and have a question concerning the embedded fonts. I only use external (and free) fonts (eg. DejaVu) for my documents. These fonts are correctly embedded in the final document. But in the font list there is also a font type "Helvetica". I do not use such a font. Is this something internal? How to rid of this font?
>
> Regards Klaus
.....
Hi Klaus,

it seems there is no obvious way to ensure that Helvetica is not referenced, but
there is a tricky way.

Let's assume you want to use 'Arial' as your embedded font.

1) find a place to create a settings file. This can be

i: reportlab/rl_local_settings.py
ii: reportlab_settings.py somewhere on the PYTHONPATH.
iii: ~/.reportlab_settings.py for unix like systems.

2) put a module level definition in the file

canvas_basefontname = 'arial'

3) modify your startup script to add the following right at the top of module
level execution ie before importing any other bits of reportlab

from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import registerFont
registerFont(TTFont('arial','Arial.ttf'))

the statement in 2 declares the name of the font to be used by default. The
above statements ensure that the name is a registered font name.

Then run your script eg


from reportlab.pdfgen.canvas import Canvas
canv=Canvas('thello.pdf')
canv.drawString(72,72,'Hello World')
canv.save()


at canvas instantiation the default fontname is now 'arial' and not Helvetica.
The Helvetica font is not used and we won't see it in the output PDF.

It seems we used to inject the default fonts automatically, but now it seems as
though they are referenced if used and it seems we have to have an initial font.


If you don't want to mess with the settings overrides then this code at the
start of your initial script should do the trick

from reportlab import rl_config
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import registerFont
registerFont(TTFont('arial','Arial.ttf'))
rl_config._SAVED['canvas_basefontname'] = 'arial'
rl_config._startUp()
--
Robin Becker

Glenn Linderman

unread,
Jun 17, 2015, 3:55:48 PM6/17/15
to reportl...@lists2.reportlab.com
On 6/17/2015 5:09 AM, Robin Becker wrote:
If you don't want to mess with the settings overrides then this code at the start of your initial script should do the trick

from reportlab import rl_config
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import registerFont
registerFont(TTFont('arial','Arial.ttf'))
rl_config._SAVED['canvas_basefontname'] = 'arial'
rl_config._startUp()

So what is the real restriction?  This has to be done before what?  Before first canvas instantiation, or before other imports, or before what, specifically?

Andy Robinson

unread,
Jun 18, 2015, 2:14:04 AM6/18/15
to reportlab-users
On 17 June 2015 at 22:55, Glenn Linderman <v+py...@g.nevcal.com> wrote:
> So what is the real restriction? This has to be done before what? Before
> first canvas instantiation, or before other imports, or before what,
> specifically?

Before canvas instantiation.

The problem is that there is a "graphics state" vector we keep track
of, and it has to have a default font.

Being brutal, I believe the printer that rejected the font is in error
here, but if printers are going to do this, we should think about some
way to remove fonts not actually used. We'd have to make it an error
to call drawString(...) before you have explicitly set a font, or
allow a default font to be passed to canvas creation.

- Andy

Robin Becker

unread,
Jun 18, 2015, 8:08:32 AM6/18/15
to reportlab-users
On 17/06/2015 20:55, Glenn Linderman wrote:
> On 6/17/2015 5:09 AM, Robin Becker wrote:
>> If you don't want to mess with the settings overrides then this code at the
>> start of your initial script should do the trick
.........
>
> So what is the real restriction? This has to be done before what? Before first
> canvas instantiation, or before other imports, or before what, specifically?
.......
The Canvas class needs a default fontname at instantiation. It can be passed in,
but if the default None is present we use

reportlab.rl_config.canvas_basefontname

however, it's fairly obvious that we need to ensure the font exists at the time
of first use. With our existing simple rl_config module that's hard to do in one
place.

I did some experiments with the technique blessed by GvR here

http://stackoverflow.com/questions/2447353/getattr-on-a-module

and it seems if we adopted this technique we could then use a more simple
mechanism like this in our settings file overrides so in one of

>
> i: reportlab/rl_local_settings.py
> ii: reportlab_settings.py somewhere on the PYTHONPATH.
> iii: ~/.reportlab_settings.py for unix like systems.

you could do this

def canvas_basefontname():
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import registerFont, registerFontFamily
registerFont(TTFont('arial','arial.ttf'),)
registerFont(TTFont('arial-bold','arialbd.ttf'),)
registerFont(TTFont('arial-italic','ariali.ttf'),)
registerFont(TTFont('arial-bolditalic','arialbi.ttf'),)
registerFontFamily('arial',
normal='arial',
bold='arial-bold',
italic='arial-italic',
boldItalic='arial-bolditalic',
)
return 'arial'

and the rl_config object could check for and defer evaluation until the first
import/use of rl_config.canvas_basefontname. This avoids circular importing
which happens otherwise.

Glenn Linderman

unread,
Jun 18, 2015, 3:32:56 PM6/18/15
to reportl...@lists2.reportlab.com
On 6/18/2015 5:08 AM, Robin Becker wrote:
On 17/06/2015 20:55, Glenn Linderman wrote:
On 6/17/2015 5:09 AM, Robin Becker wrote:
If you don't want to mess with the settings overrides then this code at the
start of your initial script should do the trick
.........

So what is the real restriction?  This has to be done before what? Before first
canvas instantiation, or before other imports, or before what, specifically?
.......
The Canvas class needs a default fontname at instantiation. It can be passed in,

But do I understand correctly that simply providing the fontname='arial' parameter when instantiating the Canvas class could bypass all the settings weirdness, and/or the initial script hacks?

Except, in looking at Canvas, it doesn't seem to have a fontname parameter, nor a catchall keyword parameter.  So I don't understand your comment "It can be passed in"... is that just a possibility in a parallel universe?


I did some experiments with the technique blessed by GvR here

http://stackoverflow.com/questions/2447353/getattr-on-a-module

The technique you referenced is mind-blowing!


def canvas_basefontname():
    from reportlab.pdfbase.ttfonts import TTFont
    from reportlab.pdfbase.pdfmetrics import registerFont, registerFontFamily
    registerFont(TTFont('arial','arial.ttf'),)
    registerFont(TTFont('arial-bold','arialbd.ttf'),)
    registerFont(TTFont('arial-italic','ariali.ttf'),)
    registerFont(TTFont('arial-bolditalic','arialbi.ttf'),)
    registerFontFamily('arial',
            normal='arial',
            bold='arial-bold',
            italic='arial-italic',
            boldItalic='arial-bolditalic',
            )
    return 'arial'

but canvas.basefontname is a property or variable, not a function. Wouldn't this result in self._fontname being a reference to a function, instead of the string 'arial'? Or is that one of the side-effects of the __getattr__ stuff, that the function is called when the property is referenced? (maybe my mind didn't get blown far enough apart)


This avoids circular importing which happens otherwise.

I don't understand this comment.

Robin Becker

unread,
Jun 18, 2015, 4:00:03 PM6/18/15
to reportlab-users
On 18 June 2015 at 20:32, Glenn Linderman <v+py...@g.nevcal.com> wrote:
> On 6/18/2015 5:08 AM, Robin Becker wrote:
.......
> But do I understand correctly that simply providing the fontname='arial'
> parameter when instantiating the Canvas class could bypass all the settings
> weirdness, and/or the initial script hacks?
the token 'arial' is just a string. Support has to be provided by
registering the font (or by it being one of the standard 14).


>
> Except, in looking at Canvas, it doesn't seem to have a fontname parameter,
> nor a catchall keyword parameter. So I don't understand your comment "It
> can be passed in"... is that just a possibility in a parallel universe?
It can't be passed in directly, but can be via the default in
rl_config. Alternatively before a canvas is used you can call setFont
and that font will be the one used. However, unless it is one of the
standard 14 you still need to register a font before use.

>
> I did some experiments with the technique blessed by GvR here
>
> http://stackoverflow.com/questions/2447353/getattr-on-a-module
>
>
> The technique you referenced is mind-blowing!
>
> def canvas_basefontname():
> from reportlab.pdfbase.ttfonts import TTFont
> from reportlab.pdfbase.pdfmetrics import registerFont,
> registerFontFamily
> registerFont(TTFont('arial','arial.ttf'),)
> registerFont(TTFont('arial-bold','arialbd.ttf'),)
> registerFont(TTFont('arial-italic','ariali.ttf'),)
> registerFont(TTFont('arial-bolditalic','arialbi.ttf'),)
> registerFontFamily('arial',
> normal='arial',
> bold='arial-bold',
> italic='arial-italic',
> boldItalic='arial-bolditalic',
> )
> return 'arial'
>
the GvR technique effectively makes a module into a class instance so
that the module object can do all the standard getattr tricks etc etc.



> but canvas.basefontname is a property or variable, not a function. Wouldn't

well as we set it up we can check for callable things and hide them
away. That makes the attribute invisible and subject to __getattr__
magic. In the instance __getattr__ we can see all unknown. attributes.


> this result in self._fontname being a reference to a function, instead of
> the string 'arial'? Or is that one of the side-effects of the __getattr__
> stuff, that the function is called when the property is referenced? (maybe
> my mind didn't get blown far enough apart)

yes exactly; we can check in the __getattr__ for squirrelled away
callables and call them just once when first referenced. The returned
value can then be used from then on.
>
> This avoids circular importing which happens otherwise.
>
>
> I don't understand this comment.
>
>

the settings modules/files are used in defining rl_config; most of the
reportlab code will try to import rl_config so if a settings file
contains complex rl code then we have eg

canvas --> rl_config --> settings --> ttfont --> rl_config

Glenn Linderman

unread,
Jun 18, 2015, 6:50:35 PM6/18/15
to reportl...@lists2.reportlab.com
On 6/18/2015 12:59 PM, Robin Becker wrote:

Thanks for all the deleted stuff. Clear now.

Except, in looking at Canvas, it doesn't seem to have a fontname parameter,
> nor a catchall keyword parameter.  So I don't understand your comment "It
> can be passed in"... is that just a possibility in a parallel universe?
It can't be passed in directly, but can be via the default in
rl_config. Alternatively before a canvas is used you can call setFont
and that font will be the one used. However, unless it is one of the
standard 14 you still need to register a font before use.


So you are saying that if you call

from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import registerFont, registerFontFamily
registerFont(TTFont('arial','arial.ttf'),)
registerFont(TTFont('arial-bold','arialbd.ttf'),)
registerFont(TTFont('arial-italic','ariali.ttf'),)
registerFont(TTFont('arial-bolditalic','arialbi.ttf'),)
registerFontFamily('arial',
            normal='arial',
            bold='arial-bold',
            italic='arial-italic',
            boldItalic='arial-bolditalic',
            )
canv = reportlab.pdfgen.canvas.Canvas( sys.stdout )
canv.setFont('arial', 10 )

before doing any other Canvas operations, that 'Helvetica' will not appear in the output file?

That seems simpler than doing all the configuration stuff ahead of time... because the registration of fonts is often coded around the same time as the Canvas is initialized in setup code.

I suppose the reason you described the configuration tricks first, is that once created they minimize the code changes in all the applications using that configuration.

Robin Becker

unread,
Jun 19, 2015, 5:13:30 AM6/19/15
to reportlab-users
On 18/06/2015 23:50, Glenn Linderman wrote:
> On 6/18/2015 12:59 PM, Robin Becker wrote:
>
............
> from reportlab.pdfbase.ttfonts import TTFont
> from reportlab.pdfbase.pdfmetrics import registerFont, registerFontFamily
> registerFont(TTFont('arial','arial.ttf'),)
> registerFont(TTFont('arial-bold','arialbd.ttf'),)
> registerFont(TTFont('arial-italic','ariali.ttf'),)
> registerFont(TTFont('arial-bolditalic','arialbi.ttf'),)
> registerFontFamily('arial',
> normal='arial',
> bold='arial-bold',
> italic='arial-italic',
> boldItalic='arial-bolditalic',
> )
> canv = reportlab.pdfgen.canvas.Canvas( sys.stdout )
> canv.setFont('arial', 10 )
>
>
> before doing any other Canvas operations, that 'Helvetica' will not appear in
> the output file?
>
> That seems simpler than doing all the configuration stuff ahead of time...
> because the registration of fonts is often coded around the same time as the
> Canvas is initialized in setup code.
>
> I suppose the reason you described the configuration tricks first, is that once
> created they minimize the code changes in all the applications using that
> configuration.
.......
unfortunately not, it seems as though we are setting up the graphics state
before you can set the font, so it really needs to be in the config stuff. Even
though we never use the Helvetica font it still appears as a resource.

Probably it would be better to allow a canvas argument to be used to initialize
the graphics state. There are a lot of things in there, but the one that's
bothersome is the font.


> def init_graphics_state(self):
> #initial graphics state, never modify any of these in place
> self._x = 0
> self._y = 0
> self._fontname = rl_config.canvas_basefontname
> self._fontsize = 12
>
> self._textMode = 0 #track if between BT/ET
> self._leading = 14.4
> self._currentMatrix = (1., 0., 0., 1., 0., 0.)
> self._fillMode = 0 #even-odd
>
> #text state
> self._charSpace = 0
> self._wordSpace = 0
> self._horizScale = 100
> self._textRenderMode = 0
> self._rise = 0
> self._textLineMatrix = (1., 0., 0., 1., 0., 0.)
> self._textMatrix = (1., 0., 0., 1., 0., 0.)
>
> # line drawing
> self._lineCap = 0
> self._lineJoin = 0
> self._lineDash = None #not done
> self._lineWidth = 1
> self._mitreLimit = 0
>
> self._fillColorObj = self._strokeColorObj = rl_config.canvas_baseColor or (0,0,0)
> self._extgstate = ExtGState()

Andy Robinson

unread,
Jun 19, 2015, 5:16:23 AM6/19/15
to reportlab-users
If this is causing printers to complain about embedded fonts, then we
need some way around the problem.

I wonder if we could internally keep a little set or dictionary of
fonts that were actually used (by calls to setFont), then remove any
that are not at the end when writing the PDF? It would be a lot
simpler and would involve no API changes or weird setup incantations
for users.

- Andy

Robin Becker

unread,
Jun 19, 2015, 5:58:14 AM6/19/15
to reportlab-users
On 19/06/2015 10:16, Andy Robinson wrote:
> If this is causing printers to complain about embedded fonts, then we
> need some way around the problem.
>
> I wonder if we could internally keep a little set or dictionary of
> fonts that were actually used (by calls to setFont), then remove any
> that are not at the end when writing the PDF? It would be a lot
> simpler and would involve no API changes or weird setup incantations
> for users.
>
> - Andy
......
in fact it's not the setFont that does the deed it's _make_preamble which we use
to initialize stuff before anything has been done on a given page. PDF has
defaults built in so we have to have a font in case we don't use setFont.

We could of course delay setting any font until use in textobject, but I think
that would complicate things even further.

It would be easier just to make fontname, fontsize & leading available in Canvas
__init__. If we do that they should be obviously initialization values eg
initial_fontName,... so there's no confusion with the actual current attributes.
--
Robin Becker

Andy Robinson

unread,
Jun 19, 2015, 6:30:59 AM6/19/15
to reportlab-users
> It would be easier just to make fontname, fontsize & leading available in
> Canvas __init__. If we do that they should be obviously initialization
> values eg initial_fontName,... so there's no confusion with the actual
> current attributes.

If we did
initial_fontName = "MyFancyFont"
which is not one of the standard 14, then presumably we'd also need to
ensure they registered a font with that name? When would we complain
that "myfancyfont.ttf" had not been registered - on first use, or on
saving the canvas?

Robin Becker

unread,
Jun 19, 2015, 7:11:34 AM6/19/15
to reportlab-users
On 19/06/2015 11:30, Andy Robinson wrote:
........
> If we did
> initial_fontName = "MyFancyFont"
> which is not one of the standard 14, then presumably we'd also need to
> ensure they registered a font with that name? When would we complain
> that "myfancyfont.ttf" had not been registered - on first use, or on
> saving the canvas?
.......

any initialFontName would still need support and the error happens as soon as we
try to use it in _make_preamble.


Traceback (most recent call last):
File "C:\code\hg-repos\reportlab\tmp\thello.py", line 21, in <module>
canv = Canvas('thello.pdf',initialFontName='myfancyfont')
File "c:\code\reportlab\pdfgen\canvas.py", line 309, in __init__
self._make_preamble()
File "c:\code\reportlab\pdfgen\canvas.py", line 401, in _make_preamble
font = pdfmetrics.getFont(self._fontname)
File "c:\code\reportlab\pdfbase\pdfmetrics.py", line 673, in getFont
return findFontAndRegister(fontName)
File "c:\code\reportlab\pdfbase\pdfmetrics.py", line 655, in findFontAndRegister
face = getTypeFace(fontName)
File "c:\code\reportlab\pdfbase\pdfmetrics.py", line 612, in getTypeFace
return _typefaces[faceName]
KeyError: 'myfancyfont'


if I now run the modified Canvas with


from reportlab.pdfgen.canvas import Canvas
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import registerFont, registerFontFamily
registerFont(TTFont('arial','arial.ttf'),)
registerFont(TTFont('arial-bold','arialbd.ttf'),)
registerFont(TTFont('arial-italic','ariali.ttf'),)
registerFont(TTFont('arial-bolditalic','arialbi.ttf'),)
registerFontFamily('arial',
normal='arial',
bold='arial-bold',
italic='arial-italic',
boldItalic='arial-bolditalic',)
canv = Canvas('thello.pdf',initialFontName='arial')
canv.drawString(72,72,'Hello World')
canv.save()

then the output PDF doesn't contain 'Helvetica'.
--
Robin Becker

Andy Robinson

unread,
Jun 19, 2015, 7:17:24 AM6/19/15
to reportlab-users
OK, that looks like a reasonable way to go.

IN RML we can presumably do the rough equivalent ourselves with an
extra tag in <docinit>

- Andy

EasyClassPage via reportlab-users

unread,
Jun 20, 2015, 1:33:30 PM6/20/15
to Robin Becker, EasyClassPage, reportlab-users
Hi Robin,

thanks for finding and providing the workaround. This does the job for me:

...
# additional fonts
# ----------------
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.pdfmetrics import registerFont
registerFont(TTFont('DejaVuSans', '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'))
registerFont(TTFont('DejaVuSans-Bold', '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf'))
registerFont(TTFont('DejaVuSans-Oblique', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Oblique.ttf'))
registerFont(TTFont('DejaVuSans-BoldOblique', '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-BoldOblique.ttf'))

# workaround to supress unused default helvetica font (header)
# ------------------------------------------------------------
from reportlab import rl_config
rl_config._SAVED['canvas_basefontname'] = 'DejaVuSans'
rl_config._startUp()

# pdfgen modules
# --------------
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
...

Klaus
Reply all
Reply to author
Forward
0 new messages