diff --git a/core/document.cpp b/core/document.cpp index 7d834f54c..c7e501982 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -888,11 +888,12 @@ void DocumentPrivate::sendGeneratorRequest() while ( !m_pixmapRequestsStack.isEmpty() && !request ) { PixmapRequest * r = m_pixmapRequestsStack.last(); + const NormalizedRect visibleRect = ( r && r->visiblePageRect() ? r->visiblePageRect()->rect : NormalizedRect() ); if (!r) m_pixmapRequestsStack.pop_back(); // request only if page isn't already present or request has invalid id - else if ( ( !r->d->mForce && r->page()->hasPixmap( r->id(), r->width(), r->height() ) ) || r->id() <= 0 || r->id() >= MAX_OBSERVER_ID ) + else if ( ( !r->d->mForce && r->page()->hasPixmap( r->id(), r->width(), r->height(), visibleRect ) ) || r->id() <= 0 || r->id() >= MAX_OBSERVER_ID ) { m_pixmapRequestsStack.pop_back(); delete r; diff --git a/core/generator.cpp b/core/generator.cpp index 2c63ca17f..f35600a31 100644 --- a/core/generator.cpp +++ b/core/generator.cpp @@ -431,6 +431,7 @@ PixmapRequest::PixmapRequest( int id, int pageNumber, int width, int height, int d->mPriority = priority; d->mAsynchronous = asynchronous; d->mForce = false; + d->mVisiblePageRect = 0; } PixmapRequest::~PixmapRequest() @@ -473,6 +474,19 @@ Page* PixmapRequest::page() const return d->mPage; } +void PixmapRequest::setVisiblePageRect( VisiblePageRect *visiblePageRect ) +{ + if ( d->mVisiblePageRect == visiblePageRect ) + return; + + d->mVisiblePageRect = visiblePageRect; +} + +VisiblePageRect *PixmapRequest::visiblePageRect() const +{ + return d->mVisiblePageRect; +} + void PixmapRequestPrivate::swap() { qSwap( mWidth, mHeight ); diff --git a/core/generator.h b/core/generator.h index 213e2ad37..61735a11e 100644 --- a/core/generator.h +++ b/core/generator.h @@ -53,6 +53,7 @@ class PixmapRequestPrivate; class TextPage; class NormalizedRect; class SourceReference; +class VisiblePageRect; /* Note: on contents generation and asynchronous queries. * Many observers may want to request data syncronously or asynchronously. @@ -579,6 +580,9 @@ class OKULAR_EXPORT PixmapRequest */ Page *page() const; + void setVisiblePageRect( VisiblePageRect *visiblePageRect ); + VisiblePageRect *visiblePageRect() const; + private: Q_DISABLE_COPY( PixmapRequest ) diff --git a/core/generator_p.h b/core/generator_p.h index f2d746a19..fe757d7fa 100644 --- a/core/generator_p.h +++ b/core/generator_p.h @@ -29,6 +29,7 @@ class PixmapGenerationThread; class PixmapRequest; class TextPage; class TextPageGenerationThread; +class VisiblePageRect; class GeneratorPrivate { @@ -79,6 +80,7 @@ class PixmapRequestPrivate bool mAsynchronous; bool mForce : 1; Page *mPage; + VisiblePageRect *mVisiblePageRect; }; diff --git a/core/page.cpp b/core/page.cpp index 641e8cfe3..b0b2c7404 100644 --- a/core/page.cpp +++ b/core/page.cpp @@ -201,7 +201,7 @@ void Page::setBoundingBox( const NormalizedRect& bbox ) d->m_isBoundingBoxKnown = true; } -bool Page::hasPixmap( int id, int width, int height ) const +bool Page::hasPixmap( int id, int width, int height, const NormalizedRect &rect ) const { QMap< int, PagePrivate::PixmapObject >::const_iterator it = d->m_pixmaps.constFind( id ); if ( it == d->m_pixmaps.constEnd() ) @@ -212,7 +212,13 @@ bool Page::hasPixmap( int id, int width, int height ) const const QPixmap *pixmap = it.value().m_pixmap; - return (pixmap->width() == width && pixmap->height() == height); + if ( pixmap->width() != width || pixmap->height() != height ) + return false; + + if ( rect.isNull() ) + return true; + + return (rect == it.value().m_rect); } bool Page::hasTextPage() const @@ -459,7 +465,7 @@ QLinkedList< FormField * > Page::formFields() const return d->formfields; } -void Page::setPixmap( int id, QPixmap *pixmap ) +void Page::setPixmap( int id, QPixmap *pixmap, const NormalizedRect &rect ) { if ( d->m_rotation == Rotation0 ) { QMap< int, PagePrivate::PixmapObject >::iterator it = d->m_pixmaps.find( id ); @@ -472,6 +478,7 @@ void Page::setPixmap( int id, QPixmap *pixmap ) it = d->m_pixmaps.insert( id, PagePrivate::PixmapObject() ); } it.value().m_pixmap = pixmap; + it.value().m_rect = rect; it.value().m_rotation = d->m_rotation; } else { RotationJob *job = new RotationJob( pixmap->toImage(), Rotation0, d->m_rotation, id ); diff --git a/core/page.h b/core/page.h index a2571b753..19321609c 100644 --- a/core/page.h +++ b/core/page.h @@ -139,7 +139,7 @@ class OKULAR_EXPORT Page * Returns whether the page has a pixmap of size @p width x @p height * for the observer with given @p id. */ - bool hasPixmap( int id, int width = -1, int height = -1 ) const; + bool hasPixmap( int id, int width = -1, int height = -1, const NormalizedRect &rect = NormalizedRect() ) const; /** * Returns whether the page provides a text page (@ref TextPage). @@ -255,7 +255,7 @@ class OKULAR_EXPORT Page /** * Sets the @p pixmap for the observer with the given @p id. */ - void setPixmap( int id, QPixmap *pixmap ); + void setPixmap( int id, QPixmap *pixmap, const NormalizedRect &rect = NormalizedRect() ); /** * Sets the @p text page. diff --git a/core/page_p.h b/core/page_p.h index 4cbfb193a..3ad435cdd 100644 --- a/core/page_p.h +++ b/core/page_p.h @@ -103,6 +103,7 @@ class PagePrivate { public: QPixmap *m_pixmap; + NormalizedRect m_rect; Rotation m_rotation; }; QMap< int, PixmapObject > m_pixmaps; diff --git a/ui/pageview.cpp b/ui/pageview.cpp index 0015aa19e..168352618 100644 --- a/ui/pageview.cpp +++ b/ui/pageview.cpp @@ -3963,13 +3963,14 @@ void PageView::slotRequestVisiblePixmaps( int newValue ) #endif // if the item has not the right pixmap, add a request for it // TODO: We presently request a pixmap for the full page, and then render just the crop part. This waste memory and cycles. - if ( !i->page()->hasPixmap( PAGEVIEW_ID, i->uncroppedWidth(), i->uncroppedHeight() ) ) + if ( !i->page()->hasPixmap( PAGEVIEW_ID, i->uncroppedWidth(), i->uncroppedHeight(), vItem->rect ) ) { #ifdef PAGEVIEW_DEBUG kWarning() << "rerequesting visible pixmaps for page" << i->pageNumber() << "!"; #endif Okular::PixmapRequest * p = new Okular::PixmapRequest( PAGEVIEW_ID, i->pageNumber(), i->uncroppedWidth(), i->uncroppedHeight(), PAGEVIEW_PRIO, true ); + p->setVisiblePageRect( vItem ); requestedPixmaps.push_back( p ); }