Commit a02490d1 authored by Enrico Ros's avatar Enrico Ros
Browse files

Decoupling drawing code and KPDFPage class. Work to get a common and shared

rendering function is underway ...

svn path=/branches/kpdf_experiments/kdegraphics/kpdf/; revision=360883
parent 3596d8ae
......@@ -254,6 +254,7 @@ void KPDFDocument::requestPixmap( int id, uint page, int width, int height, bool
if ( !d->pdfdoc || !kp || kp->width() < 1 || kp->height() < 1 )
return;
//kdDebug() << "id: " << id << " is requesting pixmap for page " << page << " [" << width << " x " << height << "]." << endl;
if ( syn )
{
// in-place Pixmap generation for syncronous requests
......@@ -367,12 +368,12 @@ void KPDFDocument::slotSetFilter( const QString & pattern, bool keepCase )
processPageList( false );
}
void KPDFDocument::slotBookmarkPage( int n, bool on )
void KPDFDocument::slotToggleBookmark( int n )
{
KPDFPage * page = ( n < (int)d->pages.count() ) ? d->pages[ n ] : 0;
if ( page )
{
page->bookmark( on );
page->toggleAttribute( KPDFPage::Bookmark );
foreachObserver( notifyPixmapChanged( n ) );
}
}
......@@ -400,7 +401,7 @@ void KPDFDocument::slotFind( const QString & string, bool keepCase )
foundPage = lastPage;
else
{
lastPage->hilightLastSearch( false );
lastPage->clearAttribute( KPDFPage::Highlight );
currentPage++;
pageCount--;
}
......@@ -431,7 +432,7 @@ void KPDFDocument::slotFind( const QString & string, bool keepCase )
{
int pageNumber = foundPage->number();
d->searchPage = pageNumber;
foundPage->hilightLastSearch( true );
foundPage->setAttribute( KPDFPage::Highlight );
slotSetCurrentPage( pageNumber );
foreachObserver( notifyPixmapChanged( pageNumber ) );
}
......@@ -633,9 +634,8 @@ void KPDFDocument::processPageList( bool documentChanged )
for ( uint i = 0; i < pageCount ; i++ )
{
KPDFPage * page = d->pages[ i ];
if ( d->filterText.length() < 3 )
page->hilightLastSearch( false );
else
page->clearAttribute( KPDFPage::Highlight );
if ( d->filterText.length() > 2 )
{
if ( !page->hasSearchPage() )
{
......@@ -647,8 +647,8 @@ void KPDFDocument::processPageList( bool documentChanged )
// ..and attach it to the page
page->setSearchPage( td.takeTextPage() );
}
bool found = page->hasText( d->filterText, d->filterCase, true );
page->hilightLastSearch( found );
if ( page->hasText( d->filterText, d->filterCase, true ) )
page->setAttribute( KPDFPage::Highlight );
}
}
}
......@@ -662,14 +662,14 @@ void KPDFDocument::unHilightPages()
if ( d->filterText.isEmpty() )
return;
d->filterText = "";
d->filterText = QString::null;
QValueVector<KPDFPage*>::iterator it = d->pages.begin(), end = d->pages.end();
for ( ; it != end; ++it )
{
KPDFPage * page = *it;
if ( page->isHilighted() )
if ( page->attributes() & KPDFPage::Highlight )
{
page->hilightLastSearch( false );
page->clearAttribute( KPDFPage::Highlight );
foreachObserver( notifyPixmapChanged( page->number() ) );
}
}
......
......@@ -83,7 +83,7 @@ public:
// document commands via slots
void slotSetCurrentPage( int page, const QRect & viewport = QRect() );
void slotSetFilter( const QString & pattern, bool caseSensitive );
void slotBookmarkPage( int page, bool enabled );
void slotToggleBookmark( int page );
void slotFind( const QString & text = "", bool caseSensitive = false );
void slotProcessLink( const KPDFLink * link );
......
......@@ -26,10 +26,10 @@
// TODO add painting effects (plus selection rectangle)
// TODO think about moving rendering ...
KPDFPage::KPDFPage( int page, float w, float h, int r )
: m_number( page ), m_rotation( r ), m_width( w ), m_height( h ),
m_hilighting( false ), m_bookmarking( false ), m_sLeft( 0 ),
m_sTop( 0 ), m_sRight( 0 ), m_sBottom( 0 ), m_text( 0 )
KPDFPage::KPDFPage( uint page, float w, float h, int r )
: m_number( page ), m_rotation( r ), m_attributes( 0 ),
m_width( w ), m_height( h ), m_sLeft( 0 ), m_sTop( 0 ),
m_sRight( 0 ), m_sBottom( 0 ), m_text( 0 )
{
// if landscape swap width <-> height (rotate 90deg CCW)
if ( r == 90 || r == 270 )
......@@ -62,23 +62,6 @@ bool KPDFPage::hasPixmap( int id, int width, int height ) const
return p ? ( p->width() == width && p->height() == height ) : false;
}
bool KPDFPage::hasSearchPage() const
{
return ( m_text != 0 );
}
QString KPDFPage::getTextInRect( const QRect & rect, double zoom ) const
{
if ( !m_text )
return QString();
int left = (int)((double)rect.left() / zoom),
top = (int)((double)rect.top() / zoom),
right = (int)((double)rect.right() / zoom),
bottom = (int)((double)rect.bottom() / zoom);
GString * text = m_text->getText( left, top, right, bottom );
return QString( text->getCString() );
}
bool KPDFPage::hasLink( int mouseX, int mouseY ) const
{
if ( m_links.count() < 1 )
......@@ -101,7 +84,18 @@ bool KPDFPage::hasActiveRect( int mouseX, int mouseY ) const
return false;
}
// BEGIN commands (paint / search)
const QString KPDFPage::getTextInRect( const QRect & rect, double zoom ) const
{
if ( !m_text )
return QString::null;
int left = (int)((double)rect.left() / zoom),
top = (int)((double)rect.top() / zoom),
right = (int)((double)rect.right() / zoom),
bottom = (int)((double)rect.bottom() / zoom);
GString * text = m_text->getText( left, top, right, bottom );
return QString( text->getCString() );
}
const KPDFLink * KPDFPage::getLink( int mouseX, int mouseY ) const
{
QValueList< KPDFLink * >::const_iterator it = m_links.begin(), end = m_links.end();
......@@ -111,71 +105,6 @@ const KPDFLink * KPDFPage::getLink( int mouseX, int mouseY ) const
return 0;
}
void KPDFPage::drawPixmap( int id, QPainter * p, const QRect & limits, int width, int height ) const
{
QPixmap * pixmap = 0;
// if a pixmap is present for given id, use it
if ( m_pixmaps.contains( id ) )
pixmap = m_pixmaps[ id ];
// else find the closest match using pixmaps of other IDs (great optim!)
else if ( !m_pixmaps.isEmpty() )
{
int minDistance = -1;
QMap<int,QPixmap *>::const_iterator it = m_pixmaps.begin(), end = m_pixmaps.end();
for ( ; it != end; ++it )
{
int pixWidth = (*it)->width(),
distance = pixWidth > width ? pixWidth - width : width - pixWidth;
if ( minDistance == -1 || distance < minDistance )
{
pixmap = *it;
minDistance = distance;
}
}
}
// if we found a pixmap draw it
if ( pixmap )
{
// fast blit the pixmap if it has the right size..
if ( pixmap->width() == width && pixmap->height() == height )
p->drawPixmap( limits.topLeft(), *pixmap, limits );
// ..else set a scale matrix to the painter and paint a quick 'zoomed' pixmap
else
{
p->save();
// TODO paint only the needed part
p->scale( width / (double)pixmap->width(), height / (double)pixmap->height() );
p->drawPixmap( 0,0, *pixmap, 0,0, pixmap->width(), pixmap->height() );
p->restore();
// draw a cross (to that the pixmap has not the right size)
p->setPen( Qt::gray );
p->drawLine( 0, 0, width-1, height-1 );
p->drawLine( 0, height-1, width-1, 0 );
}
// draw selection (note: it is rescaled since the text page is at 100% scale)
if ( m_hilighting )
{
int x = (int)( m_sLeft * width / m_width ),
y = (int)( m_sTop * height / m_height ),
w = (int)( m_sRight * width / m_width ) - x,
h = (int)( m_sBottom * height / m_height ) - y;
if ( w > 0 && h > 0 )
{
// setRasterOp is no more on Qt4 find an alternative way of doing this
p->setBrush( Qt::SolidPattern );
p->setPen( QPen( Qt::black, 1 ) ); // should not be necessary bug a Qt bug makes it necessary
p->setRasterOp( Qt::NotROP );
p->drawRect( x, y, w, h );
}
}
}
// else draw a blank area
else
p->fillRect( limits, Qt::white /*FIXME change to the page bg color*/ );
}
bool KPDFPage::hasText( const QString & text, bool strictCase, bool fromTop )
{
......@@ -197,18 +126,6 @@ bool KPDFPage::hasText( const QString & text, bool strictCase, bool fromTop )
return found;
}
void KPDFPage::hilightLastSearch( bool on )
{
m_hilighting = on;
//if ( !on ) -> invalidate search rect?
}
void KPDFPage::bookmark( bool on )
{
m_bookmarking = on;
}
// END commands (paint / search)
void KPDFPage::setPixmap( int id, QPixmap * pixmap )
{
......@@ -239,11 +156,71 @@ void KPDFPage::setActiveRects( const QValueList<KPDFActiveRect *> rects )
m_rects = rects;
}
/*
void KPDFPage::setPixmapOverlayNotations( ..DOMdescription.. )
{ //TODO this
void PagePainter::paintPageOnPainter( const KPDFPage * page, int id, QPainter * p, const QRect & limits, int width, int height )
{
QPixmap * pixmap = 0;
// if a pixmap is present for given id, use it
if ( page->m_pixmaps.contains( id ) )
pixmap = page->m_pixmaps[ id ];
// else find the closest match using pixmaps of other IDs (great optim!)
else if ( !page->m_pixmaps.isEmpty() && width != -1 )
{
int minDistance = -1;
QMap< int,QPixmap * >::const_iterator it = page->m_pixmaps.begin(), end = page->m_pixmaps.end();
for ( ; it != end; ++it )
{
int pixWidth = (*it)->width(),
distance = pixWidth > width ? pixWidth - width : width - pixWidth;
if ( minDistance == -1 || distance < minDistance )
{
pixmap = *it;
minDistance = distance;
}
}
}
if ( !pixmap )
{
p->fillRect( limits, Qt::white );
return;
}
// fast blit the pixmap if it has the right size..
if ( pixmap->width() == width && pixmap->height() == height )
p->drawPixmap( limits.topLeft(), *pixmap, limits );
// ..else set a scale matrix to the painter and paint a quick 'zoomed' pixmap
else
{
p->save();
// TODO paint only the needed part
p->scale( width / (double)pixmap->width(), height / (double)pixmap->height() );
p->drawPixmap( 0,0, *pixmap, 0,0, pixmap->width(), pixmap->height() );
p->restore();
// draw a cross (to that the pixmap has not the right size)
p->setPen( Qt::gray );
p->drawLine( 0, 0, width-1, height-1 );
p->drawLine( 0, height-1, width-1, 0 );
}
// draw selection (note: it is rescaled since the text page is at 100% scale)
if ( page->attributes() & KPDFPage::Highlight )
{
int x = (int)( page->m_sLeft * width / page->m_width ),
y = (int)( page->m_sTop * height / page->m_height ),
w = (int)( page->m_sRight * width / page->m_width ) - x,
h = (int)( page->m_sBottom * height / page->m_height ) - y;
if ( w > 0 && h > 0 )
{
// setRasterOp is no more on Qt4 find an alternative way of doing this
p->setBrush( Qt::SolidPattern );
p->setPen( QPen( Qt::black, 1 ) ); // should not be necessary bug a Qt bug makes it necessary
p->setRasterOp( Qt::NotROP );
p->drawRect( x, y, w, h );
}
}
}
*/
......@@ -393,4 +370,3 @@ bool KPDFActiveRect::contains(int x, int y)
{
return (x > m_left) && (x < m_right) && (y > m_top) && (y < m_bottom);
}
......@@ -32,51 +32,59 @@ class KPDFActiveRect;
*/
class KPDFPage
{
public:
KPDFPage( int number, float width, float height, int rotation );
~KPDFPage();
// query properties and draw (const read-only methods)
uint number() const { return m_number; }
float width() const { return m_width; }
float height() const { return m_height; }
float ratio() const { return m_height / m_width; }
float rotation() const { return m_rotation; }
bool isHilighted() const { return m_hilighting; }
bool isBookmarked() const { return m_bookmarking; }
bool hasPixmap( int id, int width, int height ) const;
bool hasSearchPage() const;
QString getTextInRect( const QRect & rect, double zoom = 1.0 ) const;
bool hasLink( int mouseX, int mouseY ) const;
const KPDFLink * getLink( int mouseX, int mouseY ) const;
bool hasActiveRect( int mouseX, int mouseY ) const;
void drawPixmap( int id, QPainter * p, const QRect & rect, int width, int height ) const;
// commands (not const methods caled by KPDFDocument)
bool hasText( const QString & text, bool strictCase, bool fromTop );
void hilightLastSearch( bool enabled );
void bookmark( bool enabled );
// set page contents (not const methods caled by KPDFDocument)
void setPixmap( int id, QPixmap * pixmap );
void setSearchPage( TextPage * text );
void setLinks( const QValueList<KPDFLink *> links );
void setActiveRects( const QValueList<KPDFActiveRect *> rects );
/*void setPixmapOverlayNotations( ..DOMdescription.. );*/
private:
int m_number, m_rotation;
float m_width, m_height;
bool m_hilighting, m_bookmarking;
double m_sLeft, m_sTop, m_sRight, m_sBottom;
QMap< int, QPixmap * > m_pixmaps;
TextPage * m_text;
QValueList< KPDFLink * > m_links;
QValueList< KPDFActiveRect * > m_rects;
public:
KPDFPage( uint number, float width, float height, int rotation );
~KPDFPage();
enum KPDFPageAttributes { Highlight = 1, Bookmark = 2 };
// query properties (const read-only methods)
inline int number() const { return m_number; }
inline int rotation() const { return m_rotation; }
inline int attributes() const { return m_attributes; }
inline float width() const { return m_width; }
inline float height() const { return m_height; }
inline float ratio() const { return m_height / m_width; }
bool hasPixmap( int id, int width, int height ) const;
bool hasSearchPage() const { return m_text != 0; }
bool hasLink( int mouseX, int mouseY ) const;
bool hasActiveRect( int mouseX, int mouseY ) const;
const QString getTextInRect( const QRect & rect, double zoom = 1.0 ) const;
const KPDFLink * getLink( int mouseX, int mouseY ) const;
// operations (not const methods caled by KPDFDocument)
inline void setAttribute( int att ) { m_attributes |= att; }
inline void clearAttribute( int att ) { m_attributes &= ~att; }
inline void toggleAttribute( int att ) { m_attributes ^= att; }
bool hasText( const QString & text, bool strictCase, bool fromTop );
// set contents (not const methods caled by KPDFDocument)
void setPixmap( int id, QPixmap * pixmap );
void setSearchPage( TextPage * text );
void setLinks( const QValueList<KPDFLink *> links );
void setActiveRects( const QValueList<KPDFActiveRect *> rects );
private:
friend class PagePainter;
int m_number, m_rotation, m_attributes;
float m_width, m_height;
double m_sLeft, m_sTop, m_sRight, m_sBottom;
QMap< int, QPixmap * > m_pixmaps;
TextPage * m_text;
QValueList< KPDFLink * > m_links;
QValueList< KPDFActiveRect * > m_rects;
};
class PagePainter
{
public:
static void paintPageOnPainter( const KPDFPage * page, int id,
QPainter * p, const QRect & limits, int width = -1, int height = -1 );
};
/**
* @short Encapsulates data that describes a link.
*
......
......@@ -623,7 +623,7 @@ void PageView::contentsMouseReleaseEvent( QMouseEvent * e )
const KPDFPage * kpdfPage = pageItem->page();
KPopupMenu * m_popup = new KPopupMenu( this, "rmb popup" );
m_popup->insertTitle( i18n( "Page %1" ).arg( kpdfPage->number() + 1 ) );
if ( kpdfPage->isBookmarked() )
if ( kpdfPage->attributes() & KPDFPage::Bookmark )
m_popup->insertItem( SmallIcon("bookmark"), i18n("Remove Bookmark"), 1 );
else
m_popup->insertItem( SmallIcon("bookmark_add"), i18n("Add Bookmark"), 1 );
......@@ -638,7 +638,7 @@ void PageView::contentsMouseReleaseEvent( QMouseEvent * e )
switch ( m_popup->exec(e->globalPos()) )
{
case 1:
d->document->slotBookmarkPage( kpdfPage->number(), !kpdfPage->isBookmarked() );
d->document->slotToggleBookmark( kpdfPage->number() );
break;
case 2:
// zoom: Fit Width, columns: 1. setActions + relayout + setPage + update
......@@ -898,7 +898,7 @@ void PageView::paintItems( QPainter * p, const QRect & contentsRect )
QPixmap pagePix( pixmapRect.width(), pixmapRect.height() );
QPainter pixmapPainter( &pagePix );
pixmapPainter.translate( -pixmapRect.left(), -pixmapRect.top() );
item->page()->drawPixmap( PAGEVIEW_ID, &pixmapPainter, pixmapRect, pixmapGeometry.width(), pixmapGeometry.height() );
PagePainter::paintPageOnPainter( item->page(), PAGEVIEW_ID, &pixmapPainter, pixmapRect, pixmapGeometry.width(), pixmapGeometry.height() );
pixmapPainter.end();
// perform 'accessbility' enhancements on the (already painted) pixmap
......@@ -943,7 +943,7 @@ void PageView::paintItems( QPainter * p, const QRect & contentsRect )
p->drawPixmap( pixmapRect.left(), pixmapRect.top(), pagePix );
}
else // paint pixmapRect area (as it is) in external painter
item->page()->drawPixmap( PAGEVIEW_ID, p, pixmapRect, pixmapGeometry.width(), pixmapGeometry.height() );
PagePainter::paintPageOnPainter( item->page(), PAGEVIEW_ID, p, pixmapRect, pixmapGeometry.width(), pixmapGeometry.height() );
}
// remove painted area from 'remainingArea' and restore painter
......
......@@ -95,7 +95,7 @@ void ThumbnailList::pageSetup( const QValueVector<KPDFPage*> & pages, bool /*doc
//FIXME change this quick fix (lines that follows). Check if filtering:
bool skipCheck = true;
for ( uint i = 0; i < pages.count(); i++ )
if ( pages[i]->isHilighted() )
if ( pages[i]->attributes() & KPDFPage::Highlight )
skipCheck = false;
// generate Thumbnails for the given set of pages
......@@ -105,7 +105,7 @@ void ThumbnailList::pageSetup( const QValueVector<KPDFPage*> & pages, bool /*doc
QValueVector<KPDFPage*>::const_iterator pageIt = pages.begin();
QValueVector<KPDFPage*>::const_iterator pageEnd = pages.end();
for (; pageIt != pageEnd ; ++pageIt)
if ( skipCheck || (*pageIt)->isHilighted() ) {
if ( skipCheck || ( (*pageIt)->attributes() & KPDFPage::Highlight ) ) {
t = new ThumbnailWidget( viewport(), *pageIt );
t->setFocusProxy( this );
// add to the scrollview
......@@ -357,7 +357,7 @@ void ThumbnailWidget::paintEvent( QPaintEvent * e )
p.translate( 2, 2 );
clipRect.moveBy( -2, -2 );
clipRect = clipRect.intersect( QRect( 0, 0, m_pixmapWidth, m_pixmapHeight ) );
m_page->drawPixmap( THUMBNAILS_ID, &p, clipRect, m_pixmapWidth, m_pixmapHeight );
PagePainter::paintPageOnPainter( m_page, THUMBNAILS_ID, &p, clipRect, m_pixmapWidth, m_pixmapHeight );
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment