reportlab/pdfgen/pycanvas.py
changeset 1771 105572a4222f
parent 1756 ad131d58acab
child 1777 48870c5f865a
--- a/reportlab/pdfgen/pycanvas.py	Sun Nov 03 23:47:05 2002 +0000
+++ b/reportlab/pdfgen/pycanvas.py	Mon Nov 04 00:11:49 2002 +0000
@@ -5,94 +5,94 @@
 
 __doc__ = """pycanvas.Canvas : a Canvas class which can also output Python source code.
 
-pycanvas.Canvas class works exactly like canvas.Canvas, but you can 
-call str() on pycanvas.Canvas instances. Doing so will return the 
-Python source code equivalent to your own program, which would, when 
-run, produce the same PDF document as your original program. 
+pycanvas.Canvas class works exactly like canvas.Canvas, but you can
+call str() on pycanvas.Canvas instances. Doing so will return the
+Python source code equivalent to your own program, which would, when
+run, produce the same PDF document as your original program.
 
-Generated Python source code defines a doIt() function which accepts 
-a filename or file-like object as its first parameter, and an 
-optional boolean parameter named "regenerate". 
+Generated Python source code defines a doIt() function which accepts
+a filename or file-like object as its first parameter, and an
+optional boolean parameter named "regenerate".
 
-The doIt() function will generate a PDF document and save it in the 
-file you specified in this argument. If the regenerate parameter is 
-set then it will also return an automatically generated equivalent 
-Python source code as a string of text, which you can run again to 
-produce the very same PDF document and the Python source code, which 
-you can run again... ad nauseam ! If the regenerate parameter is 
-unset or not used at all (it then defaults to being unset) then None 
-is returned and the doIt() function is much much faster, it is also 
-much faster than the original non-serialized program. 
+The doIt() function will generate a PDF document and save it in the
+file you specified in this argument. If the regenerate parameter is
+set then it will also return an automatically generated equivalent
+Python source code as a string of text, which you can run again to
+produce the very same PDF document and the Python source code, which
+you can run again... ad nauseam ! If the regenerate parameter is
+unset or not used at all (it then defaults to being unset) then None
+is returned and the doIt() function is much much faster, it is also
+much faster than the original non-serialized program.
 
-the reportlab/test/test_pdfgen_pycanvas.py program is the test suite 
-for pycanvas, you can do the following to run it : 
+the reportlab/test/test_pdfgen_pycanvas.py program is the test suite
+for pycanvas, you can do the following to run it :
 
     First set verbose=1 in reportlab/rl_config.py
-    
+
     then from the command interpreter :
-    
+
     $ cd reportlab/test
     $ python test_pdfgen_pycanvas.py >n1.py
-    
+
     this will produce both n1.py and test_pdfgen_pycanvas.pdf
-    
+
     then :
-    
+
     $ python n1.py n1.pdf >n2.py
     $ python n2.py n2.pdf >n3.py
     $ ...
-    
+
     n1.py, n2.py, n3.py and so on will be identical files.
-    they eventually may end being a bit different because of 
-    rounding problems, mostly in the comments, but this 
+    they eventually may end being a bit different because of
+    rounding problems, mostly in the comments, but this
     doesn't matter since the values really are the same
     (e.g. 0 instead of 0.0, or .53 instead of 0.53)
-    
+
     n1.pdf, n2.pdf, n3.pdf and so on will be PDF files
     similar to test_pdfgen_pycanvas.pdf.
-    
+
 Alternatively you can import n1.py (or n3.py, or n16384.py if you prefer)
 in your own program, and then call its doIt function :
 
     import n1
     pythonsource = n1.doIt("myfile.pdf", regenerate=1)
-    
+
 Or if you don't need the python source code and want a faster result :
 
     import n1
     n1.doIt("myfile.pdf")
-    
+
 When the generated source code is run directly as an independant program,
 then the equivalent python source code is printed to stdout, e.g. :
 
-    python n1.py 
-    
+    python n1.py
+
     will print the python source code equivalent to n1.py
 
 Why would you want to use such a beast ?
-    
-    - To linearize (serialize?) a program : optimizing some complex 
-      parts for example. 
-    
+
+    - To linearize (serialize?) a program : optimizing some complex
+      parts for example.
+
     - To debug : reading the generated Python source code may help you or
       the ReportLab team to diagnose problems. The generated code is now
       clearly commented and shows nesting levels, page numbers, and so
       on. You can use the generated script when asking for support : we
       can see the results you obtain without needing your datas or complete
       application.
-    
+
     - To create standalone scripts : say your program uses a high level
-      environment to generate its output (databases, RML, etc...), using 
-      this class would give you an equivalent program but with complete 
-      independance from the high level environment (e.g. if you don't 
+      environment to generate its output (databases, RML, etc...), using
+      this class would give you an equivalent program but with complete
+      independance from the high level environment (e.g. if you don't
       have Oracle).
-    
+
     - To contribute some nice looking PDF documents to the ReportLab website
       without having to send a complete application you don't want to
       distribute.
-      
+
     - ... Insert your own ideas here ...
-    
+
     - For fun because you can do it !
 """
 
