iPDFdev Tips & Tricks for PDF development

IFXPDFFactory – part 9 – PDF optional content / layers

September 04th, 2013

PDF optional content (also known as PDF layers) refers to sections of content in a PDF document that can be selectively viewed, printed or hidden by document authors or consumers. This feature is now implemented in IFXPDFFactory framework.
Optional content sections in a PDF page are started using an optional content group start marker and finished by an optional content group end marker. The optional content group is represented by IFXPDFOptionalContentGroup class. The optional content group is identified by its name which is also used to display the optional content group in the PDF viewer user interface.

The optional content in the page content is defined using beginOptionalContentGroup: and endOptionalContentGroup methods included in IFXPDFPageGraphics class.

IFXPDFOptionalContentGroup* ocg1 = 
    [IFXPDFOptionalContentGroup optionalContentGroupWithName:@"OptionalContentGroup1"];
[page.graphics beginOptionalContentGroup:ocg1];
// draw page content
[page.graphics endOptionalContentGroup];

The optional content group has a default state which can be On or Off. Also the visibility of the optional content can be controlled depending on the usage of the optional content: for viewing, for printing or for export to other formats. The visible state for viewing operations has the following options: visible when on, always visible, never visible. The visible state for printing operations has the following options: print when visible, always print, never print. The visible state for export operations has the following options: export when visible, always export, never export.

IFXPDFOptionalContentGroup* ocgView = 
    [IFXPDFOptionalContentGroup optionalContentGroupWithName:@"View only"];
ocgView.visibleState = IFXPDFOptionalContentGroupAlwaysVisibleState;
ocgView.printState = IFXPDFOptionalContentGroupNeverPrintState;
ocgView.exportState = IFXPDFOptionalContentGroupNeverExportState;
[page.graphics beginOptionalContentGroup:ocgView];
// Draw page content. It will be displayed in the viewer but it will not be printed.
[page.graphics endOptionalContentGroup];
IFXPDFOptionalContentGroup* ocgPrint = 
    [IFXPDFOptionalContentGroup optionalContentGroupWithName:@"Print only"];
ocgPrint.visibleState = IFXPDFOptionalContentGroupNeverVisibleState;
ocgPrint.printState = IFXPDFOptionalContentGroupAlwaysPrintState;
ocgPrint.exportState = IFXPDFOptionalContentGroupAlwaysExportState;
[page.graphics beginOptionalContentGroup:ocgPrint];
// Draw page content. It will not be displayed in the viewer but it will be printed (useful for watermarks).
[page.graphics endOptionalContentGroup];

While the code above creates optional content sections in PDF page content, they are not visible in PDF viewer user interface (the Layers tab in Adobe Reader) so that the end user can show/hide them. The optional content is displayed in this tab in a tree structure where each node of the tree displays the optional content group name. A node is this tree is represented by a IFXPDFOptionalContentVisualTreeNode object, each node having an optional content group associated with it. Each node also has a collection of child nodes which is used to create in the end the optional content visual tree.

Note: there is no relation between how the optional content groups are represented in the visual tree and how they are actually laid out on the page. Two sibling optional content groups in the page content can be represented as parent-child in the visual tree. It is only up to you how the visual tree is built.

The optional content visual tree is represented by IFXPDFOptionalContentVisualTree class. It has the nodes property which represents the root nodes in the tree. The optional content visual tree is created automatically as a part of IFXPDFOptionalContentProperties class and it is available through the visualTree property. An IFXPDFOptionalContentProperties object must be created and added to the PDF document in order for the optional content infrastructure to work.

The sample below shows how to create 2 optional content groups on the page and how to setup the optional content visual tree for the PDF viewer.

IFXPDFDocument* doc = [[IFXPDFDocument alloc] init];
doc.optionalContentProperties = [IFXPDFOptionalContentProperties optionalContentProperties];
IFXPDFPage* page = [IFXPDFPage emptyPage];
[doc.pages addPage:page];
IFXPDFPen* redPen = [IFXPDFPen penWithColor:[IFXPDFRgbColor redColor] andWidth:10];
IFXPDFBrush* blueBrush = [IFXPDFBrush brushWithColor:[IFXPDFRgbColor blueVioletColor]];
IFXPDFOptionalContentGroup* ocg1 = 
    [IFXPDFOptionalContentGroup optionalContentGroupWithName:@"Top ellipse"];
[page.graphics beginOptionalContentGroup:ocg1];
[page.graphics drawEllipseWithPen:redPen andBrush:blueBrush atX:50 y:50 withWidth:500 height:200];
[page.graphics endOptionalContentGroup];
IFXPDFOptionalContentGroup* ocg2 = 
    [IFXPDFOptionalContentGroup optionalContentGroupWithName:@"Bottom ellipse"];
[page.graphics beginOptionalContentGroup:ocg2];
[page.graphics drawEllipseWithPen:redPen andBrush:blueBrush atX:50 y:500 withWidth:500 height:200];
[page.graphics endOptionalContentGroup];
IFXPDFOptionalContentVisualTreeNode* ocg1Node =
    [[IFXPDFOptionalContentVisualTreeNode optionalContentVisualTreeNodeWithGroup:ocg1];
[doc.optionalContentProperties.visualTree.nodes addOptionalContentVisualTreeNode:ocg1Node];
IFXPDFOptionalContentVisualTreeNode* ocg2Node =
    [[IFXPDFOptionalContentVisualTreeNode optionalContentVisualTreeNodeWithGroup:ocg2];
[doc.optionalContentProperties.visualTree.nodes addOptionalContentVisualTreeNode:ocg2Node];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfFile = [documentsDirectory stringByAppendingPathComponent:@"OptionalContent.pdf"];
[doc writeToFile:pdfFile];
[doc release];
Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

No trackbacks yet.