Changes to allow invariant documents when needed
authorandy_robinson
Sun, 02 Feb 2003 08:37:33 +0000
changeset 1838 f7eeee67832c
parent 1837 a3920893b1b8
child 1839 084e4af662dc
Changes to allow invariant documents when needed
reportlab/pdfbase/pdfdoc.py
reportlab/pdfgen/canvas.py
reportlab/platypus/doctemplate.py
reportlab/platypus/frames.py
reportlab/rl_config.py
--- a/reportlab/pdfbase/pdfdoc.py	Mon Jan 20 21:11:22 2003 +0000
+++ b/reportlab/pdfbase/pdfdoc.py	Sun Feb 02 08:37:33 2003 +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/pdfbase/pdfdoc.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/pdfbase/pdfdoc.py,v 1.75 2002/11/28 18:36:46 rgbecker Exp $
-__version__=''' $Id: pdfdoc.py,v 1.75 2002/11/28 18:36:46 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/pdfbase/pdfdoc.py,v 1.76 2003/02/02 08:37:33 andy_robinson Exp $
+__version__=''' $Id: pdfdoc.py,v 1.76 2003/02/02 08:37:33 andy_robinson Exp $ '''
 __doc__="""
 The module pdfdoc.py handles the 'outer structure' of PDF documents, ensuring that
 all objects are properly cross-referenced and indexed to the nearest byte.  The
@@ -151,7 +151,11 @@
     defaultStreamFilters = None
     encrypt = NoEncryption() # default no encryption
     pageCounter = 1
-    def __init__(self, encoding=rl_config.defaultEncoding, dummyoutline=0,compression=rl_config.pageCompression):
+    def __init__(self,
+                 encoding=rl_config.defaultEncoding,
+                 dummyoutline=0,
+                 compression=rl_config.pageCompression,
+                 invariant=rl_config.invariant):
         #self.defaultStreamFilters = [PDFBase85Encode, PDFZCompress] # for testing!
         #self.defaultStreamFilters = [PDFZCompress] # for testing!
         assert encoding in ['MacRomanEncoding',
@@ -161,6 +165,11 @@
         if encoding[-8:] <> 'Encoding':
             encoding = encoding + 'Encoding'
 
+        # allow None value to be passed in to mean 'give system defaults'
+        if invariant is None:
+            self.invariant = rl_config.invariant
+        else:
+            self.invariant = invariant
         self.setCompression(compression)
         self.encoding = encoding
         # signature for creating PDF ID
@@ -186,6 +195,7 @@
         self.Outlines = self.outline = outlines
         cat.Outlines = outlines
         self.info = PDFInfo()
+        self.info.invariant = self.invariant
         #self.Reference(self.Catalog)
         #self.Reference(self.Info)
         self.fontMapping = {}
@@ -205,14 +215,19 @@
         self.signature.update(str(thing))
 
     def ID(self):
+        "A unique fingerprint for the file (unless in invariant mode)"
         if self._ID:
             return self._ID
-        digest = self.signature.digest()
-        doc = DummyDoc()
-        ID = PDFString(digest)
-        IDs = ID.format(doc)
-        self._ID = "%s %% ReportLab generated PDF document -- digest (http://www.reportlab.com) %s [%s %s] %s" % (
-            LINEEND, LINEEND, IDs, IDs, LINEEND)
+        if self.invariant:
+            s = PDFString('constantconstant')
+            self._ID = PDFArray([s,s])
+        else:
+            digest = self.signature.digest()
+            doc = DummyDoc()
+            ID = PDFString(digest)
+            IDs = ID.format(doc)
+            self._ID = "%s %% ReportLab generated PDF document -- digest (http://www.reportlab.com) %s [%s %s] %s" % (
+                LINEEND, LINEEND, IDs, IDs, LINEEND)
         return self._ID
 
     def SaveToFile(self, filename, canvas):
@@ -220,6 +235,7 @@
         for fnt in self.delayedFonts:
             fnt.addObjects(self)
         # add info stuff to signature
+        self.info.invariant = self.invariant
         self.info.digest(self.signature)
         ### later: maybe add more info to sig?
         # prepare outline
@@ -366,7 +382,7 @@
                 IOf = IO.format(self)
                 # add a comment to the PDF output
                 if DoComments:
-                    File.add("%% %s %s %s" % (repr(id), repr(repr(obj)[:50]), LINEEND))
+                    File.add("%% %s: class %s %s" % (repr(id), obj.__class__.__name__[:50], LINEEND))
                 offset = File.add(IOf)
                 idToOf[id] = offset
                 ids.append(id)
@@ -1286,6 +1302,7 @@
     File | Document Info in Acrobat Reader.  If this is wrong, you get
     Postscript errors while printing, even though it does not print."""
     def __init__(self):
+        self.invariant = 1
         self.title = "untitled"
         self.author = "anonymous"
         self.subject = "unspecified"
@@ -1300,7 +1317,10 @@
         D = {}
         D["Title"] = PDFString(self.title)
         D["Author"] = PDFString(self.author)
-        D["CreationDate"] = PDFDate()
+        if self.invariant:
+            D["CreationDate"] = PDFString('19001231000000')
+        else:
+            D["CreationDate"] = PDFDate()
         D["Producer"] = PDFString("ReportLab http://www.reportlab.com")
         D["Subject"] = PDFString(self.subject)
         PD = PDFDictionary(D)
--- a/reportlab/pdfgen/canvas.py	Mon Jan 20 21:11:22 2003 +0000
+++ b/reportlab/pdfgen/canvas.py	Sun Feb 02 08:37:33 2003 +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/pdfgen/canvas.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/pdfgen/canvas.py,v 1.108 2002/11/06 11:32:42 rgbecker Exp $
-__version__=''' $Id: canvas.py,v 1.108 2002/11/06 11:32:42 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/pdfgen/canvas.py,v 1.109 2003/02/02 08:37:33 andy_robinson Exp $
+__version__=''' $Id: canvas.py,v 1.109 2003/02/02 08:37:33 andy_robinson Exp $ '''
 __doc__="""
 The Canvas object is the primary interface for creating PDF files. See
 doc/userguide.pdf for copious examples.
@@ -115,13 +115,16 @@
                  bottomup = 1,
                  pageCompression=None,
                  encoding=rl_config.defaultEncoding,
+                 invariant=rl_config.invariant,
                  verbosity=0):
         """Create a canvas of a given size. etc.
         Most of the attributes are private - we will use set/get methods
         as the preferred interface.  Default page size is A4."""
         self._filename = filename
         self._encodingName = encoding
-        self._doc = pdfdoc.PDFDocument(encoding,compression=pageCompression)
+        self._doc = pdfdoc.PDFDocument(encoding,
+                                       compression=pageCompression,
+                                       invariant=invariant)
 
         #this only controls whether it prints 'saved ...' - 0 disables
         self._verbosity = verbosity
--- a/reportlab/platypus/doctemplate.py	Mon Jan 20 21:11:22 2003 +0000
+++ b/reportlab/platypus/doctemplate.py	Sun Feb 02 08:37:33 2003 +0000
@@ -1,9 +1,9 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/doctemplate.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/platypus/doctemplate.py,v 1.59 2003/01/06 11:36:18 rgbecker Exp $
+#$Header: /tmp/reportlab/reportlab/platypus/doctemplate.py,v 1.60 2003/02/02 08:37:33 andy_robinson Exp $
 
-__version__=''' $Id: doctemplate.py,v 1.59 2003/01/06 11:36:18 rgbecker Exp $ '''
+__version__=''' $Id: doctemplate.py,v 1.60 2003/02/02 08:37:33 andy_robinson Exp $ '''
 
 __doc__="""
 This module contains the core structure of platypus.
