[poppler] poppler/qt4/src: Doxyfile, NONE, 1.1 Makefile.am, NONE, 1.1 poppler-document.cc, NONE, 1.1 poppler-page.cc, NONE, 1.1 poppler-private.h, NONE, 1.1 poppler-qt4.h, NONE, 1.1

Brad Hards bradh at freedesktop.org
Tue Jun 28 03:00:12 PDT 2005


Update of /cvs/poppler/poppler/qt4/src
In directory gabe:/tmp/cvs-serv23886/qt4/src

Added Files:
	Doxyfile Makefile.am poppler-document.cc poppler-page.cc 
	poppler-private.h poppler-qt4.h 
Log Message:
Initial import of Qt4 bindings, and for a Qt4 "Arthur" (QPainter)
backend renderer.

The bindings are currently unstable - you can expect substantial change
in both source and binary interfaces. 

The Arthur renderer currently does a reasonable job of rendering path
and fill, but the image rendering doesn't work (for reasons that aren't
clear to me) and text rendering doesn't use the right glyphs - it just
draws with the current font. There is a lot of work to do on this
too. Help is, of coure, welcome.



--- NEW FILE: Doxyfile ---
# Doxyfile 1.4.1

# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
#       TAG = value [value, ...]
# For lists items can also be appended using:
#       TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")

#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------

# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
# by quotes) that should identify the project.

[...1173 lines suppressed...]
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
# generate a legend page explaining the meaning of the various boxes and 
# arrows in the dot generated graphs.

GENERATE_LEGEND        = YES

# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
# remove the intermediate dot files that are used to generate 
# the various graphs.

DOT_CLEANUP            = YES

#---------------------------------------------------------------------------
# Configuration::additions related to the search engine   
#---------------------------------------------------------------------------

# The SEARCHENGINE tag specifies whether or not a search engine should be 
# used. If set to NO the values of all tags below this one will be ignored.

SEARCHENGINE           = NO

--- NEW FILE: Makefile.am ---
INCLUDES =					\
	-I$(top_srcdir)				\
	-I$(top_srcdir)/poppler			\
	$(POPPLER_QT4_CXXFLAGS)


poppler_includedir = $(includedir)/poppler

poppler_include_HEADERS =			\
	poppler-qt4.h

lib_LTLIBRARIES=libpoppler-qt4.la

libpoppler_qt4_la_SOURCES =			\
	poppler-document.cc			\
	poppler-page.cc				\
	poppler-private.h

libpoppler_qt4_la_LIBADD= 			\
	$(top_builddir)/poppler/libpoppler.la	\
	$(POPPLER_QT4_LIBS)


--- NEW FILE: poppler-document.cc ---
/* poppler-document.cc: 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.
 */

#define UNSTABLE_POPPLER_QT4
#include <poppler-qt4.h>
#include <QtCore/QFile>
#include <QtGui/QImage>
#include <QtCore/QByteArray>
#include <GlobalParams.h>
#include <PDFDoc.h>
#include <Catalog.h>
#include <ErrorCodes.h>
#include <SplashOutputDev.h>
#include <splash/SplashBitmap.h>
#include "poppler-private.h"

