[reportlab-users] PDFMetrics.RegisterFont should walk into subdirectories

Robin Becker robin at reportlab.com
Tue Nov 24 11:23:47 EST 2009

Hosam Aly wrote:

> Hello,


> I am having a small problem with

> `reportlab.pdfbase.pdfmetrics.registerFont`. This method currently looks

> for fonts in the directories specified in `rl_config.TTFSearchPath`, but

> does not descend into subdirectories. This is problematic, because in

> Ubuntu 9.04 and 9.10 true type font files are in subdirectories of

> '/usr/share/fonts', and thus `registerFont` does not find them.


> I think `registerFont` should `os.walk` each of the directories in

> `rl_config.TTFSearchPath`.




well the patch below will make all of the search paths recur. It's done at
startup so it's not as dynamic as it could be. A similar approach could be
applied just to the ttfonts filename search; perhaps we should consider
recurring only if the top level search is about to fail; that would entail a
breadth first recursion in the TTFont creation

I am not convinced automatic recursion is the right way to do this. Python wants
us to be specific and avoid magic. When I use recursion on my TTFSearchPath I
get more .svn folders than anything else. There are also dangers in following
links around ie loops etc etc.

We do have a mechanism for configuring the individual values in rl_config. Just
place a module called local_rl_config beside it. On a linux system it can't be
too hard to work out which folders are to be used using a find command or
similar and place the definitions into that module.

--- rl_config.py (revision 3600)
+++ rl_config.py (working copy)
@@ -172,7 +172,7 @@
global sys_version, _unset_
sys_version = sys.version.split()[0] #strip off the other garbage
from reportlab.lib import pagesizes
- from reportlab.lib.utils import rl_isdir
+ from reportlab.lib.utils import rl_isdir, rl_listdir

if _SAVED=={}:
_unset_ = getattr(sys,'_rl_config__unset_',None)
@@ -190,13 +190,6 @@
'sys_version': sys_version,

- for name in ('T1SearchPath','TTFSearchPath','CMapSearchPath'):
- P=[]
- for p in _SAVED[name]:
- d = (p % D).replace('/',os.sep)
- if rl_isdir(d): P.append(d)
- _setOpt(name,P)
for k in V[3:]:
v = _SAVED[k]
if isinstance(v,(int,float)): conv = type(v)
@@ -204,6 +197,18 @@
else: conv = None

+ def w(d,P):
+ if rl_isdir(d):
+ P(d)
+ for sd in rl_listdir(d):
+ w(os.path.join(d,sd),P)
+ for name in ('T1SearchPath','TTFSearchPath','CMapSearchPath'):
+ P=[].append
+ for p in _SAVED[name]:
+ w((p % D).replace('/',os.sep),P)
+ _setOpt(name,P.__self__)
def register_reset(func):
_registered_resets[:] = [x for x in _registered_resets if x()]

Robin Becker

More information about the reportlab-users mailing list