[reportlab-users] renderPM
Andrew Dalke
reportlab-users@reportlab.com
Fri, 17 Oct 2003 04:26:05 -0600
Hello,
Here's the summary version:
- there's a typo in the graphics documentation; saveToFile
should be drawToFile for the renderPM example
- here is a more complete description of a way to get missing
pfb files working for Mac OS X
- there's a bus error bug somewhere in renderPM that I'm unable
to track down
I am trying to get renderPM to work under Mac OS X with Python 2.3
but I am having/did have a few problems. I built it from a fresh copy
out of CVS on top of the latest standard distributions of PIL and
reportlab. Here's the driver code
=======
from reportlab.lib import colors
from reportlab.graphics.shapes import *
d = Drawing(400, 200)
d.add(Rect(50, 50, 300, 100, fillColor=colors.yellow))
d.add(String(150,100, 'Hello World',
fontSize=18, fillColor=colors.red))
from reportlab.graphics import renderPM
renderPM.drawToFile(d, 'example1.png', 'PNG')
=======
This comes right from the documentation for the graphics
library except that the documented method 'saveToFile'
should really be 'drawToFile'.
Here's what I get when I run it
=====
[Andrew-Dalkes-Computer:~/cvses/rl_addons/renderPM] dalke% python
example1.py
Warn: Can't find .pfb for face 'Times-Roman'
Traceback (most recent call last):
File "example1.py", line 12, in ?
renderPM.drawToFile(d, 'example1.png', 'PNG')
File
"/usr/local/lib/python2.3/site-packages/reportlab/graphics/
renderPM.py", line 521, in drawToFile
c = drawToPMCanvas(d, dpi=dpi, bg=bg, configPIL=configPIL,
showBoundary=showBoundary)
File
"/usr/local/lib/python2.3/site-packages/reportlab/graphics/
renderPM.py", line 507, in drawToPMCanvas
draw(d, c, 0, 0)
File
"/usr/local/lib/python2.3/site-packages/reportlab/graphics/
renderPM.py", line 51, in draw
R.draw(drawing, canvas, x, y)
File
"/usr/local/lib/python2.3/site-packages/reportlab/graphics/
renderPM.py", line 97, in draw
self.applyState()
File
"/usr/local/lib/python2.3/site-packages/reportlab/graphics/
renderPM.py", line 82, in applyState
self._canvas.setFont(s['fontName'], s['fontSize'])
File
"/usr/local/lib/python2.3/site-packages/reportlab/graphics/
renderPM.py", line 329, in setFont
_setFont(self._gs,fontName,fontSize)
File
"/usr/local/lib/python2.3/site-packages/reportlab/graphics/
renderPM.py", line 233, in _setFont
raise RenderPMError, "Can't setFont(%s) missing the T1
files?\nOriginally %s: %s" % (fontName,s1,s2)
reportlab.graphics.renderPM.RenderPMError: Can't setFont(Times-Roman)
missing the T1 files?
Originally exceptions.TypeError: makeT1Font() argument 2 must be
string, not None
=====
This has been reported before. The suggestion at
http://two.pairlist.net/pipermail/reportlab-users/2002-June/000072.html
is to
>get the pfb's for the standard things from www.adobe.com. When
>you get acrobat reader for windows it normally comes with a whole bunch
>of [.pfb] files.
I looked in my Mac Acrobat reader files but didn't those files
dalke% find ~/Desktop/Adobe\ Reader\ 6.0/ -name '*.pfb' -print
dalke%
I also looked on Adobe's site but failed miserably to find them.
Luckily, Leighton Pritchard reported a solution at
http://two.pairlist.net/pipermail/reportlab-users/2003-August/
001980.html
which was to download the files from
http://www.genesys.ro/download/Networking/Allied_Telesyn/Switchblade_1/
ACROBAT/RESOURCE/FONT/
I made it work by:
- making the directory "reportlab/fonts" (this is one of the paths
defined
in T1SearchPath from reportlab/rl_config.py)
- copy the files from that site, but make sure the filenames are in
lower case (needed because of a string.lower in
reportlab/pdfbase/pdfmetrics.py:TypeFace.findT1File )
I mention this here to suggest some documentation about this problem
(and hopefully a better source for those files) be included in
renderPM README, and so that people searching for a solution based
on the keywords I tried will find an answer in one single file.
The last thing to note is that the test_renderPM.py test code gives
dalke% python test_renderPM.py
Bus error
dalke%
It occurs in the setattr when a == 'fillColor'
for a in ('strokeColor','fillColor'):
try:
setattr(g,a,(1,2,3))
print 'Wrong handling of bad '+a
except ValueError:
pass
Here's the stack trace
Program received signal EXC_BAD_ACCESS, Could not access memory.
PyObject_GenericGetAttr (obj=0x515c88, name=0x510520) at
Objects/object.c:1399
1399 n = PyTuple_GET_SIZE(mro);
(gdb) where
#0 PyObject_GenericGetAttr (obj=0x515c88, name=0x510520) at
Objects/object.c:1399
#1 0x00035e4c in PyObject_HasAttrString (v=0x515c88, name=0xb2
<Address 0xb2 out of bounds>) at Objects/object.c:1182
#2 0x005894a4 in _set_gstateColor (value=0x515c88, c=0x99c1b8) at
_renderPM.c:866
#3 0x005876d4 in gstate_setattr (self=0x99c160, name=0x40ff84
"fillColor", value=0x515c88) at _renderPM.c:1006
#4 0x00034c50 in PyObject_SetAttr (v=0x99c160, name=0x40ff70,
value=0x515c88) at Objects/object.c:1294
#5 0x0009debc in builtin_setattr (self=0xe07ec, args=0xb1) at
Python/bltinmodule.c:913
#6 0x00086378 in call_function (pp_stack=0xbffff65c, oparg=177) at
Python/ceval.c:3439
#7 0x00083f50 in eval_frame (f=0x8eedd0) at Python/ceval.c:2116
#8 0x000865c8 in fast_function (func=0xe07ec, pp_stack=0xbffff7ec,
n=0, na=216420, nk=0) at Python/ceval.c:3518
#9 0x00086450 in call_function (pp_stack=0xbffff7ec, oparg=177) at
Python/ceval.c:3458
#10 0x00083f50 in eval_frame (f=0x43cdc0) at Python/ceval.c:2116
#11 0x00085268 in PyEval_EvalCodeEx (co=0x470ce0, globals=0xb1,
locals=0xb2, args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0,
defcount=0, closure=0x0) at Python/ceval.c:2663
#12 0x000880dc in PyEval_EvalCode (co=0xe07ec, globals=0xb1,
locals=0x48004444) at Python/ceval.c:537
#13 0x0000c78c in run_node (n=0x0, filename=0xb1 <Address 0xb1 out of
bounds>, globals=0x4019c0, locals=0x4019c0, flags=0x68220) at
Python/pythonrun.c:1205
#14 0x0000bf38 in PyRun_SimpleFileExFlags (fp=0xa0006b4c,
filename=0xbffffc22 "test_renderPM.py", closeit=4443916,
flags=0x470ce0) at Python/pythonrun.c:802
#15 0x00006498 in Py_Main (argc=-2013264827, argv=0xbffffb74) at
Modules/main.c:415
#16 0x00001eec in _start (argc=2, argv=0xbffffb74, envp=0xbffffb80) at
/SourceCache/Csu/Csu-45/crt.c:267
#17 0x00001d6c in start ()
More specifically, it's testing the tuple (1,2,3) to see if it has
the attribute named "red"
(gdb) up
(gdb) up
#2 0x005894a4 in _set_gstateColor (value=0x515c88, c=0x99c1b8) at
_renderPM.c:866
866 else if(PyObject_HasAttrString(value,"red")
(gdb) print *value
$3 = {
ob_refcnt = 1,
ob_type = 0xe57f4
}
(gdb) print *value->ob_type
$4 = {
ob_refcnt = 47,
ob_type = 0xe0ae4,
ob_size = 0,
tp_name = 0xd57ec "tuple",
tp_basicsize = 12,
tp_itemsize = 4,
tp_dealloc = 0x68dd8 <tupledealloc>,
tp_print = 0x68f48 <tupleprint>,
tp_getattr = 0,
tp_setattr = 0,
tp_compare = 0,
tp_repr = 0x69010 <tuplerepr>,
tp_as_number = 0x0,
tp_as_sequence = 0xe57a0,
tp_as_mapping = 0xe57e8,
tp_hash = 0x691d0 <tuplehash>,
tp_call = 0,
tp_str = 0,
tp_getattro = 0x34d64 <PyObject_GenericGetAttr>,
tp_setattro = 0,
tp_as_buffer = 0x0,
tp_flags = 17899,
tp_doc = 0xe5708 "tuple() -> an empty tuple\ntuple(sequence) -> tuple
initialized from sequence's items\n\nIf the argument is a tuple, the
return value is the same object.",
tp_traverse = 0x696c0 <tupletraverse>,
tp_clear = 0,
tp_richcompare = 0x69738 <tuplerichcompare>,
tp_weaklistoffset = 0,
tp_iter = 0x69d68 <tuple_iter>,
tp_iternext = 0,
tp_methods = 0xe57c8,
tp_members = 0x0,
tp_getset = 0x0,
tp_base = 0xe0bfc,
tp_dict = 0x9a1300,
tp_descr_get = 0,
tp_descr_set = 0,
tp_dictoffset = 0,
tp_init = 0,
tp_alloc = 0,
tp_new = 0x69964 <tuple_new>,
tp_free = 0x91094 <PyObject_GC_Del>,
tp_is_gc = 0,
tp_bases = 0x4236f0,
tp_mro = 0x0,
tp_cache = 0x0,
tp_subclasses = 0x0,
tp_weaklist = 0x0,
tp_del = 0
}
Looking at the code, I can't figure out what's wrong .... Ahh, there's
a CVS commit on 2003/08/15 from mwh "fix obscure crash in descriptor
handling" which looks like it fixes a reference count bug, and it's
in the right section of code. If there's an extra decref, that would
explain why the error occurs on the second time through the list.
However, rebuilding Python out of CVS doesn't remove the bus error.
I have very little experience with the Python/C API so this is as
far as I'll take it for now -- it only happens with a getattr
failure so shouldn't affect any of my production code.
Andrew
dalke@dalkescientific.com