The problem

To illustrate this, imagine that you have 2 PDF documents open, docA and docB. Imagine that we want to lookup an object from docA, and insert into docB. A naive code fragment to do this might be:


\begin{lstlisting}
pdf_dict_putp_drop(ctx,
pdf_trailer(ctx, docB),
''Root/Exam...
...f_dict_getp(ctx,
pdf_trailer(ctx, docA),
''Root/Example''));
\end{lstlisting}

This may actually work in limited cases, such as:


\begin{lstlisting}
1 0 obj
<<
/Type /Catalog
/Pages 3 0 R
/Metadata 9 0 R
/Example true
>>
endobj
...
trailer
<<
/Root 1 0 R
>>
\end{lstlisting}

The value of Root/Example is read as true, which can safely be written into another file.

This can easily fall down though, as can be seen in more complex cases:


\begin{lstlisting}
2 0 obj
/Complex
endobj
1 0 obj
<<
/Type /Catalog
/Pages 3 ...
...ample [ (More) 2 0 R ]
>>
endobj
...
trailer
<<
/Root 1 0 R
>>
\end{lstlisting}

In this case the value of Root/Example is read as an array of 2 elements; the first element being the string "More", and the second being a reference to object 2 in the file.

If this was to be written directly into the new file, we'd still have an array of 2 elements, with the first element being the string "More". The second would refer to whatever object 2 in the new file happens to be.

The solution to this requires us to walk the directed (possibly cyclic) graph of child objects within the object to be copied from one file to another, and to `deep copy' the contents.

We refer to this process as `grafting' objects from one tree into another.