namespace Poppler {

    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, NULL);
	Document *pdoc;
	if (doc->doc.isOk() || doc->doc.getErrorCode() == errEncrypted) {
	    pdoc = new Document(doc);
	    if (doc->doc.getErrorCode() == errEncrypted)
		pdoc->m_doc->locked = true;
	    else
		pdoc->m_doc->locked = false;
	    pdoc->m_doc->m_fontInfoScanner = new FontInfoScanner(&(doc->doc));
	    return pdoc;
	}
	else
	    return NULL;

    }

    Document::Document(DocumentData *dataA)
    {
	m_doc = dataA;
    }

    Document::~Document()
    {
	delete m_doc;
    }

    bool Document::isLocked() const
    {
	return m_doc->locked;
    }

    bool Document::unlock(const QByteArray &ownerPassword,
			  const QByteArray &userPassword)
    {
	if (m_doc->locked) {
	    /* racier then it needs to be */
	    GooString *ownerPwd = new GooString(ownerPassword.data());
	    GooString *userPwd = new GooString(userPassword.data());
	    DocumentData *doc2 = new DocumentData(m_doc->doc.getFileName(),
						  ownerPwd,
						  userPwd);
	    delete ownerPwd;
	    delete userPwd;
	    if (!doc2->doc.isOk()) {
		delete doc2;
	    } else {
		delete m_doc;
		m_doc = doc2;
		m_doc->locked = false;
	    }
	}
	return m_doc->locked;
    }

    Document::PageMode Document::pageMode(void) const
    {
	switch (m_doc->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;
	}
    }

    int Document::numPages() const
    {
	return m_doc->doc.getNumPages();
    }

    QList<FontInfo> Document::fonts() const
    {
	QList<FontInfo> ourList;
	scanForFonts(numPages(), &ourList);
	return ourList;
    }

    bool Document::scanForFonts( int numPages, QList<FontInfo> *fontList ) const
    {
	GooList *items = m_doc->m_fontInfoScanner->scan( numPages );

	if ( NULL == items )
	    return false;

	for ( int i = 0; i < items->getLength(); ++i ) {
	    FontInfo thisFont(((::FontInfo*)items->get(i))->getName()->getCString());
	    fontList->append(thisFont);
	}
	return true;
    }


    /* borrowed from kpdf */
    static QString unicodeToQString(Unicode* u, int len) {
	QString ret;
	ret.resize(len);
	QChar* qch = (QChar*) ret.unicode();
	for (;len;--len)
	    *qch++ = (QChar) *u++;
	return ret;
    }

    /* borrowed from kpdf */
    QString Document::info( const QString & type ) const
    {
	// [Albert] Code adapted from pdfinfo.cc on xpdf
	Object info;
	if ( m_doc->locked )
	    return NULL;

	m_doc->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( type.toLatin1().data(), &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::date( const QString & type ) const
    {
	// [Albert] Code adapted from pdfinfo.cc on xpdf
	if ( m_doc->locked )
	    return QDateTime();

	Object info;
	m_doc->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( type.toLatin1().data(), &obj )->isString() )
	{
	    s = obj.getString()->getCString();
	    if ( s[0] == 'D' && s[1] == ':' )
		s += 2;
	    /* FIXME process time zone on systems that support it */  
	    if ( sscanf( s, "%4d%2d%2d%2d%2d%2d", &year, &mon, &day, &hour, &min, &sec ) == 6 )
	    {
		/* Workaround for y2k bug in Distiller 3 stolen from gpdf, hoping that it won't
		 *   * be used after y2.2k */
		if ( year < 1930 && strlen (s) > 14) {
		    int century, years_since_1900;
		    if ( sscanf( s, "%2d%3d%2d%2d%2d%2d%2d",
				 &century, &years_since_1900,
				 &mon, &day, &hour, &min, &sec) == 7 )
			year = century * 100 + years_since_1900;
		    else {
			obj.free();
			info.free();
			return QDateTime();
		    }
		}

		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();
    }

    bool Document::isEncrypted() const
    {
	return m_doc->doc.isEncrypted();
    }

    bool Document::isLinearized() const
    {
	return m_doc->doc.isLinearized();
    }

    bool Document::okToPrint() const
    {
	return m_doc->doc.okToPrint();
    }

    bool Document::okToChange() const
    {
	return m_doc->doc.okToChange();
    }

    bool Document::okToCopy() const
    {
	return m_doc->doc.okToCopy();
    }

    bool Document::okToAddNotes() const
    {
	return m_doc->doc.okToAddNotes();
    }

    double Document::pdfVersion() const
    {
	return m_doc->doc.getPDFVersion();
    }

    Page *Document::page(QString label) const
    {
	GooString label_g(label.toAscii().data());
	int index;

	if (!m_doc->doc.getCatalog()->labelToIndex (&label_g, &index))
	    return NULL;

	return page(index);
    }

}

--- NEW FILE: poppler-page.cc ---
/* poppler-page.cc: 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.
 */

#define UNSTABLE_POPPLER_QT4
#include <poppler-qt4.h>
#include <QtCore/QFile>
#include <QtGui/QImage>
#include <QtGui/QPixmap>
#include <GlobalParams.h>
#include <PDFDoc.h>
#include <Catalog.h>
#include <ErrorCodes.h>
#include <ArthurOutputDev.h>
#include <TextOutputDev.h>
#include "poppler-private.h"

#include <SplashOutputDev.h>
#include <splash/SplashBitmap.h>

namespace Poppler {

class PageData {
  public:
  const Document *parentDoc;
  int index;
};

Page::Page(const Document *doc, int index) {
  m_page = new PageData();
  m_page->index = index;
  m_page->parentDoc = doc;
}

Page::~Page()
{
  delete m_page;
}


void Page::splashRenderToPixmap(QPixmap **q, int x, int y, int w, int h) const
{
  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(m_page->parentDoc->m_doc->doc.getXRef ());
  
  m_page->parentDoc->m_doc->doc.displayPageSlice(output_dev, m_page->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(), QImage::Format_RGB32 );
  *q = new QPixmap(QPixmap::fromImage(*img));
  
  delete img;
  delete output_dev;
}

void Page::renderToPixmap(QPixmap **pixmap, QSize size) const
{
  *pixmap = new QPixmap(size);
  QPainter* painter = new QPainter(*pixmap);
  painter->setRenderHint(QPainter::Antialiasing);
  ArthurOutputDev output_dev(painter);

  m_page->parentDoc->m_doc->doc.displayPageSlice(&output_dev,
						 m_page->index + 1,
						 72,
						 72,
						 0,
						 -1,
						 -1,
						 -1,
						 -1,
						 true,
						 false);
  painter->end();
}

QString Page::text(const QRectF &r) const
{
  TextOutputDev *output_dev;
  GooString *s;
  PDFRectangle *rect;
  QString result;
  ::Page *p;
  
  output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse);
  m_page->parentDoc->m_doc->doc.displayPageSlice(output_dev, m_page->index + 1, 72, 72,
      0, -1, -1, -1, -1,
      true,
      false);
  p = m_page->parentDoc->m_doc->doc.getCatalog()->getPage(m_page->index + 1);
  if (r.isNull())
  {
    rect = p->getBox();
    s = output_dev->getText(rect->x1, rect->y1, rect->x2, rect->y2);
  }
  else
  {
    double height, y1, y2;
    height = p->getHeight();
    y1 = height - r.top();
    y2 = height - r.bottom();
    s = output_dev->getText(r.left(), y1, r.right(), y2);
  }

  result = QString::fromUtf8(s->getCString());

  delete output_dev;
  delete s;
  return result;
}

QSizeF Page::pageSizeF() const
{
  ::Page *p;
  
  p = m_page->parentDoc->m_doc->doc.getCatalog()->getPage(m_page->index + 1);
  if ( ( Page::Landscape == orientation() ) || (Page::Seascape == orientation() ) ) {
      return QSizeF( p->getHeight(), p->getWidth() );
  } else {
    return QSizeF( p->getWidth(), p->getHeight() );
  }
}

QSize Page::pageSize() const
{
  return QSize( (int)pageSizeF().width(), (int)pageSizeF().height() );
}

Page::Orientation Page::orientation() const
{
  int rotation = m_page->parentDoc->m_doc->doc.getCatalog()->getPage(m_page->index + 1)->getRotate();
  switch (rotation) {
  case 90:
    return Page::Landscape;
    break;
  case 190:
    return Page::UpsideDown;
    break;
  case 270:
    return Page::Seascape;
    break;
  default:
    return Page::Portrait;
  }
}

}

--- NEW FILE: poppler-private.h ---
/* poppler-private.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.
 */

#include <PDFDoc.h>
#include <GfxState.h>
#include <FontInfo.h>

namespace Poppler {

    class DocumentData {
    public:
	DocumentData(GooString *filePath, GooString *ownerPassword, GooString *userPassword) :
	    doc(filePath, ownerPassword, userPassword) {}
	class PDFDoc doc;
	bool locked;
	FontInfoScanner *m_fontInfoScanner;
    };

}



--- NEW FILE: poppler-qt4.h ---
/* poppler-qt.h: qt interface to poppler
 * Copyright (C) 2005, Net Integration Technologies, Inc.
 * Copyright (C) 2005, Brad Hards <bradh at frogmouth.net>
 *
 * 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__

#ifdef UNSTABLE_POPPLER_QT4

#include <QtCore/QByteArray>
#include <QtCore/QDateTime>
#include <QtGui/QPixmap>

/**
   The Poppler Qt bindings
*/
namespace Poppler {

    class Document;

    class PageData;


    /**
       Container class for information about a font within a PDF
       document
    */
    class FontInfo {
    public:
	/**
	   Create a new font information container
	*/
	FontInfo( const QString fontName ):
	    m_fontName(fontName) {};

	/**
	   The name of the font
	*/
	QString name() const
	    { return m_fontName; }
	
    private:
	QString m_fontName;
    };


    /**
       Page within a PDF document
    */
    class Page {
	friend class Document;
    public:
	~Page();

	/**
	   Render the page to a pixmap using the Splash renderer
	*/
	void splashRenderToPixmap(QPixmap **q, int x, int y, int w, int h) const;

	/**
	   Render the page to a pixmap using the Arthur (Qt4) renderer
	*/
	void renderToPixmap(QPixmap **q, QSize size) const;

	/**
	   Returns the text that is inside a specified rectangle

	   \param rect the rectangle specifying the area of interest
	   If rect is null, all text on the page is given
	**/
	QString text(const QRectF &rect) const;

	/**
	   The dimensions of the page, in points.
	*/
	QSizeF pageSizeF() const;

	/**
	   The dimensions of the page, in points.
	*/
	QSize pageSize() const;

	enum Orientation {
	    Landscape,
	    Portrait,
	    Seascape,
	    UpsideDown
	};

	/**
	   The orientation of the page
	*/
	Orientation orientation() const;
    private:
	Page(const Document *doc, int index);
	PageData *m_page;
    };

    class DocumentData;

/**
   PDF document

   A document potentially contains multiple Pages
*/
    class Document {
	friend class Page;
  
    public:
	/**
	   The mode
	*/
	enum PageMode {
	    UseNone,     ///< No mode 
	    UseOutlines, ///< Outline mode
	    UseThumbs,   ///< Thumbnail mode
	    FullScreen,  ///< Fullscreen mode
	    UseOC        ///< OC mode
	};
  
	/**
	   Load the document from a file on disk

	   \param filePath the name (and path, if required) of the file to load
	*/
	static Document *Document::load(const QString & filePath);
  
	/**
	   Get a specified page
     
	   Note that this follows the PDF standard of being zero based - if you
	   want the first page, then you need an index of zero.

	   \param index the page number index
	*/
	Page *page(int index) const{ return new Page(this, index); }

	/**
	   \overload

	   The intent is that you can pass in a label like "ix" and
	   get the page with that label (which might be in the table of
	   contents), or pass in "1" and get the page that the user
	   expects (which might not be the first page, if there is a
	   title page and a table of contents).

	   \param label the page label
	*/
	Page *page(QString label) const;

	/**
	   The number of pages in the document
	*/
	int numPages() const;
  
	/**
	   The type of mode that is in use
	*/
	PageMode pageMode() const;

	/**
	   Provide the passwords required to unlock the document
	*/
	bool unlock(const QByteArray &ownerPassword, const QByteArray &userPassword);

	/**
	   Determine if the document is locked
	*/
	bool isLocked() const;

	/**
	   The date associated with the document

	   You would use this method with something like:
	   \code
	   QDateTime created = m_doc->date("CreationDate");
	   QDateTime modded = m_doc->date("ModDate");
	   \endcode

	   \param data the type of date that is required (such as CreationDate or ModDate)

	*/
	QDateTime date( const QString & data ) const;

	/**
	   Get specified information associated with the document

	   You would use this method with something like:
	   \code
	   QString title = m_doc->info("Title");
	   QString subject = m_doc->info("Subject");
	   \endcode

	   In addition to Title and Subject, other information that may be available
	   includes Author, Keywords, Creator and Producer.

	   \param data the information that is required
	*/
	QString info( const QString & data ) const;

	/**
	   Test if the document is encrypted
	*/
	bool isEncrypted() const;

	/**
	   Test if the document is linearised
	*/
	bool isLinearized() const;

	/**
	   Test if the permissions on the document allow it to be
	   printed
	*/
	bool okToPrint() const;

	/**
	   Test if the permissions on the document allow it to be
	   changed
	*/
	bool okToChange() const;

	/**
	   Test if the permissions on the document allow it to be
	   copied
	*/
	bool okToCopy() const;

	/**
	   Test if the permissions on the document allow notes to be
	   added
	*/
	bool okToAddNotes() const;

	/**
	   The version of the PDF specification that the document
	   conforms to
	*/
	double pdfVersion() const;
  
	/**
	   The fonts within the PDF document.

	   \note this can take a very long time to run with a large
	   document. You may wish to use the call below if you have more
	   than say 20 pages
	*/
	QList<FontInfo> fonts() const;

	/**
	   \overload

	   \param numPages the number of pages to scan
	   \param fontList pointer to the list where the font information
	   should be placed

	   \return false if the end of the document has been reached
	*/
	bool scanForFonts( int numPages, QList<FontInfo> *fontList ) const; 

	Document::~Document();
  
    private:
	DocumentData *m_doc;
	Document::Document(DocumentData *dataA);
    };

}
#endif

#endif



More information about the poppler mailing list