pages have orientation

document has a rotation to apply over the page's own orientation
text search really works now when rotating (at least all my tests here worked)

svn path=/branches/work/kde4/playground/graphics/okular/; revision=547644
This commit is contained in:
Albert Astals Cid 2006-06-02 20:42:57 +00:00
parent bb0f9f6bfb
commit cb7ca95e94
14 changed files with 65 additions and 55 deletions

View file

@ -73,6 +73,9 @@ class KPDFDocumentPrivate
int allocatedPixmapsTotalMemory;
bool warnedOutOfMemory;
// the rotation applied to the document, 0,1,2,3 * 90 degrees
int rotation;
// timers (memory checking / info saver)
QTimer * memCheckTimer;
QTimer * saveBookmarksTimer;
@ -118,6 +121,7 @@ KPDFDocument::KPDFDocument( QHash<QString, Generator*> * genList )
d->memCheckTimer = 0;
d->saveBookmarksTimer = 0;
d->warnedOutOfMemory = false;
d->rotation = 0;
m_usingCachedGenerator = false;
}
@ -554,6 +558,11 @@ QString KPDFDocument::getMetaData( const QString & key, const QString & option )
return generator ? generator->getMetaData( key, option ) : QString();
}
int KPDFDocument::rotation() const
{
return d->rotation;
}
void KPDFDocument::requestPixmaps( const QLinkedList< PixmapRequest * > & requests )
{
if ( !generator )
@ -596,6 +605,8 @@ void KPDFDocument::requestPixmaps( const QLinkedList< PixmapRequest * > & reques
continue;
}
request->documentRotation = d->rotation;
if ( !request->async )
request->priority = 0;
@ -1606,16 +1617,17 @@ void KPDFDocument::slotTimedMemoryCheck()
cleanupPixmapMemory();
}
void KPDFDocument::slotOrientation( int orientation )
void KPDFDocument::slotRotation( int rotation )
{
if ( generator->supportsRotation() )
{
generator->setOrientation(pages_vector,orientation);
d->rotation = rotation;
generator->setOrientation(pages_vector,rotation);
foreachObserver( notifySetup( pages_vector, true ) );
foreachObserver( notifyContentsCleared (DocumentObserver::Pixmap | DocumentObserver::Highlights | DocumentObserver::Annotations));
// foreachObserver( notifyViewportChanged( false /*disables smoothMove*/ ));
// foreachObserver( notifyPageChanged( ) );
kDebug() << "Oreint: " << orientation << endl;
kDebug() << "Rotated: " << rotation << endl;
}
}

View file

@ -104,6 +104,7 @@ class OKULAR_EXPORT KPDFDocument : public QObject
bool historyAtBegin() const;
bool historyAtEnd() const;
QString getMetaData( const QString & key, const QString & option = QString() ) const;
int rotation() const;
// gui altering stuff
QString getXMLFile();
@ -134,7 +135,7 @@ class OKULAR_EXPORT KPDFDocument : public QObject
// inline pagesVector() { return pages_vector; };
public slots:
void slotOrientation( int orientation );
void slotRotation( int rotation );
void slotPaperSizes( int );
signals:

View file

@ -10,6 +10,6 @@ QTextStream& operator<< (QTextStream& str, const PixmapRequest *req)
else
s += "S";
s += QString ("ync PixmapRequest (id: %1) (%2x%3) ").arg(req->id,req->width,req->height);
s += QString("rot:%4, prio: %5, pageNo: %6) ").arg(req->rotation,req->priority,req->pageNumber);
s += QString("prio: %1, pageNo: %2) ").arg(req->priority,req->pageNumber);
return (str << s);
}

View file

@ -144,9 +144,9 @@ class OKULAR_EXPORT Generator : public QObject
*/
struct OKULAR_EXPORT PixmapRequest
{
PixmapRequest( int rId, int n, int w, int h, /*double z,*/ int r, int p, bool a = false )
PixmapRequest( int rId, int n, int w, int h, /*double z,*/ int p, bool a )
: id( rId ), pageNumber( n ), width( w ), height( h ), /*zoom(z),*/
rotation(r) , priority( p ), async( a ), page( 0 ) {};
priority( p ), async( a ), page( 0 ) {};
PixmapRequest() {;};
// observer id
@ -156,14 +156,14 @@ struct OKULAR_EXPORT PixmapRequest
int width;
int height;
// double zoom;
int rotation;
// asyncronous request priority (less is better, 0 is max)
int priority;
// generate the pixmap in a thread and notify observer when done
bool async;
// this field is set by the Docuemnt prior passing the
// these fields are set by the Document prior passing the
// request to the generator
int documentRotation;
KPDFPage * page;
};

