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