# -*- encoding: utf-8 -*-
##############################################################################
#
-# Copyright (c) 2004-2008 Tiny SPRL (http://tiny.be) All Rights Reserved.
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+# $Id$
#
-# $Id$
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
#
-# WARNING: This program as such is intended to be used by professional
-# programmers who take the whole responsability of assessing all potential
-# consequences resulting from its eventual inadequacies and bugs
-# End users who are looking for a ready-to-use solution with commercial
-# garantees and support are strongly adviced to contract a Free Software
-# Service Company
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
#
-# This program is Free Software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-###############################################################################
-#!/usr/bin/python
+##############################################################################
# trml2pdf - An RML to PDF converter
# Copyright (C) 2003, Fabien Pinckaers, UCL, FSA
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import sys
-import StringIO
+from StringIO import StringIO
import xml.dom.minidom
import copy
import re
from reportlab.pdfgen import canvas
from reportlab import platypus
-
+import cStringIO
import utils
import color
import os
-ftitle=""
+
#
# Change this to UTF-8 if you plan tu use Reportlab's UTF-8 support
#
return style
class _rml_doc(object):
- def __init__(self, data, images={}, path='.'):
+ def __init__(self, data, images={}, path='.', title=None):
self.dom = xml.dom.minidom.parseString(data)
self.filename = self.dom.documentElement.getAttribute('filename')
self.images = images
self.path = path
+ self.title = title
def docinit(self, els):
from reportlab.lib.fonts import addMapping
addMapping(name, 1, 0, name) #bold
addMapping(name, 1, 1, name) #italic and bold
+ def setTTFontMapping(self,face, fontname,filename, mode='all'):
+ from reportlab.lib.fonts import addMapping
+ from reportlab.pdfbase import pdfmetrics
+ from reportlab.pdfbase.ttfonts import TTFont
+
+ pdfmetrics.registerFont(TTFont(fontname, filename ))
+ if (mode == 'all'):
+ addMapping(face, 0, 0, fontname) #normal
+ addMapping(face, 0, 1, fontname) #italic
+ addMapping(face, 1, 0, fontname) #bold
+ addMapping(face, 1, 1, fontname) #italic and bold
+ elif (mode== 'normal') or (mode == 'regular'):
+ addMapping(face, 0, 0, fontname) #normal
+ elif (mode == 'italic'):
+ addMapping(face, 0, 1, fontname) #italic
+ elif (mode == 'bold'):
+ addMapping(face, 1, 0, fontname) #bold
+ elif (mode == 'bolditalic'):
+ addMapping(face, 1, 1, fontname) #italic and bold
+
def _textual_image(self, node):
import base64
rc = ''
el = self.dom.documentElement.getElementsByTagName('template')
if len(el):
- pt_obj = _rml_template(out, el[0], self, images=self.images, path=self.path)
+ pt_obj = _rml_template(out, el[0], self, images=self.images, path=self.path, title=self.title)
pt_obj.render(self.dom.documentElement.getElementsByTagName('story'))
else:
self.canvas = canvas.Canvas(out)
pd = self.dom.documentElement.getElementsByTagName('pageDrawing')[0]
- pd_obj = _rml_canvas(self.canvas, None, self, self.images, path=self.path)
+ pd_obj = _rml_canvas(self.canvas, None, self, self.images, path=self.path, title=self.title)
pd_obj.render(pd)
self.canvas.showPage()
self.canvas.save()
class _rml_canvas(object):
- def __init__(self, canvas, doc_tmpl=None, doc=None, images={}, path='.'):
+ def __init__(self, canvas, doc_tmpl=None, doc=None, images={}, path='.', title=None):
self.canvas = canvas
self.styles = doc.styles
self.doc_tmpl = doc_tmpl
self.doc = doc
self.images = images
self.path = path
- global ftitle
- if ftitle:
- self.canvas.setTitle(ftitle)
+ self.title = title
+ if self.title:
+ self.canvas.setTitle(self.title)
def _textual(self, node, x=0, y=0):
rc = ''
self.canvas.circle(x_cen=utils.unit_get(node.getAttribute('x')), y_cen=utils.unit_get(node.getAttribute('y')), r=utils.unit_get(node.getAttribute('radius')), **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'}))
def _place(self, node):
- flows = _rml_flowable(self.doc, images=self.images, path=self.path).render(node)
+ flows = _rml_flowable(self.doc, images=self.images, path=self.path, title=self.title).render(node)
infos = utils.attr_get(node, ['x','y','width','height'])
infos['y']+=infos['height']
import urllib
from reportlab.lib.utils import ImageReader
+# s = StringIO()
if not node.hasAttribute('file'):
if node.hasAttribute('name'):
image_data = self.images[node.getAttribute('name')]
- s = StringIO.StringIO(image_data)
+ s = cStringIO.StringIO(image_data)
else:
import base64
image_data = base64.decodestring(node.firstChild.nodeValue)
if not image_data: return False
- s = StringIO.StringIO(image_data)
+ s = cStringIO.StringIO(image_data)
+# s.write(image_data)
else:
if node.getAttribute('file') in self.images:
- s = StringIO.StringIO(self.images[node.getAttribute('file')])
+ s = cStringIO.StringIO(self.images[node.getAttribute('file')])
+# s.write(self.images[node.getAttribute('file')])
else:
try:
u = urllib.urlopen(str(node.getAttribute('file')))
- s = StringIO.StringIO(u.read())
except:
u = file(os.path.join(self.path,str(node.getAttribute('file'))), 'rb')
- s = StringIO.StringIO(u.read())
+ s = cStringIO.StringIO(u.read())
img = ImageReader(s)
(sx,sy) = img.getSize()
break
class _rml_draw(object):
- def __init__(self, node, styles, images={}, path='.'):
+ def __init__(self, node, styles, images={}, path='.', title=None):
self.node = node
self.styles = styles
self.canvas = None
self.images = images
self.path = path
+ self.canvas_title = title
def render(self, canvas, doc):
canvas.saveState()
- cnv = _rml_canvas(canvas, doc, self.styles, images=self.images, path=self.path)
+ cnv = _rml_canvas(canvas, doc, self.styles, images=self.images, path=self.path, title=self.canvas_title)
cnv.render(self.node)
canvas.restoreState()
class _rml_flowable(object):
- def __init__(self, doc, images={}, path='.'):
+ def __init__(self, doc, images={}, path='.', title=None):
self.doc = doc
self.styles = doc.styles
self.images = images
self.path = path
+ self.title = title
def _textual(self, node):
rc = ''
rowheights = [utils.unit_get(f.strip()) for f in node.getAttribute('rowHeights').split(',')]
if len(rowheights) == 1:
rowheights = rowheights[0]
- table = platypus.Table(data = data, colWidths=colwidths, rowHeights=rowheights, **(utils.attr_get(node, ['splitByRow'] ,{'repeatRows':'int','repeatCols':'int'})))
+ table = platypus.LongTable(data = data, colWidths=colwidths, rowHeights=rowheights, **(utils.attr_get(node, ['splitByRow'] ,{'repeatRows':'int','repeatCols':'int'})))
if node.hasAttribute('style'):
table.setStyle(self.styles.table_styles[node.getAttribute('style')])
for s in styles:
return (self.width, self.height)
def draw(self):
canvas = self.canv
- drw = _rml_draw(self.node, self.styles, images=self.self2.images, path=self.self2.path)
+ drw = _rml_draw(self.node, self.styles, images=self.self2.images, path=self.self2.path, title=self.self2.title)
drw.render(self.canv, None)
return Illustration(node, self.styles, self)
else:
import base64
image_data = base64.decodestring(node.firstChild.nodeValue)
- image = StringIO.StringIO(image_data)
+
+ image = StringIO()
+ image.write(image_data)
+ image.seek(0)
return platypus.Image(image, mask=(250,255,250,255,250,255), **(utils.attr_get(node, ['width','height'])))
else:
return platypus.Image(node.getAttribute('file'), mask=(250,255,250,255,250,255), **(utils.attr_get(node, ['width','height'])))
return CurrentFrameFlowable(str(node.getAttribute('name')))
elif node.localName == 'frameEnd':
return EndFrameFlowable()
+ elif node.localName == 'hr':
+ width_hr=node.hasAttribute('width') and node.getAttribute('width') or '100%'
+ color_hr=node.hasAttribute('color') and node.getAttribute('color') or 'black'
+ thickness_hr=node.hasAttribute('thickness') and node.getAttribute('thickness') or 1
+ lineCap_hr=node.hasAttribute('lineCap') and node.getAttribute('lineCap') or 'round'
+ return platypus.flowables.HRFlowable(width=width_hr,color=color.get(color_hr),thickness=float(thickness_hr),lineCap=str(lineCap_hr))
else:
sys.stderr.write('Warning: flowable not yet implemented: %s !\n' % (node.localName,))
return None
self.canv._pageNumber = 0
class _rml_template(object):
- def __init__(self, out, node, doc, images={}, path='.'):
+ def __init__(self, out, node, doc, images={}, path='.', title=None):
self.images= images
self.path = path
+ self.title = title
if not node.hasAttribute('pageSize'):
pageSize = (utils.unit_get('21cm'), utils.unit_get('29.7cm'))
else:
frames.append( frame )
gr = pt.getElementsByTagName('pageGraphics')
if len(gr):
- drw = _rml_draw(gr[0], self.doc, images=images, path=self.path)
+ drw = _rml_draw(gr[0], self.doc, images=images, path=self.path, title=self.title)
self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) ))
else:
- self.page_templates.append( platypus.PageTemplate(frames=frames, **utils.attr_get(pt, [], {'id':'str'}) ))
+ drw = _rml_draw(node,self.doc,title=self.title)
+ self.page_templates.append( platypus.PageTemplate(frames=frames,onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) ))
self.doc_tmpl.addPageTemplates(self.page_templates)
def render(self, node_stories):
fis = []
- r = _rml_flowable(self.doc,images=self.images, path=self.path)
+ r = _rml_flowable(self.doc,images=self.images, path=self.path, title=self.title)
for node_story in node_stories:
fis += r.render(node_story)
if node_story==node_stories[-1]:
self.doc_tmpl.build(fis)
def parseString(data, fout=None, images={}, path='.',title=None):
- r = _rml_doc(data, images, path)
- global ftitle
- ftitle=title
+ r = _rml_doc(data, images, path, title=title)
+
+ #try to override some font mappings
+ try:
+ from customfonts import SetCustomFonts
+ SetCustomFonts(r)
+ except:
+ pass
+
if fout:
fp = file(fout,'wb')
r.render(fp)
fp.close()
return fout
else:
- fp = StringIO.StringIO()
+ fp = StringIO()
r.render(fp)
return fp.getvalue()