src/reportlab/graphics/renderPM.py
branchpy33
changeset 3721 0c93dd8ff567
parent 3617 ae5744e97c42
child 3723 99aa837b6703
equal deleted inserted replaced
3720:7a059dde5bf5 3721:0c93dd8ff567
    24 
    24 
    25 import string, os, sys
    25 import string, os, sys
    26 
    26 
    27 try:
    27 try:
    28     import _renderPM
    28     import _renderPM
    29 except ImportError, errMsg:
    29 except ImportError as errMsg:
    30     raise ImportError, "No module named _renderPM\n" + \
    30     raise ImportError("No module named _renderPM\n" + \
    31         (str(errMsg)!='No module named _renderPM' and "it may be the wrong version or badly installed!" or
    31         (str(errMsg)!='No module named _renderPM' and "it may be the wrong version or badly installed!" or
    32                                     "see https://www.reportlab.com/software/opensource/rl-addons/")
    32                                     "see https://www.reportlab.com/software/opensource/rl-addons/"))
    33 
    33 
    34 def _getImage():
    34 def _getImage():
    35     try:
    35     try:
    36         from PIL import Image
    36         from PIL import Image
    37     except ImportError:
    37     except ImportError:
   122     def drawLine(self, line):
   122     def drawLine(self, line):
   123         self._canvas.line(line.x1,line.y1,line.x2,line.y2)
   123         self._canvas.line(line.x1,line.y1,line.x2,line.y2)
   124 
   124 
   125     def drawImage(self, image):
   125     def drawImage(self, image):
   126         path = image.path
   126         path = image.path
   127         if isinstance(path,basestring):
   127         if isinstance(path,str):
   128             if not (path and os.path.isfile(path)): return
   128             if not (path and os.path.isfile(path)): return
   129             im = _getImage().open(path).convert('RGB')
   129             im = _getImage().open(path).convert('RGB')
   130         elif hasattr(path,'convert'):
   130         elif hasattr(path,'convert'):
   131             im = path.convert('RGB')
   131             im = path.convert('RGB')
   132         else:
   132         else:
   184                 elif text_anchor=='middle':
   184                 elif text_anchor=='middle':
   185                     x -= textLen/2
   185                     x -= textLen/2
   186                 elif text_anchor=='numeric':
   186                 elif text_anchor=='numeric':
   187                     x -= numericXShift(text_anchor,text,textLen,fontName,fontSize,stringObj.encoding)
   187                     x -= numericXShift(text_anchor,text,textLen,fontName,fontSize,stringObj.encoding)
   188                 else:
   188                 else:
   189                     raise ValueError, 'bad value for textAnchor '+str(text_anchor)
   189                     raise ValueError('bad value for textAnchor '+str(text_anchor))
   190             canv.drawString(x,y,text,_fontInfo=(fontName,fontSize))
   190             canv.drawString(x,y,text,_fontInfo=(fontName,fontSize))
   191 
   191 
   192     def drawPath(self, path):
   192     def drawPath(self, path):
   193         c = self._canvas
   193         c = self._canvas
   194         if path is EmptyClipPath:
   194         if path is EmptyClipPath:
   214             c.pathStroke()
   214             c.pathStroke()
   215 
   215 
   216 def _setFont(gs,fontName,fontSize):
   216 def _setFont(gs,fontName,fontSize):
   217     try:
   217     try:
   218         gs.setFont(fontName,fontSize)
   218         gs.setFont(fontName,fontSize)
   219     except _renderPM.Error, errMsg:
   219     except _renderPM.Error as errMsg:
   220         if errMsg.args[0]!="Can't find font!": raise
   220         if errMsg.args[0]!="Can't find font!": raise
   221         #here's where we try to add a font to the canvas
   221         #here's where we try to add a font to the canvas
   222         try:
   222         try:
   223             f = getFont(fontName)
   223             f = getFont(fontName)
   224             if _renderPM._version<='0.98':  #added reader arg in 0.99
   224             if _renderPM._version<='0.98':  #added reader arg in 0.99
   225                 _renderPM.makeT1Font(fontName,f.face.findT1File(),f.encoding.vector)
   225                 _renderPM.makeT1Font(fontName,f.face.findT1File(),f.encoding.vector)
   226             else:
   226             else:
   227                 _renderPM.makeT1Font(fontName,f.face.findT1File(),f.encoding.vector,open_and_read)
   227                 _renderPM.makeT1Font(fontName,f.face.findT1File(),f.encoding.vector,open_and_read)
   228         except:
   228         except:
   229             s1, s2 = map(str,sys.exc_info()[:2])
   229             s1, s2 = list(map(str,sys.exc_info()[:2]))
   230             raise RenderPMError, "Can't setFont(%s) missing the T1 files?\nOriginally %s: %s" % (fontName,s1,s2)
   230             raise RenderPMError("Can't setFont(%s) missing the T1 files?\nOriginally %s: %s" % (fontName,s1,s2))
   231         gs.setFont(fontName,fontSize)
   231         gs.setFont(fontName,fontSize)
   232 
   232 
   233 def _convert2pilp(im):
   233 def _convert2pilp(im):
   234     Image = _getImage()
   234     Image = _getImage()
   235     return im.convert("P", dither=Image.NONE, palette=Image.ADAPTIVE)
   235     return im.convert("P", dither=Image.NONE, palette=Image.ADAPTIVE)
   272         if bg is None: bg = self._bg
   272         if bg is None: bg = self._bg
   273         self._drawing.width, self._drawing.height = w, h
   273         self._drawing.width, self._drawing.height = w, h
   274         A = {'ctm':None, 'strokeWidth':None, 'strokeColor':None, 'lineCap':None, 'lineJoin':None, 'dashArray':None, 'fillColor':None}
   274         A = {'ctm':None, 'strokeWidth':None, 'strokeColor':None, 'lineCap':None, 'lineJoin':None, 'dashArray':None, 'fillColor':None}
   275         gs = self._gs
   275         gs = self._gs
   276         fN,fS = gs.fontName, gs.fontSize
   276         fN,fS = gs.fontName, gs.fontSize
   277         for k in A.keys():
   277         for k in list(A.keys()):
   278             A[k] = getattr(gs,k)
   278             A[k] = getattr(gs,k)
   279         del gs, self._gs
   279         del gs, self._gs
   280         gs = self.__dict__['_gs'] = _renderPM.gstate(w,h,bg=bg)
   280         gs = self.__dict__['_gs'] = _renderPM.gstate(w,h,bg=bg)
   281         for k in A.keys():
   281         for k in list(A.keys()):
   282             setattr(self,k,A[k])
   282             setattr(self,k,A[k])
   283         gs.setFont(fN,fS)
   283         gs.setFont(fN,fS)
   284 
   284 
   285     def toPIL(self):
   285     def toPIL(self):
   286         im = _getImage().new('RGB', size=(self._gs.width, self._gs.height))
   286         im = _getImage().new('RGB', size=(self._gs.width, self._gs.height))
   289 
   289 
   290     def saveToFile(self,fn,fmt=None):
   290     def saveToFile(self,fn,fmt=None):
   291         im = self.toPIL()
   291         im = self.toPIL()
   292         if fmt is None:
   292         if fmt is None:
   293             if type(fn) is not StringType:
   293             if type(fn) is not StringType:
   294                 raise ValueError, "Invalid type '%s' for fn when fmt is None" % type(fn)
   294                 raise ValueError("Invalid type '%s' for fn when fmt is None" % type(fn))
   295             fmt = os.path.splitext(fn)[1]
   295             fmt = os.path.splitext(fn)[1]
   296             if fmt.startswith('.'): fmt = fmt[1:]
   296             if fmt.startswith('.'): fmt = fmt[1:]
   297         configPIL = self.configPIL or {}
   297         configPIL = self.configPIL or {}
   298         configPIL.setdefault('preConvertCB',None)
   298         configPIL.setdefault('preConvertCB',None)
   299         preConvertCB=configPIL.pop('preConvertCB')
   299         preConvertCB=configPIL.pop('preConvertCB')
   326         elif fmt in ('JPG','JPEG'):
   326         elif fmt in ('JPG','JPEG'):
   327             fmt = 'JPEG'
   327             fmt = 'JPEG'
   328         elif fmt in ('GIF',):
   328         elif fmt in ('GIF',):
   329             pass
   329             pass
   330         else:
   330         else:
   331             raise RenderPMError,"Unknown image kind %s" % fmt
   331             raise RenderPMError("Unknown image kind %s" % fmt)
   332         if fmt=='TIFF':
   332         if fmt=='TIFF':
   333             tc = configPIL.get('transparent',None)
   333             tc = configPIL.get('transparent',None)
   334             if tc:
   334             if tc:
   335                 from PIL import ImageChops, Image
   335                 from PIL import ImageChops, Image
   336                 T = 768*[0]
   336                 T = 768*[0]
   487             gfont=getFont(gs.fontName)
   487             gfont=getFont(gs.fontName)
   488         except:
   488         except:
   489             gfont = None
   489             gfont = None
   490         font = getFont(fontName)
   490         font = getFont(fontName)
   491         if font._dynamicFont:
   491         if font._dynamicFont:
   492             if isinstance(text,unicode): text = text.encode('utf8')
   492             if isinstance(text,str): text = text.encode('utf8')
   493             gs.drawString(x,y,text)
   493             gs.drawString(x,y,text)
   494         else:
   494         else:
   495             fc = font
   495             fc = font
   496             if not isinstance(text,unicode):
   496             if not isinstance(text,str):
   497                 try:
   497                 try:
   498                     text = text.decode('utf8')
   498                     text = text.decode('utf8')
   499                 except UnicodeDecodeError,e:
   499                 except UnicodeDecodeError as e:
   500                     i,j = e.args[2:4]
   500                     i,j = e.args[2:4]
   501                     raise UnicodeDecodeError(*(e.args[:4]+('%s\n%s-->%s<--%s' % (e.args[4],text[i-10:i],text[i:j],text[j:j+10]),)))
   501                     raise UnicodeDecodeError(*(e.args[:4]+('%s\n%s-->%s<--%s' % (e.args[4],text[i-10:i],text[i:j],text[j:j+10]),)))
   502 
   502 
   503             FT = unicode2T1(text,[font]+font.substitutionFonts)
   503             FT = unicode2T1(text,[font]+font.substitutionFonts)
   504             n = len(FT)
   504             n = len(FT)
   505             nm1 = n-1
   505             nm1 = n-1
   506             wscale = 0.001*fontSize
   506             wscale = 0.001*fontSize
   507             for i in xrange(n):
   507             for i in range(n):
   508                 f, t = FT[i]
   508                 f, t = FT[i]
   509                 if f!=fc:
   509                 if f!=fc:
   510                     _setFont(gs,f.fontName,fontSize)
   510                     _setFont(gs,f.fontName,fontSize)
   511                     fc = f
   511                     fc = f
   512                 gs.drawString(x,y,t)
   512                 gs.drawString(x,y,t)
   513                 if i!=nm1:
   513                 if i!=nm1:
   514                     x += wscale*sum(map(f.widths.__getitem__,map(ord,t)))
   514                     x += wscale*sum(map(f.widths.__getitem__,list(map(ord,t))))
   515             if font!=fc:
   515             if font!=fc:
   516                 _setFont(gs,fontName,fontSize)
   516                 _setFont(gs,fontName,fontSize)
   517 
   517 
   518     def line(self,x1,y1,x2,y2):
   518     def line(self,x1,y1,x2,y2):
   519         if self.strokeColor is not None:
   519         if self.strokeColor is not None:
   726                     html.append('<img src="%s" border="1"><br>\n' % filename)
   726                     html.append('<img src="%s" border="1"><br>\n' % filename)
   727                 elif k=='py':
   727                 elif k=='py':
   728                     html.append('<a href="%s">python source</a><br>\n' % filename)
   728                     html.append('<a href="%s">python source</a><br>\n' % filename)
   729                 elif k=='svg':
   729                 elif k=='svg':
   730                     html.append('<a href="%s">SVG</a><br>\n' % filename)
   730                     html.append('<a href="%s">SVG</a><br>\n' % filename)
   731                 if verbose: print 'wrote',fullpath
   731                 if verbose: print('wrote',fullpath)
   732             except AttributeError:
   732             except AttributeError:
   733                 print 'Problem drawing %s file'%k
   733                 print('Problem drawing %s file'%k)
   734                 raise
   734                 raise
   735         if os.environ.get('RL_NOEPSPREVIEW','0')=='1': drawing.__dict__['preview'] = 0
   735         if os.environ.get('RL_NOEPSPREVIEW','0')=='1': drawing.__dict__['preview'] = 0
   736         drawing.save(formats=['eps','pdf'],outDir='pmout',fnRoot=fnRoot)
   736         drawing.save(formats=['eps','pdf'],outDir='pmout',fnRoot=fnRoot)
   737     html.append(htmlBottom)
   737     html.append(htmlBottom)
   738     htmlFileName = os.path.join('pmout', 'index.html')
   738     htmlFileName = os.path.join('pmout', 'index.html')
   739     open(htmlFileName, 'w').writelines(html)
   739     open(htmlFileName, 'w').writelines(html)
   740     if sys.platform=='mac':
   740     if sys.platform=='mac':
   741         from reportlab.lib.utils import markfilename
   741         from reportlab.lib.utils import markfilename
   742         markfilename(htmlFileName,ext='HTML')
   742         markfilename(htmlFileName,ext='HTML')
   743     if verbose: print 'wrote %s' % htmlFileName
   743     if verbose: print('wrote %s' % htmlFileName)
   744 
   744 
   745 if __name__=='__main__':
   745 if __name__=='__main__':
   746     test()
   746     test()