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

Reply via email to