[poppler] [PATCH] poppler-qt again

Jeff Muizelaar jrmuizel at nit.ca
Tue Apr 5 15:13:51 PDT 2005


Attached is my cvs candidate for the begining of poppler-qt.

Changes of Note:
	* uses Poppler namespace instead of Poppler prefix
	* no more namespace polution with PDFDoc
	* renderSlice instead of just render
	* nearly verbatim inclusion of some of meta-data functions
	  from kpdf and kfile_pdf

With this patch it should be pretty trivial to convert kfile_pdf to
poppler-qt.

-Jeff


diff -X /home/jrmuizel/rsrc/autoignore -urN poppler/Makefile.am poppler-qt-new/Makefile.am
--- poppler/Makefile.am	2005-03-30 12:19:15.000000000 -0500
+++ poppler-qt-new/Makefile.am	2005-03-30 12:14:26.000000000 -0500
@@ -12,17 +12,24 @@
 glib_pc_file = poppler-glib.pc
 endif
 
-SUBDIRS = goo fofi $(splash_subdir) poppler $(glib_subdir) test
+if BUILD_POPPLER_QT
+qt_subdir = qt
+qt_pc_file = poppler-qt.pc
+endif
+
+SUBDIRS = goo fofi $(splash_subdir) poppler $(glib_subdir) $(qt_subdir) test
 
 EXTRA_DIST =					\
 	README-XPDF				\
 	poppler.pc.in				\
 	poppler-cairo.pc.in			\
-	poppler-splash.pc.in
+	poppler-splash.pc.in			\
+	poppler-qt.pc.in
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA =				\
 	poppler.pc				\
 	$(cairo_pc_file)			\
 	$(splash_pc_file)			\
-	$(glib_pc_file)
+	$(glib_pc_file)				\
+	$(qt_pc_file)
diff -X /home/jrmuizel/rsrc/autoignore -urN poppler/configure.ac poppler-qt-new/configure.ac
--- poppler/configure.ac	2005-04-05 18:00:47.000000000 -0400
+++ poppler-qt-new/configure.ac	2005-04-05 18:01:06.000000000 -0400
@@ -180,6 +180,65 @@
 fi
 AM_CONDITIONAL(BUILD_POPPLER_GLIB, test x$enable_poppler_glib = xyes)
 
+AC_ARG_ENABLE(poppler-qt,
+	      AC_HELP_STRING([--disable-poppler-qt],
+			     [Don't compile poppler qt wrapper.]),
+	      enable_poppler_qt=$enableval,
+	      enable_poppler_qt="try")
+# Qt detection
+AC_PATH_PROG(QT_MOC, moc, no)
+
+have_qt=no
+AC_MSG_CHECKING([for qglobal.h])
+if test -n "$QTDIR" -a -f "$QTDIR/include/qglobal.h"; then
+    have_qt=yes
+    POPPLER_QT_CXXFLAGS="-I$QTDIR/include"
+else
+    for dir in "${prefix}/include/qt" "/usr/include/qt-3.1" "/usr/include/qt3" "/usr/include/qt" "/usr/lib/qt/include" "/usr/lib/qt-3.1/include"; do
+        if test -f "$dir/qglobal.h"; then
+            have_qt=yes
+            POPPLER_QT_CXXFLAGS="-I$dir"
+       fi
+    done
+fi
+if test x"$have_qt" = x"yes"; then
+   AC_MSG_RESULT([found])
+else
+   AC_MSG_RESULT([not found])
+fi
+
+dnl linking to kdecore will give us a bit of help from libtool
+if (! kde-config >& /dev/null); then
+    have_qt=no
+else
+    kdelibs=`kde-config --install lib --expandvars 2>/dev/null`
+    if test -z $kdelibs -o ! -f $kdelibs/libkdecore.la; then
+        have_qt=no
+    else
+        POPPLER_QT_LIBS="$kdelibs/libkdecore.la /usr/lib/libqt-mt.la"
+    fi
+fi
+
+if test x$have_qt = xno ; then
+    AC_MSG_WARN([Qt development libraries not found])
+fi
+
+if test x$enable_poppler_qt = xyes; then
+  if test x$have_qt = xno; then
+    AC_MSG_ERROR([Qt integration explicitly required, and Qt libraries not found])
+  fi
+elif test x$enable_poppler_qt = xtry; then
+  if test x$have_qt = xyes; then
+    enable_poppler_qt="yes"
+  else
+    enable_poppler_qt="no"
+  fi
+fi
+AM_CONDITIONAL(BUILD_POPPLER_QT, test x$enable_poppler_glib = xyes)
+
+dnl Qt flags
+AC_SUBST(POPPLER_QT_CXXFLAGS)
+AC_SUBST(POPPLER_QT_LIBS)
 
 AC_ARG_ENABLE(gtk-test,
               AC_HELP_STRING([--disable-gtk-test],
@@ -224,15 +283,18 @@
 poppler/Makefile
 glib/Makefile
 test/Makefile
+qt/Makefile
 poppler.pc
 poppler-cairo.pc
 poppler-splash.pc
-poppler-glib.pc])
+poppler-glib.pc
+poppler-qt.pc])
 
 
 echo ""
 echo "Building poppler with support for:"
 echo "  splash output: $enable_splash_output"
 echo "  cairo output:  $enable_cairo_output"