@@ -114,9 +114,9 @@
 
 def doIt(file, regenerate=0) :
     """Generates a PDF document, save it into file.
-    
+
        file : either a filename or a file-like object.
-       
+
        regenerate : if set then this function returns the Python source
                     code which when run will produce the same result.
                     if unset then this function returns None, and is
@@ -140,9 +140,9 @@
         sys.exit(-1)
     else :
         # we've got a filename, we can proceed.
-        print doIt(sys.argv[1], regenerate=1)    
+        print doIt(sys.argv[1], regenerate=1)
         sys.exit(0)'''
-    
+
 def buildargs(*args, **kwargs) :
     """Constructs a printable list of arguments suitable for use in source function calls."""
     arguments = ""
@@ -152,7 +152,7 @@
         arguments = arguments+ ("%s=%s, " % (kw, repr(val)))
     if arguments[-2:] == ", " :
         arguments = arguments[:-2]
-    return arguments    
+    return arguments
 
 class PDFAction :
     """Base class to fake method calls or attributes on PDF objects (Canvas, PDFPathObject, PDFTextObject)."""
@@ -160,38 +160,38 @@
         """Saves a pointer to the parent object, and the method name."""
         self._parent = parent
         self._action = action
-    
+
     def __getattr__(self, name) :
         """Probably a method call on an attribute, returns the real one."""
         return getattr(getattr(self._parent._object, self._action), name)
-        
+
     def __call__(self, *args, **kwargs) :
         """The fake method is called, print it then call the real one."""
         if not self._parent._parent._in :
             self._precomment()
             self._parent._parent._PyWrite("    %s.%s(%s)" % (self._parent._name, self._action, apply(buildargs, args, kwargs)))
-            self._postcomment() 
-        self._parent._parent._in = self._parent._parent._in + 1 
+            self._postcomment()
+        self._parent._parent._in = self._parent._parent._in + 1
         retcode = apply(getattr(self._parent._object, self._action), args, kwargs)
         self._parent._parent._in = self._parent._parent._in - 1
         return retcode
-        
+
     def __str__(self) :
         """Needed for Python 2.1"""
         return str(getattr(self._parent._object, self._action))
-    
+
     def __coerce__(self, other) :
         """Needed for Python 2.1"""
         return coerce(getattr(self._parent._object, self._action), other)
-        
-    def _precomment(self) : 
+
+    def _precomment(self) :
         """To be overriden."""
         pass
-        
+
     def _postcomment(self) :
         """To be overriden."""
         pass
-        
+
 class PDFObject :
     """Base class for PDF objects like PDFPathObject and PDFTextObject."""
     _number = 0
@@ -199,15 +199,15 @@
         """Saves a pointer to the parent Canvas."""
         self._parent = parent
         self._initdone = 0
-    
+
     def __getattr__(self, name) :
         """The user's programs wants to call one of our methods or get an attribute, fake it."""
         return PDFAction(self, name)
