Commit 36ab5c89 authored by Piotr Szymanski's avatar Piotr Szymanski

- make generators plugins by:

   * moving all xpdf stuff from core and part to inside generator_pdf
   * adding abstract KPDFText class and KPDFTextEntity to hold either
     glyph, or word or textline
- support for importing PS files as pdf like on annots branch
- synced with annots branch
- abstract text layer with search for words in different lines
- added RegularArea<NormalizedShape,Shape> template class
  which inherits QValueList<NormalizedShape*> and is used
  to hold regular areas of given shape (finite collections of the shape)
- loading of relevant generators via ktrader for given mimetype
- the deliverables 1 and 2 of my SoC proposition are delivered
  next: 1. fix one spotted regression and 2. code ghostview backend


svn path=/trunk/playground/graphics/oKular/kpdf/; revision=434883
parent 369803e6
......@@ -15,7 +15,7 @@ KDE_ICON = kpdf
#########################################################################
kde_module_LTLIBRARIES = libkpdfpart.la
libkpdfpart_la_SOURCES = dcop.skel error.cpp part.cpp
libkpdfpart_la_SOURCES = dcop.skel part.cpp
libkpdfpart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
libkpdfpart_la_LIBADD = xpdf/xpdf/libxpdf.la conf/libkpdfconf.la core/libkpdfcore.la \
ui/libkpdfui.la ui/painter_agg2/libagg2.la $(LIB_KPARTS) \
......
SUBDIRS = generator_pdf generator_kimgio
kde_module_LTLIBRARIES = \
libokularGenerator_xpdf.la
INCLUDES = -I$(srcdir)/generator_pdf -I$(srcdir)/.. -I$(srcdir)/../xpdf -I$(srcdir)/../xpdf/goo -I$(top_builddir)/kpdf $(all_includes)
INCLUDES = -I$(srcdir)/../.. -I$(srcdir)/../../xpdf -I$(srcdir)/../../xpdf/goo -I$(srcdir)/../../xpdf/splash -I$(top_builddir)/kpdf $(all_includes)
METASOURCES = AUTO
libokularGenerator_xpdf_la_LIBADD = $(top_builddir)/kpdf/core/libkpdfcore.la $(top_builddir)/kpdf/conf/libkpdfconf.la $(top_builddir)/kpdf/xpdf/xpdf/libxpdf.la -lkdeui -lkdeprint
libokularGenerator_xpdf_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
libokularGenerator_xpdf_la_SOURCES = generator_pdf.cpp gp_outputdev.cpp
libkpdfcore_la_LIBADD = ./generator_pdf/libgeneratorpdf.la ./generator_kimgio/libgeneratorkimgio.la
libkpdfcore_la_SOURCES = page.cpp document.cpp link.cpp annotations.cpp \
pagetransition.cpp
KDE_OPTIONS = nofinal
noinst_LTLIBRARIES = libkpdfcore.la
kde_services_DATA = libokularGenerator_xpdf.desktop
document.lo: ../conf/settings.h
page.lo: ../conf/settings.h
generator_pdf.lo: ../../conf/settings.h
/***************************************************************************
* Copyright (C) 2004-05 by Enrico Ros <eros.kde@email.it> *
* Copyright (C) 2005 by Piotr Szymanski <niedakh@gmail.com> *
* 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 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#include <qrect.h>
#include <kdebug.h>
#include "link.h"
#include "area.h"
/** class NormalizedPoint **/
NormalizedPoint::NormalizedPoint()
: x( 0.0 ), y( 0.0 ) {}
NormalizedPoint::NormalizedPoint( double dX, double dY )
: x( dX ), y( dY ) {}
NormalizedPoint::NormalizedPoint( int iX, int iY, int xScale, int yScale )
: x( (double)iX / (double)xScale ), y( (double)iY / (double)yScale ) {}
/** class NormalizedRect **/
NormalizedRect::NormalizedRect()
: left( 0.0 ), top( 0.0 ), right( 0.0 ), bottom( 0.0 ) {}
NormalizedRect::NormalizedRect( double l, double t, double r, double b )
// note: check for swapping coords?
: left( l ), top( t ), right( r ), bottom( b ) {}
NormalizedRect::NormalizedRect( const QRect & r, double xScale, double yScale )
: left( (double)r.left() / xScale ), top( (double)r.top() / yScale ),
right( (double)r.right() / xScale ), bottom( (double)r.bottom() / yScale ) {}
bool NormalizedRect::isNull() const
{
return left == 0 && top == 0 && right == 0 && bottom == 0;
}
bool NormalizedRect::contains( double x, double y ) const
{
return x >= left && x <= right && y >= top && y <= bottom;
}
bool NormalizedRect::intersects( const NormalizedRect & r ) const
{
return (r.left <= right) && (r.right >= left) && (r.top <= bottom) && (r.bottom >= top);
}
bool NormalizedRect::intersects( const NormalizedRect * r ) const
{
return (r->left <= right) && (r->right >= left) && (r->top <= bottom) && (r->bottom >= top);
}
bool NormalizedRect::intersects( double l, double t, double r, double b ) const
{
return (l <= right) && (r >= left) && (t <= bottom) && (b >= top);
}
QRect NormalizedRect::geometry( int xScale, int yScale ) const
{
int l = (int)( left * xScale ),
t = (int)( top * yScale ),
r = (int)( right * xScale ),
b = (int)( bottom * yScale );
return QRect( l, t, r - l + 1, b - t + 1 );
}
HighlightAreaRect::HighlightAreaRect(RegularAreaRect *area)
{
RegularAreaRect::Iterator i;
for (i=area->begin();i!=area->end();++i)
{
append(*i);
}
s_id=-1;
color=QColor();
}
/** class ObjectRect **/
ObjectRect::ObjectRect( double l, double t, double r, double b, ObjectType type, void * pnt )
// assign coordinates swapping them if negative width or height
: NormalizedRect( r > l ? l : r, b > t ? t : b, r > l ? r : l, b > t ? b : t ),
m_objectType( type ), m_pointer( pnt )
{
}
ObjectRect::~ObjectRect()
{
if ( !m_pointer )
return;
if ( m_objectType == Link )
delete static_cast<KPDFLink*>( m_pointer );
else
kdDebug() << "Object deletion not implemented for type '" << m_objectType << "' ." << endl;
}
/***************************************************************************
* Copyright (C) 2004-05 by Enrico Ros <eros.kde@email.it> *
* Copyright (C) 2005 by Piotr Szymanski <niedakh@gmail.com> *
* 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 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef _KPDF_AREA_H_
#define _KPDF_AREA_H_
#include <qvaluelist.h>
#include <qcolor.h>
class QRect;
class KPDFLink;
/**
* @short A point in [0,1] coordinates (only used in annotations atm)
*/
class NormalizedPoint
{
public:
double x, y;
NormalizedPoint();
NormalizedPoint( double dX, double dY );
NormalizedPoint( int ix, int iy, int xScale, int yScale );
};
/**
* @short A rect in normalized [0,1] coordinates.
*/
class NormalizedRect
{
public:
double left, top, right, bottom;
NormalizedRect();
NormalizedRect( double l, double t, double r, double b );
NormalizedRect( const QRect &r, double xScale, double yScale );
bool isNull() const;
bool contains( double x, double y ) const;
bool intersects( const NormalizedRect & normRect ) const;
bool intersects( double l, double t, double r, double b ) const;
bool intersects( const NormalizedRect * r ) const;
QRect geometry( int xScale, int yScale ) const;
};
/**
* @short NormalizedRect that contains a reference to an object.
*
* These rects contains a pointer to a kpdf object (such as a link or something
* like that). The pointer is read and stored as 'void pointer' so cast is
* performed by accessors based on the value returned by objectType(). Objects
* are reparented to this class.
*
* Type / Class correspondency tab:
* - Link : class KPDFLink : description of a link
* - Image : class KPDFImage : description of an image (n/a)
*/
class ObjectRect : public NormalizedRect
{
public:
// definition of the types of storable objects
enum ObjectType { Link, Image };
// default constructor: initialize all parameters
ObjectRect( double l, double t, double r, double b, ObjectType typ, void * obj );
~ObjectRect();
// query type and get a const pointer to the stored object
inline ObjectType objectType() const { return m_objectType; }
inline const void * pointer() const { return m_pointer; }
private:
ObjectType m_objectType;
void * m_pointer;
};
/**
* Internal Storage: normalized colored highlight owned by id
*/
struct HighlightRect : public NormalizedRect
{
// searchID of the highlight owner
int s_id;
// color of the highlight
QColor color;
};
/**
* @short A regular area of NormalizedShape which normalizes a Shape
*
* Class NormalizedShape must have the following functions defined:
* contains (double, double)
* intersects(NormalizedShape)
* isNull()
* geometry(int,int)
*/
template <class NormalizedShape, class Shape> class RegularArea :
public QValueList<NormalizedShape*> {
public:
typedef QValueListIterator<NormalizedShape*> Iterator;
typedef QValueListConstIterator<NormalizedShape*> ConstIterator;
// RegularArea<NormalizedShape,Shape> (NormalizedShape* x) { QValueList(x) ; } ;
// class Iterator : public QValueListIterator<NormalizedShape*> {};
bool contains( double x, double y ) const;
bool intersects (const RegularArea<NormalizedShape,Shape> * area) const;
bool intersects (const NormalizedShape * shape) const;
void appendArea (const RegularArea<NormalizedShape,Shape> *area);
bool isNull() const;
QValueList<Shape>* geometry( int xScale, int yScale ) const;
};
template <class NormalizedShape, class Shape>
bool RegularArea<NormalizedShape, Shape>::isNull() const
{
if (!this)
return false;
if (this->isEmpty())
return false;
ConstIterator i;
for (i=this->begin();i!=this->end();++i)
if (!((*i)->isNull()))
return false;
return true;
}
template <class NormalizedShape, class Shape>
bool RegularArea<NormalizedShape, Shape>::intersects (const NormalizedShape *rect) const
{
if (!this)
return false;
if (this->isEmpty())
return false;
ConstIterator i;
for (i=this->begin();i!=this->end();++i)
{
if(!((*i)->isNull()) && (*i)->intersects (rect))
return true;
}
return false;
}
template <class NormalizedShape, class Shape>
bool RegularArea<NormalizedShape, Shape>::intersects
(const RegularArea<NormalizedShape,Shape> *area) const
{
if (!this)
return false;
if (this->isEmpty())
return false;
Iterator i,j;
for (i=this->begin();i!=this->end();++i)
{
for (j=area->begin();j!=area->end();++j)
{
if(!((*i)->isNull) && (*i)->intersects (j))
return true;
}
}
return false;
}
template <class NormalizedShape, class Shape>
void RegularArea<NormalizedShape, Shape>::appendArea
(const RegularArea<NormalizedShape, Shape> *area)
{
if (!this)
return false;
ConstIterator j;
for (j=area->begin();j!=area->end();++j)
{
this->append(*j);
}
}
template <class NormalizedShape, class Shape>
bool RegularArea<NormalizedShape, Shape>::contains (double x, double y) const
{
if (!this)
return false;
if (this->isEmpty())
return false;
ConstIterator i;
for (i=this->begin();i!=this->end();++i)
{
if((*i)->contains (x,y))
return true;
}
return false;
}
template <class NormalizedShape, class Shape>
QValueList<Shape> *
RegularArea<NormalizedShape, Shape>::geometry( int xScale, int yScale ) const
{
if (!this)
return false;
if (this->isEmpty())
return 0;
ConstIterator i;
QValueList<Shape>* ret=0;
for (i=this->begin();i!=this->end();++i)
{
ret.append((*i)->geometry(xScale,yScale));
}
return ret;
}
typedef RegularArea<NormalizedRect,QRect> RegularAreaRect;
class HighlightAreaRect : public RegularAreaRect {
public:
HighlightAreaRect(RegularAreaRect *area);
// searchID of the highlight owner
int s_id;
// color of the highlight
QColor color;
};
#endif
This diff is collapsed.
......@@ -77,6 +77,8 @@ class KPDFDocument : public QObject
KURL currentDocument() const;
bool isAllowed( int /*Document::Permisison(s)*/ ) const;
bool supportsSearching() const;
// might be useful later
// bool hasFonts() const;
bool historyAtBegin() const;
bool historyAtEnd() const;
QString getMetaData( const QString & key, const QString & option = QString() ) const;
......
......@@ -10,10 +10,17 @@
#ifndef _KPDF_GENERATOR_H_
#define _KPDF_GENERATOR_H_
#define KPDF_EXPORT_PLUGIN( classname ) \
extern "C" { \
Generator* create_plugin(KPDFDocument* doc) { return new classname(doc); } \
}
#include <qobject.h>
#include <qvaluevector.h>
#include <qstring.h>
#include "core/document.h"
#include "core/textpage.h"
class KPrinter;
class KPDFPage;
class KPDFLink;
......@@ -57,8 +64,19 @@ class Generator : public QObject
// page contents generation
virtual bool canGeneratePixmap() = 0;
virtual void generatePixmap( PixmapRequest * request ) = 0;
// can generate a KPDFText Page
virtual bool canGenerateTextPage() = 0;
virtual void generateSyncTextPage( KPDFPage * page ) = 0;
// capability querying
// provides internal search
virtual bool supportsSearching() = 0;
virtual bool prefersInternalSearching() = 0;
// internal search and gettext
virtual RegularAreaRect * findText( const QString & text, SearchDir dir, const bool strictCase,
const RegularAreaRect * lastRect, KPDFPage * page) = 0;
virtual QString* getText( const RegularAreaRect * area, KPDFPage * page ) = 0;
// may come useful later
//virtual bool hasFonts() const = 0;
// print document using already configured kprinter
virtual bool print( KPrinter& /*printer*/ ) { return false; }
......
kde_module_LTLIBRARIES = \
libokularGenerator_kimgio.la
INCLUDES = -I$(srcdir)/../../ $(all_includes)
libgeneratorkimgio_la_LDFLAGS = $(all_libraries)
libgeneratorkimgio_la_SOURCES = generator_kimgio.cpp
libokularGenerator_kimgio_la_LIBADD = $(top_builddir)/kpdf/core/libkpdfcore.la $(top_builddir)/kpdf/conf/libkpdfconf.la -lkdeui
libokularGenerator_kimgio_la_LDFLAGS = -module -avoid-version $(KDE_PLUGIN) $(all_libraries)
libokularGenerator_kimgio_la_SOURCES = generator_kimgio.cpp
noinst_LTLIBRARIES = libgeneratorkimgio.la
kde_services_DATA = libokularGenerator_kimgio.desktop
......@@ -15,6 +15,8 @@
#include "core/page.h"
#include "generator_kimgio.h"
KPDF_EXPORT_PLUGIN(KIMGIOGenerator)
KIMGIOGenerator::KIMGIOGenerator( KPDFDocument * document ) : Generator( document )
{
}
......@@ -52,14 +54,11 @@ void KIMGIOGenerator::generatePixmap( PixmapRequest * request )
signalRequestDone(request);
}
bool KIMGIOGenerator::canGenerateTextPage()
bool KIMGIOGenerator::hasFonts() const
{
return false;
}
void KIMGIOGenerator::generateSyncTextPage( KPDFPage * /*page*/ )
{
}
bool KIMGIOGenerator::print( KPrinter& printer )
{
......@@ -67,3 +66,8 @@ bool KIMGIOGenerator::print( KPrinter& printer )
p.drawPixmap(0, 0, *m_pix);
return true;
}
bool KIMGIOGenerator::supportsSearching() const
{
return false;
}
......@@ -9,9 +9,9 @@
#ifndef _KPDF_GENERATOR_PNG_H_
#define _KPDF_GENERATOR_PNG_H_
#include "core/generator.h"
class KIMGIOGenerator : public Generator
{
public:
......@@ -24,9 +24,19 @@ class KIMGIOGenerator : public Generator
// [INHERITED] perform actions on document / pages
bool canGeneratePixmap();
void generatePixmap( PixmapRequest * request );
bool canGenerateTextPage();
void generateSyncTextPage( KPDFPage * page );
void generateSyncTextPage( KPDFPage * page ) {;};
// [INHERITED] capability querying
bool supportsSearching() const;
bool hasFonts() const;
bool canGenerateTextPage() { return false; };
bool supportsSearching() { return false; };
bool prefersInternalSearching() { return false; };
RegularAreaRect* findText(const QString&, SearchDir, bool, const RegularAreaRect*, KPDFPage*)
{ return 0; };
QString * getText(const RegularAreaRect*, KPDFPage*) { return 0; };
// font related
// [INHERITED] print document using already configured kprinter
bool print( KPrinter& printer );
......
This diff is collapsed.
/***************************************************************************
* Copyright (C) 2004 by Albert Astals Cid <tsdgeos@terra.es> *
* 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 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef _KPDF_GENERATOR_PDF_H_
#define _KPDF_GENERATOR_PDF_H_
#include <qmutex.h>
#include <qcolor.h>
#include <qstring.h>
#include <qthread.h>
#include "core/generator.h"
#include "core/document.h"
#include "core/link.h"
#include "core/textpage.h"
class PDFDoc;
class GList;
class TextPage;
class Page;
class Dict;
class Ref;
class ObjectRect;
class KPDFOutputDev;
class PDFPixmapGeneratorThread;
/**
* @short A generator that builds contents from a PDF document.
*
* All Generator features are supported and implented by this one.
* Internally this holds a reference to xpdf's core objects and provides
* contents generation using the PDFDoc object and a couple of OutputDevices
* called KPDFOutputDev and KPDFTextDev (both defined in gp_outputdev.h).
*
* For generating page contents we tell PDFDoc to render a page and grab
* contents from out OutputDevs when rendering finishes.
*
* Background asyncronous contents providing is done via a QThread inherited
* class defined at the bottom of the file.
*/
class PDFGenerator : public Generator
{
public:
PDFGenerator( KPDFDocument * document );
virtual ~PDFGenerator();
// [INHERITED] load a document and fill up the pagesVector
bool loadDocument( const QString & fileName, QValueVector<KPDFPage*> & pagesVector );
// [INHERITED] document informations
const DocumentInfo * generateDocumentInfo();
const DocumentSynopsis * generateDocumentSynopsis();
const DocumentFonts * generateDocumentFonts();
// [INHERITED] document informations
bool isAllowed( int permissions );
// [INHERITED] perform actions on document / pages
bool canGeneratePixmap();
void generatePixmap( PixmapRequest * request );
bool canGenerateTextPage();
void generateSyncTextPage( KPDFPage * page );
bool supportsSearching() { return true; };
bool prefersInternalSearching() { return false; };
RegularAreaRect * findText (const QString & text, SearchDir dir,
const bool strictCase, const RegularAreaRect * lastRect,
KPDFPage * page );
QString * getText( const RegularAreaRect * area, KPDFPage * page );
// [INHERITED] print page using an already configured kprinter
bool print( KPrinter& printer );
// [INHERITED] reply to some metadata requests
QString getMetaData( const QString & key, const QString & option );
// [INHERITED] reparse configuration
bool reparseConfig();
private:
// friend class to access private document related variables
friend class PDFPixmapGeneratorThread;
// access document informations
QString getDocumentInfo( const QString & data ) const;
QString getDocumentDate( const QString & data ) const;
// create the document synopsis hieracy
void addSynopsisChildren( QDomNode * parent, GList * items );
// add fonts (in resDict) to the private 'docFonts' class
void addFonts( Dict * resDict, Ref ** fonts, int &fontsLen, int &fontsSize );
// fetch annotations from the pdf file and add they to the page
void addAnnotations( Page * xpdfPage, KPDFPage * page );
// fetch the transition information and add it to the page
void addTransition( Page * xpdfPage, KPDFPage * page );
static KPDFTextPage * abstractTextPage(TextPage *tp, double height, double width);
TextPage * fastTextPage (KPDFPage * page);
// (async related) receive data from the generator thread
void customEvent( QCustomEvent * );
// xpdf dependant stuff
QMutex docLock;
PDFDoc * pdfdoc;
KPDFOutputDev * kpdfOutputDev;
QColor paperColor;
// asyncronous generation related stuff
PDFPixmapGeneratorThread * generatorThread;
// misc variables for document info and synopsis caching
bool ready;
PixmapRequest * pixmapRequest;
bool docInfoDirty;
DocumentInfo docInfo;
bool docSynopsisDirty;
DocumentSynopsis docSyn;
bool docFontsDirty;
DocumentFonts docFonts;
// static instances counter
static unsigned int m_count;
};
/**
* @short A thread that builds contents for PDFGenerator in the background.
*
*/
class PDFPixmapGeneratorThread : public QThread
{
public:
PDFPixmapGeneratorThread( PDFGenerator * generator );
~PDFPixmapGeneratorThread();
// set the request to the thread (it will be reparented)
void startGeneration( PixmapRequest * request );
// end generation
void endGeneration();
// methods for getting contents from the GUI thread
QImage * takeImage() const;
TextPage * takeTextPage() const;
QValueList< ObjectRect * > takeObjectRects() const;
private:
// can't be called from the outside (but from startGeneration)
void run();
class PPGThreadPrivate * d;
};
#endif
This diff is collapsed.
/***************************************************************************
* Copyright (C) 2003-2004 by Christophe Devriese *
* <Christophe.Devriese@student.kuleuven.ac.be> *
* Copyright (C) 2003 by Helio Chissini de Castro *
* <helio@conectiva.com.br> *
* Copyright (C) 2004 by Dominique Devriese <devriese@kde.org> *
* Copyright (C) 2004 by Albert Astals Cid <tsdgeos@terra.es> *
* *
* 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 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef KPDFOUTPUTDEV_H
#define KPDFOUTPUTDEV_H