Okay, here's a first stab at a patch to make the POPPLER_DATADIR
slightly more configurable.
By default, it will act exactly the same (configure's datarootdir).
I've modified the GlobalParams constructor to take an optional (defaults
to POPPLER_DATADIR) char* which it will pass along to
scanEncodingDirs(). To support this, I added an additional constructor
to GDir which takes a second char*, concatenating the two together with
the appropriate slash if necessary.
I then modified the qt4 backend (since that is what I'm most familiar
with) to actually use the new parameter:
- If the application does nothing differently, then the location can be
overridden with an environment variable POPPLER_DATADIR
- Otherwise, the application can call Poppler::configurePoppler() and
pass a char* pointing to a directory that it would like to be used as
the data directory (which can also be overridden by the environment
variable).
* This method also bypasses the static DocumentData::count reference
counting for the GlobalParams object, making the library slightly more
thread-safe
* This is also a slight performance enhancement as the GlobalParams
object won't get destroyed and recreated if you create and destroy
documents one-at-a-time
* And if you want to manually cleanup the GlobalParams, just call
Poppler::unconfigurePoppler().
I'm sure it's not perfect, but I thought I'd get some comments, make
sure I was heading down a reasonable path, etc...
-Adam Batkin
diff --git a/goo/gfile.cc b/goo/gfile.cc
index 811ad14..ecec3f2 100644
--- a/goo/gfile.cc
+++ b/goo/gfile.cc
@@ -634,9 +634,24 @@ GDirEntry::~GDirEntry() {
delete name;
}
-GDir::GDir(char *name, GBool doStatA) {
+GDir::GDir(const char *name, GBool doStatA) {
path = new GooString(name);
doStat = doStatA;
+ initialize();
+}
+
+GDir::GDir(const char *parent, const char *name, GBool doStatA) {
+ path = new GooString(parent);
+ char last_char = path->getChar(path->getLength() - 1);
+ char first_char = name[0];
+ if (!(last_char == '/' || last_char == '\\' || first_char == '/' || first_char == '\\'))
+ path->append(PATH_SEPARATOR_CHAR);
+ path->append(name);
+ doStat = doStatA;
+ initialize();
+}
+
+void GDir::initialize() {
#if defined(WIN32)
GooString *tmp;
@@ -647,9 +662,9 @@ GDir::GDir(char *name, GBool doStatA) {
#elif defined(ACORN)
#elif defined(MACOS)
#else
- dir = opendir(name);
+ dir = opendir(path->getCString());
#ifdef VMS
- needParent = strchr(name, '[') != NULL;
+ needParent = strchr(path->getCString(), '[') != NULL;
#endif
#endif
}
diff --git a/goo/gfile.h b/goo/gfile.h
index ce50562..9169643 100644
--- a/goo/gfile.h
+++ b/goo/gfile.h
@@ -50,6 +50,12 @@ extern "C" {
}
#include "gtypes.h"
+#ifdef WIN32
+# define PATH_SEPARATOR_CHAR '\\'
+#else
+# define PATH_SEPARATOR_CHAR '/'
+#endif
+
class GooString;
//------------------------------------------------------------------------
@@ -117,7 +123,8 @@ private:
class GDir {
public:
- GDir(char *name, GBool doStatA = gTrue);
+ GDir(const char *name, GBool doStatA = gTrue);
+ GDir(const char *parent, const char *name, GBool doStatA = gTrue);
~GDir();
GDirEntry *getNextEntry();
void rewind();
@@ -137,6 +144,7 @@ private:
GBool needParent; // need to return an entry for [-]
#endif
#endif
+ void initialize();
};
#endif
diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc
index 925a602..2e88eba 100644
--- a/poppler/GlobalParams.cc
+++ b/poppler/GlobalParams.cc
@@ -529,7 +529,7 @@ Plugin::~Plugin() {
// parsing
//------------------------------------------------------------------------
-GlobalParams::GlobalParams() {
+GlobalParams::GlobalParams(const char* popplerDir) {
UnicodeMap *map;
int i;
@@ -648,14 +648,14 @@ GlobalParams::GlobalParams() {
map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
residentUnicodeMaps->add(map->getEncodingName(), map);
- scanEncodingDirs();
+ scanEncodingDirs(popplerDir);
}
-void GlobalParams::scanEncodingDirs() {
+void GlobalParams::scanEncodingDirs(const char *popplerDir) {
GDir *dir;
GDirEntry *entry;
- dir = new GDir(POPPLER_DATADIR "/nameToUnicode", gTrue);
+ dir = new GDir(popplerDir, "/nameToUnicode", gTrue);
while (entry = dir->getNextEntry(), entry != NULL) {
if (!entry->isDir()) {
parseNameToUnicode(entry->getFullPath());
@@ -664,21 +664,21 @@ void GlobalParams::scanEncodingDirs() {
}
delete dir;
- dir = new GDir(POPPLER_DATADIR "/cidToUnicode", gFalse);
+ dir = new GDir(popplerDir, "/cidToUnicode", gFalse);
while (entry = dir->getNextEntry(), entry != NULL) {
addCIDToUnicode(entry->getName(), entry->getFullPath());
delete entry;
}
delete dir;
- dir = new GDir(POPPLER_DATADIR "/unicodeMap", gFalse);
+ dir = new GDir(popplerDir, "/unicodeMap", gFalse);
while (entry = dir->getNextEntry(), entry != NULL) {
addUnicodeMap(entry->getName(), entry->getFullPath());
delete entry;
}
delete dir;
- dir = new GDir(POPPLER_DATADIR "/cMap", gFalse);
+ dir = new GDir(popplerDir, "/cMap", gFalse);
while (entry = dir->getNextEntry(), entry != NULL) {
addCMapDir(entry->getName(), entry->getFullPath());
toUnicodeDirs->append(entry->getFullPath()->copy());
diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h
index d505d74..c4b884c 100644
--- a/poppler/GlobalParams.h
+++ b/poppler/GlobalParams.h
@@ -13,6 +13,8 @@
#pragma interface
#endif
+#include <config.h>
+
#include <assert.h>
#include "poppler-config.h"
#include <stdio.h>
@@ -141,7 +143,7 @@ public:
// Initialize the global parameters by attempting to read a config
// file.
- GlobalParams();
+ GlobalParams(const char* popplerDir = POPPLER_DATADIR);
~GlobalParams();
@@ -248,7 +250,7 @@ private:
GBool parseYesNo2(char *token, GBool *flag);
UnicodeMap *getUnicodeMap2(GooString *encodingName);
- void scanEncodingDirs();
+ void scanEncodingDirs(const char* popplerDir);
void addCIDToUnicode(GooString *collection, GooString *fileName);
void addUnicodeMap(GooString *encodingName, GooString *fileName);
void addCMapDir(GooString *collection, GooString *dir);
diff --git a/qt4/src/poppler-private.cc b/qt4/src/poppler-private.cc
index d525e56..f18d0b9 100644
--- a/qt4/src/poppler-private.cc
+++ b/qt4/src/poppler-private.cc
@@ -24,6 +24,9 @@
#include <QtCore/QByteArray>
#include <QtCore/QDebug>
+#include <QtCore/QDir>
+
+#include <stdlib.h>
namespace Poppler {
@@ -113,4 +116,28 @@ namespace Poppler {
gfree(cstring);
return ret;
}
+
+ void configurePoppler(const char* baseDir) {
+ DocumentData::count = POPPLER_MANUALLY_INITIALIZED;
+ configurePopplerInternal(baseDir);
+ }
+
+ void configurePopplerInternal(const char* baseDir) {
+ if ( baseDir == NULL ) baseDir = POPPLER_DATADIR;
+ char* envVal = getenv( "POPPLER_DATADIR" );
+ if ( envVal != NULL ) {
+ QDir temp( envVal );
+ if ( temp.exists() ) baseDir = envVal;
+ }
+ globalParams = new GlobalParams(baseDir);
+ setErrorFunction(qt4ErrorFunction);
+ }
+
+ void unconfigurePoppler() {
+ delete globalParams;
+ globalParams = NULL;
+ DocumentData::count = 0;
+ }
+
+
}
diff --git a/qt4/src/poppler-private.h b/qt4/src/poppler-private.h
index 6f55f18..29ba474 100644
--- a/qt4/src/poppler-private.h
+++ b/qt4/src/poppler-private.h
@@ -42,10 +42,14 @@
#include "poppler-qt4.h"
+#define POPPLER_MANUALLY_INITIALIZED -1
+
class FormWidget;
namespace Poppler {
+ void configurePopplerInternal(const char* baseDir);
+
/* borrowed from kpdf */
QString unicodeToQString(Unicode* u, int len);
@@ -100,10 +104,13 @@ namespace Poppler {
delete ownerPassword;
delete userPassword;
- if ( count == 0 )
+ if ( count == POPPLER_MANUALLY_INITIALIZED )
+ {
+ return;
+ }
+ else if ( count == 0 )
{
- globalParams = new GlobalParams();
- setErrorFunction(qt4ErrorFunction);
+ configurePopplerInternal(NULL);
}
count ++;
}
@@ -116,8 +123,9 @@ namespace Poppler {
delete m_outputDev;
delete m_fontInfoScanner;
+ if ( count == POPPLER_MANUALLY_INITIALIZED ) return;
count --;
- if ( count == 0 ) delete globalParams;
+ if ( count == 0 ) unconfigurePoppler();
}
OutputDev *getOutputDev()
diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h
index ac106ae..a4a1d25 100644
--- a/qt4/src/poppler-qt4.h
+++ b/qt4/src/poppler-qt4.h
@@ -39,6 +39,9 @@ class Sound;
*/
namespace Poppler {
+ void configurePoppler(const char* baseDir);
+ void unconfigurePoppler();
+
class Document;
class DocumentData;
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler