Commit d0b5207b authored by Pino Toscano's avatar Pino Toscano
Browse files

Extract the table of contents from DVI documents.

svn path=/trunk/playground/graphics/okular/; revision=556622
parent a3247812
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <QX11Info> #include <QX11Info>
#include <qstring.h> #include <qstring.h>
#include <qurl.h> #include <qurl.h>
#include <qstack.h>
#include <kdebug.h> #include <kdebug.h>
#include <kimageeffect.h> #include <kimageeffect.h>
...@@ -27,7 +28,7 @@ ...@@ -27,7 +28,7 @@
OKULAR_EXPORT_PLUGIN(DviGenerator) OKULAR_EXPORT_PLUGIN(DviGenerator)
DviGenerator::DviGenerator( KPDFDocument * doc ) : Generator ( doc ), DviGenerator::DviGenerator( KPDFDocument * doc ) : Generator ( doc ),
m_docInfo( 0 ), m_dviRenderer( 0 ) m_docInfo( 0 ), m_docSynopsis( 0 ), ready( false ), m_dviRenderer( 0 )
{ {
} }
...@@ -38,6 +39,8 @@ bool DviGenerator::loadDocument( const QString & fileName, QVector< KPDFPage * > ...@@ -38,6 +39,8 @@ bool DviGenerator::loadDocument( const QString & fileName, QVector< KPDFPage * >
delete m_docInfo; delete m_docInfo;
m_docInfo = 0; m_docInfo = 0;
delete m_docSynopsis;
m_docSynopsis = 0;
delete m_dviRenderer; delete m_dviRenderer;
...@@ -125,6 +128,32 @@ static QRect rotateQRect( QRect source, int pageWidth, int pageHeight, int orien ...@@ -125,6 +128,32 @@ static QRect rotateQRect( QRect source, int pageWidth, int pageHeight, int orien
return tr; return tr;
} }
void DviGenerator::fillViewportFromAnchor( DocumentViewport &vp,
const Anchor &anch, int pW, int pH,
int orientation )
{
vp.pageNumber = anch.page - 1;
double vp_x = 0.0, vp_y = 0.0;
SimplePageSize ps = m_dviRenderer->sizeOfPage( vp.pageNumber );
double resolution = 0;
if ( orientation % 2 == 0 )
resolution = (double)(pW)/ps.width().getLength_in_inch();
else
resolution = (double)(pH)/ps.height().getLength_in_inch();
double py = (double)anch.distance_from_top.getLength_in_inch()*resolution + 0.5;
rotateCoordinates( 0.5, py / (double)pH,
vp_x, vp_y, orientation );
vp.rePos.normalizedX = vp_x;
vp.rePos.normalizedY = vp_y;
vp.rePos.enabled = true;
vp.rePos.pos = DocumentViewport::TopLeft;
}
QLinkedList<ObjectRect*> DviGenerator::generateDviLinks( const dviPageInfo *pageInfo, QLinkedList<ObjectRect*> DviGenerator::generateDviLinks( const dviPageInfo *pageInfo,
int orientation ) int orientation )
...@@ -145,31 +174,17 @@ QLinkedList<ObjectRect*> DviGenerator::generateDviLinks( const dviPageInfo *page ...@@ -145,31 +174,17 @@ QLinkedList<ObjectRect*> DviGenerator::generateDviLinks( const dviPageInfo *page
nr = (double)boxArea.right() / pageWidth, nr = (double)boxArea.right() / pageWidth,
nb = (double)boxArea.bottom() / pageHeight; nb = (double)boxArea.bottom() / pageHeight;
/* distinguish between local (-> anchor) and remote links */
Anchor anch = m_dviRenderer->findAnchor(dviLink.linkText); Anchor anch = m_dviRenderer->findAnchor(dviLink.linkText);
KPDFLink *okuLink = 0; KPDFLink *okuLink = 0;
if (anch.isValid()) /* distinguish between local (-> anchor) and remote links */
if (anch.isValid())
{ {
/* TODO: internal link */ /* internal link */
DocumentViewport vp; DocumentViewport vp;
vp.pageNumber = anch.page - 1; fillViewportFromAnchor( vp, anch, pageWidth, pageHeight,
orientation );
double vp_x = 0.0, vp_y = 0.0;
SimplePageSize ps = m_dviRenderer->sizeOfPage( vp.pageNumber );
double resolution = (double)(pageInfo->width)/ps.width().getLength_in_inch();
double py = (double)anch.distance_from_top.getLength_in_inch()*resolution + 0.5;
rotateCoordinates( 0.5, py / (double)pageHeight,
vp_x, vp_y, orientation );
vp.rePos.normalizedX = vp_x;
vp.rePos.normalizedY = vp_y;
vp.rePos.enabled = true;
vp.rePos.pos = DocumentViewport::Center;
okuLink = new KPDFLinkGoto( "", vp ); okuLink = new KPDFLinkGoto( "", vp );
} }
else else
...@@ -295,7 +310,7 @@ KPDFTextPage *DviGenerator::extractTextFromPage( dviPageInfo *pageInfo, int orie ...@@ -295,7 +310,7 @@ KPDFTextPage *DviGenerator::extractTextFromPage( dviPageInfo *pageInfo, int orie
for ( ; it != itEnd ; ++it ) for ( ; it != itEnd ; ++it )
{ {
TextBox curTB = *it; TextBox curTB = *it;
//tmpRect = curTB.box;
tmpRect = rotateQRect( curTB.box, pageWidth, pageHeight, orientation ); tmpRect = rotateQRect( curTB.box, pageWidth, pageHeight, orientation );
#if 0 #if 0
...@@ -337,6 +352,51 @@ const DocumentInfo *DviGenerator::generateDocumentInfo() ...@@ -337,6 +352,51 @@ const DocumentInfo *DviGenerator::generateDocumentInfo()
return m_docInfo; return m_docInfo;
} }
const DocumentSynopsis *DviGenerator::generateDocumentSynopsis()
{
if ( m_docSynopsis )
return m_docSynopsis;
m_docSynopsis = new DocumentSynopsis();
QStack<QDomElement*> stack;
Q3ValueVector<PreBookmark> prebookmarks = m_dviRenderer->getPrebookmarks();
if ( prebookmarks.isEmpty() )
return m_docSynopsis;
Q3ValueVector<PreBookmark>::ConstIterator it = prebookmarks.begin();
Q3ValueVector<PreBookmark>::ConstIterator itEnd = prebookmarks.end();
for( ; it != itEnd; ++it )
{
QDomElement *domel = new QDomElement;
*domel= m_docSynopsis->createElement( (*it).title );
Anchor a = m_dviRenderer->findAnchor((*it).anchorName);
if ( a.isValid() )
{
DocumentViewport vp;
const KPDFPage *p = m_document->page( a.page - 1 );
/* Don't care about rotations... */
fillViewportFromAnchor( vp, a, (int)p->width(), (int)p->height(), 0 );
domel->setAttribute( "Viewport", vp.toString() );
}
if ( stack.isEmpty() )
m_docSynopsis->appendChild( *domel );
else
{
stack.top()->appendChild( *domel );
stack.pop();
}
for ( int i = 0; i < (*it).noOfChildren; ++i )
stack.push( domel );
}
return m_docSynopsis;
}
void DviGenerator::setOrientation(QVector<KPDFPage*> & pagesVector, int orientation) void DviGenerator::setOrientation(QVector<KPDFPage*> & pagesVector, int orientation)
{ {
loadPages( pagesVector, orientation ); loadPages( pagesVector, orientation );
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
class dviRenderer; class dviRenderer;
class dviPageInfo; class dviPageInfo;
class DocumentViewport;
class Anchor;
class DviGenerator : public Generator class DviGenerator : public Generator
{ {
...@@ -29,7 +31,10 @@ class DviGenerator : public Generator ...@@ -29,7 +31,10 @@ class DviGenerator : public Generator
void generateSyncTextPage( KPDFPage * page ); void generateSyncTextPage( KPDFPage * page );
// document information // document information
const DocumentInfo * generateDocumentInfo(); const DocumentInfo *generateDocumentInfo();
// table of contents
const DocumentSynopsis *generateDocumentSynopsis();
// rotation // rotation
bool supportsRotation() { return true; }; bool supportsRotation() { return true; };
...@@ -42,11 +47,15 @@ class DviGenerator : public Generator ...@@ -42,11 +47,15 @@ class DviGenerator : public Generator
double m_resolution; double m_resolution;
DocumentInfo *m_docInfo; DocumentInfo *m_docInfo;
dviRenderer *m_dviRenderer; DocumentSynopsis *m_docSynopsis;
bool ready; bool ready;
dviRenderer *m_dviRenderer;
void loadPages( QVector< KPDFPage * > & pagesVector, int orientation ); void loadPages( QVector< KPDFPage * > & pagesVector, int orientation );
KPDFTextPage *extractTextFromPage( dviPageInfo *pageInfo, int orientation ); KPDFTextPage *extractTextFromPage( dviPageInfo *pageInfo, int orientation );
void fillViewportFromAnchor( DocumentViewport &vp, const Anchor &anch,
int pW, int pH, int orientation );
QLinkedList<ObjectRect*> generateDviLinks( const dviPageInfo *pageInfo, QLinkedList<ObjectRect*> generateDviLinks( const dviPageInfo *pageInfo,
int orientation ); int orientation );
}; };
......
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