diff --git a/poppler/Annot.cc b/poppler/Annot.cc index dae0f62..d910832 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -6494,6 +6494,293 @@ Annot3D::Activation::Activation(Dict *dict) { } //------------------------------------------------------------------------ +// AnnotRichMedia +//------------------------------------------------------------------------ +AnnotRichMediaInstance::AnnotRichMediaInstance(Dict *dict){ + type = richMediaInstanceType; + subtype = richMediaSubTypeUnknown; + fileSpec = NULL; + Object obj1; + obj1.free(); + //Subtype name (Optional; ExtensionLevel 3) + if(dict->lookup("Subtype", &obj1)->isName()){ + const char *name = obj1.getName(); + if(strcmp(name, "3D") == 0){ + subtype = richMediaSubType3D; + }else if(strcmp(name, "Flash") == 0){ + subtype = richMediaSubTypeFlash; + }else if(strcmp(name, "Sound") == 0){ + subtype = richMediaSubTypeSound; + }else if(strcmp(name, "Video") == 0){ + subtype = richMediaSubTypeVideo; + } + } + obj1.free(); + //Params dictionary (Optional; ExtensionLevel 3) This entry is valid only for subtype Flash. + if(dict->lookup("Params", &obj1)->isDict()){ + //TODO + } + obj1.free(); + //Asset dictionary (Optional; ExtensionLevel 3) + if(dict->lookup("Asset", &obj1)->isDict()){ + fileSpec = new FileSpec(&obj1); + } + obj1.free(); +} + +AnnotRichMediaInstance::~AnnotRichMediaInstance(){ + if(fileSpec != NULL){ + delete fileSpec; + fileSpec = NULL; + } +} + + + +AnnotRichMediaConfiguration::AnnotRichMediaConfiguration(Dict *dict){ + instances = new GooList(); + type = richMediaConfigurationType; + subtype = richMediaSubTypeUnknown; + Object obj1; + Object obj2; + + //Subtype name (Optional; ExtensionLevel 3) + if(dict->lookup("Subtype", &obj1)->isName()){ + char *stype = obj1.getName(); + if(strcmp(stype, "3D") == 0){ + subtype = richMediaSubType3D; + }else if(strcmp(stype, "Flash") == 0){ + subtype = richMediaSubTypeFlash; + }else if(strcmp(stype, "Sound") == 0){ + subtype = richMediaSubTypeSound; + }else if(strcmp(stype, "Video") == 0){ + subtype = richMediaSubTypeVideo; + } + } + obj1.free(); + //Name text tree (Optional; ExtensionLevel 3) + if(dict->lookup("Name", &obj1)->isName()){ + name = obj1.getName(); + } + obj1.free(); + //Instances array (Optional; ExtensionLevel 3) + if(dict->lookup("Instances", &obj1)->isArray()){ + Array* insts = obj1.getArray(); + AnnotRichMediaInstance *instance; + for (int i = 0; i < insts->getLength(); ++i) { + if(insts->get(i, &obj2)->isDict()){ + instance = new AnnotRichMediaInstance(obj2.getDict()); + instances->append(instance); + } + obj2.free(); + } + } +} + +AnnotRichMediaConfiguration::~AnnotRichMediaConfiguration() { + if(instances != NULL){ + deleteGooList(instances, AnnotRichMediaInstance); + instances = NULL; + } +} + +AnnotRichMediaContent::AnnotRichMediaContent(Dict *dict){ + Object obj1; + Object obj2; + Object obj3; + type = richMediaContentType; + configurations = new GooList(); + assets = new GooList(); + + //Assets name tree (Optional; ExtensionLevel 3) + if (dict->lookup("Assets", &obj1)) { + Dict* asts = obj1.getDict(); + if(asts->lookup("Names", &obj2)->isArray()){ + Array* names = obj2.getArray(); + for (int iName = 0; iName < names->getLength(); iName = iName+2) { + if(names->get(iName, &obj3)->isString()){ + //TODO + } + obj3.free(); + if (names->get(iName + 1, &obj3)->isDict()) { + FileSpec* fSpec = new FileSpec(&obj3); + assets->append(fSpec); + } + obj3.free(); + } + } + obj2.free(); + } + obj1.free(); + + //Configurations array (Optional; ExtensionLevel 3) + if (dict->lookup("Configurations", &obj1)->isArray()) { + //Type name (Optional; ExtensionLevel 3) + Array* conf = obj1.getArray(); + AnnotRichMediaConfiguration* configuration; + for (int i = 0; i < conf->getLength(); ++i) { + if(conf->get(0, &obj2)->isDict()){ + configuration = new AnnotRichMediaConfiguration(obj2.getDict()); + configurations->append(configuration); + }else{ + //TODO error; + } + obj2.free(); + } + } + obj1.free(); + //Views array (Optional; ExtensionLevel 3) +} + +AnnotRichMediaContent::~AnnotRichMediaContent() { + if(configurations != NULL){ + deleteGooList(configurations, AnnotRichMediaConfiguration); + configurations = NULL; + } + if(assets != NULL){ + deleteGooList(assets, FileSpec); + assets = NULL; + } +} + +AnnotRichMediaActivation::AnnotRichMediaActivation(Dict *dict){ + type = richMediaActivationType; + condition = activationConditionUserAction; + Object obj1; + + //Condition name (Optional; ExtensionLevel 3) + if (dict->lookup("Condition", &obj1)->isName()) { + const char *name = obj1.getName(); + if(!strcmp("XA", name)){ + condition = activationConditionUserAction; + }else if(!strcmp("PO", name)){ + condition = activationConditionPageOpened; + }else if(!strcmp("PV", name)){ + condition = activationConditionPageVisible; + } + } + obj1.free(); + //Animation dictionary (Optional; ExtensionLevel 3) + + //View dictionary (Optional; ExtensionLevel 3) + + //Configuration dictionary (Optional; ExtensionLevel 3) + + //Presentation dictionary (Optional; ExtensionLevel 3) + + //Scripts array (Optional; ExtensionLevel 3) + +} + +AnnotRichMediaActivation::~AnnotRichMediaActivation() { + +} + +AnnotRichMediaDeactivation::AnnotRichMediaDeactivation(Dict *dict){ + type = richMediaActivationType; + condition = deactivationConditionUserAction; + Object obj1; + + //Condition name (Optional; ExtensionLevel 3) + if (dict->lookup("Condition", &obj1)->isName()) { + const char *name = obj1.getName(); + if(!strcmp("PC", name)){ + condition = deactivationConditionPageClosed; + }else if(!strcmp("PI", name)){ + condition = deactivationConditionPageInvisible; + }else if(!strcmp("XD", name)){ + condition = deactivationConditionUserAction; + } + } + obj1.free(); +} + +AnnotRichMediaDeactivation::~AnnotRichMediaDeactivation() { + +} + +AnnotRichMediaSettings::AnnotRichMediaSettings(Dict *dict){ + type = richMediaSettingsType; + Object obj1; + + //Activation dictionary (Optional; ExtensionLevel 3) + if (dict->lookup("Activation", &obj1)->isDict()) { + activation = new AnnotRichMediaActivation(obj1.getDict()); + } + obj1.free(); + //Deactivation dictionary (Optional; ExtensionLevel 3) + if (dict->lookup("Deactivation", &obj1)->isDict()) { + deactivation = new AnnotRichMediaDeactivation(obj1.getDict()); + } + obj1.free(); +} + +AnnotRichMediaSettings::~AnnotRichMediaSettings() { + if(activation != NULL){ + delete activation; + activation = NULL; + } + if(deactivation != NULL){ + delete deactivation; + deactivation = NULL; + } +} + + +AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, Dict *dict, Object *obj) : + Annot(docA, dict, obj) { + type = typeRichMedia; + initialize(docA, dict); +} + +AnnotRichMedia::~AnnotRichMedia() { + if(settings != NULL){ + delete settings; + settings = NULL; + } + if(content != NULL){ + delete content; + content = NULL; + } +} + +void AnnotRichMedia::initialize(PDFDoc *docA, Dict* dict) { + subtype = richMediaType; + Object obj1; + + //Subtype name (Required; ExtensionLevel 3) + if(dict->lookup("Subtype", &obj1)->isName()){ + subtype = richMediaType; + }else{ + error(errSyntaxError, -1, "Bad Annot RichMedia"); + //ok = gFalse; + } + obj1.free(); + + //RichMediaSettings dictionary (Optional; ExtensionLevel 3) + if (dict->lookup("RichMediaSettings", &obj1)->isDict()) { + settings = new AnnotRichMediaSettings(obj1.getDict()); + } + obj1.free(); + + //RichMediaContent dictionary (Required; ExtensionLevel 3) + if (dict->lookup("RichMediaContent", &obj1)->isDict()) { + content = new AnnotRichMediaContent(obj1.getDict()); + } + obj1.free(); +} + +void AnnotRichMedia::draw(Gfx *gfx, GBool printing) {} + +GooList* AnnotRichMedia::getConfigurations(){ + GooList* configurations = new GooList(); + if(content != NULL){ + configurations->append(content->getConfigurations()); + } + return configurations; +} + +//------------------------------------------------------------------------ // Annots //------------------------------------------------------------------------ @@ -6639,6 +6926,8 @@ Annot *Annots::createAnnot(Dict* dict, Object *obj) { annot = NULL; obj2.free(); + } else if (!strcmp(typeName, "RichMedia")) { + annot = new AnnotRichMedia(doc, dict, obj); } else { annot = new Annot(doc, dict, obj); } diff --git a/poppler/Annot.h b/poppler/Annot.h index 68ddeb7..b3fdb71 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -54,6 +54,8 @@ class PDFRectangle; class Movie; class LinkAction; class Sound; +class GooList; +class FileSpec; enum AnnotLineEndingStyle { annotLineEndingSquare, // Square @@ -73,6 +75,11 @@ enum AnnotExternalDataType { annotExternalDataMarkup3D // Markup3D }; +enum AnnotRichMediaSubType { + subTypeMovie, // 0 + subTypeSound // 1 +}; + //------------------------------------------------------------------------ // AnnotCoord //------------------------------------------------------------------------ @@ -516,7 +523,8 @@ public: typePrinterMark, // PrinterMark 22 typeTrapNet, // TrapNet 23 typeWatermark, // Watermark 24 - type3D // 3D 25 + type3D, // 3D 25 + typeRichMedia // RichMedia 26 }; /** @@ -1383,6 +1391,129 @@ private: }; //------------------------------------------------------------------------ +// AnnotRichMedia +//------------------------------------------------------------------------ + +enum RichMediaActivationCondition{ + activationConditionUserAction, //XA + activationConditionPageOpened, //PO + activationConditionPageVisible //PV +}; + +enum RichMediaDeactivationCondition { + deactivationConditionPageClosed, // PC + deactivationConditionPageInvisible, // PI + deactivationConditionUserAction // XD +}; + +enum RichMediaType{ + richMediaInstanceType, + richMediaConfigurationType, + richMediaContentType, + richMediaActivationType, + richMediaDeactivationType, + richMediaSettingsType, + richMediaType +}; + +enum RichMediaSubType { + richMediaSubTypeUnknown, + richMediaSubType3D, + richMediaSubTypeFlash, + richMediaSubTypeSound, + richMediaSubTypeVideo +}; + + +class AnnotRichMediaInstance { +public: + AnnotRichMediaInstance(Dict *dict); + ~AnnotRichMediaInstance(); + int getSubType(){ return subtype; } + +private: + int type; + int subtype; + FileSpec *fileSpec; +}; + +class AnnotRichMediaConfiguration { +public: + AnnotRichMediaConfiguration(Dict *dict); + ~AnnotRichMediaConfiguration(); + int getSubType(){ return subtype; } + GooList* getInstances(){ return instances; } + +private: + int type; + int subtype; + char* name; + GooList* instances; + +}; + +class AnnotRichMediaContent { +public: + AnnotRichMediaContent(Dict *dict); + ~AnnotRichMediaContent(); + GooList* getConfigurations(){ return configurations; } + GooList* getAssets(){ return assets; } + +private: + int type; + GooList* configurations; + GooList *assets; +}; + +class AnnotRichMediaActivation { +public: + AnnotRichMediaActivation(Dict *dict); + ~AnnotRichMediaActivation(); + +private: + int type; + int condition; +}; + +class AnnotRichMediaDeactivation { +public: + AnnotRichMediaDeactivation(Dict *dict); + ~AnnotRichMediaDeactivation(); + +private: + int type; + int condition; +}; + +class AnnotRichMediaSettings { +public: + AnnotRichMediaSettings(Dict *dict); + ~AnnotRichMediaSettings(); + +private: + int type; + AnnotRichMediaActivation* activation; + AnnotRichMediaDeactivation *deactivation; +}; + +class AnnotRichMedia: public Annot { +public: + AnnotRichMedia(PDFDoc *docA, Dict *dict, Object *obj); + ~AnnotRichMedia(); + virtual void draw(Gfx *gfx, GBool printing); + GooList* getConfigurations(); + AnnotRichMediaContent* getContent(){ return content; } + +private: + void initialize(PDFDoc *docA, Dict *dict); + int subtype; + AnnotRichMediaContent* content; + AnnotRichMediaSettings* settings; +}; + + + +//------------------------------------------------------------------------ // Annots //------------------------------------------------------------------------ diff --git a/poppler/FileSpec.cc b/poppler/FileSpec.cc index bac1eae..2cfd339 100644 --- a/poppler/FileSpec.cc +++ b/poppler/FileSpec.cc @@ -176,7 +176,6 @@ GooString *FileSpec::getFileNameForPlatform() if (getFileSpecNameForPlatform(&fileSpec, &obj1)) platformFileName = obj1.getString()->copy(); obj1.free(); - return platformFileName; } diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index e4bd0b1..c4c3ab4 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -66,13 +66,14 @@ #include "HtmlUtils.h" #include "Outline.h" #include "PDFDoc.h" +#include "FileSpec.h" #define DEBUG __FILE__ << ": " << __LINE__ << ": DEBUG: " class HtmlImage { public: - HtmlImage(GooString *_fName, GfxState *state) + HtmlImage(GooString *_fName, GfxState *state) : fName(_fName) { state->transform(0, 0, &xMin, &yMax); state->transform(1, 1, &xMax, &yMin); @@ -97,6 +98,7 @@ extern GBool stout; extern GBool xml; extern GBool showHidden; extern GBool noMerge; +extern GBool withMedia; extern double wordBreakThreshold; @@ -104,7 +106,6 @@ static GBool debug = gFalse; static GooString *gstr_buff0 = NULL; // a workspace in which I format strings static GooString* basename(GooString* str){ - char *p=str->getCString(); int len=str->getLength(); for (int i=len-1;i>=0;i--) @@ -113,6 +114,15 @@ static GooString* basename(GooString* str){ return new GooString(str); } +static const char* extension(GooString* str) { + char *p=str->getCString(); + char *dot = strrchr(p, '.'); + if(!dot || dot == p) + return ""; + return dot+1; +} + + #if 0 static GooString* Dirname(GooString* str){ @@ -272,6 +282,8 @@ HtmlPage::HtmlPage(GBool rawOrder, char *imgExtVal) { fonts=new HtmlFontAccu(); links=new HtmlLinks(); imgList=new GooList(); + movieList = new GooList(); + soundList = new GooList(); pageWidth=0; pageHeight=0; fontsPageMarker = 0; @@ -287,6 +299,8 @@ HtmlPage::~HtmlPage() { delete links; delete imgExt; deleteGooList(imgList, HtmlImage); + deleteGooList(movieList, HtmlMovie); + deleteGooList(soundList, HtmlSound); } void HtmlPage::updateFont(GfxState *state) { @@ -877,22 +891,88 @@ void HtmlPage::dumpComplex(FILE *file, int page){ fprintf(pageFile,"
yMin), - xoutRound(tmp1->xMin)); + "
", tmp1->fontpos); fputs(tmp1->htext->getCString(), pageFile); - fputs("
\n", pageFile); + fputs("", pageFile); + fputs("