Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Support adding blank pages

Add methods to create blank pages, either by invoking the static method
createBlankPage on PageObject or by invoking addBlankPage or
insertBlankPage on PdfFileWriter.

Define a new PageSizeNotDefinedError, and a PyPdfError as a superclass for
all Exceptions raised by pyPdf. As a result, PdfReadError now extends
PyPdfError.

Patch from Kjo Hansi Glaz <kjo@a4nancy.net.eu.org>
  • Loading branch information...
commit 3353049b3e0e6418f6343971c3e15685c045034d 1 parent ae35d71
@mfenniak authored
Showing with 95 additions and 3 deletions.
  1. +6 −0 pyPdf/generic.py
  2. +82 −2 pyPdf/pdf.py
  3. +7 −1 pyPdf/utils.py
View
6 pyPdf/generic.py
@@ -721,6 +721,12 @@ def setUpperLeft(self, value):
def setUpperRight(self, value):
self[2], self[3] = [self.ensureIsNumber(x) for x in value]
+ def getWidth(self):
+ return self.getUpperRight_x() - self.getLowerLeft_x()
+
+ def getHeight(self):
+ return self.getUpperRight_y() - self.getLowerLeft_x()
+
lowerLeft = property(getLowerLeft, setLowerLeft, None, None)
lowerRight = property(getLowerRight, setLowerRight, None, None)
upperLeft = property(getUpperLeft, setUpperLeft, None, None)
View
84 pyPdf/pdf.py
@@ -132,6 +132,53 @@ def insertPage(self, page, index=0):
self._addPage(page, lambda l, p: l.insert(index, p))
##
+ # Retrieves a page by number from this PDF file.
+ # @return Returns a {@link #PageObject PageObject} instance.
+ def getPage(self, pageNumber):
+ pages = self.getObject(self._pages)
+ # XXX: crude hack
+ return pages["/Kids"][pageNumber].getObject()
+
+ ##
+ # Return the number of pages.
+ # @return The number of pages.
+ def getNumPages(self):
+ pages = self.getObject(self._pages)
+ return int(pages[NameObject("/Count")])
+
+ ##
+ # Append a blank page to this PDF file and returns it. If no page size
+ # is specified, use the size of the last page; throw
+ # PageSizeNotDefinedError if it doesn't exist.
+ # @param width The width of the new page expressed in default user
+ # space units.
+ # @param height The height of the new page expressed in default user
+ # space units.
+ def addBlankPage(self, width=None, height=None):
+ page = PageObject.createBlankPage(self, width, height)
+ self.addPage(page)
+ return page
+
+ ##
+ # Insert a blank page to this PDF file and returns it. If no page size
+ # is specified, use the size of the page in the given index; throw
+ # PageSizeNotDefinedError if it doesn't exist.
+ # @param width The width of the new page expressed in default user
+ # space units.
+ # @param height The height of the new page expressed in default user
+ # space units.
+ # @param index Position to add the page.
+ def insertBlankPage(self, width=None, height=None, index=0):
+ if width is None or height is None and \
+ (self.getNumPages() - 1) >= index:
+ oldpage = self.getPage(index)
+ width = oldpage.mediaBox.getWidth()
+ height = oldpage.mediaBox.getHeight()
+ page = PageObject.createBlankPage(self, width, height)
+ self.insertPage(page, index)
+ return page
+
+ ##
# Encrypt this PDF file with the PDF Standard encryption handler.
# @param user_pwd The "user password", which allows for opening and reading
# the PDF file with the restrictions provided.
@@ -913,13 +960,46 @@ def createRectangleAccessor(name, fallback):
##
# This class represents a single page within a PDF file. Typically this object
# will be created by accessing the {@link #PdfFileReader.getPage getPage}
-# function of the {@link #PdfFileReader PdfFileReader} class.
+# function of the {@link #PdfFileReader PdfFileReader} class, but it is
+# also possible to create an empty page with the createBlankPage static
+# method.
+# @param pdf PDF file the page belongs to (optional, defaults to None).
class PageObject(DictionaryObject):
- def __init__(self, pdf):
+ def __init__(self, pdf=None):
DictionaryObject.__init__(self)
self.pdf = pdf
##
+ # Returns a new blank page.
+ # If width or height is None, try to get the page size from the
+ # last page of pdf. If pdf is None or contains no page, a
+ # PageSizeNotDefinedError is raised.
+ # @param pdf PDF file the page belongs to
+ # @param width The width of the new page expressed in default user
+ # space units.
+ # @param height The height of the new page expressed in default user
+ # space units.
+ def createBlankPage(pdf=None, width=None, height=None):
+ page = PageObject(pdf)
+
+ # Creates a new page (cf PDF Reference 7.7.3.3)
+ page.__setitem__(NameObject('/Type'), NameObject('/Page'))
+ page.__setitem__(NameObject('/Parent'), NullObject())
+ page.__setitem__(NameObject('/Resources'), DictionaryObject())
+ if width is None or height is None:
+ if pdf is not None and pdf.getNumPages() > 0:
+ lastpage = pdf.getPage(pdf.getNumPages() - 1)
+ width = lastpage.mediaBox.getWidth()
+ height = lastpage.mediaBox.getHeight()
+ else:
+ raise utils.PageSizeNotDefinedError()
+ page.__setitem__(NameObject('/MediaBox'),
+ RectangleObject([0, 0, width, height]))
+
+ return page
+ createBlankPage = staticmethod(createBlankPage)
+
+ ##
# Rotates a page clockwise by increments of 90 degrees.
# <p>
# Stability: Added in v1.1, will exist for all future v1.x releases.
View
8 pyPdf/utils.py
@@ -105,7 +105,13 @@ def matrixMultiply(a, b):
) for col in zip(*b)]
for row in a]
-class PdfReadError(Exception):
+class PyPdfError(Exception):
+ pass
+
+class PdfReadError(PyPdfError):
+ pass
+
+class PageSizeNotDefinedError(PyPdfError):
pass
if __name__ == "__main__":
Please sign in to comment.
Something went wrong with that request. Please try again.