Changeset 709

Show
Ignore:
Timestamp:
01/27/06 12:23:05 (3 years ago)
Author:
mfenniak
Message:

Add object-renaming to mergePage functionality. Pages can be merged from distinctly different PDF files now.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pypdf/trunk/pyPdf/pdf.py

    r707 r709  
    6565        info = DictionaryObject() 
    6666        info.update({ 
    67                 NameObject("/Producer"): StringObject("Python PDF Library - http://stompstompstomp.com/pyPdf/") 
     67                NameObject("/Producer"): StringObject("Python PDF Library - http://pybrary.net/pyPdf/") 
    6868                }) 
    6969        self._info = self._addObject(info) 
     
    478478        """ 
    479479        assert angle % 90 == 0 
    480         self.__rotate(angle) 
     480        self._rotate(angle) 
    481481        return self 
    482482 
     
    489489        """ 
    490490        assert angle % 90 == 0 
    491         self.__rotate(-angle) 
     491        self._rotate(-angle) 
    492492        return self 
    493493 
    494     def __rotate(self, angle): 
     494    def _rotate(self, angle): 
    495495        currentAngle = self.get("/Rotate", 0) 
    496496        self[NameObject("/Rotate")] = NumberObject(currentAngle + angle) 
    497497 
    498     def __mergeResources(res1, res2, resource): 
     498    def _mergeResources(res1, res2, resource): 
    499499        newRes = DictionaryObject() 
    500500        newRes.update(res1.get(resource, DictionaryObject()).getObject()) 
     
    503503        for key in page2Res.keys(): 
    504504            if newRes.has_key(key) and newRes[key] != page2Res[key]: 
    505                 newname = NameObject(key + "_renamed") 
     505                newname = NameObject(key + "renamed") 
    506506                renameRes[key] = newname 
    507507                newRes[newname] = page2Res[key] 
     
    509509                newRes[key] = page2Res[key] 
    510510        return newRes, renameRes 
    511     __mergeResources = staticmethod(__mergeResources) 
     511    _mergeResources = staticmethod(_mergeResources) 
     512 
     513    def _contentStreamRename(stream, rename): 
     514        if not rename: 
     515            return stream 
     516        stream = ContentStream(stream) 
     517        newdata = StringIO() 
     518        for operands,operator in stream.operations: 
     519            for op in operands: 
     520                if isinstance(op, NameObject): 
     521                    op = rename.get(op, op) 
     522                op.writeToStream(newdata) 
     523                newdata.write(" ") 
     524            newdata.write(operator) 
     525            newdata.write("\n") 
     526        retval = DictionaryObject() 
     527        retval["__streamdata__"] = newdata.getvalue() 
     528        retval[NameObject('/Length')] = NumberObject(len(retval["__streamdata__"])) 
     529        return retval 
     530    _contentStreamRename = staticmethod(_contentStreamRename) 
    512531 
    513532    def mergePage(self, page2): 
    514533        """ 
    515         Merges the content streams of two pages into one. 
     534        Merges the content streams of two pages into one.  Resource 
     535        references (i.e. fonts) are maintained from both pages.  The 
     536        mediabox/cropbox/etc on "self" are not altered. 
    516537 
    517538        Stability: Added in v1.4, will exist for all v1.x releases thereafter. 
    518539        """ 
     540 
     541        # First we work on merging the resource dictionaries.  This allows us 
     542        # to find out what symbols in the content streams we might need to 
     543        # rename. 
     544 
     545        newResources = DictionaryObject() 
     546        rename = {} 
     547        originalResources = self["/Resources"].getObject() 
     548        page2Resources = page2["/Resources"].getObject() 
     549 
     550        newFonts, renameFonts = PageObject._mergeResources(originalResources, page2Resources, "/Font") 
     551        newResources[NameObject("/Font")] = newFonts 
     552        rename.update(renameFonts) 
     553 
     554        newGS, renameGS = PageObject._mergeResources(originalResources, page2Resources, "/ExtGState") 
     555        newResources[NameObject("/ExtGState")] = newGS 
     556        rename.update(renameGS) 
     557 
     558        # Combine /ProcSet sets. 
     559        newResources[NameObject("/ProcSet")] = ArrayObject( 
     560            ImmutableSet(originalResources.get("/ProcSet", ArrayObject()).getObject()).union( 
     561                ImmutableSet(page2Resources.get("/ProcSet", ArrayObject()).getObject()) 
     562            ) 
     563        ) 
     564 
    519565        newContentArray = ArrayObject() 
    520566 
     
    526572 
    527573        page2Content = page2['/Contents'].getObject() 
    528         if isinstance(page2Content, ArrayObject): 
    529             newContentArray.extend(page2Content) 
    530         else: 
    531             newContentArray.append(page2Content) 
    532  
    533         newResources = DictionaryObject() 
    534  
    535         originalResources = self["/Resources"].getObject() 
    536         page2Resources = page2["/Resources"].getObject() 
    537  
    538         newFonts, renameFonts = PageObject.__mergeResources(originalResources, page2Resources, "/Font") 
    539         newResources[NameObject("/Font")] = newFonts 
    540         newGS, renameGS = PageObject.__mergeResources(originalResources, page2Resources, "/ExtGState") 
    541         newResources[NameObject("/ExtGState")] = newGS 
    542  
    543         newResources[NameObject("/ProcSet")] = ArrayObject( 
    544             ImmutableSet(originalResources.get("/ProcSet", ArrayObject()).getObject()).union( 
    545                 ImmutableSet(page2Resources.get("/ProcSet", ArrayObject()).getObject()) 
    546             ) 
    547         ) 
     574        newContentArray.append(PageObject._contentStreamRename(page2Content, rename)) 
    548575 
    549576        self[NameObject('/Contents')] = newContentArray 
     
    594621 
    595622    def __parseContentStream(self, stream): 
    596         stream = StringIO(filters.decodeStreamData(stream)) 
     623        # stream may be an array of streams to concatenate. 
     624        stream = stream.getObject() 
     625        if isinstance(stream, ArrayObject): 
     626            data = "" 
     627            for s in stream: 
     628                data += filters.decodeStreamData(s.getObject()) 
     629            stream = StringIO(data) 
     630        else: 
     631            stream = StringIO(filters.decodeStreamData(stream)) 
    597632        operands = [] 
    598633        while True: 
     
    605640                self.operations.append((operands, operator)) 
    606641                operands = [] 
    607                 print self.operations[-1] 
    608642            else: 
    609643                operands.append(readObject(stream, None)) 
     644        stream.seek(0, 0) 
     645        data = stream.read() 
     646        if data.startswith("TJ"): 
     647            print data[:300] 
     648        print "----" 
     649        #print repr(stream.read(25)) 
     650        #print repr(self.operations[-3:]) 
    610651 
    611652 
     
    627668    output = PdfFileWriter() 
    628669 
    629     input1 = PdfFileReader(file("..\\test\\PDFReference16.pdf", "rb")) 
     670    input1 = PdfFileReader(file("..\\test\\5000-s1-05e.pdf", "rb")) 
    630671    page1 = input1.getPage(0) 
    631     page2 = input1.getPage(1) 
    632     page3 = input1.getPage(2) 
     672 
     673    input2 = PdfFileReader(file("..\\test\\PDFReference16.pdf", "rb")) 
     674    page2 = input2.getPage(0) 
     675    page3 = input2.getPage(1) 
    633676    page1.mergePage(page2) 
    634677    page1.mergePage(page3) 
     678 
    635679    output.addPage(page1) 
    636  
    637680    output.write(file("test.pdf", "wb")) 
    638681