| author | Carlos Garcia Campos <carlosgc@gnome.org> | 2008-09-05 16:17:25 (GMT) |
|---|---|---|
| committer | Carlos Garcia Campos <carlosgc@gnome.org> | 2008-09-05 16:17:25 (GMT) |
| commit | 996d2e176057e22acbc374cff7a712ce6fd92d93 (patch) | |
| tree | bb4ecb53cd3e311e3feec4585471221b3bdffe5a | |
| parent | 31f3eb2d6b43f7fbf4d978730d109b08b1563989 (diff) | |
| download | poppler-996d2e176057e22acbc374cff7a712ce6fd92d93.zip poppler-996d2e176057e22acbc374cff7a712ce6fd92d93.tar.gz poppler-996d2e176057e22acbc374cff7a712ce6fd92d93.tar.bz2 | |
Unify multiple File Specification parsers
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | poppler/FileSpec.cc | 146 | ||||
| -rw-r--r-- | poppler/FileSpec.h | 24 | ||||
| -rw-r--r-- | poppler/Link.cc | 104 | ||||
| -rw-r--r-- | poppler/Link.h | 4 | ||||
| -rw-r--r-- | poppler/Makefile.am | 2 | ||||
| -rw-r--r-- | poppler/PSOutputDev.cc | 35 | ||||
| -rw-r--r-- | poppler/PSOutputDev.h | 1 | ||||
| -rw-r--r-- | poppler/Sound.cc | 7 |
9 files changed, 197 insertions, 128 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 63ec8bd..63f28b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,6 +143,7 @@ set(poppler_SRCS poppler/Decrypt.cc poppler/Dict.cc poppler/Error.cc + poppler/FileSpec.cc poppler/FontEncodingTables.cc poppler/Form.cc poppler/FontInfo.cc @@ -272,6 +273,7 @@ if(ENABLE_XPDF_HEADERS) poppler/Decrypt.h poppler/Dict.h poppler/Error.h + poppler/FileSpec.h poppler/FontEncodingTables.h poppler/FontInfo.h poppler/Form.h diff --git a/poppler/FileSpec.cc b/poppler/FileSpec.cc new file mode 100644 index 0000000..7ef759e --- a/dev/null +++ b/poppler/FileSpec.cc @@ -0,0 +1,146 @@ +//======================================================================== +// +// FileSpec.cc +// +// All changes made under the Poppler project to this file are licensed +// under GPL version 2 or later +// +// Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org> +// +// 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 +// +//======================================================================== + +//======================================================================== +// +// Most of the code from Link.cc and PSOutputDev.cc +// +// Copyright 1996-2003 Glyph & Cog, LLC +// +//======================================================================== + +#include <config.h> + +#include "FileSpec.h" + +GBool getFileSpecName (Object *fileSpec, Object *fileName) +{ + if (fileSpec->isString()) { + fileSpec->copy(fileName); + return gTrue; + } + + if (fileSpec->isDict()) { + fileSpec->dictLookup("DOS", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("Mac", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("Unix", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + fileSpec->dictLookup("F", fileName); + if (fileName->isString()) { + return gTrue; + } + fileName->free(); + } + return gFalse; +} + +GBool getFileSpecNameForPlatform (Object *fileSpec, Object *fileName) +{ + if (fileSpec->isString()) { + fileSpec->copy(fileName); + return gTrue; + } + + Object obj1; + GooString *name; + + name = NULL; + + if (fileSpec->isDict()) { +#ifdef WIN32 + if (!fileSpec->dictLookup("DOS", &obj1)->isString()) { +#else + if (!fileSpec->dictLookup("Unix", &obj1)->isString()) { +#endif + obj1.free(); + fileSpec->dictLookup("F", &obj1); + } + + if (obj1.isString()) { + name = obj1.getString()->copy(); + } else { + error(-1, "Illegal file spec in link"); + } + obj1.free(); + + // error + } else { + error(-1, "Illegal file spec in link"); + } + + // system-dependent path manipulation + if (name) { +#ifdef WIN32 + int i, j; + + // "//...." --> "\...." + // "/x/...." --> "x:\...." + // "/server/share/...." --> "\\server\share\...." + // convert escaped slashes to slashes and unescaped slashes to backslashes + i = 0; + if (name->getChar(0) == '/') { + if (name->getLength() >= 2 && name->getChar(1) == '/') { + name->del(0); + i = 0; + } else if (name->getLength() >= 2 && + ((name->getChar(1) >= 'a' && name->getChar(1) <= 'z') || + (name->getChar(1) >= 'A' && name->getChar(1) <= 'Z')) && + (name->getLength() == 2 || name->getChar(2) == '/')) { + name->setChar(0, name->getChar(1)); + name->setChar(1, ':'); + i = 2; + } else { + for (j = 2; j < name->getLength(); ++j) { + if (name->getChar(j-1) != '\\' && + name->getChar(j) == '/') { + break; + } + } + if (j < name->getLength()) { + name->setChar(0, '\\'); + name->insert(0, '\\'); + i = 2; + } + } + } + for (; i < name->getLength(); ++i) { + if (name->getChar(i) == '/') { + name->setChar(i, '\\'); + } else if (name->getChar(i) == '\\' && + i+1 < name->getLength() && + name->getChar(i+1) == '/') { + name->del(i); + } + } +#else + // no manipulation needed for Unix +#endif + } else { + return gFalse; + } + + fileName->initString (name); + return gTrue; +} diff --git a/poppler/FileSpec.h b/poppler/FileSpec.h new file mode 100644 index 0000000..ec35f3f --- a/dev/null +++ b/poppler/FileSpec.h @@ -0,0 +1,24 @@ +//======================================================================== +// +// FileSpec.h +// +// All changes made under the Poppler project to this file are licensed +// under GPL version 2 or later +// +// Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org> +// +// 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 +// +//======================================================================== + +#ifndef FILE_SPEC_H +#define FILE_SPEC_H + +#include "goo/gtypes.h" +#include "Object.h" + +GBool getFileSpecName (Object *fileSpec, Object *fileName); +GBool getFileSpecNameForPlatform (Object *fileSpec, Object *fileName); + +#endif /* FILE_SPEC_H */ diff --git a/poppler/Link.cc b/poppler/Link.cc index 795ad40..61f05b7 100644 --- a/poppler/Link.cc +++ b/poppler/Link.cc @@ -40,6 +40,7 @@ #include "Link.h" #include "Sound.h" #include "Movie.h" +#include "FileSpec.h" //------------------------------------------------------------------------ // LinkAction @@ -136,90 +137,6 @@ LinkAction *LinkAction::parseAction(Object *obj, GooString *baseURI) { return action; } -GooString *LinkAction::getFileSpecName(Object *fileSpecObj) { - GooString *name; - Object obj1; - - name = NULL; - - // string - if (fileSpecObj->isString()) { - name = fileSpecObj->getString()->copy(); - - // dictionary - } else if (fileSpecObj->isDict()) { -#ifdef WIN32 - if (!fileSpecObj->dictLookup("DOS", &obj1)->isString()) { -#else - if (!fileSpecObj->dictLookup("Unix", &obj1)->isString()) { -#endif - obj1.free(); - fileSpecObj->dictLookup("F", &obj1); - } - if (obj1.isString()) { - name = obj1.getString()->copy(); - } else { - error(-1, "Illegal file spec in link"); - } - obj1.free(); - - // error - } else { - error(-1, "Illegal file spec in link"); - } - - // system-dependent path manipulation - if (name) { -#ifdef WIN32 - int i, j; - - // "//...." --> "\...." - // "/x/...." --> "x:\...." - // "/server/share/...." --> "\\server\share\...." - // convert escaped slashes to slashes and unescaped slashes to backslashes - i = 0; - if (name->getChar(0) == '/') { - if (name->getLength() >= 2 && name->getChar(1) == '/') { - name->del(0); - i = 0; - } else if (name->getLength() >= 2 && - ((name->getChar(1) >= 'a' && name->getChar(1) <= 'z') || - (name->getChar(1) >= 'A' && name->getChar(1) <= 'Z')) && - (name->getLength() == 2 || name->getChar(2) == '/')) { - name->setChar(0, name->getChar(1)); - name->setChar(1, ':'); - i = 2; - } else { - for (j = 2; j < name->getLength(); ++j) { - if (name->getChar(j-1) != '\\' && - name->getChar(j) == '/') { - break; - } - } - if (j < name->getLength()) { - name->setChar(0, '\\'); - name->insert(0, '\\'); - i = 2; - } - } - } - for (; i < name->getLength(); ++i) { - if (name->getChar(i) == '/') { - name->setChar(i, '\\'); - } else if (name->getChar(i) == '\\' && - i+1 < name->getLength() && - name->getChar(i+1) == '/') { - name->del(i); - } - } -#else - // no manipulation needed for Unix -#endif - } - - return name; -} - //------------------------------------------------------------------------ // LinkDest //------------------------------------------------------------------------ @@ -505,7 +422,10 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) { namedDest = NULL; // get file name - fileName = getFileSpecName(fileSpecObj); + Object obj1; + getFileSpecNameForPlatform (fileSpecObj, &obj1); + fileName = obj1.getString()->copy(); + obj1.free(); // named destination if (destObj->isName()) { @@ -542,20 +462,24 @@ LinkGoToR::~LinkGoToR() { //------------------------------------------------------------------------ LinkLaunch::LinkLaunch(Object *actionObj) { - Object obj1, obj2; + Object obj1, obj2, obj3; fileName = NULL; params = NULL; if (actionObj->isDict()) { if (!actionObj->dictLookup("F", &obj1)->isNull()) { - fileName = getFileSpecName(&obj1); + getFileSpecNameForPlatform (&obj1, &obj3); + fileName = obj3.getString()->copy(); + obj3.free(); } else { obj1.free(); #ifdef WIN32 if (actionObj->dictLookup("Win", &obj1)->isDict()) { obj1.dictLookup("F", &obj2); - fileName = getFileSpecName(&obj2); + getFileSpecNameForPlatform (&obj2, &obj3); + fileName = obj3.getString()->copy(); + obj3.free(); obj2.free(); if (obj1.dictLookup("P", &obj2)->isString()) { params = obj2.getString()->copy(); @@ -569,7 +493,9 @@ LinkLaunch::LinkLaunch(Object *actionObj) { //~ just like the Win dictionary until they say otherwise. if (actionObj->dictLookup("Unix", &obj1)->isDict()) { obj1.dictLookup("F", &obj2); - fileName = getFileSpecName(&obj2); + getFileSpecNameForPlatform (&obj2, &obj3); + fileName = obj3.getString()->copy(); + obj3.free(); obj2.free(); if (obj1.dictLookup("P", &obj2)->isString()) { params = obj2.getString()->copy(); diff --git a/poppler/Link.h b/poppler/Link.h index 12d5231..af42923 100644 --- a/poppler/Link.h +++ b/poppler/Link.h @@ -70,10 +70,6 @@ public: // Parse an action dictionary. static LinkAction *parseAction(Object *obj, GooString *baseURI = NULL); - - // Extract a file name from a file specification (string or - // dictionary). - static GooString *getFileSpecName(Object *fileSpecObj); }; //------------------------------------------------------------------------ diff --git a/poppler/Makefile.am b/poppler/Makefile.am index f19b31e..6d163f7 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -155,6 +155,7 @@ poppler_include_HEADERS = \ Decrypt.h \ Dict.h \ Error.h \ + FileSpec.h \ FontEncodingTables.h \ FontInfo.h \ Form.h \ @@ -224,6 +225,7 @@ libpoppler_la_SOURCES = \ Decrypt.cc \ Dict.cc \ Error.cc \ + FileSpec.cc \ FontEncodingTables.cc \ Form.cc \ FontInfo.cc \ diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index fecc2a3..b80654a 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -54,6 +54,7 @@ #include "Annot.h" #include "XRef.h" #include "PreScanOutputDev.h" +#include "FileSpec.h" #if HAVE_SPLASH # include "splash/Splash.h" # include "splash/SplashBitmap.h" @@ -5647,7 +5648,7 @@ void PSOutputDev::opiBegin20(GfxState *state, Dict *dict) { writePS("%%Distilled\n"); dict->lookup("F", &obj1); - if (getFileSpec(&obj1, &obj2)) { + if (getFileSpecName(&obj1, &obj2)) { writePSFmt("%%ImageFileName: {0:t}\n", obj2.getString()); obj2.free(); } @@ -5763,7 +5764,7 @@ void PSOutputDev::opiBegin13(GfxState *state, Dict *dict) { writePS("opiMatrix setmatrix\n"); dict->lookup("F", &obj1); - if (getFileSpec(&obj1, &obj2)) { + if (getFileSpecName(&obj1, &obj2)) { writePSFmt("%ALDImageFileName: {0:t}\n", obj2.getString()); obj2.free(); } @@ -6014,36 +6015,6 @@ void PSOutputDev::opiEnd(GfxState *state, Dict *opiDict) { } } } - -GBool PSOutputDev::getFileSpec(Object *fileSpec, Object *fileName) { - if (fileSpec->isString()) { - fileSpec->copy(fileName); - return gTrue; - } - if (fileSpec->isDict()) { - fileSpec->dictLookup("DOS", fileName); - if (fileName->isString()) { - return gTrue; - } - fileName->free(); - fileSpec->dictLookup("Mac", fileName); - if (fileName->isString()) { - return gTrue; - } - fileName->free(); - fileSpec->dictLookup("Unix", fileName); - if (fileName->isString()) { - return gTrue; - } - fileName->free(); - fileSpec->dictLookup("F", fileName); - if (fileName->isString()) { - return gTrue; - } - fileName->free(); - } - return gFalse; -} #endif // OPI_SUPPORT void PSOutputDev::type3D0(GfxState *state, double wx, double wy) { diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index 2c6a103..ddc2041 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -319,7 +319,6 @@ private: void opiBegin13(GfxState *state, Dict *dict); void opiTransform(GfxState *state, double x0, double y0, double *x1, double *y1); - GBool getFileSpec(Object *fileSpec, Object *fileName); #endif void cvtFunction(Function *func); void writePSChar(char c); diff --git a/poppler/Sound.cc b/poppler/Sound.cc index 8f8eadd..0dec645 100644 --- a/poppler/Sound.cc +++ b/poppler/Sound.cc @@ -20,7 +20,7 @@ #include "Object.h" #include "Sound.h" #include "Stream.h" -#include "Link.h" +#include "FileSpec.h" Sound *Sound::parseSound(Object *obj) { @@ -65,9 +65,12 @@ Sound::Sound(Object *obj, bool readAttrs) Dict *dict = streamObj->getStream()->getDict(); dict->lookup("F", &tmp); if (!tmp.isNull()) { + Object obj1; // valid 'F' key -> external file kind = soundExternal; - fileName = LinkAction::getFileSpecName(&tmp); + getFileSpecNameForPlatform (&tmp, &obj1); + fileName = obj1.getString()->copy(); + obj1.free(); } else { // no file specification, then the sound data have to be // extracted from the stream |
