Spaces:
Running
Running
//======================================================================== | |
// | |
// Link.h | |
// | |
// Copyright 1996-2003 Glyph & Cog, LLC | |
// | |
//======================================================================== | |
//======================================================================== | |
// | |
// Modified under the Poppler project - http://poppler.freedesktop.org | |
// | |
// All changes made under the Poppler project to this file are licensed | |
// under GPL version 2 or later | |
// | |
// Copyright (C) 2006, 2008 Pino Toscano <[email protected]> | |
// Copyright (C) 2008 Hugo Mercier <[email protected]> | |
// Copyright (C) 2010, 2011 Carlos Garcia Campos <[email protected]> | |
// Copyright (C) 2012 Tobias Koening <[email protected]> | |
// Copyright (C) 2018-2022 Albert Astals Cid <[email protected]> | |
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <[email protected]>. Work sponsored by the LiMux project of the city of Munich | |
// Copyright (C) 2018 Intevation GmbH <[email protected]> | |
// Copyright (C) 2019, 2020 Oliver Sander <[email protected]> | |
// Copyright (C) 2020 Adam Reichold <[email protected]> | |
// Copyright (C) 2020 Marek Kasik <[email protected]> | |
// | |
// To see a description of the changes please see the Changelog file that | |
// came with your tarball or type make ChangeLog if you are building from git | |
// | |
//======================================================================== | |
class GooString; | |
class Array; | |
class Dict; | |
class Sound; | |
class MediaRendition; | |
class AnnotLink; | |
class Annots; | |
//------------------------------------------------------------------------ | |
// LinkAction | |
//------------------------------------------------------------------------ | |
enum LinkActionKind | |
{ | |
actionGoTo, // go to destination | |
actionGoToR, // go to destination in new file | |
actionLaunch, // launch app (or open document) | |
actionURI, // URI | |
actionNamed, // named action | |
actionMovie, // movie action | |
actionRendition, // rendition action | |
actionSound, // sound action | |
actionJavaScript, // JavaScript action | |
actionOCGState, // Set-OCG-State action | |
actionHide, // Hide action | |
actionResetForm, // ResetForm action | |
actionUnknown // anything else | |
}; | |
class POPPLER_PRIVATE_EXPORT LinkAction | |
{ | |
public: | |
LinkAction(); | |
LinkAction(const LinkAction &) = delete; | |
LinkAction &operator=(const LinkAction &other) = delete; | |
// Destructor. | |
virtual ~LinkAction(); | |
// Was the LinkAction created successfully? | |
virtual bool isOk() const = 0; | |
// Check link action type. | |
virtual LinkActionKind getKind() const = 0; | |
// Parse a destination (old-style action) name, string, or array. | |
static std::unique_ptr<LinkAction> parseDest(const Object *obj); | |
// Parse an action dictionary. | |
static std::unique_ptr<LinkAction> parseAction(const Object *obj, const std::optional<std::string> &baseURI = {}); | |
// A List of the next actions to execute in order. | |
const std::vector<std::unique_ptr<LinkAction>> &nextActions() const; | |
private: | |
static std::unique_ptr<LinkAction> parseAction(const Object *obj, const std::optional<std::string> &baseURI, std::set<int> *seenNextActions); | |
std::vector<std::unique_ptr<LinkAction>> nextActionList; | |
}; | |
//------------------------------------------------------------------------ | |
// LinkDest | |
//------------------------------------------------------------------------ | |
enum LinkDestKind | |
{ | |
destXYZ, | |
destFit, | |
destFitH, | |
destFitV, | |
destFitR, | |
destFitB, | |
destFitBH, | |
destFitBV | |
}; | |
class POPPLER_PRIVATE_EXPORT LinkDest | |
{ | |
public: | |
// Build a LinkDest from the array. | |
explicit LinkDest(const Array *a); | |
// Was the LinkDest created successfully? | |
bool isOk() const { return ok; } | |
// Accessors. | |
LinkDestKind getKind() const { return kind; } | |
bool isPageRef() const { return pageIsRef; } | |
int getPageNum() const { return pageNum; } | |
Ref getPageRef() const { return pageRef; } | |
double getLeft() const { return left; } | |
double getBottom() const { return bottom; } | |
double getRight() const { return right; } | |
double getTop() const { return top; } | |
double getZoom() const { return zoom; } | |
bool getChangeLeft() const { return changeLeft; } | |
bool getChangeTop() const { return changeTop; } | |
bool getChangeZoom() const { return changeZoom; } | |
private: | |
LinkDestKind kind; // destination type | |
bool pageIsRef; // is the page a reference or number? | |
union { | |
Ref pageRef; // reference to page | |
int pageNum; // one-relative page number | |
}; | |
double left, bottom; // position | |
double right, top; | |
double zoom; // zoom factor | |
bool changeLeft, changeTop; // which position components to change: | |
bool changeZoom; // destXYZ uses all three; | |
// destFitH/BH use changeTop; | |
// destFitV/BV use changeLeft | |
bool ok; // set if created successfully | |
}; | |
//------------------------------------------------------------------------ | |
// LinkGoTo | |
//------------------------------------------------------------------------ | |
class POPPLER_PRIVATE_EXPORT LinkGoTo : public LinkAction | |
{ | |
public: | |
// Build a LinkGoTo from a destination (dictionary, name, or string). | |
explicit LinkGoTo(const Object *destObj); | |
~LinkGoTo() override; | |
// Was the LinkGoTo created successfully? | |
bool isOk() const override { return dest || namedDest; } | |
// Accessors. | |
LinkActionKind getKind() const override { return actionGoTo; } | |
const LinkDest *getDest() const { return dest.get(); } | |
const GooString *getNamedDest() const { return namedDest.get(); } | |
private: | |
std::unique_ptr<LinkDest> dest; // regular destination (nullptr for remote | |
// link with bad destination) | |
std::unique_ptr<GooString> namedDest; // named destination (only one of dest and | |
// and namedDest may be non-nullptr) | |
}; | |
//------------------------------------------------------------------------ | |
// LinkGoToR | |
//------------------------------------------------------------------------ | |
class LinkGoToR : public LinkAction | |
{ | |
public: | |
// Build a LinkGoToR from a file spec (dictionary) and destination | |
// (dictionary, name, or string). | |
LinkGoToR(Object *fileSpecObj, Object *destObj); | |
~LinkGoToR() override; | |
// Was the LinkGoToR created successfully? | |
bool isOk() const override { return fileName && (dest || namedDest); } | |
// Accessors. | |
LinkActionKind getKind() const override { return actionGoToR; } | |
const GooString *getFileName() const { return fileName.get(); } | |
const LinkDest *getDest() const { return dest.get(); } | |
const GooString *getNamedDest() const { return namedDest.get(); } | |
private: | |
std::unique_ptr<GooString> fileName; // file name | |
std::unique_ptr<LinkDest> dest; // regular destination (nullptr for remote | |
// link with bad destination) | |
std::unique_ptr<GooString> namedDest; // named destination (only one of dest and | |
// and namedDest may be non-nullptr) | |
}; | |
//------------------------------------------------------------------------ | |
// LinkLaunch | |
//------------------------------------------------------------------------ | |
class LinkLaunch : public LinkAction | |
{ | |
public: | |
// Build a LinkLaunch from an action dictionary. | |
explicit LinkLaunch(const Object *actionObj); | |
~LinkLaunch() override; | |
// Was the LinkLaunch created successfully? | |
bool isOk() const override { return fileName != nullptr; } | |
// Accessors. | |
LinkActionKind getKind() const override { return actionLaunch; } | |
const GooString *getFileName() const { return fileName.get(); } | |
const GooString *getParams() const { return params.get(); } | |
private: | |
std::unique_ptr<GooString> fileName; // file name | |
std::unique_ptr<GooString> params; // parameters | |
}; | |
//------------------------------------------------------------------------ | |
// LinkURI | |
//------------------------------------------------------------------------ | |
class POPPLER_PRIVATE_EXPORT LinkURI : public LinkAction | |
{ | |
public: | |
// Build a LinkURI given the URI (string) and base URI. | |
LinkURI(const Object *uriObj, const std::optional<std::string> &baseURI); | |
~LinkURI() override; | |
// Was the LinkURI created successfully? | |
bool isOk() const override { return hasURIFlag; } | |
// Accessors. | |
LinkActionKind getKind() const override { return actionURI; } | |
const std::string &getURI() const { return uri; } | |
private: | |
std::string uri; // the URI | |
bool hasURIFlag; | |
}; | |
//------------------------------------------------------------------------ | |
// LinkNamed | |
//------------------------------------------------------------------------ | |
class LinkNamed : public LinkAction | |
{ | |
public: | |
// Build a LinkNamed given the action name. | |
explicit LinkNamed(const Object *nameObj); | |
~LinkNamed() override; | |
bool isOk() const override { return hasNameFlag; } | |
LinkActionKind getKind() const override { return actionNamed; } | |
const std::string &getName() const { return name; } | |
private: | |
std::string name; | |
bool hasNameFlag; | |
}; | |
//------------------------------------------------------------------------ | |
// LinkMovie | |
//------------------------------------------------------------------------ | |
class LinkMovie : public LinkAction | |
{ | |
public: | |
enum OperationType | |
{ | |
operationTypePlay, | |
operationTypePause, | |
operationTypeResume, | |
operationTypeStop | |
}; | |
explicit LinkMovie(const Object *obj); | |
~LinkMovie() override; | |
bool isOk() const override { return hasAnnotRef() || hasAnnotTitleFlag; } | |
LinkActionKind getKind() const override { return actionMovie; } | |
// a movie action stores either an indirect reference to a movie annotation | |
// or the movie annotation title | |
bool hasAnnotRef() const { return annotRef != Ref::INVALID(); } | |
bool hasAnnotTitle() const { return hasAnnotTitleFlag; } | |
const Ref *getAnnotRef() const { return &annotRef; } | |
const std::string &getAnnotTitle() const { return annotTitle; } | |
OperationType getOperation() const { return operation; } | |
private: | |
Ref annotRef; // Annotation | |
std::string annotTitle; // T | |
bool hasAnnotTitleFlag; | |
OperationType operation; // Operation | |
}; | |
//------------------------------------------------------------------------ | |
// LinkRendition | |
//------------------------------------------------------------------------ | |
class LinkRendition : public LinkAction | |
{ | |
public: | |
/** | |
* Describes the possible rendition operations. | |
*/ | |
enum RenditionOperation | |
{ | |
NoRendition, | |
PlayRendition, | |
StopRendition, | |
PauseRendition, | |
ResumeRendition | |
}; | |
explicit LinkRendition(const Object *Obj); | |
~LinkRendition() override; | |
bool isOk() const override { return true; } | |
LinkActionKind getKind() const override { return actionRendition; } | |
bool hasScreenAnnot() const { return screenRef != Ref::INVALID(); } | |
Ref getScreenAnnot() const { return screenRef; } | |
RenditionOperation getOperation() const { return operation; } | |
const MediaRendition *getMedia() const { return media; } | |
const std::string &getScript() const { return js; } | |
private: | |
Ref screenRef; | |
RenditionOperation operation; | |
MediaRendition *media; | |
std::string js; | |
}; | |
//------------------------------------------------------------------------ | |
// LinkSound | |
//------------------------------------------------------------------------ | |
class LinkSound : public LinkAction | |
{ | |
public: | |
explicit LinkSound(const Object *soundObj); | |
~LinkSound() override; | |
bool isOk() const override { return sound != nullptr; } | |
LinkActionKind getKind() const override { return actionSound; } | |
double getVolume() const { return volume; } | |
bool getSynchronous() const { return sync; } | |
bool getRepeat() const { return repeat; } | |
bool getMix() const { return mix; } | |
Sound *getSound() const { return sound.get(); } | |
private: | |
double volume; | |
bool sync; | |
bool repeat; | |
bool mix; | |
std::unique_ptr<Sound> sound; | |
}; | |
//------------------------------------------------------------------------ | |
// LinkJavaScript | |
//------------------------------------------------------------------------ | |
class LinkJavaScript : public LinkAction | |
{ | |
public: | |
// Build a LinkJavaScript given the action name. | |
explicit LinkJavaScript(Object *jsObj); | |
~LinkJavaScript() override; | |
bool isOk() const override { return isValid; } | |
LinkActionKind getKind() const override { return actionJavaScript; } | |
const std::string &getScript() const { return js; } | |
static Object createObject(XRef *xref, const GooString &js); | |
private: | |
std::string js; | |
bool isValid; | |
}; | |
//------------------------------------------------------------------------ | |
// LinkOCGState | |
//------------------------------------------------------------------------ | |
class LinkOCGState : public LinkAction | |
{ | |
public: | |
explicit LinkOCGState(const Object *obj); | |
~LinkOCGState() override; | |
bool isOk() const override { return isValid; } | |
LinkActionKind getKind() const override { return actionOCGState; } | |
enum State | |
{ | |
On, | |
Off, | |
Toggle | |
}; | |
struct StateList | |
{ | |
StateList() = default; | |
~StateList() = default; | |
State st; | |
std::vector<Ref> list; | |
}; | |
const std::vector<StateList> &getStateList() const { return stateList; } | |
bool getPreserveRB() const { return preserveRB; } | |
private: | |
std::vector<StateList> stateList; | |
bool isValid; | |
bool preserveRB; | |
}; | |
//------------------------------------------------------------------------ | |
// LinkHide | |
//------------------------------------------------------------------------ | |
class LinkHide : public LinkAction | |
{ | |
public: | |
explicit LinkHide(const Object *hideObj); | |
~LinkHide() override; | |
bool isOk() const override { return hasTargetNameFlag; } | |
LinkActionKind getKind() const override { return actionHide; } | |
// According to spec the target can be either: | |
// a) A text string containing the fully qualified name of the target | |
// field. | |
// b) An indirect reference to an annotation dictionary. | |
// c) An array of "such dictionaries or text strings". | |
// | |
// While b / c appear to be very uncommon and can't easily be | |
// created with Adobe Acrobat DC. So only support hide | |
// actions with named targets (yet). | |
bool hasTargetName() const { return hasTargetNameFlag; } | |
const std::string &getTargetName() const { return targetName; } | |
// Should this action show or hide. | |
bool isShowAction() const { return show; } | |
private: | |
bool hasTargetNameFlag; | |
std::string targetName; | |
bool show; | |
}; | |
//------------------------------------------------------------------------ | |
// LinkResetForm | |
//------------------------------------------------------------------------ | |
class POPPLER_PRIVATE_EXPORT LinkResetForm : public LinkAction | |
{ | |
public: | |
// Build a LinkResetForm. | |
explicit LinkResetForm(const Object *nameObj); | |
~LinkResetForm() override; | |
bool isOk() const override { return true; } | |
LinkActionKind getKind() const override { return actionResetForm; } | |
const std::vector<std::string> &getFields() const { return fields; } | |
bool getExclude() const { return exclude; } | |
private: | |
std::vector<std::string> fields; | |
bool exclude; | |
}; | |
//------------------------------------------------------------------------ | |
// LinkUnknown | |
//------------------------------------------------------------------------ | |
class LinkUnknown : public LinkAction | |
{ | |
public: | |
// Build a LinkUnknown with the specified action type. | |
explicit LinkUnknown(const char *actionA); | |
~LinkUnknown() override; | |
// Was the LinkUnknown create successfully? | |
// Yes: nothing can go wrong when creating LinkUnknown objects | |
bool isOk() const override { return true; } | |
// Accessors. | |
LinkActionKind getKind() const override { return actionUnknown; } | |
const std::string &getAction() const { return action; } | |
private: | |
std::string action; // action subtype | |
}; | |
//------------------------------------------------------------------------ | |
// Links | |
//------------------------------------------------------------------------ | |
class POPPLER_PRIVATE_EXPORT Links | |
{ | |
public: | |
// Extract links from array of annotations. | |
explicit Links(Annots *annots); | |
// Destructor. | |
~Links(); | |
Links(const Links &) = delete; | |
Links &operator=(const Links &) = delete; | |
const std::vector<AnnotLink *> &getLinks() const { return links; } | |
private: | |
std::vector<AnnotLink *> links; | |
}; | |