summaryrefslogtreecommitdiff
path: root/xpdf/OptionalContent.h
blob: 82d3e0ef521e0a67b147b48a6021f58220e9fa64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//========================================================================
//
// OptionalContent.h
//
// Copyright 2008 Glyph & Cog, LLC
//
//========================================================================

#ifndef OPTIONALCONTENT_H
#define OPTIONALCONTENT_H

#include <aconf.h>

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#include "gtypes.h"
#include "Object.h"
#include "CharTypes.h"

class GString;
class GList;
class PDFDoc;
class XRef;
class OptionalContentGroup;
class OCDisplayNode;

//------------------------------------------------------------------------

class OptionalContent {
public:

  OptionalContent(PDFDoc *doc);
  ~OptionalContent();

  // Walk the list of optional content groups.
  int getNumOCGs();
  OptionalContentGroup *getOCG(int idx);

  // Find an OCG by indirect reference.
  OptionalContentGroup *findOCG(Ref *ref);

  // Get the root node of the optional content group display tree
  // (which does not necessarily include all of the OCGs).
  OCDisplayNode *getDisplayRoot() { return display; }

  // Evaluate an optional content object -- either an OCG or an OCMD.
  // If <obj> is a valid OCG or OCMD, sets *<visible> and returns
  // true; otherwise returns false.
  GBool evalOCObject(Object *obj, GBool *visible);

private:

  GBool evalOCVisibilityExpr(Object *expr, int recursion);

  XRef *xref;
  GList *ocgs;			// all OCGs [OptionalContentGroup]
  OCDisplayNode *display;	// root node of display tree 
};

//------------------------------------------------------------------------

// Values from the optional content usage dictionary.
enum OCUsageState {
  ocUsageOn,
  ocUsageOff,
  ocUsageUnset
};

//------------------------------------------------------------------------

class OptionalContentGroup {
public:

  static OptionalContentGroup *parse(Ref *refA, Object *obj);
  ~OptionalContentGroup();

  GBool matches(Ref *refA);

  Unicode *getName() { return name; }
  int getNameLength() { return nameLen; }
  OCUsageState getViewState() { return viewState; }
  OCUsageState getPrintState() { return printState; }
  GBool getState() { return state; }
  void setState(GBool stateA) { state = stateA; }

private:

  OptionalContentGroup(Ref *refA, Unicode *nameA, int nameLenA,
		       OCUsageState viewStateA, OCUsageState printStateA);

  Ref ref;
  Unicode *name;
  int nameLen;
  OCUsageState viewState,	// suggested state when viewing
               printState;	// suggested state when printing
  GBool state;			// current state (on/off)
};

//------------------------------------------------------------------------

class OCDisplayNode {
public:

  static OCDisplayNode *parse(Object *obj, OptionalContent *oc, XRef *xref,
			      int recursion = 0);
  OCDisplayNode();
  ~OCDisplayNode();

  Unicode *getName() { return name; }
  int getNameLength() { return nameLen; }
  OptionalContentGroup *getOCG() { return ocg; }
  int getNumChildren();
  OCDisplayNode *getChild(int idx);

private:

  OCDisplayNode(GString *nameA);
  OCDisplayNode(OptionalContentGroup *ocgA);
  void addChild(OCDisplayNode *child);
  void addChildren(GList *childrenA);
  GList *takeChildren();

  Unicode *name;		// display name (may be NULL)
  int nameLen;
  OptionalContentGroup *ocg;	// NULL for display labels
  GList *children;		// NULL if there are no children
				//   [OCDisplayNode]
};

#endif