[poppler] poppler/Annot.cc poppler/Annot.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Thu Aug 13 14:59:13 PDT 2015
poppler/Annot.cc | 404 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
poppler/Annot.h | 172 +++++++++++++++++++++++
2 files changed, 575 insertions(+), 1 deletion(-)
New commits:
commit bc01007d714a58fd0023594b055e0cd5fbad1f7e
Author: Tobias Koenig <tokoe at kdab.com>
Date: Thu Aug 13 23:57:44 2015 +0200
Patch to support RichMedia annotations in poppler core
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 18576c8..59c153c 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -6696,6 +6696,408 @@ Annot3D::Activation::Activation(Dict *dict) {
}
//------------------------------------------------------------------------
+// AnnotRichMedia
+//------------------------------------------------------------------------
+AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, PDFRectangle *rect) :
+ Annot(docA, rect) {
+ Object obj1;
+
+ type = typeRichMedia;
+
+ annotObj.dictSet ("Subtype", obj1.initName ("RichMedia"));
+
+ initialize(docA, annotObj.getDict());
+}
+
+AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, Dict *dict, Object *obj) :
+ Annot(docA, dict, obj) {
+ type = typeRichMedia;
+ initialize(docA, dict);
+}
+
+AnnotRichMedia::~AnnotRichMedia() {
+ delete content;
+ delete settings;
+}
+
+void AnnotRichMedia::initialize(PDFDoc *docA, Dict* dict) {
+ Object obj1;
+
+ if (dict->lookup("RichMediaContent", &obj1)->isDict()) {
+ content = new AnnotRichMedia::Content(obj1.getDict());
+ } else {
+ content = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("RichMediaSettings", &obj1)->isDict()) {
+ settings = new AnnotRichMedia::Settings(obj1.getDict());
+ } else {
+ settings = NULL;
+ }
+ obj1.free();
+}
+
+AnnotRichMedia::Content* AnnotRichMedia::getContent() const {
+ return content;
+}
+
+AnnotRichMedia::Settings* AnnotRichMedia::getSettings() const {
+ return settings;
+}
+
+AnnotRichMedia::Settings::Settings(Dict *dict) {
+ Object obj1;
+
+ if (dict->lookup("Activation", &obj1)->isDict()) {
+ activation = new AnnotRichMedia::Activation(obj1.getDict());
+ } else {
+ activation = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("Deactivation", &obj1)->isDict()) {
+ deactivation = new AnnotRichMedia::Deactivation(obj1.getDict());
+ } else {
+ deactivation = NULL;
+ }
+ obj1.free();
+}
+
+AnnotRichMedia::Settings::~Settings() {
+ delete activation;
+ delete deactivation;
+}
+
+AnnotRichMedia::Activation* AnnotRichMedia::Settings::getActivation() const {
+ return activation;
+}
+
+AnnotRichMedia::Deactivation* AnnotRichMedia::Settings::getDeactivation() const {
+ return deactivation;
+}
+
+AnnotRichMedia::Activation::Activation(Dict *dict) {
+ Object obj1;
+
+ if (dict->lookup("Condition", &obj1)->isName()) {
+ const char *name = obj1.getName();
+
+ if (!strcmp(name, "PO")) {
+ condition = conditionPageOpened;
+ } else if (!strcmp(name, "PV")) {
+ condition = conditionPageVisible;
+ } else if (!strcmp(name, "XA")) {
+ condition = conditionUserAction;
+ } else {
+ condition = conditionUserAction;
+ }
+ } else {
+ condition = conditionUserAction;
+ }
+ obj1.free();
+}
+
+AnnotRichMedia::Activation::Condition AnnotRichMedia::Activation::getCondition() const {
+ return condition;
+}
+
+AnnotRichMedia::Deactivation::Deactivation(Dict *dict) {
+ Object obj1;
+
+ if (dict->lookup("Condition", &obj1)->isName()) {
+ const char *name = obj1.getName();
+
+ if (!strcmp(name, "PC")) {
+ condition = conditionPageClosed;
+ } else if (!strcmp(name, "PI")) {
+ condition = conditionPageInvisible;
+ } else if (!strcmp(name, "XD")) {
+ condition = conditionUserAction;
+ } else {
+ condition = conditionUserAction;
+ }
+ } else {
+ condition = conditionUserAction;
+ }
+ obj1.free();
+}
+
+AnnotRichMedia::Deactivation::Condition AnnotRichMedia::Deactivation::getCondition() const {
+ return condition;
+}
+
+AnnotRichMedia::Content::Content(Dict *dict) {
+ Object obj1;
+
+ if (dict->lookup("Configurations", &obj1)->isArray()) {
+ nConfigurations = obj1.arrayGetLength();
+
+ configurations = (Configuration **)gmallocn(nConfigurations, sizeof(Configuration *));
+
+ for (int i = 0; i < nConfigurations; ++i) {
+ Object obj2;
+
+ if (obj1.arrayGet(i, &obj2)->isDict()) {
+ configurations[i] = new AnnotRichMedia::Configuration(obj2.getDict());
+ } else {
+ configurations[i] = NULL;
+ }
+ obj2.free();
+ }
+ } else {
+ configurations = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("Assets", &obj1)->isDict()) {
+ Object obj2;
+
+ if (obj1.getDict()->lookup("Names", &obj2)->isArray()) {
+ nAssets = obj2.arrayGetLength() / 2;
+
+ assets = (Asset **)gmallocn(nAssets, sizeof(Asset *));
+
+ int counter = 0;
+ for (int i = 0; i < obj2.arrayGetLength(); i += 2) {
+ Object objKey;
+
+ assets[counter] = new AnnotRichMedia::Asset;
+
+ obj2.arrayGet(i, &objKey);
+ obj2.arrayGet(i + 1, &assets[counter]->fileSpec);
+
+ assets[counter]->name = new GooString( objKey.getString() );
+ ++counter;
+
+ objKey.free();
+ }
+ }
+ obj2.free();
+
+ } else {
+ assets = NULL;
+ }
+ obj1.free();
+}
+
+AnnotRichMedia::Content::~Content() {
+ if (configurations) {
+ for (int i = 0; i < nConfigurations; ++i)
+ delete configurations[i];
+ gfree(configurations);
+ }
+
+ if (assets) {
+ for (int i = 0; i < nAssets; ++i)
+ delete assets[i];
+ gfree(assets);
+ }
+}
+
+int AnnotRichMedia::Content::getConfigurationsCount() const {
+ return nConfigurations;
+}
+
+AnnotRichMedia::Configuration* AnnotRichMedia::Content::getConfiguration(int index) const {
+ if (index < 0 || index >= nConfigurations)
+ return NULL;
+
+ return configurations[index];
+}
+
+int AnnotRichMedia::Content::getAssetsCount() const {
+ return nAssets;
+}
+
+AnnotRichMedia::Asset* AnnotRichMedia::Content::getAsset(int index) const {
+ if (index < 0 || index >= nAssets)
+ return NULL;
+
+ return assets[index];
+}
+
+AnnotRichMedia::Asset::Asset()
+ : name(NULL)
+{
+}
+
+AnnotRichMedia::Asset::~Asset()
+{
+ delete name;
+ fileSpec.free();
+}
+
+GooString* AnnotRichMedia::Asset::getName() const {
+ return name;
+}
+
+Object* AnnotRichMedia::Asset::getFileSpec() const {
+ return const_cast<Object*>(&fileSpec);
+}
+
+AnnotRichMedia::Configuration::Configuration(Dict *dict)
+{
+ Object obj1;
+
+ if (dict->lookup("Instances", &obj1)->isArray()) {
+ nInstances = obj1.arrayGetLength();
+
+ instances = (Instance **)gmallocn(nInstances, sizeof(Instance *));
+
+ for (int i = 0; i < nInstances; ++i) {
+ Object obj2;
+
+ if (obj1.arrayGet(i, &obj2)->isDict()) {
+ instances[i] = new AnnotRichMedia::Instance(obj2.getDict());
+ } else {
+ instances[i] = NULL;
+ }
+ obj2.free();
+ }
+ } else {
+ instances = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("Name", &obj1)->isString()) {
+ name = new GooString(obj1.getString());
+ } else {
+ name = NULL;
+ }
+ obj1.free();
+
+ if (dict->lookup("Subtype", &obj1)->isName()) {
+ const char *name = obj1.getName();
+
+ if (!strcmp(name, "3D")) {
+ type = type3D;
+ } else if (!strcmp(name, "Flash")) {
+ type = typeFlash;
+ } else if (!strcmp(name, "Sound")) {
+ type = typeSound;
+ } else if (!strcmp(name, "Video")) {
+ type = typeVideo;
+ } else {
+ // determine from first instance
+ if (instances && nInstances > 0) {
+ AnnotRichMedia::Instance *instance = instances[0];
+ switch (instance->getType()) {
+ case AnnotRichMedia::Instance::type3D:
+ type = type3D;
+ break;
+ case AnnotRichMedia::Instance::typeFlash:
+ type = typeFlash;
+ break;
+ case AnnotRichMedia::Instance::typeSound:
+ type = typeSound;
+ break;
+ case AnnotRichMedia::Instance::typeVideo:
+ type = typeVideo;
+ break;
+ default:
+ type = typeFlash;
+ break;
+ }
+ }
+ }
+ }
+ obj1.free();
+}
+
+AnnotRichMedia::Configuration::~Configuration()
+{
+ if (instances) {
+ for (int i = 0; i < nInstances; ++i)
+ delete instances[i];
+ gfree(instances);
+ }
+
+ delete name;
+}
+
+int AnnotRichMedia::Configuration::getInstancesCount() const {
+ return nInstances;
+}
+
+AnnotRichMedia::Instance* AnnotRichMedia::Configuration::getInstance(int index) const {
+ if (index < 0 || index >= nInstances)
+ return NULL;
+
+ return instances[index];
+}
+
+GooString* AnnotRichMedia::Configuration::getName() const {
+ return name;
+}
+
+AnnotRichMedia::Configuration::Type AnnotRichMedia::Configuration::getType() const {
+ return type;
+}
+
+AnnotRichMedia::Instance::Instance(Dict *dict)
+{
+ Object obj1;
+
+ if (dict->lookup("Subtype", &obj1)->isName()) {
+ const char *name = obj1.getName();
+
+ if (!strcmp(name, "3D")) {
+ type = type3D;
+ } else if (!strcmp(name, "Flash")) {
+ type = typeFlash;
+ } else if (!strcmp(name, "Sound")) {
+ type = typeSound;
+ } else if (!strcmp(name, "Video")) {
+ type = typeVideo;
+ } else {
+ type = typeFlash;
+ }
+ }
+ obj1.free();
+
+ if (dict->lookup("Params", &obj1)->isDict()) {
+ params = new AnnotRichMedia::Params(obj1.getDict());
+ } else {
+ params = NULL;
+ }
+}
+
+AnnotRichMedia::Instance::~Instance()
+{
+ delete params;
+}
+
+AnnotRichMedia::Instance::Type AnnotRichMedia::Instance::getType() const {
+ return type;
+}
+
+AnnotRichMedia::Params* AnnotRichMedia::Instance::getParams() const {
+ return params;
+}
+
+AnnotRichMedia::Params::Params(Dict *dict)
+{
+ Object obj1;
+
+ if (dict->lookup("FlashVars", &obj1)->isString()) {
+ flashVars = new GooString(obj1.getString());
+ } else {
+ flashVars = NULL;
+ }
+ obj1.free();
+}
+
+AnnotRichMedia::Params::~Params()
+{
+ delete flashVars;
+}
+
+GooString* AnnotRichMedia::Params::getFlashVars() const {
+ return flashVars;
+}
+
+//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
@@ -6828,6 +7230,8 @@ Annot *Annots::createAnnot(Dict* dict, Object *obj) {
annot = new Annot(doc, dict, obj);
} else if (!strcmp(typeName, "3D")) {
annot = new Annot3D(doc, dict, obj);
+ } else if (!strcmp(typeName, "RichMedia")) {
+ annot = new AnnotRichMedia(doc, dict, obj);
} else if (!strcmp(typeName, "Popup")) {
/* Popup annots are already handled by markup annots
* Here we only care about popup annots without a
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 1e64f59..a74e40e 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -56,6 +56,7 @@ class PDFRectangle;
class Movie;
class LinkAction;
class Sound;
+class FileSpec;
enum AnnotLineEndingStyle {
annotLineEndingSquare, // Square
@@ -526,7 +527,8 @@ public:
typePrinterMark, // PrinterMark 22
typeTrapNet, // TrapNet 23
typeWatermark, // Watermark 24
- type3D // 3D 25
+ type3D, // 3D 25
+ typeRichMedia // RichMedia 26
};
/**
@@ -1409,6 +1411,174 @@ private:
};
//------------------------------------------------------------------------
+// AnnotRichMedia
+//------------------------------------------------------------------------
+
+class AnnotRichMedia: public Annot {
+public:
+ class Params {
+ public:
+ Params(Dict *dict);
+ ~Params();
+
+ GooString* getFlashVars() const;
+
+ private:
+ // optional
+ GooString *flashVars; // FlashVars
+ };
+
+ class Instance {
+ public:
+ enum Type {
+ type3D, // 3D
+ typeFlash, // Flash
+ typeSound, // Sound
+ typeVideo // Video
+ };
+
+ Instance(Dict *dict);
+ ~Instance();
+
+ Type getType() const;
+ Params* getParams() const;
+
+ private:
+ // optional
+ Type type; // Subtype
+ Params *params; // Params
+ };
+
+ class Configuration {
+ public:
+ enum Type {
+ type3D, // 3D
+ typeFlash, // Flash
+ typeSound, // Sound
+ typeVideo // Video
+ };
+
+ Configuration(Dict *dict);
+ ~Configuration();
+
+ Type getType() const;
+ GooString* getName() const;
+ int getInstancesCount() const;
+ Instance* getInstance(int index) const;
+
+ private:
+ // optional
+ Type type; // Subtype
+ GooString *name; // Name
+ Instance **instances; // Instances
+ int nInstances;
+ };
+
+ class Content;
+
+ class Asset {
+ public:
+ Asset();
+ ~Asset();
+
+ GooString* getName() const;
+ Object* getFileSpec() const;
+
+ private:
+ friend class AnnotRichMedia::Content;
+
+ GooString *name;
+ Object fileSpec;
+ };
+
+ class Content {
+ public:
+ Content(Dict *dict);
+ ~Content();
+
+ int getConfigurationsCount() const;
+ Configuration* getConfiguration(int index) const;
+
+ int getAssetsCount() const;
+ Asset* getAsset(int index) const;
+
+ private:
+ // optional
+ Configuration **configurations; // Configurations
+ int nConfigurations;
+
+ Asset **assets; // Assets
+ int nAssets;
+ };
+
+ class Activation {
+ public:
+ enum Condition {
+ conditionPageOpened, // PO
+ conditionPageVisible, // PV
+ conditionUserAction // XA
+ };
+
+ Activation(Dict *dict);
+
+ Condition getCondition() const;
+
+ private:
+ // optional
+ Condition condition;
+ };
+
+ class Deactivation {
+ public:
+ enum Condition {
+ conditionPageClosed, // PC
+ conditionPageInvisible, // PI
+ conditionUserAction // XD
+ };
+
+ Deactivation(Dict *dict);
+
+ Condition getCondition() const;
+
+ private:
+ // optional
+ Condition condition;
+ };
+
+ class Settings {
+ public:
+ Settings(Dict *dict);
+ ~Settings();
+
+ Activation* getActivation() const;
+ Deactivation* getDeactivation() const;
+
+ private:
+ // optional
+ Activation *activation;
+ Deactivation *deactivation;
+ };
+
+ AnnotRichMedia(PDFDoc *docA, PDFRectangle *rect);
+ AnnotRichMedia(PDFDoc *docA, Dict *dict, Object *obj);
+ ~AnnotRichMedia();
+
+ Content* getContent() const;
+
+ Settings* getSettings() const;
+
+private:
+ void initialize(PDFDoc *docA, Dict *dict);
+
+ // required
+ Content *content; // RichMediaContent
+
+ // optional
+ Settings *settings; // RichMediaSettings
+};
+
+
+//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------
More information about the poppler
mailing list