[poppler] [PATCH] initial clean poppler-qt implementation
Kristian Høgsberg
krh at bitplanet.net
Wed Mar 30 23:13:00 PST 2005
Jeff Muizelaar wrote:
> renderToPixmap will be changed to render a slice and take the more of
> the other parameters.
>
> Comments welcome.
Great work, thanks for starting this, Jeff. Comments below.
cheers, Kristian
> -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-03-30 12:19:15.000000000 -0500
> +++ poppler-qt-new/configure.ac 2005-03-30 12:56:53.000000000 -0500
> @@ -169,6 +169,66 @@
> 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
> + echo "tryingidie"
Is this a debug echo?
> + 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],
> @@ -213,15 +273,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-03-30 13:28:22.000000000 -0500
> @@ -0,0 +1,123 @@
> +/* 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>
> +
> +PopplerDocument *PopplerDocument::load(const QString &filePath)
> +{
> + if (!globalParams) {
> + globalParams = new GlobalParams("/etc/xpdfrc");
> + globalParams->setupBaseFontsFc(NULL);
> + }
> +
> + PDFDoc *doc = new PDFDoc(new GooString(QFile::encodeName(filePath)), 0, 0);
> + PopplerDocument *pdoc;
> + if (doc->isOk() || doc->getErrorCode() == errEncrypted) {
> + pdoc = new PopplerDocument(doc);
> + if (doc->getErrorCode() == errEncrypted)
> + pdoc->locked = true;
> + else
> + pdoc->locked = false;
> + return pdoc;
> + }
> + else
> + return NULL;
> +}
I still think we should pass an error code back to the application here
so that it's possible to distinguish between file not found and file not
valid pdf.
> +bool PopplerDocument::unlock(QCString &password)
> +{
> + if (locked) {
> + /* racier then it needs to be */
> + GooString *pwd = new GooString(password.data());
> + PDFDoc *doc2 = new PDFDoc(doc->getFileName(), pwd, pwd);
> + delete pwd;
> + if (!doc2->isOk()) {
> + delete doc2;
> + } else {
> + delete doc;
> + doc = doc2;
> + locked = false;
> + }
> + }
> + return locked;
> +}
> +
> +
> +PopplerDocument::PopplerDocument(PDFDoc *docA)
> +{
> + doc = docA;
> +}
Is this just for testing? When we drop the xpdf headers, there will be
no way to create a PDFDoc object.
> +PopplerDocument::~PopplerDocument()
> +{
> + delete doc;
> +}
> +
> +PopplerDocument::PageMode PopplerDocument::getPageMode(void)
> +{
> + switch (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 PopplerPage::renderToPixmap(QPixmap **q)
> +{
> + 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->doc->getXRef ());
> +
> + doc->doc->displayPage(output_dev, index + 1, 72, 72,
> + 0,
> + 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 PopplerDocument::getNumPages()
> +{
> + return doc->getNumPages();
> +}
> 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-03-30 13:27:49.000000000 -0500
> @@ -0,0 +1,72 @@
> +/* 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 <qpixmap.h>
> +
> +class PDFDoc *doc;
I think we should try to design the wrapper in a way that completely
hides away the xpdf types. PDFDoc and Page are quite nasty
namespace-pollution-wise. One approach I considered was
class PopplerDocumentData;
in the header file and
class PopplerDocumentData {
PDFDoc doc;
};
in the implementation. The PDFDoc *doc member would then be
PopplerDocumentData *data instead. Could that work?
Oh, and should we use namespaces? Poppler::Document, Poppler::Page? I
think that would be nice.
> +class PopplerDocument;
> +
> +class PopplerPage {
> + friend class PopplerDocument;
> + public:
> + int index;
> + void renderToPixmap(QPixmap **q);
> + private:
> + PopplerPage(PopplerDocument *_doc, int _index) {
> + index = _index;
> + doc = _doc;
> + }
> + PopplerDocument *doc;
> +};
In the glib binding I've chosen to also cache a pointer to the
corresponding Page object in the PopplerPage object.
> +class PopplerDocument {
> + friend class PopplerPage;
> +
> +public:
> + enum PageMode {
> + UseNone,
> + UseOutlines,
> + UseThumbs,
> + FullScreen,
> + UseOC
> + };
> +
> + static PopplerDocument *PopplerDocument::load(const QString & filePath);
> +
> + PopplerPage *getPage(int index) { return new PopplerPage(this, index); }
> +
> + int getNumPages();
> +
> + PageMode getPageMode();
> +
> + bool unlock(QCString &password);
> +
> + bool isLocked() { return locked; }
> + PopplerDocument::~PopplerDocument();
> +
> +private:
> + PDFDoc *doc;
> + bool locked;
> + PopplerDocument::PopplerDocument(PDFDoc *docA);
Ahh... I get it now...
> +};
> +
> +#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-03-30 13:22:46.000000000 -0500
> @@ -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;
> + PopplerDocument *doc;
> +};
> +
> +PDFDisplay::PDFDisplay( const char *fileName )
> +{
> + doc = PopplerDocument::load(fileName);
> + if (doc) {
> + PopplerPage *page = doc->getPage(0);
> + if (page) {
> + page->renderToPixmap(&pixmap);
> + 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
> +}
> _______________________________________________
> poppler mailing list
> poppler at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/poppler
>
More information about the poppler
mailing list