Good point.  I've updated the unit test to check for page 1 content as well.
 
As you suggested, I overrode PDFCopy.getImportedPage() so it just delegates to super - that does indeed fix the problem that the unit test displays (all content streams are present and accounted for).
 
 
I think that we need to understand what PDFCopy is doing with currentPdfReaderInstance - here is my theory:
 
 
The *primary* purpose of getImportedPage() (in terms of how PdfCopy was originally designed, anyway) is to grab the imported page for the *primary* content of the PdfCopy (i.e. the source PDF - *not* the stamp PDF).  The reason there is special handling for getImportedPage is that as the primary input PdfReader changes, the state of PdfCopy has to change (does it????).
 
 
Now, we come along and try to use getImportedPage() to obtain content for a stamp, and that method just isn't intended for that (or maybe a better way of saying it is that the semantics of getImportedPage() in PdfCopy are inconsistent with the semantics of the method in PdfWriter).  So, it seems to me that there are three potential approaches here:
 
1.  Move the logic for changing the currentPdfReaderInstance into PdfCopy.addPage()  (I'm not sure if doing so will impact PdfCopy.PageStamp.alterContents() ) - interestingly, addPage() *already* changes the currentPdfReaderInstance value, so I'm pretty sure the only functionality that would need to be moved is the logic for closing the file of the old instance.
or
2.  add a special getImportedPage() call to the PdfCopy.PageStamp class
or
3.  make absolutely certain that changing the currentPdfReaderInstance in PdfCopy is actually necessary - if not, remove it.  Note that when I return getImportedPage() so it just delegates to super, the output files of my simple tests work fine.  But these all have the same page size, rotation, etc... - I'm not sure exactly what state in the currentPdfReaderInstance that PdfWriter is dependant on, so I can't say the implications of undoing this method override.
 
Thoughts or comments?
 
- K
 
 
----------------------- Original Message -----------------------
  
From: "Michael Klink" <[EMAIL PROTECTED]>
Cc: 
Date: Sat, 15 Nov 2008 22:40:21 +0100
Subject: Re: [iText-questions] Policy for adding unittests?
  
Kevin,

your fix indeed makes sure that the second XObject is included in the PDF... unfortunately the first one is not in there anymore. Therefore "testXObject(true, 2, "Xi1")" doesn't fail while a test for Xi0 on page 1 would fail.

As written before the problem is that PdfWriter.importPages only contains one PdfReaderInstance object per PdfReader while your usecase creates multiple such instances for the stampReader all of which are required during PdfWriter.close for a complete document.

Your fix only changed the Reader kept... 2.1.4 only kept the instance created first while your fix only keeps the instance created last.

A possible fix: If you simply delete the method PdfCopy (and thus don't override PdfWriter.getImportedPage anymore) the existing PdfReaderInstance object is reused, so only one XObject is created referenced indirectly as "2 0 R", on the first page named /Xi0, on the second named /Xi1.

I simply don't know whether the override which creates separate PdfReaderInstance objects fairly often, had been done for some reason that is still valid.

Regards,   Michael.

-----Ursprüngliche Nachricht-----
Von: Kevin Day [mailto:[EMAIL PROTECTED]
Gesendet: Samstag, 15. November 2008 02:23
An: [email protected]
Betreff: Re: [iText-questions] Policy for adding unittests?

Excellent information from everyone - thank you.

I did a little digging - and I think I have a fix - but I wanted to make sure my fix doesn't have any unexpected consequences before I submit it.

The fix is to add two lines (indicated in comments below) to PdfCopy.getImportedPage() :

   public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) {
    ;    if (currentPdfReaderInstance != null) {
           if (currentPdfReaderInstance.getReader() != reader) {
               try {
                   currentPdfReaderInstance.getReader().close();
                   currentPdfReaderInstance.getReaderFile().close();
               }
               catch (IOException ioe) {
                   // empty on purpose
                }
               currentPdfReaderInstance = reader.getPdfReaderInstance(this);
               importedPages.put(reader, currentPdfReaderInstance); // add this to fix issue +++++++++++++++
           }
       }
       else {
           currentPdfReaderInstance = reader.getPdfReaderInstance(this);
           importedPages.put(reader, currentPdfReaderInstance); // add this to fix issue ++++++++++++++++
       }
       return currentPd fReaderInstance.getImportedPage(pageNumber);            
   }



Once I make those changes, the unit tests pass, and the XObjects actually get written as they should.


Now - is there anything about what I'm doing here that is bad/wrong?

Also, it would be nice to get a quick explanation of why PdfCopy requires a special implementation of getImportedPage that changes the currentPdfReaderInstance whenever pages are being imported.

Thanks all,

- K


----------------------- Original Message -----------------------

From: "Michael Klink" <[EMAIL PROTECTED]>
To: [email protected]
Cc:
Date: Sat, 15 Nov 2008 00:10:29 +0100
Subject: Re: [iText-questions] Policy for adding unittests?

Kevin, Paulo,

> If I can paraphrase a bit:  if we are re-using the same stamp page,
> it would be more optimal if iText generated a single XObject for it
> and re-use the XObject on each page.

That would be ideal. But as mentioned (and as you saw yourself) even stamping from different pages of the same source file fails if you imported from some other file inbetween.

The reason are the multiple PdfReaderInstance instances generated in that case while only the one of them generated first is stored in PdfWriter.importedPages.

> If you open the PDF generated immediately following the failed test
> (if you are on Windows, you can uncomment the openFile(out) line
> in testWithoutReloadingStampReader() ), you'll see that Adobe also
> chokes on the missing Xi1 reference.

Yes, obviously, as the second XObject is not included in the document (due to the reason mentioned above), b ut an indirect reference has been created --> Acrobat chokes.

> Can anyone point me in a direction to determine when in the
> PdfContentByte.addTemplate() call the object content for the
> imported page actually gets added to the writer?  The indirect
> reference is certainly being added - but the actual object content
> (i.e. the 10 0 obj ..... stuff) is never making it into the output stream.

It is NOT added to the writer during addTemplate. In that method a PdfReaderInstance for that reader is marked for the page in question and is offered to the PdfWriter to add it to its importedPages Map. This only happens, though, if there is not yet an instance for that very reader added.
During PdfWriter.close() PdfWriter.addSharedObjectsToBody() is called and adds the pages marked in the importedPages PdfReaderInstance instances to the result document --- and, therefore, any pages marked for import in some PdfReaderInstance that h as been rejected from being added to importedPages are NOT added to the result document.

I wonder why there is an override for the PdfWriter.getImportedPage method in PdfCopy. The PdfWriter version looks as though it would work alright for PdfCopy, too. I have not yet used PdfCopy very much, so maybe there is some reason...

Regards,   Michael.

--
Sensationsangebot nur bis 30.11: GMX FreeDSL - Telefonanschluss + DSL
für nur 16,37 Euro/mtl.!* http://dsl.gmx.de/?ac=OM.AD.PD003K11308T4569a

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url="">
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions

Buy the iText book: http://www.1t3xt.com/docs/book.php

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions

Buy the iText book: http://www.1t3xt.com/docs/book.php

Reply via email to