[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