Added onDraw tag to paragraphs
authorrgbecker
Mon, 13 Nov 2000 15:26:46 +0000
changeset 506 68bd275f16e2
parent 505 405b72cdd6b3
child 507 ded036e2ac45
Added onDraw tag to paragraphs
reportlab/demos/odyssey/dodyssey.py
reportlab/pdfbase/pdfmetrics.py
reportlab/platypus/paragraph.py
reportlab/platypus/paraparser.py
--- a/reportlab/demos/odyssey/dodyssey.py	Wed Nov 08 23:58:39 2000 +0000
+++ b/reportlab/demos/odyssey/dodyssey.py	Mon Nov 13 15:26:46 2000 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/demos/odyssey/dodyssey.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/demos/odyssey/dodyssey.py,v 1.8 2000/10/25 08:57:44 rgbecker Exp $
-__version__=''' $Id: dodyssey.py,v 1.8 2000/10/25 08:57:44 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/demos/odyssey/dodyssey.py,v 1.9 2000/11/13 15:26:46 rgbecker Exp $
+__version__=''' $Id: dodyssey.py,v 1.9 2000/11/13 15:26:46 rgbecker Exp $ '''
 __doc__=''
 
 #REPORTLAB_TEST_SCRIPT
@@ -28,6 +28,13 @@
 	canvas.restoreState()
 	
 def go():
+	def myCanvasMaker(fn,**kw):
+		from reportlab.pdfgen.canvas import Canvas
+		canv = apply(Canvas,(fn,),kw)
+		# attach our callback to the canvas
+		canv.myOnDrawCB = myOnDrawCB
+		return canv
+
 	doc = BaseDocTemplate('dodyssey.pdf',showBoundary=0)
 
 	#normal frame as for SimpleFlowDocument
@@ -41,7 +48,7 @@
 						PageTemplate(id='OneCol',frames=frameT, onPage=myLaterPages),
 						PageTemplate(id='TwoCol',frames=[frame1,frame2], onPage=myLaterPages),
 						])
-	doc.build(Elements)
+	doc.build(Elements,canvasmaker=myCanvasMaker)
 
 Elements = []
 
@@ -56,10 +63,16 @@
 def newPage():
 	Elements.append(PageBreak())
 
+chNum = 0
+def myOnDrawCB(canv,kind,label):
+	print 'myOnDrawCB(%s)'%kind, 'Page number=', canv.getPageNumber(), 'label value=', label
+
 def chapter(txt, style=ChapterStyle):
+	global chNum
 	Elements.append(NextPageTemplate('OneCol'))
 	newPage()
-	Elements.append(Paragraph(txt, style))
+	chNum = chNum + 1
+	Elements.append(Paragraph(('<onDraw name=myOnDrawCB label="chap %d">'%chNum)+txt, style))
 	Elements.append(Spacer(0.2*inch, 0.3*inch))
 	if useTwoCol:
 		Elements.append(NextPageTemplate('TwoCol'))
--- a/reportlab/pdfbase/pdfmetrics.py	Wed Nov 08 23:58:39 2000 +0000
+++ b/reportlab/pdfbase/pdfmetrics.py	Mon Nov 13 15:26:46 2000 +0000
@@ -1,25 +1,25 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/pdfbase/pdfmetrics.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/pdfbase/pdfmetrics.py,v 1.15 2000/11/08 10:13:20 andy_robinson Exp $
-__version__=''' $Id: pdfmetrics.py,v 1.15 2000/11/08 10:13:20 andy_robinson Exp $ '''
+#$Header: /tmp/reportlab/reportlab/pdfbase/pdfmetrics.py,v 1.16 2000/11/13 15:26:46 rgbecker Exp $
+__version__=''' $Id: pdfmetrics.py,v 1.16 2000/11/13 15:26:46 rgbecker Exp $ '''
 __doc__="""This contains pre-canned text metrics for the PDFgen package, and may also
 be used for any other PIDDLE back ends or packages which use the standard
 Type 1 postscript fonts.
 
-Its main function is to let you work out the width of strings; it exposes a 
-single function, stringWidth(text, fontName, fontSize), which works out the width of a 
+Its main function is to let you work out the width of strings; it exposes a
+single function, stringWidth(text, fontName, fontSize), which works out the width of a
 string in the given font in points.
 
 The AFM loading stuff worked for me but is not being heavily tested, as pre-canning
 the widths for the standard 14 fonts in Acrobat Reader is so much more useful. One
-could easily extend it to get the exact bounding box for each characterm useful for 
+could easily extend it to get the exact bounding box for each characterm useful for
 kerning.
 
 
 The ascent_descent attribute of the module is a dictionary mapping font names
 (with the proper Postscript capitalisation) to ascents and descents.  I ought
-to sort out the fontname case issue and the resolution of PIDDLE fonts to 
+to sort out the fontname case issue and the resolution of PIDDLE fonts to
 Postscript font names within this module, but have not yet done so.
 """
 import string
@@ -29,8 +29,8 @@
 AFMDIR = 'C:\\code\\users\\andy\\fontembed'
 
 StandardEnglishFonts = [
-	'Courier', 'Courier-Bold', 'Courier-Oblique', 'Courier-BoldOblique',  
-	'Helvetica', 'Helvetica-Bold', 'Helvetica-Oblique', 
+	'Courier', 'Courier-Bold', 'Courier-Oblique', 'Courier-BoldOblique',
+	'Helvetica', 'Helvetica-Bold', 'Helvetica-Oblique',
 	'Helvetica-BoldOblique',
 	'Times-Roman', 'Times-Bold', 'Times-Italic', 'Times-BoldItalic',
 	'Symbol','ZapfDingbats']
@@ -198,20 +198,20 @@
 				metriclines.append(line)
 			if string.find(lline, 'startcharmetrics') > -1:
 				between = 1
-				
+
 		# break up - very shaky assumption about array size
 		widths = [0] * 256
 		widthsByName = {}
 		for line in metriclines:
 			chunks = string.split(line, ';')
-			
+
 			(c, cid) = string.split(chunks[0])
 			(wx, width) = string.split(chunks[1])
 			(n, name) = string.split(chunks[2])
 			#(b, x1, y1, x2, y2) = string.split(chunks[3])
 			widths[string.atoi(cid)] = string.atoi(width)
 			widthsByName[name] = string.atoi(width)
-		
+
 		# by default, any empties should get the width of a space
 		for i in range(len(widths)):
 			if widths[i] == 0:
@@ -243,9 +243,9 @@
 				width = 0
 			MacRomanWidths[i] = width
 		return MacRomanWidths
-	
-		
-		
+
+
+
 
 
 if _stringWidth:
@@ -263,7 +263,7 @@
 		fm = FontMetrics(filename)
 		_rl_accel.setFontInfo(string.lower(fontName), 'WinAnsiEncoding', ad[0], ad[1], fm.getWinAnsiWidths())
 		_rl_accel.setFontInfo(string.lower(fontName), 'MacRomanEncoding', ad[0], ad[1], fm.getMacRomanWidths())
-		
+
 
 	def _SWRecover(text, font, fontSize, encoding):
 		#infoOnce('_SWRecover('...',%s,%s,%s')%(font,str(fontSize),encoding))
@@ -286,14 +286,14 @@
 		def __init__(self):
 			global widths
 			self.__widtharrays = widths
-			
+
 		def loadFont(self, fontName, filename):
 			infoOnce('Info: cache loading%s' % filename)
 			assert os.path.exists(filename)
 			fm = FontMetrics(filename)
 			self.__widtharrays['WinAnsiEncoding'][string.lower(fontName)] = fm.getWinAnsiWidths()
 			self.__widtharrays['MacRomanEncoding'][string.lower(fontName)] = fm.getMacRomanWidths()
-			
+
 
 		def getfont(self, fontName, encoding):
 			try:
@@ -306,7 +306,7 @@
 					# font not found, use Courier
 					warnOnce('Font %s:%s not found - using Courier:%s for widths'%(fontName,encoding,encoding))
 					return self.getfont('courier',encoding)
-		
+
 		def stringWidth(self, text, font, fontSize, encoding=DEFAULT_ENCODING):
 			widths = self.getfont(string.lower(font),encoding)
 			w = 0
@@ -317,7 +317,7 @@
 		def status(self):
 			#returns loaded fonts
 			return self.__widtharrays.keys()
-			
+
 	TheFontCache = FontCache()
 
 	#expose the singleton as a single function
--- a/reportlab/platypus/paragraph.py	Wed Nov 08 23:58:39 2000 +0000
+++ b/reportlab/platypus/paragraph.py	Mon Nov 13 15:26:46 2000 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/paragraph.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/platypus/paragraph.py,v 1.27 2000/11/01 21:24:05 andy_robinson Exp $
-__version__=''' $Id: paragraph.py,v 1.27 2000/11/01 21:24:05 andy_robinson Exp $ '''
+#$Header: /tmp/reportlab/reportlab/platypus/paragraph.py,v 1.28 2000/11/13 15:26:46 rgbecker Exp $
+__version__=''' $Id: paragraph.py,v 1.28 2000/11/13 15:26:46 rgbecker Exp $ '''
 import string
 from types import StringType, ListType
 from reportlab.pdfbase.pdfmetrics import stringWidth
@@ -53,15 +53,21 @@
 
 def	_putFragLine(tx,words):
 	for f in words:
-		if (tx._fontname,tx._fontsize)!=(f.fontName,f.fontSize):
-			tx._setFont(f.fontName, f.fontSize)
-		if tx.XtraState.textColor!=f.textColor:
-			tx.XtraState.textColor = f.textColor
-			tx.setFillColor(f.textColor)
-		if tx.XtraState.rise!=f.rise:
-			tx.XtraState.rise=f.rise
-			tx.setRise(f.rise)
-		tx._textOut(f.text,f is words[-1])	# cheap textOut
+		if hasattr(f,'cbDefn'):
+			func = getattr(tx._canvas,f.cbDefn.name,None)
+			if not func:
+				raise AttributeError, "Missing %s callback attribute '%s'" % (f.cbDefn.kind,f.cbDefn.name)
+			func(tx._canvas,f.cbDefn.kind,f.cbDefn.label)
+		else:
+			if (tx._fontname,tx._fontsize)!=(f.fontName,f.fontSize):
+				tx._setFont(f.fontName, f.fontSize)
+			if tx.XtraState.textColor!=f.textColor:
+				tx.XtraState.textColor = f.textColor
+				tx.setFillColor(f.textColor)
+			if tx.XtraState.rise!=f.rise:
+				tx.XtraState.rise=f.rise
+				tx.setRise(f.rise)
+			tx._textOut(f.text,f is words[-1])	# cheap textOut
 
 def	_leftDrawParaLineX( tx, offset, line, last=0):
 	tx.setXPos(offset)
--- a/reportlab/platypus/paraparser.py	Wed Nov 08 23:58:39 2000 +0000
+++ b/reportlab/platypus/paraparser.py	Mon Nov 13 15:26:46 2000 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/paraparser.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/platypus/paraparser.py,v 1.28 2000/10/25 08:57:45 rgbecker Exp $
-__version__=''' $Id: paraparser.py,v 1.28 2000/10/25 08:57:45 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/platypus/paraparser.py,v 1.29 2000/11/13 15:26:46 rgbecker Exp $
+__version__=''' $Id: paraparser.py,v 1.29 2000/11/13 15:26:46 rgbecker Exp $ '''
 import string
 import re
 from types import TupleType
