How can an Acrobat plugin store document-wide information in a PDF file?
I'm looking for a way for our Acrobat plugin to store some document-wide information in a PDF file.
The info would be a simple list of strings.
The list of strings would be displayed and edited in a dialog box displayed by our plugin.
The user would later select one of the strings when using our plugin to add one of our Acrobat plugin's custom annotations to the PDF file.
Multiple annotations can be added to the PDF.
The idea is for the list of strings to be stored in one place in the PDF and for each of our plugin's annotations to store an integer index into the list of strings in the dictionary associated with the annotation.
So far I have these ideas:
APPROACH #1: Store the list of strings in the XMP metadata in the PDF file
This approach would use the functions
PDDocGetXAPMetadata() and PDDocSetXAPMetadata()
or
PDDocCountXAPMetadataArrayItems(), PDDocGetXAPMetadataArrayItem(), PDDocSetXAPMetadataArrayItem()
I read about PDF XMP XML metadata in "Developing with PDF - Dive into the Portable Document Format" by Leonard Rosenthol - a great book.
But I don't like this idea - the user can see the XMP metadata in Acrobat just by viewing document properties and opening the Additional Metadata dialog.
So far, I've only tried using PDDocGetXAPMetadata() and PDDocSetXAPMetadata() - these functions get and set ALL of the XMP metdata XML for the PDF file.
PDDocGetXAPMetadata() returns the data in an altered XML layout - if a PDF has multiple <rdf:Description> XML tags in its XMP metadata, the child tags of the separate <rdf:Description> XML tags are converted into attributes of a single <rdf:Description> XML tag, which means future calls to PDDocSetXAPMetadata() will change the original format of the PDF's XMP metadata XML.
And there is another issue - PDDocSetXAPMetadata() saves the XMP XML data, but leaves the previous copy of the XMP XML data in the PDF file, so that the file grows larger each time you call it. Future calls to PDDocGetXAPMetadata() correctly return the last XMP XML that was set, but why are previous versions of the XMP XML being left in the PDF file?
Maybe I'll have better luck with PDDocCountXAPMetadataArrayItems(), PDDocGetXAPMetadataArrayItem(), PDDocSetXAPMetadataArrayItem().
APPROACH #2: Create an indirect array and store an entry for it in the PDF file's Catalog Dictionary
This approach would use code like:
AVDoc avDoc = AVAppGetActiveDoc();
PDDoc pdDoc = AVDocGetPDDoc(avDoc);
CosDoc cosDoc = PDDocGetCosDoc (pdDoc);
CosObj catalogDict = CosDocGetRoot(cosDoc);
CosObj myStringListArray = CosDictGetKeyString(catalogDict, "MyAcrobatPluginName_MyListOfStrings");
if ( CosObjGetType( myStringListArray ) == CosNull ) {
// add mark info to the document
myStringListArray = CosNewArray( cosDoc, true, 1 );
CosDictPutKeyString( catalogDict, "MyAcrobatPluginName_MyListOfStrings", myStringListArray );
}
// Use CosArrayInsert(), CosArrayLength(), CosArrayGet(), CosArrayRemove() to get/set the contents of myStringListArray.
But is it legal for an Acrobat plugin to add any entry it wants to a PDF file's Catalog Dictionary? Or must all entries in the Catalog Dictionary be limited to those listed in the PDF standard?
A separate issue - the potential for name collisions with data stored by other Acrobat plugins exists - must the Catalog Dictionary entry name be prefixed with some kind of registered name for the plugin?
APPROACH #3:
Use a "PDF version extensions" as described at https://opensource.adobe.com/dc-acrobat-sdk-docs/library/plugin/Plugins_Documents.html#pdf-version-extensions
This approach involves adding an "Extensions" dictionary to the PDF file's Catalog Dictionary.
Then we would add an child dictionary for our Acrobat plugin to the "Extensions" dictionary, like this:
<</Type /Catalog
/Extensions
<</ADBE
<< /BaseVersion /1.7 /ExtensionLevel 3 >>
>>
<</MYCOMPANY
<< /BaseVersion /1.0 /ExtensionLevel 1 >>
>>
>>
The question is - can the child dictonary for MYCOMPANY store any information the plugin wants, like another dictionary entry with an indirect reference to a list of strings?
