Chapter 10. Optional Content

Optional content is a feature of PDF that allows specific graphic objects and/or annotations to be visible only when a certain set of criteria is met. These criteria can be specified by the author of the content—for example, that this content should only appear on the screen and never print—or can be specified by the user via some interaction with the viewer. This feature is useful for a variety of things, ranging from CAD drawings to maps to multilanguage documents and more.

The basic building block for defining optional content is the optional content group (OCG), which is a dictionary that consists of the required Type (which is always OCG), the required Name of the group (which may be displayed by a viewer), and the Usage key, which declares how the group is to be used.

Content is usually grouped together because it shares some common feature. It may be the language of the content, or that it is only for use on screen. The optional content usage dictionary, which is the value of the Usage key in the optional content group dictionary, declares the commonality (see Example 10-1). This usage information is then used by the PDF viewer to determine whether to evaluate the group’s state based on external factors in conjunction with the value of the AS key in the optional content configuration dictionary (see Optional Content Configuration).

A Usage dictionary may contain any number of keys, if the group has multiple things in common. The most commonly used keys are the following:

Export
The value of this key is a dictionary containing a single key, ExportState, whose value (of type Name) is either ON or OFF, declaring whether this content should be exported by the viewer into a nonoptional-content-aware format (such as raster images or Postscript).
Print
The key’s value is a dictionary containing a single key, PrintState, whose value (of type Name) is either ON or OFF declaring whether this content should be printed.
View
The value of this key is a dictionary containing a single key, ViewState, whose value (of type Name) is either ON or OFF, declaring whether this content should be displayed on the screen (or whatever the default “view” of the viewer is).
Zoom
The dictionary value of this key contains either the min key, the max key, or both. The values of these keys, if present, specify the minimum and maximum zoom/magnification (in percentage) at which the group should be considered ON.
Language
The value of this key is a dictionary that declares the natural language of the content in the group via its Lang key.

Note

Although Language is a great way to group content, it is not automatically detected and assigned a group state by common viewers.

While most content only needs to be a member of a single optional content group and its associated usage dictionary, sometimes content may belong to multiple groups, and those groups may have conflicting states. In order to provide the viewer with the necessary information to resolve such potential conflicts, this type of content should be associated with an optional content membership dictionary (OCMD) instead of an optional content group.

An OCMD is, at its heart, a list of the OCGs that specify the various potential visibility states along with either a visibility policy or a visibility expression that describes how to determine the state.

A visibility policy is the simplest way to specify how the various OCG states will be resolved (see Example 10-2). This is the preferred method and should be used in favor of visibility expressions if possible.

The policy is specified by a single name object with one of four possible values. This value is that of the P key in the OCMD. The available policy values are the following:

AllOn
Visible only if all of the entries in the OCGs are ON
AnyOn
Visible if any of the entries in the OCGs are ON
AnyOff
Visible if any of the entries in the OCGs are OFF
AllOff
Visible only if all of the entries in the OCGs are OFF

A visibility expression, as the name implies, allows for more complex Boolean expressions in defining how the various OCG states should be resolved. When a viewer evaluates a visibility expression, if the expression evaluates to true, then the optional content group is in the ON state. If it evaluates to false, then the state is OFF.

The expression is an array whose first element is a name representing a Boolean operator (And, Or, or Not), while subsequent elements are either optional content groups or other visibility expressions. If the first element of the expression is Not, then there is only one subsequent element; otherwise (for And or Or), it can have one or more subsequent elements.

Example 10-3 shows what the visibility policy would look like as a visibility expression.

Example 10-4 shows a more complex expression that relates five different groups, represented by the objects 1 through 5 in the PDF, named OCG 1 through OCG 5, respectively. If written out, the example would read as "OCG 1"; OR (NOT "OCG 2") OR ("OCG 3" AND "OCG 4" AND "OCG 5")“.