-        
+
     def __repr__(self) :
         """Returns the name used in the generated source code (e.g. 'p' or 't')."""
         return self._name
-        
+
     def __call__(self, *args, **kwargs) :
         """Real object initialisation is made here, because now we've got the arguments."""
         if not self._initdone :
@@ -216,51 +216,51 @@
             self._parent._PyWrite("\n    # create PDF%sObject number %i\n    %s = %s.%s(%s)" % (methodname[5:], self.__class__._number, self._name, self._parent._name, methodname, apply(buildargs, args, kwargs)))
             self._initdone = 1
         return self
-    
+
 class Canvas :
-    """Our fake Canvas class, which will intercept each and every method or attribute access.""" 
+    """Our fake Canvas class, which will intercept each and every method or attribute access."""
     class TextObject(PDFObject) :
         _name = "t"
         def _postinit(self, *args, **kwargs) :
             self._object = apply(textobject.PDFTextObject, (self._parent, ) + args, kwargs)
             return "beginText"
-        
+
     class PathObject(PDFObject) :
         _name = "p"
         def _postinit(self, *args, **kwargs) :
             self._object = apply(pathobject.PDFPathObject, args, kwargs)
             return "beginPath"
-        
+
     class Action(PDFAction) :
         """Class called for every Canvas method call."""
         def _precomment(self) :
             """Outputs comments before the method call."""
             if self._action == "showPage" :
                 self._parent._PyWrite("\n    # Ends page %i" % self._parent._pagenumber)
-            elif self._action == "saveState" :    
+            elif self._action == "saveState" :
                 state = {}
                 d = self._parent._object.__dict__
                 for name in self._parent._object.STATE_ATTRIBUTES:
-                    state[name] = d[name] 
+                    state[name] = d[name]
                 self._parent._PyWrite("\n    # Saves context level %i %s" % (self._parent._contextlevel, state))
                 self._parent._contextlevel = self._parent._contextlevel + 1
-            elif self._action == "restoreState" :    
+            elif self._action == "restoreState" :
                 self._parent._contextlevel = self._parent._contextlevel - 1
                 self._parent._PyWrite("\n    # Restores context level %i %s" % (self._parent._contextlevel, self._parent._object.state_stack[-1]))
-            elif self._action == "beginForm" :    
+            elif self._action == "beginForm" :
                 self._parent._formnumber = self._parent._formnumber + 1
                 self._parent._PyWrite("\n    # Begins form %i" % self._parent._formnumber)
-            elif self._action == "endForm" :    
+            elif self._action == "endForm" :
                 self._parent._PyWrite("\n    # Ends form %i" % self._parent._formnumber)
-            elif self._action == "save" :    
+            elif self._action == "save" :
                 self._parent._PyWrite("\n    # Saves the PDF document to disk")
-        
+
         def _postcomment(self) :
             """Outputs comments after the method call."""
             if self._action == "showPage" :
                 self._parent._pagenumber = self._parent._pagenumber + 1
                 self._parent._PyWrite("\n    # Begins page %i" % self._parent._pagenumber)
-            elif self._action in [ "endForm", "drawPath", "clipPath" ] :    
+            elif self._action in [ "endForm", "drawPath", "clipPath" ] :
                 self._parent._PyWrite("")
 
     _name = "c"
@@ -277,14 +277,14 @@
         self._PyWrite(PyHeader)
         try :
             del kwargs["filename"]
-        except KeyError :    
+        except KeyError :
             pass
         self._PyWrite("    # create the PDF document\n    %s = Canvas(file, %s)\n\n    # Begins page 1" % (self._name, apply(buildargs, args[1:], kwargs)))
 
     def __nonzero__(self) :
         """This is needed by platypus' tables."""
         return 1
-        
+
     def __str__(self) :
         """Returns the equivalent Python source code."""
         if not self._footerpresent :
@@ -298,7 +298,7 @@
             return self.PathObject(self)
         elif name == "beginText" :
             return self.TextObject(self)
-        else :    
+        else :
             return self.Action(self, name)
 
     def _PyWrite(self, pycode) :