Skip to content

Forward Referencing

gal kahana edited this page May 12, 2023 · 4 revisions

Content streams, of either Pages or Form XObjects, refer to objects, such as Images, Forms or Fonts.
Based on what is the algorithm of writing the PDF file, your application may require to first refer to the particular object and only later to define it.
For example, you could be building a PDF in which all image content is generated at the final stages of writing the PDF. however, usage is all over the PDF. This would make sense, for example, in a scenario that images in a certain pool needs to go through processing, and you wish to do that processing only on images that are actually used. you would first refer to the images, and only later actually draw them in the PDF.

However, the normal flow of the PDF library requires that you first create an object and only later use it. For example, forms creation is accompanied with an automatic object ID allocation which can later be used in references. It is true that for Pages you can pause temporarily the page creation and create the Image first drawing on the first usage. Still, you might require that the image is first referred and only later used.

it’s quite easy to do. All relevant object (at this point – images and forms) can receive an Object ID while they are being created. This Object ID can be allocated earlier, And used in all references.

here, for example, is how to do this with a Form XObject:

pageContentContext->q();
pageContentContext->cm(1,0,0,1,0,400);
ObjectIDType formXObjectID = 
    pdfWriter.GetObjectsContext().GetInDirectObjectsRegistry().AllocateNewObjectID();
pageContentContext->Do(page->GetResourcesDictionary().AddFormXObjectMapping(formXObjectID));
pageContentContext->Q();

Note the 3rd line of code – The PDFWriter object is requested for the ObjectsContext via the GetObjectsContext method. Then the IndirectObjectsReferenceRegistry is retrieved via the GetInDirectObjectsRegistry, which is then used for allocating a new object ID.
This new ID will be used for referencing the Object ID, as is shown a row later. Note the shorthand of applying “Do” directly with the mapping result.

Now, much much later you can define the Form itself with that ID:
PDFFormXObject* formXObject = pdfWriter.CreateFormXObjectFromJPGFile("C:\\otherStage.JPG",formXObjectID);

Note how the CreateFormXObjectFromJPGFile receives a second parameter which is the form XObject ID. it will use that ID for the form XObject.

The methods that can receive an object ID in the PDFWriter are:

  1. PDFFormXObject* CreateFormXObjectFromJPGFile(const string& inJPGFilePath,ObjectIDType inFormXObjectID)
    Form XObject creation from a JPG file.
  2. PDFFormXObject* CreateFormXObjectFromTIFFFile( const string& inTIFFFilePath, ObjectIDType inFormXObjectID, const TIFFUsageParameters& inTIFFUsageParameters)
    Form XObject creation from a TIFF file.
  3. PDFImageXObject* CreateImageXObjectFromJPGFile(const string& inJPGFilePath,ObjectIDType inImageXObjectID)
    Image XObject creation from a JPG file.
  4. PDFFormXObject* StartFormXObject(const PDFRectangle& inBoundingBox,ObjectIDType inFormXObjectID,const double* inMatrix)
    Start Form XObject creation.

For a complete example of how to use forward referencing see ImagesAndFormsForwardReferenceTest.

Clone this wiki locally