@@ -85,7 +85,6 @@
 				'fg': 	('textColor', toColor),
 				'color':('textColor', toColor)}
 
-
 def _addAttributeNames(m):
 	K = m.keys()
 	for k in K:
@@ -260,10 +259,8 @@
 	def end_greek(self):
 		self._pop(greek=1)
 
-
 	def start_font(self,attr):
-		A = self.getAttributes(attr,_fontAttrMap)
-		apply(self._push,(),A)
+		apply(self._push,(),self.getAttributes(attr,_fontAttrMap))
 
 	def end_font(self):
 		self._pop()
@@ -354,6 +351,20 @@
 	def end_seq(self):
 		pass
 
+	def start_onDraw(self,attr):
+		defn = ParaFrag()
+		if attr.has_key('name'): defn.name = attr['name']
+		else: self._syntax_error('<onDraw/> needs at least a name attribute')
+
+		if attr.has_key('label'): defn.label = attr['label']
+		defn.kind='onDraw'
+		self._push(cbDefn=defn)
+
+	def end_onDraw(self):
+		if hasattr(self,'text'): self._syntax_error('Only <onDraw/> tag allowed')
+		else: self.handle_data('')
+		self._pop()
+
 	#---------------------------------------------------------------
 	def _push(self,**attr):
 		frag = copy.copy(self._stack[-1])
@@ -607,3 +618,4 @@
 There was a bard also to sing to them and play
 his lyre, while two tumblers went about performing in the midst of
 them when the man struck up with his tune.]''')
+	check_text('''<onDraw name="myFunc" label="aaa   bbb">A paragraph''')