mirror of
https://invent.kde.org/graphics/okular
synced 2024-11-05 18:34:53 +00:00
* reimplemented table of contents parsing in a faster way (thanks to tronical!)
svn path=/trunk/playground/graphics/okular/; revision=586039
This commit is contained in:
parent
b273826b35
commit
21b3dc4263
3 changed files with 84 additions and 43 deletions
|
@ -59,14 +59,22 @@ bool Converter::convert()
|
|||
delete mTextDocument;
|
||||
delete mCursor;
|
||||
|
||||
mHeaderInfos.clear();
|
||||
|
||||
mTextDocument = new QTextDocument;
|
||||
mCursor = new QTextCursor( mTextDocument );
|
||||
|
||||
/**
|
||||
* Read the style properties, so the are available when
|
||||
* parsing the content.
|
||||
*/
|
||||
StyleParser styleParser( mDocument, mStyleInformation );
|
||||
if ( !styleParser.parse() )
|
||||
return false;
|
||||
|
||||
// add images to resource framework
|
||||
/**
|
||||
* Add all images of the document to resource framework
|
||||
*/
|
||||
const QMap<QString, QByteArray> images = mDocument->images();
|
||||
QMapIterator<QString, QByteArray> it( images );
|
||||
while ( it.hasNext() ) {
|
||||
|
@ -75,6 +83,9 @@ bool Converter::convert()
|
|||
mTextDocument->addResource( QTextDocument::ImageResource, QUrl( it.key() ), QImage::fromData( it.value() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the correct page size
|
||||
*/
|
||||
const QString masterLayout = mStyleInformation->masterLayout( "Standard" );
|
||||
const PageFormatProperty property = mStyleInformation->pageProperty( masterLayout );
|
||||
mTextDocument->setPageSize( QSize( qRound( property.width() ), qRound( property.height() ) ) );
|
||||
|
@ -85,6 +96,9 @@ bool Converter::convert()
|
|||
QTextFrame *rootFrame = mTextDocument->rootFrame();
|
||||
rootFrame->setFrameFormat( frameFormat );
|
||||
|
||||
/**
|
||||
* Parse the content of the document
|
||||
*/
|
||||
QXmlSimpleReader reader;
|
||||
|
||||
QXmlInputSource source;
|
||||
|
@ -111,6 +125,12 @@ bool Converter::convert()
|
|||
element = element.nextSiblingElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create table of contents
|
||||
*/
|
||||
if ( !createTableOfContents() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -183,44 +203,12 @@ bool Converter::convertHeader( QTextCursor *cursor, const QDomElement &element )
|
|||
child = child.nextSibling();
|
||||
}
|
||||
|
||||
const QSizeF pageSize = mTextDocument->pageSize();
|
||||
HeaderInfo headerInfo;
|
||||
headerInfo.block = cursor->block();
|
||||
headerInfo.text = element.text();
|
||||
headerInfo.level = element.attribute( "outline-level" ).toInt();
|
||||
|
||||
QTextBlock currentBlock = cursor->block();
|
||||
const QRectF rect = mTextDocument->documentLayout()->blockBoundingRect( currentBlock );
|
||||
// const QRectF rect(0, 0, 0, 0);
|
||||
|
||||
int page = qRound( rect.y() ) / qRound( pageSize.height() );
|
||||
int offset = qRound( rect.y() ) % qRound( pageSize.height() );
|
||||
|
||||
DocumentViewport viewport( page );
|
||||
viewport.rePos.normalizedX = (double)rect.x() / (double)pageSize.width();
|
||||
viewport.rePos.normalizedY = (double)offset / (double)pageSize.height();
|
||||
viewport.rePos.enabled = true;
|
||||
viewport.rePos.pos = DocumentViewport::Center;
|
||||
|
||||
static QStack<QDomNode> parentNodeStack;
|
||||
static QDomNode parentNode = mTableOfContents;
|
||||
static int level = 2;
|
||||
|
||||
QDomElement item = mTableOfContents.createElement( element.text() );
|
||||
item.setAttribute( "Viewport", viewport.toString() );
|
||||
|
||||
int newLevel = element.attribute( "outline-level" ).toInt();
|
||||
if ( newLevel == level ) {
|
||||
parentNode.appendChild( item );
|
||||
} else if ( newLevel > level ) {
|
||||
parentNodeStack.push( parentNode );
|
||||
parentNode = parentNode.lastChildElement();
|
||||
parentNode.appendChild( item );
|
||||
level++;
|
||||
} else {
|
||||
for ( int i = level; i > newLevel; i-- ) {
|
||||
level--;
|
||||
parentNode = parentNodeStack.pop();
|
||||
}
|
||||
|
||||
parentNode.appendChild( item );
|
||||
}
|
||||
mHeaderInfos.append( headerInfo );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -425,6 +413,52 @@ bool Converter::convertFrame( const QDomElement &element )
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Converter::createTableOfContents()
|
||||
{
|
||||
const QSizeF pageSize = mTextDocument->pageSize();
|
||||
|
||||
for ( int i = 0; i < mHeaderInfos.count(); ++i ) {
|
||||
const HeaderInfo headerInfo = mHeaderInfos[ i ];
|
||||
|
||||
const QRectF rect = mTextDocument->documentLayout()->blockBoundingRect( headerInfo.block );
|
||||
|
||||
int page = qRound( rect.y() ) / qRound( pageSize.height() );
|
||||
int offset = qRound( rect.y() ) % qRound( pageSize.height() );
|
||||
|
||||
DocumentViewport viewport( page );
|
||||
viewport.rePos.normalizedX = (double)rect.x() / (double)pageSize.width();
|
||||
viewport.rePos.normalizedY = (double)offset / (double)pageSize.height();
|
||||
viewport.rePos.enabled = true;
|
||||
viewport.rePos.pos = DocumentViewport::Center;
|
||||
|
||||
QStack<QDomNode> parentNodeStack;
|
||||
QDomNode parentNode = mTableOfContents;
|
||||
int level = 2;
|
||||
|
||||
QDomElement item = mTableOfContents.createElement( headerInfo.text );
|
||||
item.setAttribute( "Viewport", viewport.toString() );
|
||||
|
||||
int newLevel = headerInfo.level;
|
||||
if ( newLevel == level ) {
|
||||
parentNode.appendChild( item );
|
||||
} else if ( newLevel > level ) {
|
||||
parentNodeStack.push( parentNode );
|
||||
parentNode = parentNode.lastChildElement();
|
||||
parentNode.appendChild( item );
|
||||
level++;
|
||||
} else {
|
||||
for ( int i = level; i > newLevel; i-- ) {
|
||||
level--;
|
||||
parentNode = parentNodeStack.pop();
|
||||
}
|
||||
|
||||
parentNode.appendChild( item );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QTextDocument *Converter::textDocument() const
|
||||
{
|
||||
return mTextDocument;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define OOO_CONVERTER_H
|
||||
|
||||
#include <QtCore/QStack>
|
||||
#include <QtGui/QTextBlock>
|
||||
#include <QtGui/QTextCharFormat>
|
||||
#include <QtXml/QXmlDefaultHandler>
|
||||
|
||||
|
@ -61,6 +62,8 @@ class Converter
|
|||
bool convertFrame( const QDomElement &element );
|
||||
|
||||
private:
|
||||
bool createTableOfContents();
|
||||
|
||||
const Document *mDocument;
|
||||
QTextDocument *mTextDocument;
|
||||
QTextCursor *mCursor;
|
||||
|
@ -68,6 +71,15 @@ class Converter
|
|||
|
||||
StyleInformation *mStyleInformation;
|
||||
DocumentSynopsis mTableOfContents;
|
||||
|
||||
struct HeaderInfo
|
||||
{
|
||||
QTextBlock block;
|
||||
QString text;
|
||||
int level;
|
||||
};
|
||||
|
||||
QList<HeaderInfo> mHeaderInfos;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include <QtGui/QTextDocument>
|
||||
#include <QtGui/QAbstractTextDocumentLayout>
|
||||
|
||||
#include <QTime>
|
||||
|
||||
#include <qpainter.h>
|
||||
#include <qpixmap.h>
|
||||
#include <qimage.h>
|
||||
|
@ -45,11 +43,8 @@ bool KOOOGenerator::loadDocument( const QString & fileName, QVector<KPDFPage*> &
|
|||
|
||||
OOO::Converter converter( &document );
|
||||
|
||||
QTime time;
|
||||
time.start();
|
||||
if ( !converter.convert() )
|
||||
return false;
|
||||
qDebug( "creation time elapsed: %d", time.elapsed() );
|
||||
|
||||
mDocument = converter.textDocument();
|
||||
mDocumentSynopsis = converter.tableOfContents();
|
||||
|
|
Loading…
Reference in a new issue