View file

@ -27,8 +27,8 @@ class TextSelection;
/** class KPDFPage **/
KPDFPage::KPDFPage( uint page, double w, double h, int r )
: m_number( page ), m_rotation( r ), m_width( w ), m_height( h ),
KPDFPage::KPDFPage( uint page, double w, double h, int o )
: m_number( page ), m_orientation( o ), m_width( w ), m_height( h ),
m_bookmarked( false ), m_text( 0 ), m_transition( 0 )
{
// if landscape swap width <-> height (rotate 90deg CCW)

View file

@ -52,12 +52,12 @@ class ObjectRect;
class OKULAR_EXPORT KPDFPage
{
public:
KPDFPage( uint number, double width, double height, int rotation );
KPDFPage( uint number, double width, double height, int orientation );
~KPDFPage();
// query properties (const read-only methods)
inline int number() const { return m_number; }
inline int rotation() const { return m_rotation; }
inline int orientation() const { return m_orientation; }
inline double width() const { return m_width; }
inline double height() const { return m_height; }
inline double ratio() const { return m_height / m_width; }
@ -101,7 +101,7 @@ class OKULAR_EXPORT KPDFPage
private:
friend class PagePainter;
int m_number;
int m_rotation;
int m_orientation;
double m_width, m_height;
bool m_bookmarked;

View file

@ -290,7 +290,7 @@ bool PDFGenerator::loadDocument( const QString & filePath, QVector<KPDFPage*> &
uint pageCount = pdfdoc->numPages();
pagesVector.resize(pageCount);
loadPages(pagesVector, -1, false);
loadPages(pagesVector, 0, false);
// the file has been loaded correctly
return true;
@ -307,30 +307,29 @@ void PDFGenerator::loadPages(QVector<KPDFPage*> &pagesVector, int rotation, bool
QSize pSize = p->pageSize();
w = pSize.width();
h = pSize.height();
if (rotation==-1)
int orientation;
switch (p->orientation())
{
switch (p->orientation())
{
case Poppler::Page::Landscape: rotation = 1; break;
case Poppler::Page::UpsideDown: rotation = 2; break;
case Poppler::Page::Seascape: rotation = 3; break;
case Poppler::Page::Portrait: rotation = 0; break;
}
case Poppler::Page::Landscape: orientation = 1; break;
case Poppler::Page::UpsideDown: orientation = 2; break;
case Poppler::Page::Seascape: orientation = 3; break;
case Poppler::Page::Portrait: orientation = 0; break;
}
if (rotation % 2 == 1)
qSwap(w,h);
// init a kpdfpage, add transition and annotation information
KPDFPage * page = new KPDFPage( i, w, h, rotation );
KPDFPage * page = new KPDFPage( i, w, h, orientation );
addTransition( p, page );
if ( true ) //TODO real check
addAnnotations( p, page );
// kWarning() << page->width() << "x" << page->height() << endl;
// need a way to find efficient (maybe background textpage generation)
kdDebug() << "loadpages with rotation" << rotation << " and orientation " << orientation << endl;
docLock.lock();
QList<Poppler::TextBox*> textList = p->textList((Poppler::Page::Rotation)rotation);
docLock.unlock();
page->setSearchPage(abstractTextPage(textList, page->height(), page->width(), rotation));
page->setSearchPage(abstractTextPage(textList, page->height(), page->width(), orientation));
qDeleteAll(textList);
delete p;
@ -602,7 +601,7 @@ void PDFGenerator::generatePixmap( PixmapRequest * request )
Poppler::Page *p = pdfdoc->page(page->number());
// 2. Take data from outputdev and attach it to the Page
page->setPixmap( request->id, p->splashRenderToPixmap(fakeDpiX, fakeDpiY, -1, -1, -1, -1, genObjectRects, (Poppler::Page::Rotation)request->rotation) );
page->setPixmap( request->id, p->splashRenderToPixmap(fakeDpiX, fakeDpiY, -1, -1, -1, -1, genObjectRects, (Poppler::Page::Rotation)m_document->rotation()) );
if ( genObjectRects )
{
@ -616,8 +615,8 @@ void PDFGenerator::generatePixmap( PixmapRequest * request )
docLock.unlock();
if ( genTextPage )
{
QList<Poppler::TextBox*> textList = p->textList((Poppler::Page::Rotation)request->rotation);
page->setSearchPage( abstractTextPage(textList, page->height(), page->width(),page->rotation()) );
QList<Poppler::TextBox*> textList = p->textList((Poppler::Page::Rotation)m_document->rotation());
page->setSearchPage( abstractTextPage(textList, page->height(), page->width(), page->orientation()) );
qDeleteAll(textList);
}
delete p;
@ -636,14 +635,16 @@ bool PDFGenerator::canGenerateTextPage()
void PDFGenerator::generateSyncTextPage( KPDFPage * page )
{
// TODO i think this is wrong because we need the "optative rotation", not the original rotation, but AFAIK it's never called
kDebug() << "calling generateSyncTextPage( KPDFPage * page )" << endl;
// build a TextList...
Poppler::Page *pp = pdfdoc->page( page->number() );
docLock.lock();
QList<Poppler::TextBox*> textList = pp->textList((Poppler::Page::Rotation)page->rotation());
QList<Poppler::TextBox*> textList = pp->textList((Poppler::Page::Rotation)m_document->rotation());
docLock.unlock();
delete pp;
// ..and attach it to the page
page->setSearchPage( abstractTextPage(textList, page->height(), page->width(),page->rotation()) );
page->setSearchPage( abstractTextPage(textList, page->height(), page->width(), page->orientation()) );
qDeleteAll(textList);
}
@ -761,6 +762,9 @@ KPDFTextPage * PDFGenerator::abstractTextPage(const QList<Poppler::TextBox*> &te
int j;
QString s;
NormalizedRect * wordRect = new NormalizedRect;
rot = (rot + m_document->rotation()) % 4;
foreach (Poppler::TextBox *word, text)
{
wordRect->left = word->boundingBox().left();
@ -1038,7 +1042,7 @@ void PDFGenerator::threadFinished()
if ( !outText.isEmpty() )
{
request->page->setSearchPage( abstractTextPage( outText ,
request->page->height(), request->page->width(),request->page->rotation()));
request->page->height(), request->page->width(),request->page->orientation()));
qDeleteAll(outText);
}
bool genObjectRects = request->id & (PAGEVIEW_ID | PRESENTATION_ID);
@ -1198,7 +1202,7 @@ void PDFPixmapGeneratorThread::run()
if ( !d->m_textList.isEmpty() )
kDebug() << "PDFPixmapGeneratorThread: previous text not taken" << endl;
#endif
d->m_image = new QImage( pp->splashRenderToImage( fakeDpiX, fakeDpiY, -1, -1, -1, -1, genObjectRects, (Poppler::Page::Rotation)d->currentRequest->rotation ) );
d->m_image = new QImage( pp->splashRenderToImage( fakeDpiX, fakeDpiY, -1, -1, -1, -1, genObjectRects, (Poppler::Page::Rotation)d->currentRequest->documentRotation ) );
if ( genObjectRects )
{
@ -1208,7 +1212,7 @@ void PDFPixmapGeneratorThread::run()
if ( genTextPage )
{
d->m_textList = pp->textList((Poppler::Page::Rotation)d->currentRequest->rotation);
d->m_textList = pp->textList((Poppler::Page::Rotation)d->currentRequest->documentRotation);
}
delete pp;

View file

@ -110,7 +110,7 @@ class PDFGenerator : public Generator
// fetch the transition information and add it to the page
void addTransition( Poppler::Page * popplerPage, KPDFPage * page );
static KPDFTextPage * abstractTextPage(const QList<Poppler::TextBox*> &text, double height, double width, int rot);
KPDFTextPage * abstractTextPage(const QList<Poppler::TextBox*> &text, double height, double width, int rot);
// poppler dependant stuff
QMutex docLock;

View file

@ -911,7 +911,7 @@ void Part::slotPrintPreview()
page = m_document->page(i);
width = page->width();
height = page->height();
if (page->rotation() == 90 || page->rotation() == 270) qSwap(width, height);
if (page->orientation() == 90 || page->orientation() == 270) qSwap(width, height);
if (width > height) landscape++;
else portrait++;
}
@ -1040,7 +1040,7 @@ void Part::slotPrint()
page = m_document->page(i);
width = page->width();
height = page->height();
if (page->rotation() == 90 || page->rotation() == 270) qSwap(width, height);
if (page->orientation() == 90 || page->orientation() == 270) qSwap(width, height);
if (width > height) landscape++;
else portrait++;
}

View file

@ -208,15 +208,15 @@ void PageView::setupActions( KActionCollection * ac )
{
d->aOrientation=new KSelectAction( i18n( "&Orientation" ), ac, "view_orientation" );
d->aPaperSizes=new KSelectAction( i18n( "&Paper sizes" ), ac, "view_papersizes" );
QStringList orientations;
orientations.append( i18n( "Default" ) );
orientations.append( i18n( "Rotated 90 Degrees" ) );
orientations.append( i18n( "Rotated 180 Degrees" ) );
orientations.append( i18n( "Rotated 270 Degrees" ) );
d->aOrientation->setItems( orientations );
QStringList rotations;
rotations.append( i18n( "Default" ) );
rotations.append( i18n( "Rotated 90 Degrees" ) );
rotations.append( i18n( "Rotated 180 Degrees" ) );
rotations.append( i18n( "Rotated 270 Degrees" ) );
d->aOrientation->setItems( rotations );
connect( d->aOrientation , SIGNAL( triggered( int ) ),
d->document , SLOT( slotOrientation( int ) ) );
d->document , SLOT( slotRotation( int ) ) );
connect( d->aPaperSizes , SIGNAL( triggered( int ) ),
d->document , SLOT( slotPaperSizes( int ) ) );
@ -2236,7 +2236,7 @@ void PageView::slotRequestVisiblePixmaps( int newLeft, int newTop )
kWarning() << "rerequesting visible pixmaps for page " << i->pageNumber() << " !\n";
#endif
PixmapRequest * p = new PixmapRequest(
PAGEVIEW_ID, i->pageNumber(), i->width(), i->height(), i->rotation(), PAGEVIEW_PRIO, true );
PAGEVIEW_ID, i->pageNumber(), i->width(), i->height(), PAGEVIEW_PRIO, true );
requestedPixmaps.push_back( p );
}
@ -2273,7 +2273,7 @@ void PageView::slotRequestVisiblePixmaps( int newLeft, int newTop )
// request the pixmap if not already present
if ( !i->page()->hasPixmap( PAGEVIEW_ID, i->width(), i->height() ) && i->width() > 0 )
requestedPixmaps.push_back( new PixmapRequest(
PAGEVIEW_ID, i->pageNumber(), i->width(), i->height(), i->rotation(), PAGEVIEW_PRELOAD_PRIO, true ) );
PAGEVIEW_ID, i->pageNumber(), i->width(), i->height(), PAGEVIEW_PRELOAD_PRIO, true ) );
}
// add the page after the 'visible series' in preload
@ -2284,7 +2284,7 @@ void PageView::slotRequestVisiblePixmaps( int newLeft, int newTop )
// request the pixmap if not already present
if ( !i->page()->hasPixmap( PAGEVIEW_ID, i->width(), i->height() ) && i->width() > 0 )
requestedPixmaps.push_back( new PixmapRequest(
PAGEVIEW_ID, i->pageNumber(), i->width(), i->height(), i->rotation(), PAGEVIEW_PRELOAD_PRIO, true ) );
PAGEVIEW_ID, i->pageNumber(), i->width(), i->height(), PAGEVIEW_PRELOAD_PRIO, true ) );
}
}

View file

@ -48,11 +48,6 @@ int PageViewItem::pageNumber() const
return m_page->number();
}
int PageViewItem::rotation() const
{
return m_page->rotation();
}
const QRect& PageViewItem::geometry() const
{
return m_geometry;

View file

@ -34,7 +34,6 @@ class PageViewItem
int width() const;
int height() const;
double zoomFactor() const;
int rotation() const;
void setGeometry( int x, int y, int width, int height );
void setWHZ( int w, int h, double zoom );

View file

@ -442,7 +442,7 @@ void PresentationWidget::changePage( int newPage )
PresentationFrame * frame = m_frames[ m_frameIndex ];
int pixW = frame->geometry.width();
int pixH = frame->geometry.height();
int rot = frame->page->rotation();
int rot = frame->page->orientation();
// if pixmap not inside the KPDFPage we request it and wait for
// notifyPixmapChanged call or else we can proceed to pixmap generation

View file

@ -425,8 +425,7 @@ void ThumbnailList::slotRequestVisiblePixmaps( int /*newContentsY*/ )
if ( !t->page()->hasPixmap( THUMBNAILS_ID, t->pixmapWidth(), t->pixmapHeight() ) )
{
PixmapRequest * p = new PixmapRequest(
THUMBNAILS_ID, t->pageNumber(), t->pixmapWidth(), t->pixmapHeight(),
t->page()->rotation(), THUMBNAILS_PRIO, true );
THUMBNAILS_ID, t->pageNumber(), t->pixmapWidth(), t->pixmapHeight(), THUMBNAILS_PRIO, true );
requestedPixmaps.push_back( p );
}
}