+echo "  qt wrapper:    $enable_poppler_qt"
 echo "  glib wrapper:  $enable_poppler_glib"
 echo "  use libjpeg:   $enable_libjpeg"
diff -X /home/jrmuizel/rsrc/autoignore -urN poppler/qt/Makefile.am poppler-qt-new/qt/Makefile.am
--- poppler/qt/Makefile.am	1969-12-31 19:00:00.000000000 -0500
+++ poppler-qt-new/qt/Makefile.am	2005-03-30 13:14:42.000000000 -0500
@@ -0,0 +1,31 @@
+INCLUDES =					\
+	-I$(top_srcdir)				\
+	-I$(top_srcdir)/poppler			\
+	$(cairo_includes)			\
+ 	$(POPPLER_QT_CXXFLAGS)			\
+	$(FREETYPE_CFLAGS)			\
+	-DDATADIR=\""$(datadir)"\"
+
+
+poppler_includedir = $(includedir)/poppler
+poppler_include_HEADERS =			\
+	poppler-qt.h
+
+lib_LTLIBRARIES=libpoppler-qt.la
+libpoppler_qt_la_SOURCES =			\
+	poppler-qt.cc
+
+libpoppler_qt_la_LIBADD= 			\
+	$(POPPLER_QT_LIBS)			\
+	$(FREETYPE_LIBS)
+
+noinst_PROGRAMS = test-poppler-qt
+
+test_poppler_qt_SOURCES =			\
+       test-poppler-qt.cpp
+
+test_poppler_qt_LDADD =				\
+	$(top_builddir)/poppler/libpoppler.la	\
+	libpoppler-qt.la			\
+	$(POPPLER_QT_LIBS)			\
+	$(FREETYPE_LIBS)
diff -X /home/jrmuizel/rsrc/autoignore -urN poppler/qt/poppler-qt.cc poppler-qt-new/qt/poppler-qt.cc
--- poppler/qt/poppler-qt.cc	1969-12-31 19:00:00.000000000 -0500
+++ poppler-qt-new/qt/poppler-qt.cc	2005-04-05 17:58:11.000000000 -0400
@@ -0,0 +1,241 @@
+/* poppler-qt.cpp: qt interface to poppler
+ * Copyright (C) 2005, Net Integration Technologies, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <poppler-qt.h>
+#include <qfile.h>
+#include <qimage.h>
+#include <GlobalParams.h>
+#include <PDFDoc.h>
+#include <Catalog.h>
+#include <ErrorCodes.h>
+#include <SplashOutputDev.h>
+#include <splash/SplashBitmap.h>
+
+namespace Poppler {
+
+class DocumentData {
+  public:
+    DocumentData(GooString *filePath, GooString *password) : doc(filePath,password) {}
+  class PDFDoc doc;
+};
+
+Document *Document::load(const QString &filePath)
+{
+  if (!globalParams) {
+    globalParams = new GlobalParams("/etc/xpdfrc");
+    globalParams->setupBaseFontsFc(NULL);
+  }
+
+  DocumentData *doc = new DocumentData(new GooString(QFile::encodeName(filePath)), NULL);
+  Document *pdoc;
+  if (doc->doc.isOk() || doc->doc.getErrorCode() == errEncrypted) {
+    pdoc = new Document(doc);
+    if (doc->doc.getErrorCode() == errEncrypted)
+      pdoc->locked = true;
+    else
+      pdoc->locked = false;
+    return pdoc;
+  }
+  else
+    return NULL;
+}
+
+bool Document::unlock(QCString &password)
+{
+  if (locked) {
+    /* racier then it needs to be */
+    GooString *pwd = new GooString(password.data());
+    DocumentData *doc2 = new DocumentData(data->doc.getFileName(), pwd);
+    delete pwd;
+    if (!doc2->doc.isOk()) {
+      delete doc2;
+    } else {
+      delete data;
+      data = doc2;
+      locked = false;
+    }
+  }
+  return locked;
+}
+
+
+Document::Document(DocumentData *dataA)
+{
+  data = dataA;
+}
+
+Document::~Document()
+{
+  delete data;
+}
+
+Document::PageMode Document::getPageMode(void)
+{
+  switch (data->doc.getCatalog()->getPageMode()) {
+    case Catalog::pageModeNone:
+      return UseNone;
+    case Catalog::pageModeOutlines:
+      return UseOutlines;
+    case Catalog::pageModeThumbs:
+      return UseThumbs;
+    case Catalog::pageModeFullScreen:
+      return FullScreen;
+    case Catalog::pageModeOC:
+      return UseOC;
+    default:
+      return UseNone;
+  }
+}
+
+void Page::renderSliceToPixmap(QPixmap **q, int x, int y, int w, int h)
+{
+  SplashOutputDev *output_dev;
+  SplashColor white;
+  SplashBitmap *bitmap;
+  white.rgb8 = splashMakeRGB8(255,255,255);
+  SplashColorPtr color_ptr;
+  output_dev = new SplashOutputDev(splashModeRGB8, gFalse, white);
+  output_dev->startDoc(doc->data->doc.getXRef ());
+  
+  doc->data->doc.displayPageSlice(output_dev, index + 1, 72, 72,
+      0, -1, -1, -1, -1,
+      true,
+      false);
+  bitmap = output_dev->getBitmap ();
+  color_ptr = bitmap->getDataPtr ();
+  QImage * img = new QImage( (uchar*)color_ptr.rgb8, bitmap->getWidth(), bitmap->getHeight(), 32, 0, 0, QImage::IgnoreEndian );
+  *q = new QPixmap( *img );
+  
+  delete img;
+  delete output_dev;
+}
+
+int Document::getNumPages()
+{
+  return data->doc.getNumPages();
+}
+
+/* borrowed from kpdf */
+static QString unicodeToQString(Unicode* u, int len) {
+    QString ret;
+    ret.setLength(len);
+    QChar* qch = (QChar*) ret.unicode();
+    for (;len;--len)
+      *qch++ = (QChar) *u++;
+    return ret;
+}
+
+/* borrowed from kpdf */
+QString Document::getInfo( const QString & type ) const
+{
+    // [Albert] Code adapted from pdfinfo.cc on xpdf
+    Object info;
+    if ( locked )
+        return NULL;
+
+    data->doc.getDocInfo( &info );
+    if ( !info.isDict() )
+        return NULL;
+
+    QString result;
+    Object obj;
+    GooString *s1;
+    GBool isUnicode;
+    Unicode u;
+    int i;
+    Dict *infoDict = info.getDict();
+
+    if ( infoDict->lookup( (char*)type.latin1(), &obj )->isString() )
+    {
+        s1 = obj.getString();
+        if ( ( s1->getChar(0) & 0xff ) == 0xfe && ( s1->getChar(1) & 0xff ) == 0xff )
+        {
+            isUnicode = gTrue;
+            i = 2;
+        }
+        else
+        {
+            isUnicode = gFalse;
+            i = 0;
+        }
+        while ( i < obj.getString()->getLength() )
+        {
+            if ( isUnicode )
+            {
+                u = ( ( s1->getChar(i) & 0xff ) << 8 ) | ( s1->getChar(i+1) & 0xff );
+                i += 2;
+            }
+            else
+            {
+                u = s1->getChar(i) & 0xff;
+                ++i;
+            }
+            result += unicodeToQString( &u, 1 );
+        }
+        obj.free();
+        info.free();
+        return result;
+    }
+    obj.free();
+    info.free();
+    return NULL;
+}
+
+/* borrowed from kpdf */
+QDateTime Document::getDate( const QString & type ) const
+{
+    // [Albert] Code adapted from pdfinfo.cc on xpdf
+    if ( locked )
+        return QDateTime();
+
+    Object info;
+    data->doc.getDocInfo( &info );
+    if ( !info.isDict() ) {
+	info.free();
+        return QDateTime();
+    }
+
+    Object obj;
+    char *s;
+    int year, mon, day, hour, min, sec;
+    Dict *infoDict = info.getDict();
+    QString result;
+
+    if ( infoDict->lookup( (char*)type.latin1(), &obj )->isString() )
+    {
+        s = obj.getString()->getCString();
+        if ( s[0] == 'D' && s[1] == ':' )
+            s += 2;
+
+        if ( sscanf( s, "%4d%2d%2d%2d%2d%2d", &year, &mon, &day, &hour, &min, &sec ) == 6 )
+        {
+            QDate d( year, mon, day );  //CHECK: it was mon-1, Jan->0 (??)
+            QTime t( hour, min, sec );
+            if ( d.isValid() && t.isValid() ) {
+		obj.free();
+		info.free();
+		return QDateTime( d, t );
+	    }
+        }
+    }
+    obj.free();
+    info.free();
+    return QDateTime();
+}
+
+}
diff -X /home/jrmuizel/rsrc/autoignore -urN poppler/qt/poppler-qt.h poppler-qt-new/qt/poppler-qt.h
--- poppler/qt/poppler-qt.h	1969-12-31 19:00:00.000000000 -0500
+++ poppler-qt-new/qt/poppler-qt.h	2005-04-05 17:51:58.000000000 -0400
@@ -0,0 +1,80 @@
+/* poppler-qt.h: qt interface to poppler
+ * Copyright (C) 2005, Net Integration Technologies, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __POPPLER_QT_H__
+#define __POPPLER_QT_H__
+
+#include <qcstring.h>
+#include <qdatetime.h>
+#include <qpixmap.h>
+
+namespace Poppler {
+
+class DocumentData;
+class Document;
+
+class Page {
+  friend class Document;
+  public:
+    int index;
+    void renderSliceToPixmap(QPixmap **q, int x, int y, int w, int h);
+  private:
+    Page(Document *_doc, int _index) {
+      index = _index;
+      doc = _doc;
+    }
+    Document *doc;
+};
+
+class Document {
+  friend class Page;
+  
+public:
+  enum PageMode {
+    UseNone,
+    UseOutlines,
+    UseThumbs,
+    FullScreen,
+    UseOC
+  };
+  
+  static Document *Document::load(const QString & filePath);
+  
+  Page *getPage(int index) { return new Page(this, index); }
+  
+  int getNumPages();
+  
+  PageMode getPageMode();
+  
+  bool unlock(QCString &password);
+  
+  bool isLocked() { return locked; }
+  
+  QDateTime getDate( const QString & data ) const;
+  QString getInfo( const QString & data ) const;
+  
+  Document::~Document();
+  
+private:
+  DocumentData *data;
+  bool locked;
+  Document::Document(DocumentData *dataA);
+};
+
+}
+#endif
diff -X /home/jrmuizel/rsrc/autoignore -urN poppler/qt/test-poppler-qt.cpp poppler-qt-new/qt/test-poppler-qt.cpp
--- poppler/qt/test-poppler-qt.cpp	1969-12-31 19:00:00.000000000 -0500
+++ poppler-qt-new/qt/test-poppler-qt.cpp	2005-04-05 17:42:15.000000000 -0400
@@ -0,0 +1,63 @@
+#include <qapplication.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qwidget.h>
+#include <qmessagebox.h>
+#include <qfile.h>
+#include <ctype.h>
+#include <poppler-qt.h>
+
+class PDFDisplay : public QWidget           // picture display widget
+{
+public:
+    PDFDisplay( const char *fileName );
+   ~PDFDisplay();
+protected:
+    void        paintEvent( QPaintEvent * );
+private:
+    QPixmap	*pixmap;
+    Poppler::Document *doc;
+};
+
+PDFDisplay::PDFDisplay( const char *fileName )
+{
+  doc = Poppler::Document::load(fileName);
+  if (doc) {
+    Poppler::Page *page = doc->getPage(0);
+    if (page) {
+      page->renderSliceToPixmap(&pixmap, -1, -1, -1, -1);
+      delete page;
+    }
+  } else {
+    printf("doc not loaded\n");
+  }
+}
+
+PDFDisplay::~PDFDisplay()
+{
+  delete doc;
+  delete pixmap;
+}
+
+void PDFDisplay::paintEvent( QPaintEvent *e )
+{
+  QPainter paint( this );                     // paint widget
+  if (pixmap)
+    paint.drawPixmap(0, 0, *pixmap);
+}
+
+int main( int argc, char **argv )
+{
+  QApplication a( argc, argv );               // QApplication required!
+
+  if ( argc != 2 )  {                          // use argument as file name
+    printf("usage: test-poppler-qt filename\n");
+    exit(1);
+  }
+  PDFDisplay test( argv[1] );        // create picture display
+  a.setMainWidget( &test);                // set main widget
+  test.setCaption("Poppler-Qt Test");
+  test.show();                            // show it
+
+  return a.exec();                        // start event loop
+}


More information about the poppler mailing list