Q: I’m trying to add a font object to each page’s resource dictionary. My current approach is to check for the resource dictionary inside the page, and if it is not present, create it:
PDF::Page
page = doc.GetPage (1);
SDF::Obj dict = page.GetSDFObj ();
SDF::Obj resources = dict.FindObj ("Resources");
if (!(bool)resources)
resources = dict.PutDict ("Resources");
However, on certain documents, after adding the resource dictionary, ElementReader throws an exception: “Resource not found”. How is this possible, given that there was no resource dictionary in the page to start with?
A: The confusion here stems from a corner of the PDF
Specification, Inheritance of Page
Attributes. According to the specification, “when an attribute is omitted
from a page object, its value shall be inherited from an ancestor node in the
page tree.” In other words, by adding an
empty resource dictionary to the ‘Page’ dictionary, you are overriding the
existing, inherited resource dictionary.
As a result, the page loses the references to its existing resources,
and the document is now corrupt.
Fortunately, PDFNet offers a simple solution to this problem. Rather than using:
SDF::Obj resources = dict.FindObj("Resources");
You should use:
SDF::Obj resources = dict. FindInheritedAttribute("Resources");
This will resolve page attribute inheritance, and return the correct dictionary for the page. This method should be used for all inheritable attributes, as specified in the PDF specification.