An optional content configuration dictionary (OCCD) represents a preset configuration of the state for one or more groups. A PDF (that has OCGs) may contain several OCCDs, but must include at least one. The reason for the one is that when a document is first opened by a conforming reader, the groups’ states are initialized based on the document’s default OCCD.

While all of the keys in the OCCD are optional, it is most common to have at least some combination of BaseState and ON or OFF present. BaseState is a name (either ON, OFF, or Unchanged) that represents the state of all groups to start with. This “base state” can then be adjusted through the use of the ON and/or OFF keys, which list specific OCGs whose state to set to ON or OFF. It is also common to give the OCCD a name via the Name key. Example 10-5 shows a simple optional content configuration dictionary.

In some cases, the choices about which content should be visible and which should not are made by the author of the content and remain stable throughout the content’s life. However, most content that is described with optional content groups is done so that a user can manually change the visibility of the content. For example, with a complex architectural or electrical diagram, the user may need to turn on or off various groups of graphic elements in order to see just the important ones.

To request that a PDF viewer present a list of user-configurable optional content to the user, the Order key is used. For a simple list of groups like the one in Figure 10-1, the value of the key is a one-dimensional array of OCGs.

It is also possible to group the OCGs in various hierarchical groupings, in a way that might be helpful to the user or that just generally represents logical groupings of the content. For example, if there is a specialized subcategory of elements, they can be collected together.

The name of the group can be taken from the OCG that immediately precedes the subarray of elements, or it can be specified by a text string in the subarray. Figure 10-2 shows a few examples of hierarchical groupings of OCGs.

Even after all the OCGs, OCMDs, and OOCDs are added to the PDF, there is still one more dictionary that is required. This is the optional content properties dictionary; it is the value of the OCProperties key in the document catalog dictionary. Without this, a viewer will not be aware that there is any optional content in the PDF.

There are two required keys in the properties dictionary:

Optionally, if the PDF contains multiple OCCDs, they can be listed as the value of the Configs key in this dictionary. A sample optional content properties dictionary is shown in Example 10-7.

So far in this chapter we’ve seen how to create optional content groups and all of the infrastructure for making them available to a PDF viewer and its users. However, a PDF containing all of the previously described objects is still missing one key component—how are the content elements connected to the optional content groups or optional content membership dictionaries that may affect their visibility? Any content whose visibility will be affected by a given optional content group is said to belong to (or have membership in) that group.

To specify which specific content elements of a content stream are to be associated with an optional content group or optional content membership dictionary, they need to be enclosed between the marked content operators BDC and EMC. The BDC operator will use the tag of OC, and the associated property list specifies the OCG or OCMD to which the content belongs. Since the reference to the group is via its indirect object, the property list must used the named resource form for property lists.

Example 10-8 shows a simple example of how to mark content in a stream as optional.

Content can be associated with one or more OCGs and/or OCMDs, and the content of a group need not be contiguous in the content stream, or even in the same content stream (see Figure 10-4). This makes optional content extremely flexible for many purposes (see Figure 10-5).

For form XObjects or image XObjects that are used only in a single content stream, simply marking up the invoking stream can be done easily. However, when such objects are used in multiple content streams and will be consistently in the same group(s), it is easier to take advantage of the OC key in the XObject dictionary. The value of the OC key in the XObject dictionary is an indirect reference to the optional content group or optional content membership dictionary to which it belongs. Example 10-9 illustrates this usage.

If a form XObject or image XObject has an OC key and the same XObject is also part of an optional content group or optional content membership dictionary configured inside of a content stream, the combination of the two states (treated as an AND) will be used to determine the visibility of the object. For example, if the OCG value of the OC key evaluates to ON but the content stream evaluates to OFF, then the state for the object will be OFF.

It is also possible to have individual content of a form XObject be part of an OCG or OCMD. In that instance, the visibility of the XObject will be evaluated, and if its state is ON, the specific graphics objects will be evaluated.

In this chapter you learned about optional content groups, including how to create them and associate content with them. Next you will look at how to add semantic richness to PDF content.