1 //========================================================================
2 //
3 // Link.h
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8 
9 #ifndef LINK_H
10 #define LINK_H
11 
12 #include <aconf.h>
13 
14 #ifdef USE_GCC_PRAGMAS
15 #pragma interface
16 #endif
17 
18 #include "Object.h"
19 
20 class GString;
21 class Array;
22 class Dict;
23 
24 //------------------------------------------------------------------------
25 // LinkAction
26 //------------------------------------------------------------------------
27 
28 enum LinkActionKind {
29   actionGoTo,			// go to destination
30   actionGoToR,			// go to destination in new file
31   actionLaunch,			// launch app (or open document)
32   actionURI,			// URI
33   actionNamed,			// named action
34   actionMovie,			// movie action
35   actionJavaScript,		// run JavaScript
36   actionSubmitForm,		// submit form
37   actionHide,			// hide annotation
38   actionUnknown			// anything else
39 };
40 
41 class LinkAction {
42 public:
43 
44   // Destructor.
~LinkAction()45   virtual ~LinkAction() {}
46 
47   // Was the LinkAction created successfully?
48   virtual GBool isOk() = 0;
49 
50   // Check link action type.
51   virtual LinkActionKind getKind() = 0;
52 
53   // Parse a destination (old-style action) name, string, or array.
54   static LinkAction *parseDest(Object *obj);
55 
56   // Parse an action dictionary.
57   static LinkAction *parseAction(Object *obj, GString *baseURI = NULL);
58 
59   // Extract a file name from a file specification (string or
60   // dictionary).
61   static GString *getFileSpecName(Object *fileSpecObj);
62 };
63 
64 //------------------------------------------------------------------------
65 // LinkDest
66 //------------------------------------------------------------------------
67 
68 enum LinkDestKind {
69   destXYZ,
70   destFit,
71   destFitH,
72   destFitV,
73   destFitR,
74   destFitB,
75   destFitBH,
76   destFitBV
77 };
78 
79 class LinkDest {
80 public:
81 
82   // Build a LinkDest from the array.
83   LinkDest(Array *a);
84 
85   // Copy a LinkDest.
copy()86   LinkDest *copy() { return new LinkDest(this); }
87 
88   // Was the LinkDest created successfully?
isOk()89   GBool isOk() { return ok; }
90 
91   // Accessors.
getKind()92   LinkDestKind getKind() { return kind; }
isPageRef()93   GBool isPageRef() { return pageIsRef; }
getPageNum()94   int getPageNum() { return pageNum; }
getPageRef()95   Ref getPageRef() { return pageRef; }
getLeft()96   double getLeft() { return left; }
getBottom()97   double getBottom() { return bottom; }
getRight()98   double getRight() { return right; }
getTop()99   double getTop() { return top; }
getZoom()100   double getZoom() { return zoom; }
getChangeLeft()101   GBool getChangeLeft() { return changeLeft; }
getChangeTop()102   GBool getChangeTop() { return changeTop; }
getChangeZoom()103   GBool getChangeZoom() { return changeZoom; }
104 
105 private:
106 
107   LinkDestKind kind;		// destination type
108   GBool pageIsRef;		// is the page a reference or number?
109   union {
110     Ref pageRef;		// reference to page
111     int pageNum;		// one-relative page number
112   };
113   double left, bottom;		// position
114   double right, top;
115   double zoom;			// zoom factor
116   GBool changeLeft, changeTop;	// which position components to change:
117   GBool changeZoom;		//   destXYZ uses all three;
118 				//   destFitH/BH use changeTop;
119 				//   destFitV/BV use changeLeft
120   GBool ok;			// set if created successfully
121 
122   LinkDest(LinkDest *dest);
123 };
124 
125 //------------------------------------------------------------------------
126 // LinkGoTo
127 //------------------------------------------------------------------------
128 
129 class LinkGoTo: public LinkAction {
130 public:
131 
132   // Build a LinkGoTo from a destination (dictionary, name, or string).
133   LinkGoTo(Object *destObj);
134 
135   // Destructor.
136   virtual ~LinkGoTo();
137 
138   // Was the LinkGoTo created successfully?
isOk()139   virtual GBool isOk() { return dest || namedDest; }
140 
141   // Accessors.
getKind()142   virtual LinkActionKind getKind() { return actionGoTo; }
getDest()143   LinkDest *getDest() { return dest; }
getNamedDest()144   GString *getNamedDest() { return namedDest; }
145 
146 private:
147 
148   LinkDest *dest;		// regular destination (NULL for remote
149 				//   link with bad destination)
150   GString *namedDest;		// named destination (only one of dest and
151 				//   and namedDest may be non-NULL)
152 };
153 
154 //------------------------------------------------------------------------
155 // LinkGoToR
156 //------------------------------------------------------------------------
157 
158 class LinkGoToR: public LinkAction {
159 public:
160 
161   // Build a LinkGoToR from a file spec (dictionary) and destination
162   // (dictionary, name, or string).
163   LinkGoToR(Object *fileSpecObj, Object *destObj);
164 
165   // Destructor.
166   virtual ~LinkGoToR();
167 
168   // Was the LinkGoToR created successfully?
isOk()169   virtual GBool isOk() { return fileName && (dest || namedDest); }
170 
171   // Accessors.
getKind()172   virtual LinkActionKind getKind() { return actionGoToR; }
getFileName()173   GString *getFileName() { return fileName; }
getDest()174   LinkDest *getDest() { return dest; }
getNamedDest()175   GString *getNamedDest() { return namedDest; }
176 
177 private:
178 
179   GString *fileName;		// file name
180   LinkDest *dest;		// regular destination (NULL for remote
181 				//   link with bad destination)
182   GString *namedDest;		// named destination (only one of dest and
183 				//   and namedDest may be non-NULL)
184 };
185 
186 //------------------------------------------------------------------------
187 // LinkLaunch
188 //------------------------------------------------------------------------
189 
190 class LinkLaunch: public LinkAction {
191 public:
192 
193   // Build a LinkLaunch from an action dictionary.
194   LinkLaunch(Object *actionObj);
195 
196   // Destructor.
197   virtual ~LinkLaunch();
198 
199   // Was the LinkLaunch created successfully?
isOk()200   virtual GBool isOk() { return fileName != NULL; }
201 
202   // Accessors.
getKind()203   virtual LinkActionKind getKind() { return actionLaunch; }
getFileName()204   GString *getFileName() { return fileName; }
getParams()205   GString *getParams() { return params; }
206 
207 private:
208 
209   GString *fileName;		// file name
210   GString *params;		// parameters
211 };
212 
213 //------------------------------------------------------------------------
214 // LinkURI
215 //------------------------------------------------------------------------
216 
217 class LinkURI: public LinkAction {
218 public:
219 
220   // Build a LinkURI given the URI (string) and base URI.
221   LinkURI(Object *uriObj, GString *baseURI);
222 
223   // Destructor.
224   virtual ~LinkURI();
225 
226   // Was the LinkURI created successfully?
isOk()227   virtual GBool isOk() { return uri != NULL; }
228 
229   // Accessors.
getKind()230   virtual LinkActionKind getKind() { return actionURI; }
getURI()231   GString *getURI() { return uri; }
232 
233 private:
234 
235   GString *uri;			// the URI
236 };
237 
238 //------------------------------------------------------------------------
239 // LinkNamed
240 //------------------------------------------------------------------------
241 
242 class LinkNamed: public LinkAction {
243 public:
244 
245   // Build a LinkNamed given the action name.
246   LinkNamed(Object *nameObj);
247 
248   virtual ~LinkNamed();
249 
250   // Was the LinkNamed created successfully?
isOk()251   virtual GBool isOk() { return name != NULL; }
252 
253   // Accessors.
getKind()254   virtual LinkActionKind getKind() { return actionNamed; }
getName()255   GString *getName() { return name; }
256 
257 private:
258 
259   GString *name;
260 };
261 
262 //------------------------------------------------------------------------
263 // LinkMovie
264 //------------------------------------------------------------------------
265 
266 class LinkMovie: public LinkAction {
267 public:
268 
269   LinkMovie(Object *annotObj, Object *titleObj);
270 
271   virtual ~LinkMovie();
272 
273   // Was the LinkMovie created successfully?
isOk()274   virtual GBool isOk() { return annotRef.num >= 0 || title != NULL; }
275 
276   // Accessors.
getKind()277   virtual LinkActionKind getKind() { return actionMovie; }
hasAnnotRef()278   GBool hasAnnotRef() { return annotRef.num >= 0; }
getAnnotRef()279   Ref *getAnnotRef() { return &annotRef; }
getTitle()280   GString *getTitle() { return title; }
281 
282 private:
283 
284   Ref annotRef;
285   GString *title;
286 };
287 
288 //------------------------------------------------------------------------
289 // LinkJavaScript
290 //------------------------------------------------------------------------
291 
292 class LinkJavaScript: public LinkAction {
293 public:
294 
295   LinkJavaScript(Object *jsObj);
296 
297   virtual ~LinkJavaScript();
298 
299   // Was the LinkJavaScript created successfully?
isOk()300   virtual GBool isOk() { return js != NULL; }
301 
302   // Accessors.
getKind()303   virtual LinkActionKind getKind() { return actionJavaScript; }
getJS()304   GString *getJS() { return js; }
305 
306 private:
307 
308   GString *js;
309 };
310 
311 //------------------------------------------------------------------------
312 // LinkSubmitForm
313 //------------------------------------------------------------------------
314 
315 class LinkSubmitForm: public LinkAction {
316 public:
317 
318   LinkSubmitForm(Object *urlObj, Object *fieldsObj, Object *flagsObj);
319 
320   virtual ~LinkSubmitForm();
321 
322   // Was the LinkSubmitForm created successfully?
isOk()323   virtual GBool isOk() { return url != NULL; }
324 
325   // Accessors.
getKind()326   virtual LinkActionKind getKind() { return actionSubmitForm; }
getURL()327   GString *getURL() { return url; }
getFields()328   Object *getFields() { return &fields; }
getFlags()329   int getFlags() { return flags; }
330 
331 private:
332 
333   GString *url;
334   Object fields;
335   int flags;
336 };
337 
338 //------------------------------------------------------------------------
339 // LinkHide
340 //------------------------------------------------------------------------
341 
342 class LinkHide: public LinkAction {
343 public:
344 
345   LinkHide(Object *fieldsObj, Object *hideFlagObj);
346 
347   virtual ~LinkHide();
348 
349   // Was the LinkHide created successfully?
isOk()350   virtual GBool isOk() { return !fields.isNull(); }
351 
352   // Accessors.
getKind()353   virtual LinkActionKind getKind() { return actionHide; }
getFields()354   Object *getFields() { return &fields; }
getHideFlag()355   GBool getHideFlag() { return hideFlag; }
356 
357 private:
358 
359   Object fields;
360   GBool hideFlag;
361 };
362 
363 //------------------------------------------------------------------------
364 // LinkUnknown
365 //------------------------------------------------------------------------
366 
367 class LinkUnknown: public LinkAction {
368 public:
369 
370   // Build a LinkUnknown with the specified action type.
371   LinkUnknown(char *actionA);
372 
373   // Destructor.
374   virtual ~LinkUnknown();
375 
376   // Was the LinkUnknown create successfully?
isOk()377   virtual GBool isOk() { return action != NULL; }
378 
379   // Accessors.
getKind()380   virtual LinkActionKind getKind() { return actionUnknown; }
getAction()381   GString *getAction() { return action; }
382 
383 private:
384 
385   GString *action;		// action subtype
386 };
387 
388 //------------------------------------------------------------------------
389 // Link
390 //------------------------------------------------------------------------
391 
392 class Link {
393 public:
394 
395   // Construct a link, given its dictionary.
396   Link(Dict *dict, GString *baseURI);
397 
398   // Destructor.
399   ~Link();
400 
401   // Was the link created successfully?
isOk()402   GBool isOk() { return ok; }
403 
404   // Check if point is inside the link rectangle.
inRect(double x,double y)405   GBool inRect(double x, double y)
406     { return x1 <= x && x <= x2 && y1 <= y && y <= y2; }
407 
408   // Get action.
getAction()409   LinkAction *getAction() { return action; }
410 
411   // Get the link rectangle.
getRect(double * xa1,double * ya1,double * xa2,double * ya2)412   void getRect(double *xa1, double *ya1, double *xa2, double *ya2)
413     { *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; }
414 
415 private:
416 
417   double x1, y1;		// lower left corner
418   double x2, y2;		// upper right corner
419   LinkAction *action;		// action
420   GBool ok;			// is link valid?
421 };
422 
423 //------------------------------------------------------------------------
424 // Links
425 //------------------------------------------------------------------------
426 
427 class Links {
428 public:
429 
430   // Extract links from array of annotations.
431   Links(Object *annots, GString *baseURI);
432 
433   // Destructor.
434   ~Links();
435 
436   // Iterate through list of links.
getNumLinks()437   int getNumLinks() { return numLinks; }
getLink(int i)438   Link *getLink(int i) { return links[i]; }
439 
440   // If point <x>,<y> is in a link, return the associated action;
441   // else return NULL.
442   LinkAction *find(double x, double y);
443 
444   // Return true if <x>,<y> is in a link.
445   GBool onLink(double x, double y);
446 
447 private:
448 
449   Link **links;
450   int numLinks;
451 };
452 
453 #endif
454