@@ -500,6 +500,7 @@
                 if self.allowSplitting:
                     # see if this is a splittable thing
                     S = self.frame.split(f,self.canv)
+                    #print '%d parts to sequence on page %d' % (len(S), self.page)
                     n = len(S)
                 else:
                     n = 0
@@ -522,8 +523,8 @@
                         #HACK = it seems within tables we sometimes
                         #get an empty paragraph that won't fit and this
                         #causes it to fall over.  FIXME FIXME FIXME
-                        raise "LayoutError", message
-##                  f.postponed = 1
+                        #raise "LayoutError", message
+##                    f.postponed = 1
                     f._postponed = 1
                     flowables.insert(0,f)           # put the flowable back
                     self.handle_frameEnd()
--- a/reportlab/platypus/frames.py	Mon Jan 20 21:11:22 2003 +0000
+++ b/reportlab/platypus/frames.py	Sun Feb 02 08:37:33 2003 +0000
@@ -1,9 +1,9 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/frames.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/platypus/frames.py,v 1.18 2002/07/24 19:56:38 andy_robinson Exp $
+#$Header: /tmp/reportlab/reportlab/platypus/frames.py,v 1.19 2003/02/02 08:37:33 andy_robinson Exp $
 
-__version__=''' $Id: frames.py,v 1.18 2002/07/24 19:56:38 andy_robinson Exp $ '''
+__version__=''' $Id: frames.py,v 1.19 2003/02/02 08:37:33 andy_robinson Exp $ '''
 
 __doc__="""
 """
@@ -141,6 +141,8 @@
         s = 0
         if not self._atTop: s = flowable.getSpaceBefore()
         flowable.canv = canv    #some flowables might need this
+        
+        #print 'asked table to split.  _aW = %0.2f, y-p-s=%0.2f' % (self._aW, y-p-s)
         r = flowable.split(self._aW, y-p-s)
         del flowable.canv
         return r
--- a/reportlab/rl_config.py	Mon Jan 20 21:11:22 2003 +0000
+++ b/reportlab/rl_config.py	Sun Feb 02 08:37:33 2003 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000-2001
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/rl_config.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/rl_config.py,v 1.34 2002/07/24 19:56:34 andy_robinson Exp $
-__version__=''' $Id: rl_config.py,v 1.34 2002/07/24 19:56:34 andy_robinson Exp $ '''
+#$Header: /tmp/reportlab/reportlab/rl_config.py,v 1.35 2003/02/02 08:37:33 andy_robinson Exp $
+__version__=''' $Id: rl_config.py,v 1.35 2003/02/02 08:37:33 andy_robinson Exp $ '''
 
 allowTableBoundsErrors = 1 # set to 0 to die on too large elements in tables in debug (recommend 1 for production use)
 shapeChecking =             1
@@ -16,6 +16,8 @@
 verbose =                   0
 showBoundary =              0                       # turns on and off boundary behaviour in Drawing
 emptyTableAction=           'error'                 # one of 'error', 'indicate', 'ignore'
+invariant=                  0                       #produces repeatble,identical PDFs without timestamp info
+                                                    #(for regression testing)
 
 # places to look for T1Font information
 T1SearchPath =  ('c:/Program Files/Adobe/Acrobat 5.0/Resource/Font', #Win32, Acrobat 5