diff options
| -rw-r--r-- | kfile-plugins/pdf/Makefile.am | 6 | ||||
| -rw-r--r-- | kfile-plugins/pdf/configure.in.in | 17 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/Makefile.am | 42 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-document.cc | 334 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-fontinfo.cc | 83 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-link-qt3.h | 188 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-link.cc | 267 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-page-transition-private.h | 33 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-page-transition.cc | 95 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-page-transition.h | 146 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-page.cc | 362 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-private.cc | 147 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-private.h | 97 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/poppler-qt.h | 310 | ||||
| -rw-r--r-- | kfile-plugins/pdf/poppler-qt/test-poppler-qt.cpp | 122 | 
15 files changed, 2239 insertions, 10 deletions
diff --git a/kfile-plugins/pdf/Makefile.am b/kfile-plugins/pdf/Makefile.am index 841d9980..c8af5244 100644 --- a/kfile-plugins/pdf/Makefile.am +++ b/kfile-plugins/pdf/Makefile.am @@ -1,7 +1,9 @@  ## Makefile.am for the pdf file meta info plugin +subdirs=poppler-qt +  # set the include path for X, qt and KDE -INCLUDES         = $(all_includes) $(POPPLER_CFLAGS) +INCLUDES         = $(all_includes) -I$(top_srcdir)/kfile-plugins/pdf/poppler-qt  # these are the headers for your project  noinst_HEADERS   = kfile_pdf.h @@ -10,7 +12,7 @@ kde_module_LTLIBRARIES = kfile_pdf.la  kfile_pdf_la_SOURCES = kfile_pdf.cpp  kfile_pdf_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -kfile_pdf_la_LIBADD = $(LIB_KIO) $(POPPLER_LIBS) +kfile_pdf_la_LIBADD = $(LIB_KIO) -L$(top_builddir)/kfile-plugins/pdf/poppler-qt/ -lpoppler-qt  # let automoc handle all of the meta source files (moc)  METASOURCES = AUTO diff --git a/kfile-plugins/pdf/configure.in.in b/kfile-plugins/pdf/configure.in.in index 926497a5..ec2fff51 100644 --- a/kfile-plugins/pdf/configure.in.in +++ b/kfile-plugins/pdf/configure.in.in @@ -3,13 +3,14 @@ AC_ARG_WITH([poppler],      [Enable PDF support through poppler  @<:@default=check@:>@])],    [], with_poppler=check) -# Compile the pdf meta info plugin only if Poppler is available -if test "x$with_poppler" != xno; then -  PKG_CHECK_MODULES(POPPLER, poppler-qt >= 0.3.1, have_poppler=yes, have_poppler=no) - -  if test "x$with_poppler" != xcheck && test "x$have_poppler" != xyes; then -    AC_MSG_ERROR([--with-poppler was given, but test for poppler failed]) -  fi -fi +## Compile the pdf meta info plugin only if Poppler is available +#if test "x$with_poppler" != xno; then +#  PKG_CHECK_MODULES(POPPLER, poppler-qt >= 0.3.1, have_poppler=yes, have_poppler=no) +# +#  if test "x$with_poppler" != xcheck && test "x$have_poppler" != xyes; then +#    AC_MSG_ERROR([--with-poppler was given, but test for poppler failed]) +#  fi +#fi +have_poppler=yes  AM_CONDITIONAL(include_PDF, test "x$have_poppler" = xyes) diff --git a/kfile-plugins/pdf/poppler-qt/Makefile.am b/kfile-plugins/pdf/poppler-qt/Makefile.am new file mode 100644 index 00000000..f23d0307 --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/Makefile.am @@ -0,0 +1,42 @@ +INCLUDES =					\ +	-I$(top_srcdir)				\ +	-I/usr/include/poppler			\ +	$(cairo_includes)			\ +	$(QT_INCLUDES)				\ +	$(FREETYPE_CFLAGS)			\ +	$(FONTCONFIG_CFLAGS) + + +poppler_includedir = $(includedir)/poppler/qt3 +poppler_include_HEADERS =			\ +	poppler-qt.h				\ +	poppler-page-transition.h               \ +	poppler-link-qt3.h + +lib_LTLIBRARIES = libpoppler-qt.la +libpoppler_qt_la_SOURCES =			\ +	poppler-document.cc			\ +	poppler-fontinfo.cc			\ +	poppler-link.cc                         \ +	poppler-page.cc				\ +	poppler-page-transition.cc		\ +	poppler-page-transition-private.h	\ +	poppler-private.cc			\ +	poppler-private.h + +libpoppler_qt_la_LIBADD = 			\ +	-lpoppler				\ +	$(QT_LIBS)				\ +	$(FREETYPE_LIBS)			\ +	$(FONTCONFIG_LIBS) + +# libpoppler_qt_la_LDFLAGS = -version-info 2:0:0 @create_shared_lib@ + +test_poppler_qt_SOURCES =			\ +       test-poppler-qt.cpp + +test_poppler_qt_LDADD =				\ +	$(top_builddir)/poppler/libpoppler.la	\ +	libpoppler-qt.la			\ +	$(QT_LIBS)				\ +	$(FREETYPE_LIBS) diff --git a/kfile-plugins/pdf/poppler-qt/poppler-document.cc b/kfile-plugins/pdf/poppler-qt/poppler-document.cc new file mode 100644 index 00000000..a9a7a319 --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-document.cc @@ -0,0 +1,334 @@ +/* poppler-document.cc: qt interface to poppler + * Copyright (C) 2005, Net Integration Technologies, Inc. + * Copyright (C) 2005-2009, Albert Astals Cid <aacid@kde.org> + * Copyright (C) 2006, Stefan Kebekus <stefan.kebekus@math.uni-koeln.de> + * Copyright (C) 2006, Wilfried Huss <Wilfried.Huss@gmx.at> + * + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <poppler-qt.h> +#include <qfile.h> +#include <GlobalParams.h> +#include <Outline.h> +#include <PDFDoc.h> +#include <PSOutputDev.h> +#include <Catalog.h> +#include <ErrorCodes.h> +#include <SplashOutputDev.h> +#include <splash/SplashBitmap.h> +#include <DateInfo.h> +#include "poppler-private.h" + +#undef bool + +namespace Poppler { + +Document *Document::load(const QString &filePath) +{ +  if (!globalParams) { +    globalParams = new GlobalParams(); +  } + +  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->data->locked = true; +    else +      pdoc->data->locked = false; +    pdoc->data->m_fontInfoScanner = new FontInfoScanner(&(doc->doc)); +    return pdoc; +  } +  else +    return NULL; +} + +Document::Document(DocumentData *dataA) +{ +  data = dataA; +} + +Document::~Document() +{ +  delete data; +} + +bool Document::isLocked() const +{ +  return data->locked; +} + +bool Document::unlock(const QCString &password) +{ +  if (data->locked) { +    /* racier then it needs to be */ +    GooString *filename = new GooString(data->doc.getFileName()); +    GooString *pwd = new GooString(password.data()); +    DocumentData *doc2 = new DocumentData(filename, pwd); +    delete pwd; +    if (!doc2->doc.isOk()) { +      delete doc2; +    } else { +      delete data; +      data = doc2; +      data->locked = false; +      data->m_fontInfoScanner = new FontInfoScanner(&(data->doc)); +    } +  } +  return data->locked; +} + +Document::PageMode Document::getPageMode(void) const +{ +  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; +  } +} + +int Document::getNumPages() const +{ +  return data->doc.getNumPages(); +} + +QValueList<FontInfo> Document::fonts() const +{ +  QValueList<FontInfo> ourList; +  scanForFonts(getNumPages(), &ourList); +  return ourList; +} + +bool Document::scanForFonts( int numPages, QValueList<FontInfo> *fontList ) const +{ +  GooList *items = data->m_fontInfoScanner->scan( numPages ); + +  if ( NULL == items ) +    return false; + +  for ( int i = 0; i < items->getLength(); ++i ) { +    QString fontName; +    if (((::FontInfo*)items->get(i))->getName()) +      fontName = ((::FontInfo*)items->get(i))->getName()->getCString(); + +    FontInfo font(fontName, +                  ((::FontInfo*)items->get(i))->getEmbedded(), +                  ((::FontInfo*)items->get(i))->getSubset(), +                  (Poppler::FontInfo::Type)((::FontInfo*)items->get(i))->getType()); +    fontList->append(font); +  } +  deleteGooList(items, ::FontInfo); +  return true; +} + +/* borrowed from kpdf */ +QString Document::getInfo( const QString & type ) const +{ +  // [Albert] Code adapted from pdfinfo.cc on xpdf +  Object info; +  if ( data->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 ( data->locked ) +    return QDateTime(); + +  Object info; +  data->doc.getDocInfo( &info ); +  if ( !info.isDict() ) { +    info.free(); +    return QDateTime(); +  } + +  Object obj; +  int year, mon, day, hour, min, sec, tz_hour, tz_minute; +  char tz; +  Dict *infoDict = info.getDict(); +  QString result; + +  if ( infoDict->lookup( (char*)type.latin1(), &obj )->isString() ) +  { +    QString s = UnicodeParsedString(obj.getString()); +    // TODO do something with the timezone information +    if ( parseDateString( s.latin1(), &year, &mon, &day, &hour, &min, &sec, &tz, &tz_hour, &tz_minute ) ) +    { +      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 data->doc.isEncrypted(); +} + +bool Document::isLinearized() const +{ +  return data->doc.isLinearized(); +} + +bool Document::okToPrint() const +{ +  return data->doc.okToPrint(); +} + +bool Document::okToChange() const +{ +  return data->doc.okToChange(); +} + +bool Document::okToCopy() const +{ +  return data->doc.okToCopy(); +} + +bool Document::okToAddNotes() const +{ +  return data->doc.okToAddNotes(); +} + +double Document::getPDFVersion() const +{ +  return data->doc.getPDFMajorVersion () + data->doc.getPDFMinorVersion() / 10.0; +} + +void Document::getPdfVersion(int *major, int *minor) const +{ +  if (major) +    *major = data->doc.getPDFMajorVersion(); +  if (minor) +    *minor = data->doc.getPDFMinorVersion(); +} + +QDomDocument *Document::toc() const +{ +  Outline * outline = data->doc.getOutline(); +  if ( !outline ) +    return NULL; + +  GooList * items = outline->getItems(); +  if ( !items || items->getLength() < 1 ) +    return NULL; + +  QDomDocument *toc = new QDomDocument(); +  if ( items->getLength() > 0 ) +    data->addTocChildren( toc, toc, items ); + +  return toc; +} + +LinkDestination *Document::linkDestination( const QString &name ) +{ +  GooString * namedDest = QStringToGooString( name ); +  LinkDestinationData ldd(NULL, namedDest, data); +  LinkDestination *ld = new LinkDestination(ldd); +  delete namedDest; +  return ld; +} + +bool Document::print(const QString &fileName, QValueList<int> pageList, double hDPI, double vDPI, int rotate) +{ +  return print(fileName, pageList, hDPI, vDPI, rotate, -1, -1); +} + +bool Document::print(const QString &file, QValueList<int> pageList, double hDPI, double vDPI, int rotate, int paperWidth, int paperHeight) +{ +  PSOutputDev *psOut = new PSOutputDev(file.latin1(), data->doc.getXRef(), data->doc.getCatalog(), NULL, 1, data->doc.getNumPages(), psModePS, paperWidth, paperHeight); +   +  if (psOut->isOk()) { +    QValueList<int>::iterator it; +    for (it = pageList.begin(); it != pageList.end(); ++it ) +      data->doc.displayPage(psOut, *it, hDPI, vDPI, rotate, gFalse, gTrue, gTrue); +     +    delete psOut; +    return true; +  } else { +    delete psOut; +    return false; +  } +} + +} diff --git a/kfile-plugins/pdf/poppler-qt/poppler-fontinfo.cc b/kfile-plugins/pdf/poppler-qt/poppler-fontinfo.cc new file mode 100644 index 00000000..6eb9d26f --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-fontinfo.cc @@ -0,0 +1,83 @@ +/* poppler-qt.h: qt interface to poppler + * Copyright (C) 2005, Albert Astals Cid <aacid@kde.org> + * + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "poppler-qt.h" + +namespace Poppler { + +class FontInfoData +{ +	public: +		QString fontName; +		bool isEmbedded; +		bool isSubset; +		FontInfo::Type type; +}; + +FontInfo::FontInfo( const QString &fontName, const bool isEmbedded, const bool isSubset, Type type ) +{ +	data = new FontInfoData(); +	data->fontName = fontName; +	data->isEmbedded = isEmbedded; +	data->isSubset = isSubset; +	data->type = type; +} + +FontInfo::FontInfo( const FontInfo &fi ) +{ +	data = new FontInfoData(); +	data->fontName = fi.data->fontName; +	data->isEmbedded = fi.data->isEmbedded; +	data->isSubset = fi.data->isSubset; +	data->type = fi.data->type; +} + +FontInfo::FontInfo() +{ +	data = new FontInfoData(); +	data->isEmbedded = false; +	data->isSubset = false; +	data->type = unknown; +} + +FontInfo::~FontInfo() +{ +	delete data; +} + +const QString &FontInfo::name() const +{ +	return data->fontName; +} + +bool FontInfo::isEmbedded() const +{ +	return data->isEmbedded; +} + +bool FontInfo::isSubset() const +{ +	return data->isSubset; +} + +FontInfo::Type FontInfo::type() const +{ +	return data->type; +} + +} diff --git a/kfile-plugins/pdf/poppler-qt/poppler-link-qt3.h b/kfile-plugins/pdf/poppler-qt/poppler-link-qt3.h new file mode 100644 index 00000000..82127207 --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-link-qt3.h @@ -0,0 +1,188 @@ +/* poppler-link.h: qt interface to poppler + * Copyright (C) 2006, Albert Astals Cid <aacid@kde.org> + * Adapting code from + *   Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> + * + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _POPPLER_LINK_H_ +#define _POPPLER_LINK_H_ + +#include <qstring.h> +#include <qrect.h> + +namespace Poppler { + +class LinkDestinationData; + +class LinkDestination +{ +	public: +		enum Kind +		{ +			destXYZ = 1, +			destFit = 2, +			destFitH = 3, +			destFitV = 4, +			destFitR = 5, +			destFitB = 6, +			destFitBH = 7, +			destFitBV = 8 +		}; + +		LinkDestination(const LinkDestinationData &data); +		LinkDestination(const QString &description); + +		// Accessors. +		Kind kind() const; +		int pageNumber() const; +		double left() const; +		double bottom() const; +		double right() const; +		double top() const; +		double zoom() const; +		bool isChangeLeft() const; +		bool isChangeTop() const; +		bool isChangeZoom() const; + +		QString toString() const; + +	private: +		Kind m_kind; // destination type +		int m_pageNum; // page number +		double m_left, m_bottom; // position +		double m_right, m_top; +		double m_zoom; // zoom factor +		bool m_changeLeft, m_changeTop; // for destXYZ links, which position +		bool m_changeZoom; //   components to change +}; + +/** + * @short Encapsulates data that describes a link. + * + * This is the base class for links. It makes mandatory for inherited + * widgets to reimplement the 'linkType' method and return the type of + * the link described by the reimplemented class. + */ +class Link +{ +	public: +		Link( const QRect &linkArea ); +		 +		// get link type (inherited classes mustreturn an unique identifier) +		enum LinkType { None, Goto, Execute, Browse, Action, Movie }; +		virtual LinkType linkType() const; + +		// virtual destructor +		virtual ~Link(); +		 +		QRect linkArea() const; +		 +	private: +		QRect m_linkArea; +}; + + +/** Goto: a viewport and maybe a reference to an external filename **/ +class LinkGoto : public Link +{ +	public: +		LinkGoto( const QRect &linkArea, QString extFileName, const LinkDestination & destination ); +		 +		// query for goto parameters +		bool isExternal() const; +		const QString & fileName() const; +		const LinkDestination & destination() const; +		LinkType linkType() const; + +	private: +		QString m_extFileName; +		LinkDestination m_destination; +}; + +/** Execute: filename and parameters to execute **/ +class LinkExecute : public Link +{ +	public: +		// query for filename / parameters +		const QString & fileName() const; +		const QString & parameters() const; + +		// create a Link_Execute +		LinkExecute( const QRect &linkArea, const QString & file, const QString & params ); +		LinkType linkType() const; + +	private: +		QString m_fileName; +		QString m_parameters; +}; + +/** Browse: an URL to open, ranging from 'http://' to 'mailto:' etc.. **/ +class LinkBrowse : public Link +{ +	public: +		// query for URL +		const QString & url() const; + +		// create a Link_Browse +		LinkBrowse( const QRect &linkArea, const QString &url ); +		LinkType linkType() const; + +	private: +		QString m_url; +};	 + +/** Action: contains an action to perform on document / viewer **/ +class LinkAction : public Link +{ +	public: +		// define types of actions +		enum ActionType { PageFirst = 1, +		                  PagePrev = 2, +		                  PageNext = 3, +		                  PageLast = 4, +		                  HistoryBack = 5, +		                  HistoryForward = 6, +		                  Quit = 7, +		                  Presentation = 8, +		                  EndPresentation = 9, +		                  Find = 10, +		                  GoToPage = 11, +		                  Close = 12 }; + +		// query for action type +		ActionType actionType() const; + +		// create a Link_Action +		LinkAction( const QRect &linkArea, ActionType actionType ); +		LinkType linkType() const; + +	private: +		ActionType m_type; +}; + +/** Movie: Not yet defined -> think renaming to 'Media' link **/ +class LinkMovie : public Link +// TODO this (Movie link) +{ +	public: +		LinkMovie( const QRect &linkArea ); +		LinkType linkType() const; +}; + +} + +#endif diff --git a/kfile-plugins/pdf/poppler-qt/poppler-link.cc b/kfile-plugins/pdf/poppler-qt/poppler-link.cc new file mode 100644 index 00000000..af6d6452 --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-link.cc @@ -0,0 +1,267 @@ +/* poppler-link.cc: qt interface to poppler + * Copyright (C) 2006, 2008 Albert Astals Cid + * Adapting code from + *   Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> + * + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <poppler-qt.h> +#include <poppler-private.h> + +#include <qstringlist.h> + +#include <Link.h> + +namespace Poppler { + +	LinkDestination::LinkDestination(const LinkDestinationData &data) +	{ +		bool deleteDest = false; +		LinkDest *ld = data.ld; +		 +		if ( data.namedDest && !ld ) +		{ +			deleteDest = true; +			ld = data.doc->doc.findDest( data.namedDest ); +		} +		 +		if (!ld) return; +		 +		if (ld->getKind() == ::destXYZ) m_kind = destXYZ; +		else if (ld->getKind() == ::destFit) m_kind = destFit; +		else if (ld->getKind() == ::destFitH) m_kind = destFitH; +		else if (ld->getKind() == ::destFitV) m_kind = destFitV; +		else if (ld->getKind() == ::destFitR) m_kind = destFitR; +		else if (ld->getKind() == ::destFitB) m_kind = destFitB; +		else if (ld->getKind() == ::destFitBH) m_kind = destFitBH; +		else if (ld->getKind() == ::destFitBV) m_kind = destFitBV; + +		if ( !ld->isPageRef() ) m_pageNum = ld->getPageNum(); +		else +		{ +			Ref ref = ld->getPageRef(); +			m_pageNum = data.doc->doc.findPage( ref.num, ref.gen ); +		} +		double left = ld->getLeft(); +		double bottom = ld->getBottom(); +		double right = ld->getRight(); +		double top = ld->getTop(); +		m_zoom = ld->getZoom(); +		m_changeLeft = ld->getChangeLeft(); +		m_changeTop = ld->getChangeTop(); +		m_changeZoom = ld->getChangeZoom(); +		 +		int leftAux = 0, topAux = 0, rightAux = 0, bottomAux = 0; +		 +#if defined(HAVE_SPLASH) +		SplashOutputDev *sod = data.doc->getOutputDev(); +		sod->cvtUserToDev( left, top, &leftAux, &topAux ); +		sod->cvtUserToDev( right, bottom, &rightAux, &bottomAux ); +#endif +		 +		m_left = leftAux; +		m_top = topAux; +		m_right = rightAux; +		m_bottom = bottomAux; +		 +		if (deleteDest) delete ld; +	} +	 +	LinkDestination::LinkDestination(const QString &description) +	{ +		QStringList tokens = QStringList::split(';', description); +		m_kind = static_cast<Kind>(tokens[0].toInt()); +		m_pageNum = tokens[1].toInt(); +		m_left = tokens[2].toDouble(); +		m_bottom = tokens[3].toDouble(); +		m_right = tokens[4].toDouble(); +		m_top = tokens[5].toDouble(); +		m_zoom = tokens[6].toDouble(); +		m_changeLeft = static_cast<bool>(tokens[7].toInt()); +		m_changeTop = static_cast<bool>(tokens[8].toInt()); +		m_changeZoom = static_cast<bool>(tokens[9].toInt()); +	} +	 +	LinkDestination::Kind LinkDestination::kind() const +	{ +		return m_kind; +	} +	 +	int LinkDestination::pageNumber() const +	{ +		return m_pageNum; +	} +	 +	double LinkDestination::left() const +	{ +		return m_left; +	} +	 +	double LinkDestination::bottom() const +	{ +		return m_bottom; +	} +	 +	double LinkDestination::right() const +	{ +		return m_right; +	} +	 +	double LinkDestination::top() const +	{ +		return m_top; +	} +	 +	double LinkDestination::zoom() const +	{ +		return m_zoom; +	} +	 +	bool LinkDestination::isChangeLeft() const +	{ +		return m_changeLeft; +	} +	 +	bool LinkDestination::isChangeTop() const +	{ +		return m_changeTop; +	} +	 +	bool LinkDestination::isChangeZoom() const +	{ +		return m_changeZoom; +	} +	 +	QString LinkDestination::toString() const +	{ +		QString s = QString::number( (Q_INT8)m_kind ); +		s += ";" + QString::number( m_pageNum ); +		s += ";" + QString::number( m_left ); +		s += ";" + QString::number( m_bottom ); +		s += ";" + QString::number( m_right ); +		s += ";" + QString::number( m_top ); +		s += ";" + QString::number( m_zoom ); +		s += ";" + QString::number( (Q_INT8)m_changeLeft ); +		s += ";" + QString::number( (Q_INT8)m_changeTop ); +		s += ";" + QString::number( (Q_INT8)m_changeZoom ); +		return s; +	} +	 +	 +	// Link +	Link::~Link() +	{ +	} +	 +	Link::Link(const QRect &linkArea) : m_linkArea(linkArea) +	{ +	} +	 +	Link::LinkType Link::linkType() const +	{ +		return None; +	} +	 +	QRect Link::linkArea() const +	{ +		return m_linkArea; +	} +	 +	// LinkGoto +	LinkGoto::LinkGoto( const QRect &linkArea, QString extFileName, const LinkDestination & destination ) : Link(linkArea), m_extFileName(extFileName), m_destination(destination) +	{ +	} +	 +	bool LinkGoto::isExternal() const +	{ +		return !m_extFileName.isEmpty(); +	} +	 +	const QString &LinkGoto::fileName() const +	{ +		return m_extFileName; +	} +	 +	const LinkDestination &LinkGoto::destination() const +	{ +		return m_destination; +	} +	 +	Link::LinkType LinkGoto::linkType() const +	{ +		return Goto; +	} +	 +	// LinkExecute +	LinkExecute::LinkExecute( const QRect &linkArea, const QString & file, const QString & params ) : Link(linkArea), m_fileName(file), m_parameters(params) +	{ +	} +	 +	const QString & LinkExecute::fileName() const +	{ +		return m_fileName; +	} +	const QString & LinkExecute::parameters() const +	{ +		return m_parameters; +	} + +	Link::LinkType LinkExecute::linkType() const +	{ +		return Execute; +	} + +	// LinkBrowse +	LinkBrowse::LinkBrowse( const QRect &linkArea, const QString &url ) : Link(linkArea), m_url(url) +	{ +	} +	 +	const QString & LinkBrowse::url() const +	{ +		return m_url; +	} +	 +	Link::LinkType LinkBrowse::linkType() const +	{ +		return Browse; +	} + +	// LinkAction +	LinkAction::LinkAction( const QRect &linkArea, ActionType actionType ) : Link(linkArea), m_type(actionType) +	{ +	} +		 +	LinkAction::ActionType LinkAction::actionType() const +	{ +		return m_type; +	} + +	Link::LinkType LinkAction::linkType() const +	{ +		return Action; +	} + +	// LinkMovie +	LinkMovie::LinkMovie( const QRect &linkArea ) : Link(linkArea) +	{ +	} +	 +	Link::LinkType LinkMovie::linkType() const +	{ +		return Movie; +	} + +} diff --git a/kfile-plugins/pdf/poppler-qt/poppler-page-transition-private.h b/kfile-plugins/pdf/poppler-qt/poppler-page-transition-private.h new file mode 100644 index 00000000..8bc70825 --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-page-transition-private.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005, Albert Astals Cid + * + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef POPPLER_PAGE_TRANSITION_PRIVATE_H +#define POPPLER_PAGE_TRANSITION_PRIVATE_H + +class Object; + +namespace Poppler { + +class PageTransitionParams { +  public: +    Object *dictObj; +}; + +} + +#endif // POPPLER_PAGE_TRANSITION_PRIVATE_H diff --git a/kfile-plugins/pdf/poppler-qt/poppler-page-transition.cc b/kfile-plugins/pdf/poppler-qt/poppler-page-transition.cc new file mode 100644 index 00000000..cde8818d --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-page-transition.cc @@ -0,0 +1,95 @@ +/* PageTransition.cc + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "PageTransition.h" +#include "poppler-page-transition.h" +#include "poppler-page-transition-private.h" + +namespace Poppler { + +class PageTransitionData +{ +  public: +    PageTransitionData(Object *trans) +    { +        pt = new ::PageTransition(trans); +    } + +    PageTransitionData(const PageTransitionData &ptd) +    { +        pt = new ::PageTransition(*ptd.pt); +    } + +    ~PageTransitionData() +    { +        delete pt; +    } + +    ::PageTransition *pt; +}; + +PageTransition::PageTransition(const PageTransitionParams ¶ms) +{ +  data = new PageTransitionData(params.dictObj); +} + +PageTransition::PageTransition(const PageTransition &pt) +{ +  data = new PageTransitionData(*pt.data); +} + +PageTransition::~PageTransition() +{ +  delete data; +} + +PageTransition::Type PageTransition::type() const +{ +  return (Poppler::PageTransition::Type)data->pt->getType(); +} + +int PageTransition::duration() const +{ +  return data->pt->getDuration(); +} + +PageTransition::Alignment PageTransition::alignment() const +{ +  return (Poppler::PageTransition::Alignment)data->pt->getAlignment(); +} + +PageTransition::Direction PageTransition::direction() const +{ +  return (Poppler::PageTransition::Direction)data->pt->getDirection(); +} + +int PageTransition::angle() const +{ +  return data->pt->getAngle(); +} + +double PageTransition::scale() const +{ +  return data->pt->getScale(); +} +bool PageTransition::isRectangular() const +{ +  return data->pt->isRectangular(); +} + +} diff --git a/kfile-plugins/pdf/poppler-qt/poppler-page-transition.h b/kfile-plugins/pdf/poppler-qt/poppler-page-transition.h new file mode 100644 index 00000000..53002ff9 --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-page-transition.h @@ -0,0 +1,146 @@ +/* PageTransition.h + * Copyright (C) 2005, Net Integration Technologies, Inc. + * Copyright (C) 2005, Brad Hards <bradh@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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __PAGETRANSITION_X_H__ +#define __PAGETRANSITION_X_H__ + +namespace Poppler { + +class PageTransitionParams; +class PageTransitionData; + +/** +   \brief Describes how a PDF file viewer shall perform the transition +   from one page to another + +   In PDF files there is a way to specify if the viewer shall use +   certain effects to perform the transition from one page to +   another. This feature can be used, e.g., in a PDF-based beamer +   presentation. + +   This utility class represents the transition effect, and can be +   used to extract the information from a PDF object. +*/ + + +class PageTransition { + public: + +  /** \brief transition effect that shall be used +   */ +  // if changed remember to keep in sync with PageTransition.h enum +  enum Type { +    Replace = 0, +    Split, +    Blinds, +    Box, +    Wipe, +    Dissolve, +    Glitter, +    Fly, +    Push, +    Cover, +    Uncover, +    Fade +  }; +   +  /** \brief alignment of the transition effect that shall be used +   */ +  // if changed remember to keep in sync with PageTransition.h enum +  enum Alignment { +    Horizontal = 0, +    Vertical +  }; +   +  /** \brief direction of the transition effect that shall be used +   */ +  // if changed remember to keep in sync with PageTransition.h enum +  enum Direction { +    Inward = 0, +    Outward +  }; +   +  /** \brief Construct a new PageTransition object from a page dictionary. + +  Users of the library will rarely need to construct a +  PageTransition object themselves. Instead, the method +  Poppler::Page::transition() can be used to find out if a certain +  transition effect is specified. + +  @warning In case or error, this method will print an error message to stderr, +  and construct a default object. + +  @param params an object whose dictionary will be read and +   parsed. This must be a valid object, whose dictionaries are +   accessed by the constructor. The object is only accessed by this +   constructor, and may be deleted after the constructor returns. +  */ +  PageTransition(const PageTransitionParams ¶ms); + +  /** \brief copy constructor */ +  PageTransition(const PageTransition &pt); +   +  /** +     Destructor +  */ +  ~PageTransition(); +   +  /** +     \brief Get type of the transition. +  */ +  Type type() const; +   +  /** +     \brief Get duration of the transition in seconds. +  */ +  int duration() const; +   +  /** +     \brief Get dimension in which the transition effect occurs. +  */ +  Alignment alignment() const; +   +  /** +     \brief Get direction of motion of the transition effect. +  */ +  Direction direction() const; +   +  /** +     \brief Get direction in which the transition effect moves. +  */ +  int angle() const; +   +  /** +     \brief Get starting or ending scale. +  */ +  double scale() const; +   +  /** +     \brief Returns true if the area to be flown is rectangular and +     opaque. +  */ +  bool isRectangular() const; +   + private: +  PageTransitionData *data; +}; + +} + +#endif diff --git a/kfile-plugins/pdf/poppler-qt/poppler-page.cc b/kfile-plugins/pdf/poppler-qt/poppler-page.cc new file mode 100644 index 00000000..a42aa15c --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-page.cc @@ -0,0 +1,362 @@ +/* poppler-page.cc: qt interface to poppler + * Copyright (C) 2005, Net Integration Technologies, Inc. + * Copyright (C) 2005-2006, Albert Astals Cid <aacid@kde.org> + * Copyright (C) 2005, Tobias Koening <tokoe@kde.org> + * Copyright (C) 2005, Stefan Kebekus <stefan.kebekus@math.uni-koeln.de> + * Copyright (C) 2006, Wilfried Huss <Wilfried.Huss@gmx.at> + * Copyright (C) 2006, Jerry Epplin <jepplin@globalvelocity.com> + * Copyright (C) 2007, 2010, Pino Toscano <pino@kde.org> + * + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <poppler-qt.h> +#include <qfile.h> +#include <qimage.h> +#include <config.h> +#include <GlobalParams.h> +#include <PDFDoc.h> +#include <Catalog.h> +#include <ErrorCodes.h> +#include <TextOutputDev.h> +#include <Link.h> +#if defined(HAVE_SPLASH) +#include <SplashOutputDev.h> +#include <splash/SplashBitmap.h> +#endif + +#include "poppler-private.h" +#include "poppler-page-transition-private.h" + +namespace Poppler { + +class PageData { +  public: +  const Document *doc; +  int index; +  PageTransition *transition; +}; + +Page::Page(const Document *doc, int index) { +  data = new PageData(); +  data->index = index; +  data->doc = doc; +  data->transition = 0; +} + +Page::~Page() +{ +  delete data->transition; +  delete data; +} + +void Page::renderToPixmap(QPixmap **q, int x, int y, int w, int h, bool doLinks) const +{ +  renderToPixmap(q, x, y, w, h, 72.0, 72.0, doLinks); +} + +void Page::renderToPixmap(QPixmap **q, int x, int y, int w, int h, double xres, double yres, bool doLinks) const +{ +  QImage img = renderToImage(xres, yres, doLinks); +  *q = new QPixmap( img ); +} + +QImage Page::renderToImage(double xres, double yres, bool doLinks) const +{ +#if defined(HAVE_SPLASH) +  SplashOutputDev *output_dev; +  SplashBitmap *bitmap; +  SplashColorPtr color_ptr; +  output_dev = data->doc->data->getOutputDev(); + +  data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, xres, yres, +      0, false, true, false, -1, -1, -1, -1); +  bitmap = output_dev->getBitmap (); +  color_ptr = bitmap->getDataPtr (); +  int bw = output_dev->getBitmap()->getWidth(); +  int bh = output_dev->getBitmap()->getHeight(); +  SplashColorPtr dataPtr = output_dev->getBitmap()->getDataPtr(); +   +  if (QImage::BigEndian == QImage::systemByteOrder()) +  { +    uchar c; +    int count = bw * bh * 4; +    for (int k = 0; k < count; k += 4) +    { +      c = dataPtr[k]; +      dataPtr[k] = dataPtr[k+3]; +      dataPtr[k+3] = c; + +      c = dataPtr[k+1]; +      dataPtr[k+1] = dataPtr[k+2]; +      dataPtr[k+2] = c; +    } +  } +   +  // construct a qimage SHARING the raw bitmap data in memory +  QImage img( dataPtr, bw, bh, 32, 0, 0, QImage::IgnoreEndian ); +  img = img.copy(); +  // unload underlying xpdf bitmap +  output_dev->startPage( 0, NULL ); + +  return img; +#else +  (void)xres; +  (void)xres; +  (void)doLinks; + +  return QImage(); +#endif +} + +QString Page::getText(const Rectangle &r) const +{ +  TextOutputDev *output_dev; +  GooString *s; +  PDFRectangle *rect; +  QString result; +  ::Page *p; +   +  output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse); +  data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, 72, 72, +      0, false, false, false, -1, -1, -1, -1); +  p = data->doc->data->doc.getCatalog()->getPage(data->index + 1); +  if (r.isNull()) +  { +    rect = p->getCropBox(); +    s = output_dev->getText(rect->x1, rect->y1, rect->x2, rect->y2); +  } +  else +  { +    double height, y1, y2; +    height = p->getCropHeight(); +    y1 = height - r.m_y2; +    y2 = height - r.m_y1; +    s = output_dev->getText(r.m_x1, y1, r.m_x2, y2); +  } + +  result = QString::fromUtf8(s->getCString()); + +  delete output_dev; +  delete s; +  return result; +} + +QValueList<TextBox*> Page::textList() const +{ +  TextOutputDev *output_dev; +   +  QValueList<TextBox*> output_list; +   +  output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse); + +  data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, 72, 72, +      0, false, false, false, -1, -1, -1, -1); + +  TextWordList *word_list = output_dev->makeWordList(); +   +  if (!word_list) { +    delete output_dev; +    return output_list; +  } +   +  for (int i = 0; i < word_list->getLength(); i++) { +    TextWord *word = word_list->get(i); +    GooString *word_str = word->getText(); +    QString string = QString::fromUtf8(word_str->getCString()); +    delete word_str; +    double xMin, yMin, xMax, yMax; +    word->getBBox(&xMin, &yMin, &xMax, &yMax); +     +    TextBox* text_box = new TextBox(string, Rectangle(xMin, yMin, xMax, yMax)); +     +    output_list.append(text_box); +  } +   +  delete word_list; +  delete output_dev; +   +  return output_list; +} + +PageTransition *Page::getTransition() const +{ +  if (!data->transition)  +  { +    Object o; +    PageTransitionParams params; +    params.dictObj = data->doc->data->doc.getCatalog()->getPage(data->index + 1)->getTrans(&o); +    data->transition = new PageTransition(params); +    o.free(); +  } +  return data->transition; +} + +QSize Page::pageSize() const +{ +  ::Page *p; + +  p = data->doc->data->doc.getCatalog()->getPage(data->index + 1); +  if ( ( Page::Landscape == orientation() ) || (Page::Seascape == orientation() ) ) { +    return QSize( (int)p->getCropHeight(), (int)p->getCropWidth() ); +  } else { +    return QSize( (int)p->getCropWidth(), (int)p->getCropHeight() ); +  } +} + +Page::Orientation Page::orientation() const +{ +  ::Page *p = data->doc->data->doc.getCatalog()->getPage(data->index + 1); + +  int rotation = p->getRotate(); +  switch (rotation) { +  case 90: +    return Page::Landscape; +    break; +  case 180: +    return Page::UpsideDown; +    break; +  case 270: +    return Page::Seascape; +    break; +  default: +    return Page::Portrait; +  } +} + +QValueList<Link*> Page::links() const +{ +  QValueList<Link*> popplerLinks; + +#if defined(HAVE_SPLASH) +  Links *xpdfLinks = data->doc->data->doc.getLinks(data->index + 1); +  for (int i = 0; i < xpdfLinks->getNumLinks(); ++i) +  { +    ::Link *xpdfLink = xpdfLinks->getLink(i); +     +    double left, top, right, bottom; +    int leftAux, topAux, rightAux, bottomAux; +    xpdfLink->getRect( &left, &top, &right, &bottom ); +    QRect linkArea; +     +    data->doc->data->m_outputDev->cvtUserToDev( left, top, &leftAux, &topAux ); +    data->doc->data->m_outputDev->cvtUserToDev( right, bottom, &rightAux, &bottomAux ); +    linkArea.setLeft(leftAux); +    linkArea.setTop(topAux); +    linkArea.setRight(rightAux); +    linkArea.setBottom(bottomAux); + +    if (!xpdfLink->isOk()) continue; + +    Link *popplerLink = NULL; +    ::LinkAction *a = xpdfLink->getAction(); +    if ( a ) +    { +      switch ( a->getKind() ) +      { +        case actionGoTo: +        { +          LinkGoTo * g = (LinkGoTo *) a; +          // create link: no ext file, namedDest, object pointer +          popplerLink = new LinkGoto( linkArea, QString::null, LinkDestination( LinkDestinationData(g->getDest(), g->getNamedDest(), data->doc->data ) ) ); +        } +        break; + +        case actionGoToR: +        { +          LinkGoToR * g = (LinkGoToR *) a; +          // copy link file +          const QString fileName = UnicodeParsedString( g->getFileName() ); +          // ceate link: fileName, namedDest, object pointer +          popplerLink = new LinkGoto( linkArea, fileName, LinkDestination( LinkDestinationData(g->getDest(), g->getNamedDest(), data->doc->data ) ) ); +        } +        break; + +        case actionLaunch: +	{ +          LinkLaunch * e = (LinkLaunch *)a; +          GooString * p = e->getParams(); +          popplerLink = new LinkExecute( linkArea, e->getFileName()->getCString(), p ? p->getCString() : 0 ); +	} +        break; + +        case actionNamed: +	{ +          const char * name = ((LinkNamed *)a)->getName()->getCString(); +          if ( !strcmp( name, "NextPage" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::PageNext ); +          else if ( !strcmp( name, "PrevPage" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::PagePrev ); +          else if ( !strcmp( name, "FirstPage" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::PageFirst ); +          else if ( !strcmp( name, "LastPage" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::PageLast ); +          else if ( !strcmp( name, "GoBack" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::HistoryBack ); +          else if ( !strcmp( name, "GoForward" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::HistoryForward ); +          else if ( !strcmp( name, "Quit" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::Quit ); +          else if ( !strcmp( name, "GoToPage" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::GoToPage ); +          else if ( !strcmp( name, "Find" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::Find ); +          else if ( !strcmp( name, "FullScreen" ) ) +              popplerLink = new LinkAction( linkArea, LinkAction::Presentation ); +          else if ( !strcmp( name, "Close" ) ) +          { +              // acroread closes the document always, doesnt care whether  +              // its presentation mode or not +              // popplerLink = new LinkAction( linkArea, LinkAction::EndPresentation ); +              popplerLink = new LinkAction( linkArea, LinkAction::Close ); +          } +          else +          { +                // TODO +          } +	} +        break; + +        case actionURI: +	{ +          popplerLink = new LinkBrowse( linkArea, ((LinkURI *)a)->getURI()->getCString() ); +	} +        break; + +        case actionMovie: +        case actionSound: +        case actionRendition: +        case actionJavaScript: +        case actionOCGState: +        break; + +        case actionUnknown: +        break; +      } +    } +     +    if (popplerLink) +    { +      popplerLinks.append(popplerLink); +    } +  } + +  delete xpdfLinks; +#endif +   +  return popplerLinks; +} + +} diff --git a/kfile-plugins/pdf/poppler-qt/poppler-private.cc b/kfile-plugins/pdf/poppler-qt/poppler-private.cc new file mode 100644 index 00000000..2388a1b5 --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-private.cc @@ -0,0 +1,147 @@ +/* poppler-private.h: qt interface to poppler + * Copyright (C) 2005, Net Integration Technologies, Inc. + * Copyright (C) 2005-2008, Albert Astals Cid <aacid@kde.org> + * Copyright (C) 2006, Kristian Høgsberg <krh@bitplanet.net> + * Copyright (C) 2006, Wilfried Huss <Wilfried.Huss@gmx.at> + * Copyright (C) 2007, Pino Toscano <pino@kde.org> + * + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "poppler-private.h" +#include "poppler-link-qt3.h" + +#include <qstring.h> + +#include <Outline.h> +#include <Link.h> + +namespace Poppler { + +/* borrowed from kpdf */ +QString unicodeToQString(Unicode* u, int len) +{ +    QString ret; +    ret.setLength(len); +    QChar* qch = (QChar*) ret.unicode(); +    for (;len;--len) +      *qch++ = (QChar) *u++; +    return ret; +} + +QString UnicodeParsedString(GooString *s1) +{ +    GBool isUnicode; +    int i; +    Unicode u; +    QString result; +    if ( ( s1->getChar(0) & 0xff ) == 0xfe && ( s1->getChar(1) & 0xff ) == 0xff ) +    { +        isUnicode = gTrue; +        i = 2; +    } +    else +    { +        isUnicode = gFalse; +        i = 0; +    } +    while ( i < s1->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 ); +    } +    return result; +} + +GooString *QStringToGooString(const QString &s) +{ +    int len = s.length(); +    char *cstring = (char *)gmallocn(s.length(), sizeof(char)); +    for (int i = 0; i < len; ++i) +      cstring[i] = s.at(i).unicode(); +    GooString *ret = new GooString(cstring, len); +    gfree(cstring); +    return ret; +} + + +void DocumentData::addTocChildren( QDomDocument * docSyn, QDomNode * parent, GooList * items ) +{ +    int numItems = items->getLength(); +    for ( int i = 0; i < numItems; ++i ) +    { +        // iterate over every object in 'items' +        OutlineItem * outlineItem = (OutlineItem *)items->get( i ); + +        // 1. create element using outlineItem's title as tagName +        QString name; +        Unicode * uniChar = outlineItem->getTitle(); +        int titleLength = outlineItem->getTitleLength(); +        name = unicodeToQString(uniChar, titleLength); +        if ( name.isEmpty() ) +            continue; + +        QDomElement item = docSyn->createElement( name ); +        parent->appendChild( item ); + +        // 2. find the page the link refers to +        ::LinkAction * a = outlineItem->getAction(); +        if ( a && ( a->getKind() == actionGoTo || a->getKind() == actionGoToR ) ) +        { +            // page number is contained/referenced in a LinkGoTo +            LinkGoTo * g = static_cast< LinkGoTo * >( a ); +            LinkDest * destination = g->getDest(); +            if ( !destination && g->getNamedDest() ) +            { +                // no 'destination' but an internal 'named reference'. we could +                // get the destination for the page now, but it's VERY time consuming, +                // so better storing the reference and provide the viewport on demand +                GooString *s = g->getNamedDest(); +                QChar *charArray = new QChar[s->getLength()]; +                for (int i = 0; i < s->getLength(); ++i) charArray[i] = QChar(s->getCString()[i]); +                    QString aux(charArray, s->getLength()); +                    item.setAttribute( "DestinationName", aux ); +                    delete[] charArray; +                } +                else if ( destination && destination->isOk() ) +                { +                    LinkDestinationData ldd(destination, NULL, this); +                    item.setAttribute( "Destination", LinkDestination(ldd).toString() ); +                } +                if ( a->getKind() == actionGoToR ) +                { +                    LinkGoToR * g2 = static_cast< LinkGoToR * >( a ); +                    item.setAttribute( "ExternalFileName", g2->getFileName()->getCString() ); +                } +            } + +        // 3. recursively descend over children +        outlineItem->open(); +        GooList * children = outlineItem->getKids(); +        if ( children ) +            addTocChildren( docSyn, &item, children ); +    } +} + +} diff --git a/kfile-plugins/pdf/poppler-qt/poppler-private.h b/kfile-plugins/pdf/poppler-qt/poppler-private.h new file mode 100644 index 00000000..0d68e505 --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-private.h @@ -0,0 +1,97 @@ +/* poppler-private.h: qt interface to poppler + * Copyright (C) 2005, Net Integration Technologies, Inc. + * Copyright (C) 2005-2008, Albert Astals Cid <aacid@kde.org> + * Copyright (C) 2006, Kristian Høgsberg <krh@bitplanet.net> + * Copyright (C) 2006, Wilfried Huss <Wilfried.Huss@gmx.at> + * Copyright (C) 2007, Pino Toscano <pino@kde.org> + * + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef POPPLER_PRIVATE_H +#define POPPLER_PRIVATE_H + +#include <qdom.h> + +#include <config.h> +#include <Object.h> +#include <PDFDoc.h> +#include <FontInfo.h> +#if defined(HAVE_SPLASH) +#include <SplashOutputDev.h> +#else +class SplashOutputDev; +#endif + +namespace Poppler { +     +class DocumentData; + +QString unicodeToQString(Unicode* u, int len); + +QString UnicodeParsedString(GooString *s1); + +GooString *QStringToGooString(const QString &s); + +class LinkDestinationData { +  public: +     LinkDestinationData( LinkDest *l, GooString *nd, Poppler::DocumentData *pdfdoc ) : ld(l), namedDest(nd), doc(pdfdoc) +     { +     } +	 +     LinkDest *ld; +     GooString *namedDest; +     Poppler::DocumentData *doc; +}; + +class DocumentData { +  public: +    DocumentData(GooString *filePath, GooString *password) : doc(filePath,password), m_fontInfoScanner(0), m_outputDev(0) {} + +    ~DocumentData() +    { +#if defined(HAVE_SPLASH) +        delete m_outputDev; +#endif +        delete m_fontInfoScanner; +    } + +    SplashOutputDev *getOutputDev() +    { +#if defined(HAVE_SPLASH) +        if (!m_outputDev) +        { +            SplashColor white; +            white[0] = 255; +            white[1] = 255; +            white[2] = 255; +            m_outputDev = new SplashOutputDev(splashModeXBGR8, 4, gFalse, white); +            m_outputDev->startDoc(doc.getXRef()); +        } +#endif +        return m_outputDev; +    } + +    void addTocChildren( QDomDocument * docSyn, QDomNode * parent, GooList * items ); + +  class PDFDoc doc; +  bool locked; +  FontInfoScanner *m_fontInfoScanner; +  SplashOutputDev *m_outputDev; +}; + +} + +#endif // POPPLER_PRIVATE_H diff --git a/kfile-plugins/pdf/poppler-qt/poppler-qt.h b/kfile-plugins/pdf/poppler-qt/poppler-qt.h new file mode 100644 index 00000000..a6b1e6ec --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/poppler-qt.h @@ -0,0 +1,310 @@ +/* poppler-qt.h: qt interface to poppler + * Copyright (C) 2005, Net Integration Technologies, Inc. + * Copyright (C) 2005, Tobias Koening <tokoe@kde.org> + * Copyright (C) 2005-2007, Albert Astals Cid <aacid@kde.org> + * Copyright (C) 2005-2006, Stefan Kebekus <stefan.kebekus@math.uni-koeln.de> + * Copyright (C) 2006, Wilfried Huss <Wilfried.Huss@gmx.at> + * + * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __POPPLER_QT_H__ +#define __POPPLER_QT_H__ + +#include "poppler-link-qt3.h" +#include "poppler-page-transition.h" + +#include <qcstring.h> +#include <qdatetime.h> +#include <qdom.h> +#include <qpixmap.h> + +namespace Poppler { + +class Document; +class Page; + +/* A rectangle on a page, with coordinates in PDF points. */ +class Rectangle +{ +  public: +    Rectangle(double x1 = 0, double y1 = 0, double x2 = 0, double y2 = 0) :  +      m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2) {} +    bool isNull() const { return m_x1 == 0 && m_y1 == 0 && m_x2 == 0 && m_y2 == 0; } +   +    double m_x1; +    double m_y1; +    double m_x2; +    double m_y2; +}; + +class TextBox +{ + public: +    TextBox(const QString& text, const Rectangle &bBox) : +    m_text(text), m_bBox(bBox) {}; + +    QString getText() const { return m_text; }; +    Rectangle getBoundingBox() const { return m_bBox; }; + +  private: +    QString m_text; +    Rectangle m_bBox; +}; + + +/** +  Container class for information about a font within a PDF document +*/ +class FontInfoData; +class FontInfo { +public: +  enum Type { +    unknown, +    Type1, +    Type1C, +    Type1COT, +    Type3, +    TrueType, +    TrueTypeOT, +    CIDType0, +    CIDType0C, +    CIDType0COT, +    CIDTrueType, +    CIDTrueTypeOT +  }; + +  /** +    Create a new font information container +  */ +  FontInfo( const QString &fontName, const bool isEmbedded, +            const bool isSubset, Type type ); + +  FontInfo(); +   +  FontInfo( const FontInfo &fi ); + +  ~FontInfo(); + +  /** +    The name of the font. Can be QString::null if the font has no name +  */ +  const QString &name() const; + +  /** +    Whether the font is embedded in the file, or not + +    \return true if the font is embedded +  */ +  bool isEmbedded() const; + +  /** +    Whether the font provided is only a subset of the full +    font or not. This only has meaning if the font is embedded. + +    \return true if the font is only a subset +  */ +  bool isSubset() const; + +  /** +    The type of font encoding +  */ +  Type type() const; + +  const QString &typeName() const; + +private: +  FontInfoData *data; +}; + +class PageData; +class Page { +  friend class Document; +  public: +    ~Page(); +    void renderToPixmap(QPixmap **q, int x, int y, int w, int h, double xres, double yres, bool doLinks = false) const; + +    /** +      This is a convenience function that is equivalent to +      renderToPixmap() with xres and yres set to 72.0. We keep it +      only for binary compatibility + +      \sa renderToImage() +     */ +    void renderToPixmap(QPixmap **q, int x, int y, int w, int h, bool doLinks = false) const; + +    /** +      \brief Render the page to a QImage using the Splash renderer + +     This method can be used to render the page to a QImage. It +     uses the "Splash" rendering engine. + +     \param xres horizontal resolution of the graphics device, +     in dots per inch (defaults to 72 dpi) + +     \param yres vertical resolution of the graphics device, in +     dots per inch (defaults to 72 dpi) + +     \returns a QImage of the page. + +     \sa renderToPixmap() +    */ +    QImage renderToImage(double xres = 72.0, double yres = 72.0, bool doLinks = false) const; + +    /** +     * Returns the size of the page in points +     **/ +    QSize pageSize() const; + +    /** +    * Returns the text that is inside the Rectangle r +    * If r is a null Rectangle all text of the page is given +    **/ +    QString getText(const Rectangle &r) const; + +    QValueList<TextBox*> textList() const; + +    /** +    * Returns the transition of this page +    **/ +    PageTransition *getTransition() const; + +    enum Orientation { +      Landscape, +      Portrait, +      Seascape, +      UpsideDown +    }; + +    /** +    *  The orientation of the page +    **/ +    Orientation orientation() const; +     +    /** +      Gets the links of the page once it has been rendered if doLinks was true +    */ +    QValueList<Link*> links() const; + +  private: +    Page(const Document *doc, int index); +    PageData *data; +}; + +class DocumentData; + +class Document { +  friend class Page; +   +public: +  enum PageMode { +    UseNone, +    UseOutlines, +    UseThumbs, +    FullScreen, +    UseOC +  }; +   +  static Document *load(const QString & filePath); +   +  Page *getPage(int index) const{ return new Page(this, index); } +   +  int getNumPages() const; +   +  PageMode getPageMode() const; +   +  bool unlock(const QCString &password); +   +  bool isLocked() const; +   +  QDateTime getDate( const QString & data ) const; +  QString getInfo( const QString & data ) const; +  bool isEncrypted() const; +  bool isLinearized() const; +  bool okToPrint() const; +  bool okToChange() const; +  bool okToCopy() const; +  bool okToAddNotes() const; +  double getPDFVersion() const; +  /** +    The version of the PDF specification that the document +    conforms to + +    \param major an optional pointer to a variable where store the +    "major" number of the version +    \param minor an optional pointer to a variable where store the +    "minor" number of the version + +    \since 0.12 +  */ +  void getPdfVersion(int *major, int *minor) const; + +  bool print(const QString &fileName, QValueList<int> pageList, double hDPI, double vDPI, int rotate); + +  // If you are using QPrinter you can get paper size doing +  // QPrinter dummy(QPrinter::PrinterResolution); +  // dummy.setFullPage(true); +  // dummy.setPageSize(thePageSizeYouWant); +  // QPaintDeviceMetrics metrics(&dummy); +  // int width = metrics.width(); +  // int height = metrics.height(); +  bool print(const QString &fileName, QValueList<int> pageList, double hDPI, double vDPI, int rotate, int paperWidth, int paperHeight); + +  /** +    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 +  */ +  QValueList<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, QValueList<FontInfo> *fontList ) const; + +  /** +    Gets the TOC of the Document, it is application responsabiliy to delete +    it when no longer needed + +    * In the tree the tag name is the 'screen' name of the entry. A tag can have +    * attributes. Here follows the list of tag attributes with meaning: +    * - Destination: A string description of the referred destination +    * - DestinationName: A 'named reference' to the viewport that must be converted +    *      using linkDestination( *destination_name* ) +    * - ExternalFileName: A link to a external filename + +     \returns NULL if the Document does not have TOC +  */ +  QDomDocument *toc() const; + +  LinkDestination *linkDestination( const QString &name ); + +  ~Document(); +   +private: +  DocumentData *data; +  Document(DocumentData *dataA); +}; + +} +#endif diff --git a/kfile-plugins/pdf/poppler-qt/test-poppler-qt.cpp b/kfile-plugins/pdf/poppler-qt/test-poppler-qt.cpp new file mode 100644 index 00000000..d97954b8 --- /dev/null +++ b/kfile-plugins/pdf/poppler-qt/test-poppler-qt.cpp @@ -0,0 +1,122 @@ +#include <qapplication.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qwidget.h> +#include <qlabel.h> +#include <qmessagebox.h> +#include <qfile.h> +#include <ctype.h> +#include <poppler-qt.h> +#include <stdlib.h> + +class PDFDisplay : public QWidget           // picture display widget +{ +public: +    PDFDisplay( Poppler::Document *d ); +   ~PDFDisplay(); +protected: +    void        paintEvent( QPaintEvent * ); +    void        keyPressEvent( QKeyEvent * ); +private: +    void display(); +     +    int currentPage; +    QPixmap	*pixmap; +    Poppler::Document *doc; +}; + +PDFDisplay::PDFDisplay( Poppler::Document *d ) +{ +  doc = d; +  pixmap = 0; +  currentPage = 0; +  display(); +} + +PDFDisplay::~PDFDisplay() +{ +  delete doc; +  delete pixmap; +} + +void PDFDisplay::paintEvent( QPaintEvent *e ) +{ +  QPainter paint( this );                     // paint widget +  if (pixmap) +    paint.drawPixmap(0, 0, *pixmap); +} + +void PDFDisplay::keyPressEvent( QKeyEvent *e ) +{ +  if (e->key() == Qt::Key_Down) +  { +    if (currentPage + 1 < doc->getNumPages()) +    { +      currentPage++; +      display(); +    } +  } +  else if (e->key() == Qt::Key_Up) +  { +    if (currentPage > 0) +    { +      currentPage--; +      display(); +    } +  } +} + +void PDFDisplay::display() +{ +  if (doc) { +    Poppler::Page *page = doc->getPage(currentPage); +    if (page) { +      delete pixmap; +      page->renderToPixmap(&pixmap, -1, -1, -1, -1); +      delete page; +      update(); +    } +  } else { +    printf("doc not loaded\n"); +  } +} + +int main( int argc, char **argv ) +{ +  QApplication a( argc, argv );               // QApplication required! + +  if ( argc < 2  || (argc == 3 && strcmp(argv[2], "-extract") != 0) || argc > 3) +  { +    // use argument as file name +    printf("usage: test-poppler-qt filename [-extract]\n"); +    exit(1); +  } +   +  Poppler::Document *doc = Poppler::Document::load(argv[1]); +  if (!doc) +  { +    printf("doc not loaded\n"); +    exit(1); +  } +   +  if (argc == 2) +  {   +    PDFDisplay test( doc );        // create picture display +    a.setMainWidget( &test);                // set main widget +    test.setCaption("Poppler-Qt Test"); +    test.show();                            // show it + +    return a.exec();                        // start event loop +  } +  else +  { +    Poppler::Page *page = doc->getPage(0); + +    QLabel *l = new QLabel(page->getText(Poppler::Rectangle()), 0); +    l->show(); +    a.setMainWidget(l);                // set main widget +    delete page; +    delete doc; +    return a.exec(); +  } +}  | 
