Changeset 704
- Timestamp:
- 01/25/06 15:14:02 (3 years ago)
- Files:
-
- pypdf/trunk/pyPdf/pdf.py (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
pypdf/trunk/pyPdf/pdf.py
r703 r704 49 49 class PdfFileWriter(object): 50 50 def __init__(self): 51 self.header = "%PDF-1.3" 52 self.pages = [] 53 54 def addPage(self, page): 55 """ 56 Adds a page to this PDF file. A dictionary of /Type = /Page. 57 Currently usually aquired from PdfFileReader.getPage(). 58 59 Stability: Added in v1.0, will exist for all v1.x releases. 60 """ 61 self.pages.append(page) 62 63 def write(self, stream): 64 """ 65 Writes this PDF file to an output stream. Writes the file as a 66 PDF-1.3 format file. 67 68 Stability: Added in v1.0, will exist for all v1.x releases. 69 """ 70 objects = [] 71 72 # The pages will all have a new parent, so we need to replace their 73 # existing parent object. 51 self._header = "%PDF-1.3" 52 self._objects = [] # array of indirect objects 53 54 # The root of our page tree node. 74 55 pages = DictionaryObject() 75 56 pages.update({ 76 57 NameObject("/Type"): NameObject("/Pages"), 77 NameObject("/Count"): NumberObject( len(self.pages)),58 NameObject("/Count"): NumberObject(0), 78 59 NameObject("/Kids"): ArrayObject(), 79 60 }) 80 objects.append(pages) 81 pages_ido = IndirectObject(len(objects), 0, self) 82 for page in self.pages: 83 page[NameObject("/Parent")] = pages_ido 61 self._pages = self._addObject(pages) 84 62 85 63 # info object 86 64 info = DictionaryObject() 87 65 info.update({ 88 NameObject("/Producer"): StringObject("Python PDF Library - mfenniak@pobox.com")66 NameObject("/Producer"): StringObject("Python PDF Library - http://stompstompstomp.com/pyPdf/") 89 67 }) 90 objects.append(info) 91 info = IndirectObject(len(objects), 0, self) 68 self._info = self._addObject(info) 92 69 93 70 # root object … … 95 72 root.update({ 96 73 NameObject("/Type"): NameObject("/Catalog"), 97 NameObject("/Pages"): pages_ido,74 NameObject("/Pages"): self._pages, 98 75 }) 99 objects.append(root) 100 root = IndirectObject(len(objects), 0, self) 101 102 # The real work. Find any indirect references in out pages, 103 # and make them into objects for us to write. 76 self._root = self._addObject(root) 77 78 def _addObject(self, obj): 79 self._objects.append(obj) 80 return IndirectObject(len(self._objects), 0, self) 81 82 def _getObject(self, ido): 83 assert ido.pdf == self 84 return self._objects[ido.idnum - 1] 85 86 def addPage(self, page): 87 """ 88 Adds a page to this PDF file. A dictionary of /Type = /Page. 89 Currently usually aquired from PdfFileReader.getPage(). 90 91 Stability: Added in v1.0, will exist for all v1.x releases. 92 """ 93 assert page["/Type"] == "/Page" 94 page[NameObject("/Parent")] = self._pages 95 page = self._addObject(page) 96 pages = self._getObject(self._pages) 97 pages["/Kids"].append(page) 98 pages["/Count"] = NumberObject(pages["/Count"] + 1) 99 100 def write(self, stream): 101 """ 102 Writes this PDF file to an output stream. Writes the file as a 103 PDF-1.3 format file. 104 105 Stability: Added in v1.0, will exist for all v1.x releases. 106 """ 107 104 108 externalReferenceMap = {} 105 for page in self.pages: 106 page = self.sweepIndirectReferences(externalReferenceMap, objects, page) 107 objects.append(page) 108 pages["/Kids"].append(IndirectObject(len(objects), 0, self)) 109 self.stack = [] 110 self._sweepIndirectReferences(externalReferenceMap, self._root) 111 del self.stack 109 112 110 113 # Begin writing: 111 stream.write(self.header + "\n") 112 for i in range(len(objects)): 113 obj = objects[i] 114 objects[i] = stream.tell() 114 object_positions = [] 115 stream.write(self._header + "\n") 116 for i in range(len(self._objects)): 117 obj = self._objects[i] 118 object_positions.append(stream.tell()) 115 119 stream.write(str(i + 1) + " 0 obj\n") 116 120 obj.writeToStream(stream) … … 120 124 xref_location = stream.tell() 121 125 stream.write("xref\n") 122 stream.write("0 %s\n" % (len( objects) + 1))126 stream.write("0 %s\n" % (len(self._objects) + 1)) 123 127 stream.write("%010d %05d f \n" % (0, 65535)) 124 for offset in object s:128 for offset in object_positions: 125 129 stream.write("%010d %05d n \n" % (offset, 0)) 126 130 … … 129 133 trailer = DictionaryObject() 130 134 trailer.update({ 131 NameObject("/Size"): NumberObject(len( objects) + 1),132 NameObject("/Root"): root,133 NameObject("/Info"): info,135 NameObject("/Size"): NumberObject(len(self._objects) + 1), 136 NameObject("/Root"): self._root, 137 NameObject("/Info"): self._info, 134 138 }) 135 139 trailer.writeToStream(stream) … … 138 142 stream.write("\nstartxref\n%s\n%%%%EOF\n" % (xref_location)) 139 143 140 def sweepIndirectReferences(self, externMap, objects, data):144 def _sweepIndirectReferences(self, externMap, data): 141 145 if isinstance(data, DictionaryObject): 142 146 for key, value in data.items(): 143 147 origvalue = value 144 value = self. sweepIndirectReferences(externMap, objects, value)148 value = self._sweepIndirectReferences(externMap, value) 145 149 if value == None: 146 150 print objects, value, origvalue … … 148 152 # a dictionary value is a stream. streams must be indirect 149 153 # objects, so we need to change this value. 150 objects.append(value) 151 value = IndirectObject(len(objects), 0, self) 154 value = self._addObject(value) 152 155 data[key] = value 153 156 return data 154 157 elif isinstance(data, ArrayObject): 155 158 for i in range(len(data)): 156 data[i] = self. sweepIndirectReferences(externMap, objects, data[i])159 data[i] = self._sweepIndirectReferences(externMap, data[i]) 157 160 return data 158 161 elif isinstance(data, IndirectObject): 159 162 # internal indirect references are fine 160 if data.pdf != self: 163 if data.pdf == self: 164 if data.idnum in self.stack: 165 return data 166 else: 167 self.stack.append(data.idnum) 168 realdata = self._getObject(data) 169 self._sweepIndirectReferences(externMap, realdata) 170 self.stack.pop() 171 return data 172 else: 161 173 newobj = externMap.get(data.pdf, {}).get(data.generation, {}).get(data.idnum, None) 162 174 if newobj == None: 163 175 newobj = data.pdf.getObject(data) 164 objects.append(None) # placeholder165 idnum = len( objects)176 self._objects.append(None) # placeholder 177 idnum = len(self._objects) 166 178 newobj_ido = IndirectObject(idnum, 0, self) 167 179 if not externMap.has_key(data.pdf): … … 170 182 externMap[data.pdf][data.generation] = {} 171 183 externMap[data.pdf][data.generation][data.idnum] = newobj_ido 172 newobj = self. sweepIndirectReferences(externMap, objects, newobj)173 objects[idnum-1] = newobj184 newobj = self._sweepIndirectReferences(externMap, newobj) 185 self._objects[idnum-1] = newobj 174 186 return newobj_ido 175 187 return newobj 176 else:177 return data178 188 else: 179 189 return data … … 201 211 """ 202 212 if self.flattenedPages == None: 203 self. flatten()213 self._flatten() 204 214 return len(self.flattenedPages) 205 215 … … 214 224 assert not self.trailer.has_key("/Encrypt") 215 225 if self.flattenedPages == None: 216 self. flatten()226 self._flatten() 217 227 return self.flattenedPages[pageNumber] 218 228 219 def flatten(self, pages = None, inherit = None):229 def _flatten(self, pages = None, inherit = None): 220 230 inheritablePageAttributes = ( 221 231 NameObject("/Resources"), NameObject("/MediaBox"), … … 236 246 inherit[attr] = pages[attr] 237 247 for page in pages["/Kids"]: 238 self. flatten(page, inherit)248 self._flatten(page, inherit) 239 249 elif t == "/Page": 240 250 for attr,value in inherit.items():
