1 //========================================================================
2 //
3 // Link.h
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8 
9 //========================================================================
10 //
11 // Modified under the Poppler project - http://poppler.freedesktop.org
12 //
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
15 //
16 // Copyright (C) 2006, 2008 Pino Toscano <pino@kde.org>
17 // Copyright (C) 2008 Hugo Mercier <hmercier31@gmail.com>
18 // Copyright (C) 2010 Carlos Garcia Campos <carlosgc@gnome.org>
19 //
20 // To see a description of the changes please see the Changelog file that
21 // came with your tarball or type make ChangeLog if you are building from git
22 //
23 //========================================================================
24 
25 #ifndef LINK_H
26 #define LINK_H
27 
28 #ifdef USE_GCC_PRAGMAS
29 #pragma interface
30 #endif
31 
32 #include "Object.h"
33 
34 class GooString;
35 class GooList;
36 class Array;
37 class Dict;
38 class Sound;
39 class MediaRendition;
40 
41 //------------------------------------------------------------------------
42 // LinkAction
43 //------------------------------------------------------------------------
44 
45 enum LinkActionKind {
46   actionGoTo,			// go to destination
47   actionGoToR,			// go to destination in new file
48   actionLaunch,			// launch app (or open document)
49   actionURI,			// URI
50   actionNamed,			// named action
51   actionMovie,			// movie action
52   actionRendition,
53   actionSound,			// sound action
54   actionJavaScript,		// JavaScript action
55   actionOCGState,               // Set-OCG-State action
56   actionUnknown			// anything else
57 };
58 
59 class LinkAction {
60 public:
61 
62   // Destructor.
~LinkAction()63   virtual ~LinkAction() {}
64 
65   // Was the LinkAction created successfully?
66   virtual GBool isOk() = 0;
67 
68   // Check link action type.
69   virtual LinkActionKind getKind() = 0;
70 
71   // Parse a destination (old-style action) name, string, or array.
72   static LinkAction *parseDest(Object *obj);
73 
74   // Parse an action dictionary.
75   static LinkAction *parseAction(Object *obj, GooString *baseURI = NULL);
76 };
77 
78 //------------------------------------------------------------------------
79 // LinkDest
80 //------------------------------------------------------------------------
81 
82 enum LinkDestKind {
83   destXYZ,
84   destFit,
85   destFitH,
86   destFitV,
87   destFitR,
88   destFitB,
89   destFitBH,
90   destFitBV
91 };
92 
93 class LinkDest {
94 public:
95 
96   // Build a LinkDest from the array.
97   LinkDest(Array *a);
98 
99   // Copy a LinkDest.
copy()100   LinkDest *copy() { return new LinkDest(this); }
101 
102   // Was the LinkDest created successfully?
isOk()103   GBool isOk() { return ok; }
104 
105   // Accessors.
getKind()106   LinkDestKind getKind() { return kind; }
isPageRef()107   GBool isPageRef() { return pageIsRef; }
getPageNum()108   int getPageNum() { return pageNum; }
getPageRef()109   Ref getPageRef() { return pageRef; }
getLeft()110   double getLeft() { return left; }
getBottom()111   double getBottom() { return bottom; }
getRight()112   double getRight() { return right; }
getTop()113   double getTop() { return top; }
getZoom()114   double getZoom() { return zoom; }
getChangeLeft()115   GBool getChangeLeft() { return changeLeft; }
getChangeTop()116   GBool getChangeTop() { return changeTop; }
getChangeZoom()117   GBool getChangeZoom() { return changeZoom; }
118 
119 private:
120 
121   LinkDestKind kind;		// destination type
122   GBool pageIsRef;		// is the page a reference or number?
123   union {
124     Ref pageRef;		// reference to page
125     int pageNum;		// one-relative page number
126   };
127   double left, bottom;		// position
128   double right, top;
129   double zoom;			// zoom factor
130   GBool changeLeft, changeTop;	// for destXYZ links, which position
131   GBool changeZoom;		//   components to change
132   GBool ok;			// set if created successfully
133 
134   LinkDest(LinkDest *dest);
135 };
136 
137 //------------------------------------------------------------------------
138 // LinkGoTo
139 //------------------------------------------------------------------------
140 
141 class LinkGoTo: public LinkAction {
142 public:
143 
144   // Build a LinkGoTo from a destination (dictionary, name, or string).
145   LinkGoTo(Object *destObj);
146 
147   // Destructor.
148   virtual ~LinkGoTo();
149 
150   // Was the LinkGoTo created successfully?
isOk()151   virtual GBool isOk() { return dest || namedDest; }
152 
153   // Accessors.
getKind()154   virtual LinkActionKind getKind() { return actionGoTo; }
getDest()155   LinkDest *getDest() { return dest; }
getNamedDest()156   GooString *getNamedDest() { return namedDest; }
157 
158 private:
159 
160   LinkDest *dest;		// regular destination (NULL for remote
161 				//   link with bad destination)
162   GooString *namedDest;	// named destination (only one of dest and
163 				//   and namedDest may be non-NULL)
164 };
165 
166 //------------------------------------------------------------------------
167 // LinkGoToR
168 //------------------------------------------------------------------------
169 
170 class LinkGoToR: public LinkAction {
171 public:
172 
173   // Build a LinkGoToR from a file spec (dictionary) and destination
174   // (dictionary, name, or string).
175   LinkGoToR(Object *fileSpecObj, Object *destObj);
176 
177   // Destructor.
178   virtual ~LinkGoToR();
179 
180   // Was the LinkGoToR created successfully?
isOk()181   virtual GBool isOk() { return fileName && (dest || namedDest); }
182 
183   // Accessors.
getKind()184   virtual LinkActionKind getKind() { return actionGoToR; }
getFileName()185   GooString *getFileName() { return fileName; }
getDest()186   LinkDest *getDest() { return dest; }
getNamedDest()187   GooString *getNamedDest() { return namedDest; }
188 
189 private:
190 
191   GooString *fileName;		// file name
192   LinkDest *dest;		// regular destination (NULL for remote
193 				//   link with bad destination)
194   GooString *namedDest;	// named destination (only one of dest and
195 				//   and namedDest may be non-NULL)
196 };
197 
198 //------------------------------------------------------------------------
199 // LinkLaunch
200 //------------------------------------------------------------------------
201 
202 class LinkLaunch: public LinkAction {
203 public:
204 
205   // Build a LinkLaunch from an action dictionary.
206   LinkLaunch(Object *actionObj);
207 
208   // Destructor.
209   virtual ~LinkLaunch();
210 
211   // Was the LinkLaunch created successfully?
isOk()212   virtual GBool isOk() { return fileName != NULL; }
213 
214   // Accessors.
getKind()215   virtual LinkActionKind getKind() { return actionLaunch; }
getFileName()216   GooString *getFileName() { return fileName; }
getParams()217   GooString *getParams() { return params; }
218 
219 private:
220 
221   GooString *fileName;		// file name
222   GooString *params;		// parameters
223 };
224 
225 //------------------------------------------------------------------------
226 // LinkURI
227 //------------------------------------------------------------------------
228 
229 class LinkURI: public LinkAction {
230 public:
231 
232   // Build a LinkURI given the URI (string) and base URI.
233   LinkURI(Object *uriObj, GooString *baseURI);
234 
235   // Destructor.
236   virtual ~LinkURI();
237 
238   // Was the LinkURI created successfully?
isOk()239   virtual GBool isOk() { return uri != NULL; }
240 
241   // Accessors.
getKind()242   virtual LinkActionKind getKind() { return actionURI; }
getURI()243   GooString *getURI() { return uri; }
244 
245 private:
246 
247   GooString *uri;			// the URI
248 };
249 
250 //------------------------------------------------------------------------
251 // LinkNamed
252 //------------------------------------------------------------------------
253 
254 class LinkNamed: public LinkAction {
255 public:
256 
257   // Build a LinkNamed given the action name.
258   LinkNamed(Object *nameObj);
259 
260   virtual ~LinkNamed();
261 
isOk()262   virtual GBool isOk() { return name != NULL; }
263 
getKind()264   virtual LinkActionKind getKind() { return actionNamed; }
getName()265   GooString *getName() { return name; }
266 
267 private:
268 
269   GooString *name;
270 };
271 
272 
273 //------------------------------------------------------------------------
274 // LinkMovie
275 //------------------------------------------------------------------------
276 
277 class LinkMovie: public LinkAction {
278 public:
279 
280   enum OperationType {
281     operationTypePlay,
282     operationTypePause,
283     operationTypeResume,
284     operationTypeStop
285   };
286 
287   LinkMovie(Object *obj);
288   virtual ~LinkMovie();
289 
isOk()290   virtual GBool isOk() { return annotRef.num >= 0 || annotTitle != NULL; }
getKind()291   virtual LinkActionKind getKind() { return actionMovie; }
292 
293   // a movie action stores either an indirect reference to a movie annotation
294   // or the movie annotation title
295 
hasAnnotRef()296   GBool hasAnnotRef() { return annotRef.num >= 0; }
hasAnnotTitle()297   GBool hasAnnotTitle() { return annotTitle != NULL; }
getAnnotRef()298   Ref *getAnnotRef() { return &annotRef; }
getAnnotTitle()299   GooString *getAnnotTitle() { return annotTitle; }
300 
getOperation()301   OperationType getOperation() { return operation; }
302 
303 private:
304 
305   Ref annotRef;            // Annotation
306   GooString *annotTitle;   // T
307 
308   OperationType operation; // Operation
309 };
310 
311 
312 //------------------------------------------------------------------------
313 // LinkRendition
314 //------------------------------------------------------------------------
315 
316 class LinkRendition: public LinkAction {
317 public:
318 
319   LinkRendition(Object *Obj);
320 
321   virtual ~LinkRendition();
322 
isOk()323   virtual GBool isOk() { return true; }
324 
getKind()325   virtual LinkActionKind getKind() { return actionRendition; }
326 
hasRenditionObject()327   GBool hasRenditionObject() { return renditionObj.isDict(); }
getRenditionObject()328   Object* getRenditionObject() { return &renditionObj; }
329 
hasScreenAnnot()330   GBool hasScreenAnnot() { return screenRef.isRef(); }
getScreenAnnot()331   Ref getScreenAnnot() { return screenRef.getRef(); }
332 
getOperation()333   int getOperation() { return operation; }
334 
getMedia()335   MediaRendition* getMedia() { return media; }
336 
getScript()337   GooString *getScript() { return js; }
338 
339 private:
340 
341   Object screenRef;
342   Object renditionObj;
343   int operation;
344 
345   MediaRendition* media;
346 
347   GooString *js;
348 };
349 
350 //------------------------------------------------------------------------
351 // LinkSound
352 //------------------------------------------------------------------------
353 
354 class LinkSound: public LinkAction {
355 public:
356 
357   LinkSound(Object *soundObj);
358 
359   virtual ~LinkSound();
360 
isOk()361   virtual GBool isOk() { return sound != NULL; }
362 
getKind()363   virtual LinkActionKind getKind() { return actionSound; }
364 
getVolume()365   double getVolume() { return volume; }
getSynchronous()366   GBool getSynchronous() { return sync; }
getRepeat()367   GBool getRepeat() { return repeat; }
getMix()368   GBool getMix() { return mix; }
getSound()369   Sound *getSound() { return sound; }
370 
371 private:
372 
373   double volume;
374   GBool sync;
375   GBool repeat;
376   GBool mix;
377   Sound *sound;
378 };
379 
380 //------------------------------------------------------------------------
381 // LinkJavaScript
382 //------------------------------------------------------------------------
383 
384 class LinkJavaScript: public LinkAction {
385 public:
386 
387   // Build a LinkJavaScript given the action name.
388   LinkJavaScript(Object *jsObj);
389 
390   virtual ~LinkJavaScript();
391 
isOk()392   virtual GBool isOk() { return js != NULL; }
393 
getKind()394   virtual LinkActionKind getKind() { return actionJavaScript; }
getScript()395   GooString *getScript() { return js; }
396 
397 private:
398 
399   GooString *js;
400 };
401 
402 //------------------------------------------------------------------------
403 // LinkOCGState
404 //------------------------------------------------------------------------
405 class LinkOCGState: public LinkAction {
406 public:
407   LinkOCGState(Object *obj);
408 
409   virtual ~LinkOCGState();
410 
isOk()411   virtual GBool isOk() { return stateList != NULL; }
412 
getKind()413   virtual LinkActionKind getKind() { return actionOCGState; }
414 
415   enum State { On, Off, Toggle};
416   struct StateList {
StateListStateList417     StateList() { list = NULL; }
418     ~StateList();
419     State st;
420     GooList *list;
421   };
422 
getStateList()423   GooList *getStateList() { return stateList; }
getPreserveRB()424   GBool getPreserveRB() { return preserveRB; }
425 
426 private:
427   GooList *stateList;
428   GBool preserveRB;
429 };
430 
431 //------------------------------------------------------------------------
432 // LinkUnknown
433 //------------------------------------------------------------------------
434 
435 class LinkUnknown: public LinkAction {
436 public:
437 
438   // Build a LinkUnknown with the specified action type.
439   LinkUnknown(char *actionA);
440 
441   // Destructor.
442   virtual ~LinkUnknown();
443 
444   // Was the LinkUnknown create successfully?
isOk()445   virtual GBool isOk() { return action != NULL; }
446 
447   // Accessors.
getKind()448   virtual LinkActionKind getKind() { return actionUnknown; }
getAction()449   GooString *getAction() { return action; }
450 
451 private:
452 
453   GooString *action;		// action subtype
454 };
455 
456 //------------------------------------------------------------------------
457 // Link
458 //------------------------------------------------------------------------
459 
460 class Link {
461 public:
462 
463   // Construct a link, given its dictionary.
464   Link(Dict *dict, GooString *baseURI);
465 
466   // Destructor.
467   ~Link();
468 
469   // Was the link created successfully?
isOk()470   GBool isOk() { return ok; }
471 
472   // Check if point is inside the link rectangle.
inRect(double x,double y)473   GBool inRect(double x, double y)
474     { return x1 <= x && x <= x2 && y1 <= y && y <= y2; }
475 
476   // Get action.
getAction()477   LinkAction *getAction() { return action; }
478 
479   // Get the link rectangle.
getRect(double * xa1,double * ya1,double * xa2,double * ya2)480   void getRect(double *xa1, double *ya1, double *xa2, double *ya2)
481     { *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; }
482 
483 private:
484 
485   double x1, y1;		// lower left corner
486   double x2, y2;		// upper right corner
487   LinkAction *action;		// action
488   GBool ok;			// is link valid?
489 };
490 
491 //------------------------------------------------------------------------
492 // Links
493 //------------------------------------------------------------------------
494 
495 class Links {
496 public:
497 
498   // Extract links from array of annotations.
499   Links(Object *annots, GooString *baseURI);
500 
501   // Destructor.
502   ~Links();
503 
504   // Iterate through list of links.
getNumLinks()505   int getNumLinks() const { return numLinks; }
getLink(int i)506   Link *getLink(int i) const { return links[i]; }
507 
508   // If point <x>,<y> is in a link, return the associated action;
509   // else return NULL.
510   LinkAction *find(double x, double y) const;
511 
512   // Return true if <x>,<y> is in a link.
513   GBool onLink(double x, double y) const;
514 
515 private:
516 
517   Link **links;
518   int numLinks;
519 };
520 
521 #endif
522