John Hewson created PDFBOX-2592:
-----------------------------------
Summary: Allow sharing of COS objects between different documents
Key: PDFBOX-2592
URL: https://issues.apache.org/jira/browse/PDFBOX-2592
Project: PDFBox
Issue Type: Improvement
Components: PDModel
Affects Versions: 2.0.0
Reporter: John Hewson
A number of users on the mailing list have asked about how to import pages from
other PDFs as forms, our current solution is LayerUtility, which is depends on
PDFCloneUtility. Both these classes are surprisingly complex for what should be
a simple task.
The two main tasks which these classes perform is copying the page's COSStream
and cloning every relevant COS object. However, there seems to be no real need
to do any of this copying and cloning - there's nothing about any of the COS
objects which is specific to a given document. While a COSStream can share the
same backing file as the COSDocument, this isn't a problem for COSWriter, even
then we need only make sure that an exception is thrown if a COSStream is used
after its parent COSDocument is closed.
Note that there *is* one artificial dependency between COSDictionary and
COSArrays and their parent COSDocument, that is that calling close() on the
COSDocument clears the contents of all child COSDictionary and COSArrays.
However, there's no need for this, it seems to have come about due to some long
past confusion regarding how garbage collection works in Java - we all know
that it's not necessary to set objects to null or clear lists when we are done
with them.
I propose that we get rid of the unnecessary object and list clearing in
COSDocument#close() and add some checks to COSStream to throw user-friendly
exceptions when reading from a closed backing stream. This will allow us to
directly share COS objects between different COSDocuments, allowing simple "x =
y" copying and making LayerUtility and PDFCloneUtility unnecessary. Instead of:
{code}
COSStream pageStream = (COSStream)page.getStream().getCOSObject();
PDStream newStream = new PDStream(targetDoc,
pageStream.getUnfilteredStream(), false);
PDFormXObject form = new PDFormXObject(newStream);
//Copy resources
PDResources pageRes = page.getResources();
PDResources formRes = new PDResources();
cloner.cloneMerge(pageRes, formRes);
form.setResources(formRes);
{code}
We could have:
{code}
PDFormXObject form = new PDFormXObject(page.getStream());
form.setResources(page.getResources());
{code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)