Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-10 10:23:47

0001 //========================================================================
0002 //
0003 // Link.h
0004 //
0005 // Copyright 1996-2003 Glyph & Cog, LLC
0006 //
0007 //========================================================================
0008 
0009 //========================================================================
0010 //
0011 // Modified under the Poppler project - http://poppler.freedesktop.org
0012 //
0013 // All changes made under the Poppler project to this file are licensed
0014 // under GPL version 2 or later
0015 //
0016 // Copyright (C) 2006, 2008 Pino Toscano <pino@kde.org>
0017 // Copyright (C) 2008 Hugo Mercier <hmercier31@gmail.com>
0018 // Copyright (C) 2010, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
0019 // Copyright (C) 2012 Tobias Koening <tobias.koenig@kdab.com>
0020 // Copyright (C) 2018-2022 Albert Astals Cid <aacid@kde.org>
0021 // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
0022 // Copyright (C) 2018 Intevation GmbH <intevation@intevation.de>
0023 // Copyright (C) 2019, 2020 Oliver Sander <oliver.sander@tu-dresden.de>
0024 // Copyright (C) 2020 Adam Reichold <adam.reichold@t-online.de>
0025 // Copyright (C) 2020 Marek Kasik <mkasik@redhat.com>
0026 //
0027 // To see a description of the changes please see the Changelog file that
0028 // came with your tarball or type make ChangeLog if you are building from git
0029 //
0030 //========================================================================
0031 
0032 #ifndef LINK_H
0033 #define LINK_H
0034 
0035 #include "Object.h"
0036 #include "poppler_private_export.h"
0037 #include <memory>
0038 #include <optional>
0039 #include <set>
0040 
0041 class GooString;
0042 class Array;
0043 class Dict;
0044 class Sound;
0045 class MediaRendition;
0046 class AnnotLink;
0047 class Annots;
0048 
0049 //------------------------------------------------------------------------
0050 // LinkAction
0051 //------------------------------------------------------------------------
0052 
0053 enum LinkActionKind
0054 {
0055     actionGoTo, // go to destination
0056     actionGoToR, // go to destination in new file
0057     actionLaunch, // launch app (or open document)
0058     actionURI, // URI
0059     actionNamed, // named action
0060     actionMovie, // movie action
0061     actionRendition, // rendition action
0062     actionSound, // sound action
0063     actionJavaScript, // JavaScript action
0064     actionOCGState, // Set-OCG-State action
0065     actionHide, // Hide action
0066     actionResetForm, // ResetForm action
0067     actionUnknown // anything else
0068 };
0069 
0070 class POPPLER_PRIVATE_EXPORT LinkAction
0071 {
0072 public:
0073     LinkAction();
0074     LinkAction(const LinkAction &) = delete;
0075     LinkAction &operator=(const LinkAction &other) = delete;
0076 
0077     // Destructor.
0078     virtual ~LinkAction();
0079 
0080     // Was the LinkAction created successfully?
0081     virtual bool isOk() const = 0;
0082 
0083     // Check link action type.
0084     virtual LinkActionKind getKind() const = 0;
0085 
0086     // Parse a destination (old-style action) name, string, or array.
0087     static std::unique_ptr<LinkAction> parseDest(const Object *obj);
0088 
0089     // Parse an action dictionary.
0090     static std::unique_ptr<LinkAction> parseAction(const Object *obj, const std::optional<std::string> &baseURI = {});
0091 
0092     // A List of the next actions to execute in order.
0093     const std::vector<std::unique_ptr<LinkAction>> &nextActions() const;
0094 
0095 private:
0096     static std::unique_ptr<LinkAction> parseAction(const Object *obj, const std::optional<std::string> &baseURI, std::set<int> *seenNextActions);
0097 
0098     std::vector<std::unique_ptr<LinkAction>> nextActionList;
0099 };
0100 
0101 //------------------------------------------------------------------------
0102 // LinkDest
0103 //------------------------------------------------------------------------
0104 
0105 enum LinkDestKind
0106 {
0107     destXYZ,
0108     destFit,
0109     destFitH,
0110     destFitV,
0111     destFitR,
0112     destFitB,
0113     destFitBH,
0114     destFitBV
0115 };
0116 
0117 class POPPLER_PRIVATE_EXPORT LinkDest
0118 {
0119 public:
0120     // Build a LinkDest from the array.
0121     explicit LinkDest(const Array *a);
0122 
0123     // Was the LinkDest created successfully?
0124     bool isOk() const { return ok; }
0125 
0126     // Accessors.
0127     LinkDestKind getKind() const { return kind; }
0128     bool isPageRef() const { return pageIsRef; }
0129     int getPageNum() const { return pageNum; }
0130     Ref getPageRef() const { return pageRef; }
0131     double getLeft() const { return left; }
0132     double getBottom() const { return bottom; }
0133     double getRight() const { return right; }
0134     double getTop() const { return top; }
0135     double getZoom() const { return zoom; }
0136     bool getChangeLeft() const { return changeLeft; }
0137     bool getChangeTop() const { return changeTop; }
0138     bool getChangeZoom() const { return changeZoom; }
0139 
0140 private:
0141     LinkDestKind kind; // destination type
0142     bool pageIsRef; // is the page a reference or number?
0143     union {
0144         Ref pageRef; // reference to page
0145         int pageNum; // one-relative page number
0146     };
0147     double left, bottom; // position
0148     double right, top;
0149     double zoom; // zoom factor
0150     bool changeLeft, changeTop; // which position components to change:
0151     bool changeZoom; //   destXYZ uses all three;
0152                      //   destFitH/BH use changeTop;
0153                      //   destFitV/BV use changeLeft
0154     bool ok; // set if created successfully
0155 };
0156 
0157 //------------------------------------------------------------------------
0158 // LinkGoTo
0159 //------------------------------------------------------------------------
0160 
0161 class POPPLER_PRIVATE_EXPORT LinkGoTo : public LinkAction
0162 {
0163 public:
0164     // Build a LinkGoTo from a destination (dictionary, name, or string).
0165     explicit LinkGoTo(const Object *destObj);
0166 
0167     ~LinkGoTo() override;
0168 
0169     // Was the LinkGoTo created successfully?
0170     bool isOk() const override { return dest || namedDest; }
0171 
0172     // Accessors.
0173     LinkActionKind getKind() const override { return actionGoTo; }
0174     const LinkDest *getDest() const { return dest.get(); }
0175     const GooString *getNamedDest() const { return namedDest.get(); }
0176 
0177 private:
0178     std::unique_ptr<LinkDest> dest; // regular destination (nullptr for remote
0179                                     //   link with bad destination)
0180     std::unique_ptr<GooString> namedDest; // named destination (only one of dest and
0181                                           //   and namedDest may be non-nullptr)
0182 };
0183 
0184 //------------------------------------------------------------------------
0185 // LinkGoToR
0186 //------------------------------------------------------------------------
0187 
0188 class LinkGoToR : public LinkAction
0189 {
0190 public:
0191     // Build a LinkGoToR from a file spec (dictionary) and destination
0192     // (dictionary, name, or string).
0193     LinkGoToR(Object *fileSpecObj, Object *destObj);
0194 
0195     ~LinkGoToR() override;
0196 
0197     // Was the LinkGoToR created successfully?
0198     bool isOk() const override { return fileName && (dest || namedDest); }
0199 
0200     // Accessors.
0201     LinkActionKind getKind() const override { return actionGoToR; }
0202     const GooString *getFileName() const { return fileName.get(); }
0203     const LinkDest *getDest() const { return dest.get(); }
0204     const GooString *getNamedDest() const { return namedDest.get(); }
0205 
0206 private:
0207     std::unique_ptr<GooString> fileName; // file name
0208     std::unique_ptr<LinkDest> dest; // regular destination (nullptr for remote
0209                                     //   link with bad destination)
0210     std::unique_ptr<GooString> namedDest; // named destination (only one of dest and
0211                                           //   and namedDest may be non-nullptr)
0212 };
0213 
0214 //------------------------------------------------------------------------
0215 // LinkLaunch
0216 //------------------------------------------------------------------------
0217 
0218 class LinkLaunch : public LinkAction
0219 {
0220 public:
0221     // Build a LinkLaunch from an action dictionary.
0222     explicit LinkLaunch(const Object *actionObj);
0223     ~LinkLaunch() override;
0224 
0225     // Was the LinkLaunch created successfully?
0226     bool isOk() const override { return fileName != nullptr; }
0227 
0228     // Accessors.
0229     LinkActionKind getKind() const override { return actionLaunch; }
0230     const GooString *getFileName() const { return fileName.get(); }
0231     const GooString *getParams() const { return params.get(); }
0232 
0233 private:
0234     std::unique_ptr<GooString> fileName; // file name
0235     std::unique_ptr<GooString> params; // parameters
0236 };
0237 
0238 //------------------------------------------------------------------------
0239 // LinkURI
0240 //------------------------------------------------------------------------
0241 
0242 class POPPLER_PRIVATE_EXPORT LinkURI : public LinkAction
0243 {
0244 public:
0245     // Build a LinkURI given the URI (string) and base URI.
0246     LinkURI(const Object *uriObj, const std::optional<std::string> &baseURI);
0247 
0248     ~LinkURI() override;
0249 
0250     // Was the LinkURI created successfully?
0251     bool isOk() const override { return hasURIFlag; }
0252 
0253     // Accessors.
0254     LinkActionKind getKind() const override { return actionURI; }
0255     const std::string &getURI() const { return uri; }
0256 
0257 private:
0258     std::string uri; // the URI
0259     bool hasURIFlag;
0260 };
0261 
0262 //------------------------------------------------------------------------
0263 // LinkNamed
0264 //------------------------------------------------------------------------
0265 
0266 class LinkNamed : public LinkAction
0267 {
0268 public:
0269     // Build a LinkNamed given the action name.
0270     explicit LinkNamed(const Object *nameObj);
0271 
0272     ~LinkNamed() override;
0273 
0274     bool isOk() const override { return hasNameFlag; }
0275 
0276     LinkActionKind getKind() const override { return actionNamed; }
0277     const std::string &getName() const { return name; }
0278 
0279 private:
0280     std::string name;
0281     bool hasNameFlag;
0282 };
0283 
0284 //------------------------------------------------------------------------
0285 // LinkMovie
0286 //------------------------------------------------------------------------
0287 
0288 class LinkMovie : public LinkAction
0289 {
0290 public:
0291     enum OperationType
0292     {
0293         operationTypePlay,
0294         operationTypePause,
0295         operationTypeResume,
0296         operationTypeStop
0297     };
0298 
0299     explicit LinkMovie(const Object *obj);
0300 
0301     ~LinkMovie() override;
0302 
0303     bool isOk() const override { return hasAnnotRef() || hasAnnotTitleFlag; }
0304     LinkActionKind getKind() const override { return actionMovie; }
0305 
0306     // a movie action stores either an indirect reference to a movie annotation
0307     // or the movie annotation title
0308 
0309     bool hasAnnotRef() const { return annotRef != Ref::INVALID(); }
0310     bool hasAnnotTitle() const { return hasAnnotTitleFlag; }
0311     const Ref *getAnnotRef() const { return &annotRef; }
0312     const std::string &getAnnotTitle() const { return annotTitle; }
0313 
0314     OperationType getOperation() const { return operation; }
0315 
0316 private:
0317     Ref annotRef; // Annotation
0318     std::string annotTitle; // T
0319     bool hasAnnotTitleFlag;
0320 
0321     OperationType operation; // Operation
0322 };
0323 
0324 //------------------------------------------------------------------------
0325 // LinkRendition
0326 //------------------------------------------------------------------------
0327 
0328 class LinkRendition : public LinkAction
0329 {
0330 public:
0331     /**
0332      * Describes the possible rendition operations.
0333      */
0334     enum RenditionOperation
0335     {
0336         NoRendition,
0337         PlayRendition,
0338         StopRendition,
0339         PauseRendition,
0340         ResumeRendition
0341     };
0342 
0343     explicit LinkRendition(const Object *Obj);
0344 
0345     ~LinkRendition() override;
0346 
0347     bool isOk() const override { return true; }
0348 
0349     LinkActionKind getKind() const override { return actionRendition; }
0350 
0351     bool hasScreenAnnot() const { return screenRef != Ref::INVALID(); }
0352     Ref getScreenAnnot() const { return screenRef; }
0353 
0354     RenditionOperation getOperation() const { return operation; }
0355 
0356     const MediaRendition *getMedia() const { return media; }
0357 
0358     const std::string &getScript() const { return js; }
0359 
0360 private:
0361     Ref screenRef;
0362     RenditionOperation operation;
0363 
0364     MediaRendition *media;
0365 
0366     std::string js;
0367 };
0368 
0369 //------------------------------------------------------------------------
0370 // LinkSound
0371 //------------------------------------------------------------------------
0372 
0373 class LinkSound : public LinkAction
0374 {
0375 public:
0376     explicit LinkSound(const Object *soundObj);
0377 
0378     ~LinkSound() override;
0379 
0380     bool isOk() const override { return sound != nullptr; }
0381 
0382     LinkActionKind getKind() const override { return actionSound; }
0383 
0384     double getVolume() const { return volume; }
0385     bool getSynchronous() const { return sync; }
0386     bool getRepeat() const { return repeat; }
0387     bool getMix() const { return mix; }
0388     Sound *getSound() const { return sound.get(); }
0389 
0390 private:
0391     double volume;
0392     bool sync;
0393     bool repeat;
0394     bool mix;
0395     std::unique_ptr<Sound> sound;
0396 };
0397 
0398 //------------------------------------------------------------------------
0399 // LinkJavaScript
0400 //------------------------------------------------------------------------
0401 
0402 class LinkJavaScript : public LinkAction
0403 {
0404 public:
0405     // Build a LinkJavaScript given the action name.
0406     explicit LinkJavaScript(Object *jsObj);
0407 
0408     ~LinkJavaScript() override;
0409 
0410     bool isOk() const override { return isValid; }
0411 
0412     LinkActionKind getKind() const override { return actionJavaScript; }
0413     const std::string &getScript() const { return js; }
0414 
0415     static Object createObject(XRef *xref, const GooString &js);
0416 
0417 private:
0418     std::string js;
0419     bool isValid;
0420 };
0421 
0422 //------------------------------------------------------------------------
0423 // LinkOCGState
0424 //------------------------------------------------------------------------
0425 class LinkOCGState : public LinkAction
0426 {
0427 public:
0428     explicit LinkOCGState(const Object *obj);
0429 
0430     ~LinkOCGState() override;
0431 
0432     bool isOk() const override { return isValid; }
0433 
0434     LinkActionKind getKind() const override { return actionOCGState; }
0435 
0436     enum State
0437     {
0438         On,
0439         Off,
0440         Toggle
0441     };
0442     struct StateList
0443     {
0444         StateList() = default;
0445         ~StateList() = default;
0446         State st;
0447         std::vector<Ref> list;
0448     };
0449 
0450     const std::vector<StateList> &getStateList() const { return stateList; }
0451     bool getPreserveRB() const { return preserveRB; }
0452 
0453 private:
0454     std::vector<StateList> stateList;
0455     bool isValid;
0456     bool preserveRB;
0457 };
0458 
0459 //------------------------------------------------------------------------
0460 // LinkHide
0461 //------------------------------------------------------------------------
0462 
0463 class LinkHide : public LinkAction
0464 {
0465 public:
0466     explicit LinkHide(const Object *hideObj);
0467 
0468     ~LinkHide() override;
0469 
0470     bool isOk() const override { return hasTargetNameFlag; }
0471     LinkActionKind getKind() const override { return actionHide; }
0472 
0473     // According to spec the target can be either:
0474     // a) A text string containing the fully qualified name of the target
0475     //    field.
0476     // b) An indirect reference to an annotation dictionary.
0477     // c) An array of "such dictionaries or text strings".
0478     //
0479     // While b / c appear to be very uncommon and can't easily be
0480     // created with Adobe Acrobat DC. So only support hide
0481     // actions with named targets (yet).
0482     bool hasTargetName() const { return hasTargetNameFlag; }
0483     const std::string &getTargetName() const { return targetName; }
0484 
0485     // Should this action show or hide.
0486     bool isShowAction() const { return show; }
0487 
0488 private:
0489     bool hasTargetNameFlag;
0490     std::string targetName;
0491     bool show;
0492 };
0493 
0494 //------------------------------------------------------------------------
0495 // LinkResetForm
0496 //------------------------------------------------------------------------
0497 
0498 class POPPLER_PRIVATE_EXPORT LinkResetForm : public LinkAction
0499 {
0500 public:
0501     // Build a LinkResetForm.
0502     explicit LinkResetForm(const Object *nameObj);
0503 
0504     ~LinkResetForm() override;
0505 
0506     bool isOk() const override { return true; }
0507 
0508     LinkActionKind getKind() const override { return actionResetForm; }
0509 
0510     const std::vector<std::string> &getFields() const { return fields; }
0511     bool getExclude() const { return exclude; }
0512 
0513 private:
0514     std::vector<std::string> fields;
0515     bool exclude;
0516 };
0517 
0518 //------------------------------------------------------------------------
0519 // LinkUnknown
0520 //------------------------------------------------------------------------
0521 
0522 class LinkUnknown : public LinkAction
0523 {
0524 public:
0525     // Build a LinkUnknown with the specified action type.
0526     explicit LinkUnknown(const char *actionA);
0527 
0528     ~LinkUnknown() override;
0529 
0530     // Was the LinkUnknown create successfully?
0531     // Yes: nothing can go wrong when creating LinkUnknown objects
0532     bool isOk() const override { return true; }
0533 
0534     // Accessors.
0535     LinkActionKind getKind() const override { return actionUnknown; }
0536     const std::string &getAction() const { return action; }
0537 
0538 private:
0539     std::string action; // action subtype
0540 };
0541 
0542 //------------------------------------------------------------------------
0543 // Links
0544 //------------------------------------------------------------------------
0545 
0546 class POPPLER_PRIVATE_EXPORT Links
0547 {
0548 public:
0549     // Extract links from array of annotations.
0550     explicit Links(Annots *annots);
0551 
0552     // Destructor.
0553     ~Links();
0554 
0555     Links(const Links &) = delete;
0556     Links &operator=(const Links &) = delete;
0557 
0558     const std::vector<AnnotLink *> &getLinks() const { return links; }
0559 
0560 private:
0561     std::vector<AnnotLink *> links;
0562 };
0563 
0564 #endif