src/reportlab/graphics/renderSVG.py
branchpy33
changeset 3765 a7e7cd6e0003
parent 3723 99aa837b6703
child 3781 df8b57380768
equal deleted inserted replaced
3764:010823faf496 3765:a7e7cd6e0003
    15 from reportlab.lib.colors import black
    15 from reportlab.lib.colors import black
    16 from reportlab.graphics.renderbase import StateTracker, getStateDelta, Renderer, renderScaledDrawing
    16 from reportlab.graphics.renderbase import StateTracker, getStateDelta, Renderer, renderScaledDrawing
    17 from reportlab.graphics.shapes import STATE_DEFAULTS, Path, UserNode
    17 from reportlab.graphics.shapes import STATE_DEFAULTS, Path, UserNode
    18 from reportlab.graphics.shapes import * # (only for test0)
    18 from reportlab.graphics.shapes import * # (only for test0)
    19 from reportlab import rl_config
    19 from reportlab import rl_config
    20 from reportlab.lib.utils import getBytesIO, RLString
    20 from reportlab.lib.utils import getBytesIO, RLString, isPy3
    21 
    21 
    22 from xml.dom import getDOMImplementation
    22 from xml.dom import getDOMImplementation
    23 
    23 
    24 ### some constants ###
    24 ### some constants ###
    25 
    25 
    94     return newNode
    94     return newNode
    95 
    95 
    96 class EncodedWriter(list):
    96 class EncodedWriter(list):
    97     '''
    97     '''
    98     EncodedWriter(encoding) assumes .write will be called with
    98     EncodedWriter(encoding) assumes .write will be called with
    99     either unicode or utf8 encoded strings.  it will accumulate
    99     either trnicode or utf8 encoded bytes. it will accumulate
   100     strings encoded as the specified encoding.
   100     unicode
   101     '''
   101     '''
   102     BOMS =  {
   102     BOMS =  {
   103         'utf-32':codecs.BOM_UTF32,
   103         'utf-32':codecs.BOM_UTF32,
   104         'utf-32-be':codecs.BOM_UTF32_BE,
   104         'utf-32-be':codecs.BOM_UTF32_BE,
   105         'utf-32-le':codecs.BOM_UTF32_LE,
   105         'utf-32-le':codecs.BOM_UTF32_LE,
   111         list.__init__(self)
   111         list.__init__(self)
   112         self.encoding = encoding = codecs.lookup(encoding).name
   112         self.encoding = encoding = codecs.lookup(encoding).name
   113         if bom and '16' in encoding or '32' in encoding:
   113         if bom and '16' in encoding or '32' in encoding:
   114             self.write(self.BOMS[encoding])
   114             self.write(self.BOMS[encoding])
   115 
   115 
   116     def write(self,s):
   116     def write(self,u):
   117         if isinstance(s,str):
   117         if isinstance(u,bytes):
   118             s = s.encode(self.encoding)
       
   119         elif isinstance(s,str):
       
   120             try:
   118             try:
   121                  u = s.decode('utf-8')
   119                  u = u.decode('utf-8')
   122             except:
   120             except:
   123                 et, ev, tb = sys.exc_info()
   121                 et, ev, tb = sys.exc_info()
   124                 ev = str(ev)
   122                 ev = str(ev)
   125                 del et, tb
   123                 del et, tb
   126                 raise ValueError("String %r not encoded as 'utf-8'\nerror=%s" % (s,ev))
   124                 raise ValueError("String %r not encoded as 'utf-8'\nerror=%s" % (u,ev))
   127             if self.encoding!='utf-8':
   125         elif not isinstance(u,str):
   128                 s = u.decode(self.encoding)
   126             raise ValueError("EncodedWriter.write(%r) argument should be 'utf-8' bytes or str" % u)
   129         else:
   127         self.append(u)
   130             raise ValueError("EncodedWriter.write(%r) argument should be 'utf-8' string or unicode" % s)
       
   131         self.append(s)
       
   132 
   128 
   133     def getvalue(self):
   129     def getvalue(self):
   134         r = ''.join(self)
   130         r = ''.join(self)
   135         del self[:]
   131         del self[:]
   136         return r
   132         return r
   240 
   236 
   241     def save(self, fn=None):
   237     def save(self, fn=None):
   242         writer = EncodedWriter(self.encoding,bom=self.bom)
   238         writer = EncodedWriter(self.encoding,bom=self.bom)
   243         self.doc.writexml(writer,addindent="\t",newl="\n",encoding=self.encoding)
   239         self.doc.writexml(writer,addindent="\t",newl="\n",encoding=self.encoding)
   244 
   240 
   245         if type(fn) in str:
   241         if hasattr(fn,'write'):
   246             f = open(fn, 'w')
   242             f = fn
   247         else:
   243         else:
   248             f = fn
   244             if isPy3:
       
   245                 f = open(fn, 'w',encoding=self.encoding)
       
   246             else:
       
   247                 f = open(fn, 'w')
       
   248 
   249         svg = writer.getvalue()
   249         svg = writer.getvalue()
   250         exd = self.extraXmlDecl
   250         exd = self.extraXmlDecl
   251         if exd:
   251         if exd:
   252             svg = svg.replace('?>','?>'+exd)
   252             svg = svg.replace('?>','?>'+exd)
   253         f.write(svg)
   253         f.write(svg)