improved support for images in renderPM/renderSVG bug report from Claude Paroz; version --> 3.3.26
--- a/setup.py Fri Dec 23 15:17:18 2016 +0000
+++ b/setup.py Tue Jan 03 14:08:34 2017 +0000
@@ -1,6 +1,6 @@
#Copyright ReportLab Europe Ltd. 2000-2012
#see license.txt for license details
-__version__='3.3.0'
+__version__='3.3.26'
import os, sys, glob, shutil
def specialOption(n):
v = False
--- a/src/reportlab/__init__.py Fri Dec 23 15:17:18 2016 +0000
+++ b/src/reportlab/__init__.py Tue Jan 03 14:08:34 2017 +0000
@@ -1,9 +1,9 @@
-#Copyright ReportLab Europe Ltd. 2000-2016
+#Copyright ReportLab Europe Ltd. 2000-2017
#see license.txt for license details
__doc__="""The Reportlab PDF generation library."""
-Version = "3.3.25"
+Version = "3.3.26"
__version__=Version
-__date__='20161223'
+__date__='20170103'
import sys, os
--- a/src/reportlab/graphics/renderSVG.py Fri Dec 23 15:17:18 2016 +0000
+++ b/src/reportlab/graphics/renderSVG.py Tue Jan 03 14:08:34 2017 +0000
@@ -7,13 +7,13 @@
http://python.net/~gherman/#svglib
"""
-import math, types, sys, os, codecs
+import math, types, sys, os, codecs, base64
from operator import getitem
from reportlab.pdfbase.pdfmetrics import stringWidth # for font info
from reportlab.lib.rl_accel import fp_str
from reportlab.lib.colors import black
-from reportlab.lib.utils import asNative
+from reportlab.lib.utils import asNative, getBytesIO
from reportlab.graphics.renderbase import StateTracker, getStateDelta, Renderer, renderScaledDrawing
from reportlab.graphics.shapes import STATE_DEFAULTS, Path, UserNode
from reportlab.graphics.shapes import * # (only for test0)
@@ -483,8 +483,16 @@
comment = self.doc.createComment(data)
# self.currGroup.appendChild(comment)
- def drawImage(self, image, x1, y1, x2=None, y2=None):
- pass
+ def drawImage(self, image, x, y, width, height, embed=True):
+ buf = getBytesIO()
+ image.save(buf,'png')
+ buf = asNative(base64.b64encode(buf.getvalue()))
+ self.currGroup.appendChild(
+ transformNode(self.doc,'image',
+ x=x,y=y,width=width,height=height,
+ href="data:image/png;base64,"+buf,
+ )
+ )
def line(self, x1, y1, x2, y2):
if self._strokeColor != None:
@@ -850,6 +858,21 @@
link_info = None
c._fillAndStroke([], clip=path.isClipPath, link_info=link_info)
+ def drawImage(self, image):
+ path = image.path
+ if isinstance(path,str):
+ if not (path and os.path.isfile(path)): return
+ im = _getImage().open(path)
+ elif hasattr(path,'convert'):
+ im = path
+ else:
+ return
+ srcW, srcH = im.size
+ dstW, dstH = image.width, image.height
+ if dstW is None: dstW = srcW
+ if dstH is None: dstH = srcH
+ self._canvas.drawImage(im, image.x, image.y, dstW, dstH, embed=True)
+
def applyStateChanges(self, delta, newState):
"""This takes a set of states, and outputs the operators
needed to set those properties"""
--- a/src/reportlab/graphics/renderbase.py Fri Dec 23 15:17:18 2016 +0000
+++ b/src/reportlab/graphics/renderbase.py Tue Jan 03 14:08:34 2017 +0000
@@ -354,6 +354,9 @@
needed to set those properties"""
self.undefined("applyStateChanges")
+ def drawImage(self,*args,**kwds):
+ raise NotImplementedError('drawImage')
+
if __name__=='__main__':
print("this file has no script interpretation")
print(__doc__)
--- a/src/reportlab/graphics/testshapes.py Fri Dec 23 15:17:18 2016 +0000
+++ b/src/reportlab/graphics/testshapes.py Tue Jan 03 14:08:34 2017 +0000
@@ -15,7 +15,7 @@
Feel free to add more.
'''
-import os, sys
+import os, sys, base64
from reportlab.lib import colors
from reportlab.lib.units import cm
@@ -452,30 +452,25 @@
if maxx>400 or maxy>200: _,_,D = drawit(_FONTS,maxx,maxy)
return D
-##def getDrawing14():
-## """This tests inherited properties. Each font should be as it says."""
-## D = Drawing(400, 200)
-##
-## fontSize = 12
-## D.fontName = 'Courier'
-##
-## g1 = Group(
-## Rect(0, 0, 150, 20, fillColor=colors.yellow),
-## String(5, 5, 'Inherited Courier', fontName=inherit, fontSize = fontSize)
-## )
-## D.add(g1)
-##
-## g2 = Group(g1, transform = translate(25,25))
-## D.add(g2)
-##
-## g3 = Group(g2, transform = translate(25,25))
-## D.add(g3)
-##
-## g4 = Group(g3, transform = translate(25,25))
-## D.add(g4)
-##
-##
-## return D
+def smallArrow():
+ '''create a small PIL image'''
+ from reportlab.graphics.renderPM import _getImage
+ from reportlab.lib.utils import getBytesIO
+ b = base64.decodestring(b'''R0lGODdhCgAHAIMAAP/////29v/d3f+ysv9/f/9VVf9MTP8iIv8ICP8AAAAAAAAAAAAAAAAAAAAA
+AAAAACwAAAAACgAHAAAIMwABCBxIsKABAQASFli4MAECAgEAJJhIceKBAQkyasx4YECBjx8TICAQ
+AIDJkwYEAFgZEAA7''')
+ return _getImage().open(getBytesIO(b))
+
+def getDrawing14():
+ '''test shapes.Image'''
+ from reportlab.graphics.shapes import Image
+ D = Drawing(400, 200)
+ im0 = smallArrow()
+ D.add(Image(x=0,y=0,width=None,height=None,path=im0))
+ im1 = smallArrow()
+ D.add(Image(x=400-20,y=200-14,width=20,height=14,path=im1))
+ return D
+
def getAllFunctionDrawingNames(doTTF=1):
"Get a list of drawing function names from somewhere."
--- a/src/rl_addons/renderPM/_renderPM.c Fri Dec 23 15:17:18 2016 +0000
+++ b/src/rl_addons/renderPM/_renderPM.c Tue Jan 03 14:08:34 2017 +0000
@@ -18,7 +18,7 @@
#endif
-#define VERSION "2.01"
+#define VERSION "2.02"
#define MODULENAME "_renderPM"
#ifdef isPy3
# define PyInt_FromLong PyLong_FromLong
@@ -1267,9 +1267,14 @@
ArtPixBuf src;
src.n_channels = 3;
+#ifdef isPy3
+ #define AAPIXBUFFMT "ddddy#ii|i:_aapixbuf"
+#else
+ #define AAPIXBUFFMT "ddddt#ii|i:_aapixbuf"
+#endif
/*(dstX,dstY,dstW,dstH,src,srcW,srcH[,srcD[,aff]])*/
- if(!PyArg_ParseTuple(args,"ddddt#ii|i:_aapixbuf",
+ if(!PyArg_ParseTuple(args,AAPIXBUFFMT,
&dstX, &dstY, &dstW, &dstH,
&src.pixels,&srclen,&src.width,&src.height,&src.n_channels)) return NULL;
ctm[0] = dstW/src.width;